# Test equivalence of circuits exactly on qiskit

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.

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

• 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. Commented Sep 12, 2020 at 23:21
• 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) Commented Sep 13, 2020 at 0:41
• 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. Commented Sep 13, 2020 at 1:40
• 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. Commented Sep 13, 2020 at 6:10
• 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. Commented Sep 13, 2020 at 6:26

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.

• simple and straight to the point! good answer. Commented May 11, 2022 at 20:42
• Does this answer ignore the overall phase? Commented Dec 9, 2023 at 20:19