question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[BUG] Tensor Product of observables depends on order of operators and ignores wires information

See original GitHub issue

It seems that the tensor product operator @ only depends on the order of the operators and not on their wire information. Not sure if this is intentional, but seems to be counterintuitive.

Expected behaviour

(qml.PauliZ(1)@qml.Identity(0)).matrix == (qml.PauliZ(0)@qml.Identity(1)).matrix is false

Or both return statements of the following circuit should return the same value

dev = qml.device('default.qubit.jax', wires=n_qubits//2)
np.random.seed(1)

@qml.qnode(dev, interface='jax', diff_method="backprop")
def qnode(params):
    for i in range(n_qubits//2):
        qml.RX(jnp.pi*np.random.rand(), wires=i)
    return qml.expval(qml.PauliZ(wires = 1)@qml.Identity(wires = 0))
    return qml.expval(qml.Identity(wires=0)@qml.PauliZ(wires=1))

Actual Behaviour:

(qml.PauliZ(1)@qml.Identity(0)).matrix == (qml.PauliZ(0)@qml.Identity(1)).matrix is true but (qml.Identity(0)@qml.PauliZ(1)).matrix == (qml.PauliZ(1)@qml.Identity(0)).matrix is false

And the circuit from above returns different values for the two different return statements.

System information

Name: PennyLane
Version: 0.21.0
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/XanaduAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: /Users/patrickhumbeli/anaconda3/envs/JAX/lib/python3.10/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, retworkx, scipy, semantic-version, toml
Required-by: PennyLane-Lightning
Platform info:           macOS-12.1-x86_64-i386-64bit
Python version:          3.10.2
Numpy version:           1.21.5
Scipy version:           1.8.0
Installed devices:
- lightning.qubit (PennyLane-Lightning-0.21.0)
- default.gaussian (PennyLane-0.21.0)
- default.mixed (PennyLane-0.21.0)
- default.qubit (PennyLane-0.21.0)
- default.qubit.autograd (PennyLane-0.21.0)
- default.qubit.jax (PennyLane-0.21.0)
- default.qubit.tf (PennyLane-0.21.0)
- default.qubit.torch (PennyLane-0.21.0)

Existing GitHub issues

  • I have searched existing GitHub issues to make sure the issue does not already exist.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
josh146commented, Mar 4, 2022

I think if we remove the sort in the eigenvalues then we will be taking the convention in which the wire labels are ignored. While this makes sense in the case where custom wire labels are used, it is less intuitive than using the sorted order as the wires provided are ignored. I think in the majority of cases, taking the sorted convention makes more sense/.

@Jaybsoni something to keep in mind is that we shouldn’t treat integer wires differently from other wire labels, as this introduces more inconsistency!

Say we consider the case

op1 = qml.PauliZ(1) @ qml.Identity(0)
op2 = qml.PauliZ(0) @ qml.Identity(1)
op3 = qml.PauliZ("a") @ qml.Identity(7)

Since we have no context as to what the canonical wire ordering is, I would argue that it doesn’t make sense to attempt to order the eigenvalues by default! Instead, by default, we should expect all three of the above to return eigenvalues in the same order:

>>> np.kron([1, -1], [1, 1])
array([ 1,  1, -1, -1])

However, this is not the case, since Tensor.eigvals is doing an implicit sort by default:

>>>> qml.eigvals(op3)
array([ 1, -1,  1, -1])
>>> qml.eigvals(op2)
array([ 1,  1, -1, -1])
>>> qml.eigvals(op1)
array([ 1, -1,  1, -1])

It is making an assumption that may have no basis.

Instead, we should do the following here:

  • If no canonical wire order is known, qml.eigvals() should make no assumptions, and simply use the ordering of the tensor product observables.

  • If a canonical wire ordering is known, we should be able to pass it to qml.eigvals() to take into account.

This is identical to how qml.matrix() behaves, and we should bring qml.eigvals() inline with this behaviour:

>>> np.all(qml.matrix(op1) == qml.matrix(op2))
True
>>> np.all(qml.matrix(op1) == qml.matrix(op3))
True
>>> np.all(qml.matrix(op1, wire_order=[0, 1]) == qml.matrix(op2, wire_order=[0, 1]))
False
1reaction
josh146commented, Mar 3, 2022

Regarding point (2), I think the issue might be these lines here, inside the PennyLane QubitDevice class:

https://github.com/PennyLaneAI/pennylane/blob/b494a2bf1b68156a9688178e1d97dc348ebf1583/pennylane/_qubit_device.py#L782-L783

Here, the eigenvalue order is being computed by sorting the wires:

>>> op1 = qml.PauliZ(1) @ qml.Identity(0)
>>> qml.eigvals(op1)
array([ 1, -1,  1, -1])
>>> np.kron([1, 1], [1, -1])
array([ 1, -1,  1, -1])
>>> op2 = qml.Identity(0) @ qml.PauliZ(1)
>>> qml.eigvals(op2)
array([ 1, -1,  1, -1])

So the eigenvalues of op1 and op2 are both being computed by assuming wire 0 < wire 1.

The problem is that the probability computation is not doing this; it is preserving the order of the observables in the tensor product, as it is being called with op.wires:

>>> op1.wires
<Wires = [1, 0]>
>>> op2.wires
<Wires = [0, 1]>

So there is a mismatch between how a tensor product observable computes its matrix, and how it reports its wires. The question then becomes: which is correct? As long as we ensure both have the same convention, this will be fixed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Tensor product in Pennylane · Issue #715 - GitHub
Hello, I'm confused by the output of qml.operation.Tensor. It doesn't seem like a usual tensor product that I would expect.
Read more >
Source code for pennylane.operation
Operators act on a sequence of wires (subsystems) using given parameter values. ... multiplication operation between a scalar and an Observable/Tensor.
Read more >
Lecture Notes for Ph219/CS219: Quantum Information Chapter 3
(3.32) is said to be an operator-sum representation of the quantum channel, and the operators {Ma} are called the Kraus operators or operation...
Read more >
Interacting quantum observables - IOPscience
While quantum information and computation (QIC) has proposed new ... framework where composing systems (cf the tensor product '⊗' in the ...
Read more >
Lectures on Quantum Tensor Networks - arXiv
Transposition of 1st-order vectors and dual-vectors, and 2nd-order linear operators is repre- sented by a bending of a tensors wires as ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found