Qiskit / qiskit

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
https://www.ibm.com/quantum/qiskit
Apache License 2.0
5.09k stars 2.34k forks source link

Incorrect relative phase added for controlled Pauli-X from quantum_info.operators #5235

Closed oneTimePad closed 3 years ago

oneTimePad commented 3 years ago

Information

What is the current behavior?

Most of the info and explanation is described in this post : https://quantumcomputing.stackexchange.com/questions/14147/odd-behavior-with-qiskit-pauli-operators

To summarize the issue, when adding a control qubit to a qiskit.quantum_info.operators.Pauli object, at least I tested for Pauli-X, that is wrapped in qiskit.quantum_info.operators.Operator, there is an incorrect relative phase introduced between the control system and the target system. This issue might be present for other Pauli operators as well.

Steps to reproduce the problem

As mentioned in the post on 'Quantum Computing Stackexchange', the user (tsgeorgios) answering my question posted a quick and easy way to verify what I found:

from qiskit.quantum_info import Operator, Pauli

gate = QuantumCircuit(1)
gate.append(Operator(Pauli(label='X')), [0])
gate = gate.control() 

print(Operator(gate).data)

----
Output:

[[ 1   0   0   0]
 [ 0   0   0  1j]
 [ 0   0   1   0]
 [ 0  1j   0   0]]

What is the expected behavior?

The relative phase introduced should not be there.

Suggested solutions

No suggestions.

g-ebbs commented 3 years ago

Are you currently working on a solution? I'd like to take a look at this issue if that's alright.

oneTimePad commented 3 years ago

@g-ebbs Yes please do! No I am not currently working on anything.

Cryoris commented 3 years ago

Hm, the issue comes likely from the the workflow:

  1. The Pauli gate is converted to a matrix when put into Operator
  2. If the Operator is appended a generic synthesis algorithm is used that implements the operation up to a global phase
  3. Upon controlling, the global phase becomes a relativ phase

If the operator would be synthesized w/o global phase that error would likely be resolved. However, the algorithms for exact synthesis are more expensive afaik. You could argue that adding a matrix to a circuit is inefficient either way and it might as well be exact.

georgios-ts commented 3 years ago

@Cryoris In this case, the synthesis algorithm tracks the global phase

pauli = Operator(Pauli(label='X'))
gate = UnitaryGate(pauli)

print(gate.definition)
Operator(gate.definition)
---
global phase: -π/2
     ┌────────────────┐
q_0: ┤ U3(π,π/2,-π/2) ├
     └────────────────┘
array([[0.-0.j, 1.+0.j],
       [1.+0.j, 0.-0.j]])

but control() fails to do so.