5
$\begingroup$

I have two circuits that I believe are equivalent. When I say 'equivalent' I mean that they have equivalent unitary representations up to a global phase. How can one check this using Qiskit? How I would show equivalence isn't clear to me.

$\endgroup$

2 Answers 2

2
$\begingroup$

As it is point out, depends on your notion of equivalence.

State vectors

Two circuits are equivalent upto global phase if they represent the same state vector. Consider the following two circuits:

from qiskit import QuantumCircuit
import numpy as np

qc1 = QuantumCircuit(2)
qc1.h(0)
qc1.cx(0,1)

qc2 = QuantumCircuit(2)
qc2.u2(0, np.pi, 0)
qc2.cx(0,1)

It is possible to check if their state vector is the same with the Qiskit qiskit.quantum_info module:

from qiskit.quantum_info import Statevector
Statevector.from_instruction(qc1).equiv(Statevector.from_instruction(qc2)) # True

Unitary matrices

If you need to consider global phase, in that case you need to compare their unitary matrices via simulation.

In the following case:

qc1 = QuantumCircuit(1)
qc1.x(0)

qc2 = QuantumCircuit(1)
qc2.rx(np.pi, 0)

These circuit has the same state vector, but not the same unitary:

Statevector.from_instruction(qc1).equiv(Statevector.from_instruction(qc2))  # True

backend_sim = Aer.get_backend('unitary_simulator')
job_sim = execute([qc1, qc2], backend_sim)
result_sim = job_sim.result()
unitary1 = result_sim.get_unitary(qc1)
unitary2 = result_sim.get_unitary(qc2)

np.allclose(unitary1, unitary2)  # False

Counts

If your circuits have measurements, you probably want to consider these to circuits equivalent, since their measured results are equivalent.

qc1 = QuantumCircuit(2,2)
qc1.h(0)
qc1.measure(0,0)
qc1.measure(1,1)

qc2 = QuantumCircuit(2,2)
qc2.h(0)
qc2.swap(0,1)
qc2.measure(0,1)
qc2.measure(1,0)

In this case, you want to compare their result counts, considering some statistical error:

backend_sim = Aer.get_backend('qasm_simulator')
job_sim = execute([qc1, qc2], backend_sim, shots=1000)
result_sim = job_sim.result()
counts1 = result_sim.get_counts(qc1)
counts2 = result_sim.get_counts(qc2)
print(counts1, counts2)

Up to Ancillas

You might want to consider these two circuits equivalent:

qc1 = QuantumCircuit(3)
qc1.x(0)

qc2 = QuantumCircuit(1)
qc2.rx(np.pi, 0)

It was suggested to invert one of them, compose them (wiring the ancillas) and check if it is the identity. For example:

from qiskit.quantum_info import Operator

composed = qc1.compose(qc2.inverse(), qubits=range(len(qc2.qubits)))
Operator(composed).equiv(Operator.from_label('I'*len(qc1.qubits))) # True
$\endgroup$
7
  • 1
    $\begingroup$ Actually the statevector is not enough. You need to show the unitaries corresponding to the circuits are the same. This check must take into account That there could be a global phase difference that may or may not matter depending on if you are later going to control the circuit. if the circuits are the same up to swap mapping then you need to check for equivalence up to a one sided permutation. If the qubit orderings are different than there is also a row and column permutation to deal with. In the case above one can simply use the definition of unitary to verify equiv up to phase. $\endgroup$ Sep 12, 2020 at 23:21
  • $\begingroup$ Generally, the statevector is not the same because there is a global phase. For example, I tried using a circuit with only 1 qubit. Let the circuit be obtained through circ.x(0) and circ.rx(numpy.pi, 0) and this solution fails due to numerical error (there is a $10^{-17}$ somewhere and a phase error) $\endgroup$ Sep 13, 2020 at 0:41
  • $\begingroup$ I updated the answer with unitary matrices and one example considering swap. @JasonFring, if you want to add tolerance for floating point errors when checking for equivalence, equiv allows you to set relative (rtol) and absolute (atol) tolerance values for comparison. $\endgroup$
    – luciano
    Sep 13, 2020 at 1:40
  • 1
    $\begingroup$ A couple of comments: 1) You may want to compute the unitary of the first circuit concatenated with the inverse of the second circuit, and check if it's the identity. Simiarly can also be done for the state vector. 2) There is a notion of equivalent circuits with a different number of qubits (for example because of ancilla qubits), which may make this somewhat more complex. $\endgroup$ Sep 13, 2020 at 6:10
  • 1
    $\begingroup$ Also note that there's a difference between comparing the unitary and comparing the single outcome on the |0> state - the former verifies the circuits produce the same outcome for every input, not just |0>, which is similar to our usual notions of "equivalance"; but if you only want output on |0> unitary is overkill in terms of runtime and you can deduce the phase difference from two nonzero entries in the statevectors. $\endgroup$
    – Gadi A
    Sep 13, 2020 at 6:26
2
$\begingroup$

A simpler method is to use equiv method directly from the Operator class. Basically convert both the circuits to operators and then use equiv. You can check out the documentation for the Operator class here.

The basic syntax would be something like,

from qiskit import *
from qiskit.quantum_info import Operator

Op1 = Operator(qc1)
Op2 = Operator(qc2)

Op1.equiv(Op2)

Where qc1 and qc2 are your two quantum circuits.

$\endgroup$
1
  • $\begingroup$ simple and straight to the point! good answer. $\endgroup$ May 11, 2022 at 20:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.