Bit-ordering in the Qiskit SDK
If you have a set of bits (or qubits), you'll usually label each bit . Different softwares and resources must choose how they order these bits both in computer memory and when displayed on-screen.
Qiskit conventions
Here's how the Qiskit SDK orders bits in different scenarios.
Quantum circuits
The QuantumCircuit
class stores its qubits in a list
(QuantumCircuit.qubits
). The index of a qubit in this list defines the
qubit's label.
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.qubits[0] # qubit "0"
Qubit(QuantumRegister(2, 'q'), 0)
Circuit diagrams
On a circuit diagram, qubit is the topmost qubit, and qubit the
bottommost qubit. You can change this with the reverse_bits
argument of
QuantumCircuit.draw
(see Change ordering in
Qiskit).
qc.x(1)
qc.draw()
q_0: ─────
┌───┐
q_1: ┤ X ├
└───┘
Integers
When interpreting bits as a number, bit is the least significant bit, and
bit the most significant. This is helpful when coding because each bit has
the value (label being the qubit's index in
QuantumCircuit.qubits
). For example, the following circuit execution ends
with bit being 0
, and bit being 1
. This is interpreted as the
decimal integer 2
(measured with probability 1.0
).
from qiskit.primitives import SamplerV2 as Sampler
qc.measure_all()
job = sampler.run([qc])
result = job.result()
print(f" > Counts: {result[0].data.meas.get_counts()}")
{2: 1.0}
Strings
When displaying or interpreting a list of bits (or qubits) as a string, bit is the leftmost bit, and bit is the rightmost bit. This is because we usually write numbers with the most significant digit on the left, and in Qiskit, bit is interpreted as the most significant bit.
For example, the following cell defines a Statevector
from a string of
single-qubit states. In this case, qubit is in state , and
qubit in state .
from qiskit.quantum_info import Statevector
sv = Statevector.from_label("0+")
sv.probabilities_dict()
{'00': 0.4999999999999999, '01': 0.4999999999999999}
This occasionally causes confusion when interpreting a string of bits, as you might expect the leftmost bit to be bit , whereas it usually represents bit .
Statevector matrices
When representing a statevector as a list of complex numbers (amplitudes), Qiskit orders these amplitudes such that the amplitude at index represents the computational basis state .
print(sv[1]) # amplitude of state |01>
print(sv[2]) # amplitude of state |10>
(0.7071067811865475+0j)
0j
Gates
Each gate in Qiskit can interpret a list of qubits in its own way, but
controlled gates usually follow the convention (control, target)
.
For example, the following cell adds a controlled-X gate where qubit is the control and qubit is the target.
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.cx(0, 1)
qc.draw()
q_0: ──■──
┌─┴─┐
q_1: ┤ X ├
└───┘
Following all the previously mentioned conventions in Qiskit, this CX-gate performs the transformation , so has the following matrix.
Change ordering in Qiskit
To draw a circuit with qubits in reversed order (that is, qubit at the
bottom), use the reverse_bits
argument. This only affects the generated
diagram and does not affect the circuit; the X-gate still acts on qubit .
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.x(0)
qc.draw(reverse_bits=True)
q_1: ─────
┌───┐
q_0: ┤ X ├
└───┘
You can use the reverse_bits
method to return a new circuit with the
qubits' labels reversed (this does not mutate the original circuit).
qc.reverse_bits().draw()
q_0: ─────
┌───┐
q_1: ┤ X ├
└───┘
Note that in this new circuit, the X-gate acts on qubit .
Next steps
- See an example of using circuits in the Grover's Algorithm tutorial.
- Explore the QuantumCircuit API reference.