Pennylane, qml.matrix(), bug?


Happy New Year 2023!

I was trying to use qml.matrix() and found that there seems to be a bug! See the two screen captures below.

The two CNOT should have different matrix outputs but it was not the case as shown in the first figure.

Then, test0_mat() and test1_mat() should have the same output but it was not the case as shown in the first figure.

Then, test2_mat() and test3_mat() should have the same output but it was not the case as shown in the 2nd figure.

Not sure whether I use it in the wrong way. Version information is given below. Thanks!

import numpy as np
from pennylane.optimize import AdamOptimizer
from pennylane import numpy as qml_np
import pennylane as qml

Name: PennyLane
Version: 0.28.0
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: GitHub - PennyLaneAI/pennylane: PennyLane is a cross-platform Python library for differentiable programming of quantum computers. Train a quantum computer the same way as a neural network.
License: Apache License 2.0
Location: c:\users\user\anaconda3\envs\py310penl028\lib\site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, retworkx, scipy, semantic-version, toml
Required-by: PennyLane-Lightning

Platform info: Windows-10-10.0.19045-SP0
Python version: 3.10.8
Numpy version: 1.23.5
Scipy version: 1.9.3
Installed devices:

  • default.gaussian (PennyLane-0.28.0)
  • default.mixed (PennyLane-0.28.0)
  • default.qubit (PennyLane-0.28.0)
  • default.qubit.autograd (PennyLane-0.28.0)
  • default.qubit.jax (PennyLane-0.28.0)
  • (PennyLane-0.28.0)
  • default.qubit.torch (PennyLane-0.28.0)
  • default.qutrit (PennyLane-0.28.0)
  • null.qubit (PennyLane-0.28.0)
  • lightning.qubit (PennyLane-Lightning-0.28.0)

Hi @Jim, thank you very much for reporting this bug! We will look into it.

Hi @Jim,

This is in the fine print of how PennyLane orders the wires. In fact there’s a useful example in the Usage details of the documentation for qml.matrix. Basically if the first operation is on wire ‘1’ then that will become the first wire, instead of wire ‘0’. For example:

For CNOT(wires=(1,0)), the wire order for the operator is (1,0). So it returns the matrix corresponding to a wire order of (1,0). Same for the examples with the PauliX operators. If the first operator is on zero, then wire order will be (0,1). If the first operator is on one, the wire order will be (1,0) .

You can set the wire order by using the wire_order argument. So in your case you would have something like qml.matrix(quantum_circuit ,wire_order=[0, 1]).

Alternatively, you can convert these circuits into qnodes by defining a device, adding the @qml.qnode(dev) decorator and returning a measurement (eg. return qml.state()). Once they’re a qnode you won’t have the wire-ordering changing anymore.

Please let me know if this helps!