# From `qml.Hamiltonian` to numpy representation

Hi,

I have a question regarding the `qml.Hamiltonian` function. Given that I have a Hamiltonian written as a `qml.Hamiltonian`, can I see it’s matrix representation as a `np.array`? The point of this is because I want to use a circuit that does the following:

``````def circuit(params):
# performs some operations
return qml.expval(qml.Hermitian(array), wires = [...])
``````

I know that a possibility is to use `qml.ExpvalCost()` instead of doing this. However, I want to use JAX here so that instead of working with `circuit` I work with `vcircuit = jax.vmap(circuit)` so I can run the same circuit for multiple parameters simultaneously.

Also, the point of this is because I know how to write my Hamiltonian efficiently in terms of the parameters needed for `qml.Hamiltonian` (it’s basically a sum of local terms so I can use `qml.PauliX` operations together with the Y and Z).

On the other hand, in the `qml.Hamiltonian` documentation I see that it is possible to go from `qml.Hermitian` to `qml.Hamiltonian`, so I wonder whether it is possible to do it the other way around, i.e., given that I have a `qml.Hamiltonian`, could I generate the corresponding `qml.Hermitian`?

Thank you very much for your attention.

Cheers,
Javier.

Hi Javier,

Thanks for the question! The `qml.Hamilonian` class does not currently have a `matrix` attribute however the `qml.Operation` class does which returns a numpy (nd)array as you’re looking for. Since a Hamiltonian is built up of operators and coefficients we can find work around e.g

``````import pennylane as qml

coeffs = [0.2, -0.543]
ops = [qml.PauliX(0) @ qml.PauliZ(1), qml.PauliZ(0) @ qml.Hadamard(2)]
H = qml.Hamiltonian(coeffs, ops)

matrix = 0
for coeff, op in zip(H.coeffs, H.ops):
matrix += coeff * op.matrix

``````

where the variable `matrix` gives the array

`````` array([[-0.38395898, -0.38395898,  0.2       ,  0.        ],
[-0.38395898,  0.38395898,  0.        , -0.2       ],
[ 0.2       ,  0.        ,  0.38395898,  0.38395898],
[ 0.        , -0.2       ,  0.38395898, -0.38395898]])
``````

Let us know if you have any more questions!

2 Likes

I’m a bit late to the party, but wanted to point out that in addition to @anthayes92 excellent answer above, we also have a utility in PennyLane to convert Hamiltonian’s to sparse matrices:

``````>>> coeffs = [0.2, -0.543]
>>> ops = [
...   qml.PauliX(0) @ qml.PauliZ(1),
... ]
>>> H = qml.Hamiltonian(coeffs, ops)
>>> Hmat = qml.utils.sparse_hamiltonian(H).real
>>> Hmat
<4x4 sparse matrix of type '<class 'numpy.float64'>'
with 12 stored elements in COOrdinate format>
``````

You can directly manipulate this sparse matrix using `scipy.sparse`, or you can convert it to a NumPy array:

``````>>> Hmat.toarray()
array([[-0.38395898, -0.38395898,  0.2       ,  0.        ],
[-0.38395898,  0.38395898,  0.        , -0.2       ],
[ 0.2       ,  0.        ,  0.38395898,  0.38395898],
[ 0.        , -0.2       ,  0.38395898, -0.38395898]])
``````
2 Likes

Hi,

thank you very much for your answers! They are both super useful and exactly what I was looking for!

Cheers,
Javier.

No worries, glad they helped @Javier!

Hi,
I think this doesn’t really work - if you chance the wires for the Paulis in the ops, the final Hamiltonian in numpy representation does not change! It seems like the whole method doesn’t care about what wires the gates are acting on, which means the final numpy representation is almost always wrong!

Hi @eigentejas, welcome to the Forum!

Please notice that this thread was from about 1.5 years ago and PennyLane has evolved a lot since then! Would you like to describe the problem you’re having? I might be able to help you. Please if possible also post:

• Your code so that I can try to replicate your issue