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),
...   qml.PauliZ(0) @ qml.Hadamard(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!