pennylane
pennylane copied to clipboard
[BUG] `qml.matrix` for a `qml.Hamiltonian` produces a NumPy array for non-NumPy coefficients
Expected behavior
qml.matrix
should respect the framework-specific tensors used to construct the qml.Hamiltonian
, and return the matrix representation of that Hamiltonian in the same framework. For example, executing the following code should yield a TensorFlow tensor:
>>> h = qml.Hamiltonian([tf.Variable(0.3)], [qml.PauliX(0)])
>>> qml.matrix(h)
Actual behavior
The code above instead produces a NumPy array:
>>> h = qml.Hamiltonian([tf.Variable(0.3)], [qml.PauliX(0)])
>>> qml.matrix(h)
array([[0. +0.j, 0.30000001+0.j],
[0.30000001+0.j, 0. +0.j]])
Additional information
The matrix representation of the Hamiltonian is computed in qml.utils.sparse_hamiltonian
, which uses a SciPy sparse matrix data structure and thus converts the framework-specific tensors into NumPy arrays.
Source code
No response
Tracebacks
No response
System information
Name: PennyLane
Version: 0.25.0.dev0
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/XanaduAI/pennylane
Author: None
Author-email: None
License: Apache License 2.0
Location: c:\users\edward.jiang\documents\pennylane
Requires: numpy, scipy, networkx, retworkx, autograd, toml, appdirs, semantic-version, autoray, cachetools, pennylane
-lightning
Required-by: PennyLane-qiskit, PennyLane-Lightning
Platform info: Windows-10-10.0.19042-SP0
Python version: 3.8.10
Numpy version: 1.20.3
Scipy version: 1.7.3
Installed devices:
- default.gaussian (PennyLane-0.25.0.dev0)
- default.mixed (PennyLane-0.25.0.dev0)
- default.qubit (PennyLane-0.25.0.dev0)
- default.qubit.autograd (PennyLane-0.25.0.dev0)
- default.qubit.jax (PennyLane-0.25.0.dev0)
- default.qubit.tf (PennyLane-0.25.0.dev0)
- default.qubit.torch (PennyLane-0.25.0.dev0)
- qiskit.aer (PennyLane-qiskit-0.24.0)
- qiskit.basicaer (PennyLane-qiskit-0.24.0)
- qiskit.ibmq (PennyLane-qiskit-0.24.0)
- qiskit.ibmq.circuit_runner (PennyLane-qiskit-0.24.0)
- qiskit.ibmq.sampler (PennyLane-qiskit-0.24.0)
- lightning.qubit (PennyLane-Lightning-0.25.0)
Existing GitHub issues
- [X] I have searched existing GitHub issues to make sure the issue does not already exist.
I believe this will be fixed with the new operator arithmetic:
>>> s_prod = qml.s_prod(tf.Variable(0.3), qml.PauliX(0))
>>> qml.matrix(s_prod)
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[0. , 0.3],
[0.3, 0. ]], dtype=float32)>
However I just realised that we still need to support the dunder methods for all interfaces.
That's great! Is the above code also differentiable in the expected way? If so, then it's definitely something I can replace in my code to get the behaviour I want.
That's great! Is the above code also differentiable in the expected way? If so, then it's definitely something I can replace in my code to get the behaviour I want.
@albi3ro or @Jaybsoni might know better.
import tensorflow as tf
dev = qml.device("default.qubit", wires=5)
@qml.qnode(dev, interface="tensorflow", diff_method='backprop')
def circuit(s):
return qml.expval(qml.s_prod(s, qml.PauliZ(0)))
x = tf.Variable(2.0)
with tf.GradientTape() as tape:
res = circuit(x)
tape.gradient(res, [x])
Works absolutely fine.
Yes I think this is another issue with Hamiltonian
, it uses this sparse representation by default. This is a problem because the I don't think the logic is compatible with any other interface other then scipy sparse arrays!