The Quantum Circuit
MPQP is focused on gate-based quantum computing. As such, the main element of
a script using MPQP is the quantum circuit, or QCircuit. The
QCircuit contains the data for all gates, measurements, and noise models you
want to apply to your qubits.
The qubits are only referred to by their indices, so one could keep track of specific registers using Python features, for instance
>>> circ = QCircuit(6)
>>> targets = range(3)
>>> ancillas = range(3,6)
>>> for i in range(3):
... circ.add(CNOT(targets[i], ancillas[i]))
>>> print(circ)
q_0: ──■────────────
│
q_1: ──┼────■───────
│ │
q_2: ──┼────┼────■──
┌─┴─┐ │ │
q_3: ┤ X ├──┼────┼──
└───┘┌─┴─┐ │
q_4: ─────┤ X ├──┼──
└───┘┌─┴─┐
q_5: ──────────┤ X ├
└───┘
could be used to add CNOT gates to your circuit, using the two registers
targets and ancillas.
- class QCircuit(data=None, *, nb_qubits=None, nb_cbits=None, label=None)[source]
Bases:
objectThis class models a quantum circuit.
A circuit is composed of instructions and noise models applied to quantum and/or classical bits. These elements (instructions and noise models) will be called
componentshereafter.- Parameters:
data (Optional[int | Sequence[Instruction | NoiseModel]]) – Number of qubits or list of
componentsto initialize the circuit with. If the number of qubits is passed, it should be a positive integer.nb_qubits (Optional[int]) – Optional number of qubits, in case you input the sequence of instructions and want to hardcode the number of qubits.
nb_cbits (Optional[int]) – Number of classical bits. It should be positive.
label (Optional[str]) – Name of the circuit.
- Raises:
ValueError – If a negative number of qubits is passed to the circuit.
Examples
>>> circuit = QCircuit(2) >>> circuit.pretty_print() QCircuit : Size (Qubits, Cbits) = (2, 0), Nb instructions = 0 q_0: q_1:
>>> circuit = QCircuit([Rx(1.23, 2)], nb_qubits=4, nb_cbits=2, label="Circuit 1") >>> circuit.pretty_print() QCircuit Circuit 1: Size (Qubits, Cbits) = (4, 2), Nb instructions = 1 q_0: ──────────── q_1: ──────────── ┌──────────┐ q_2: ┤ Rx(1.23) ├ └──────────┘ q_3: ──────────── c: 2/════════════
>>> circuit = QCircuit(3, label="NoiseExample") >>> circuit.add([H(0), T(1), CNOT(0,1), S(2)]) >>> circuit.add(BasisMeasure(shots=2345)) >>> circuit.add(Depolarizing(prob=0.50, targets=[0, 1])) >>> circuit.pretty_print() QCircuit NoiseExample: Size (Qubits, Cbits) = (3, 3), Nb instructions = 5 Depolarizing noise: on qubits [0, 1] with probability 0.5 ┌───┐ ┌─┐ q_0: ┤ H ├──■──┤M├─── ├───┤┌─┴─┐└╥┘┌─┐ q_1: ┤ T ├┤ X ├─╫─┤M├ ├───┤└┬─┬┘ ║ └╥┘ q_2: ┤ S ├─┤M├──╫──╫─ └───┘ └╥┘ ║ ║ c: 3/═══════╩═══╩══╩═ 2 0 1
- classmethod from_other_language(qcircuit)[source]
Transforms a quantum circuit from an external representation (Qiskit, Cirq, Braket, MyQLM, QASM2 or QASM3) into the corresponding internal
QCircuitformat.- Parameters:
qcircuit (QuantumCircuit | cirq_Circuit | braket_Circuit | myQLM_Circuit | str) – The input quantum circuit which can be one of the following types: -
QuantumCircuit: A Qiskit QuantumCircuit object. -cirq_Circuit: A Cirq Circuit object. -braket_Circuit: A Braket Circuit object. -myQLM_Circuit: A MyQLM Circuit object. -str: A string representing an OpenQASM 2.0 or OpenQASM3 circuit.- Returns:
The mpqp
QCircuitcorresponding to the external circuit in parameter.- Raises:
NotImplementedError – If the input circuit is from an other provider or a string but not in OpenQASM 2.0 or 3.0 format.
- Return type:
Examples
>>> from qiskit.circuit import QuantumCircuit >>> qiskit_circuit = QuantumCircuit(2) >>> _ = qiskit_circuit.h(0) >>> _ = qiskit_circuit.cx(0, 1) >>> qcircuit1 = QCircuit.from_other_language(qiskit_circuit) >>> print(qcircuit1) ┌───┐ q_0: ┤ H ├──■── └───┘┌─┴─┐ q_1: ─────┤ X ├ └───┘
>>> import cirq >>> q0, q1 = cirq.LineQubit.range(2) >>> cirq_circuit = cirq.Circuit() >>> cirq_circuit.append(cirq.H(q0)) >>> cirq_circuit.append(cirq.CNOT(q0, q1)) >>> qcircuit2 = QCircuit.from_other_language(cirq_circuit) >>> print(qcircuit2) ┌───┐ q_0: ┤ H ├──■── └───┘┌─┴─┐ q_1: ─────┤ X ├ └───┘
>>> from braket.circuits import Circuit >>> braket_circuit = Circuit().h(0).cnot(0, 1) >>> qcircuit3 = QCircuit.from_other_language(braket_circuit) >>> print(qcircuit3) ┌───┐ q_0: ┤ H ├──■── └───┘┌─┴─┐ q_1: ─────┤ X ├ └───┘ c: 2/══════════
>>> from qat.lang.AQASM import Program, H, CNOT >>> prog = Program() >>> qbits = prog.qalloc(2) >>> _ = H(qbits[0]) >>> _ = CNOT(qbits[0], qbits[1]) >>> myqlm_circuit = prog.to_circ() >>> qcircuit4 = QCircuit.from_other_language(myqlm_circuit) >>> print(qcircuit4) ┌───┐ q_0: ┤ H ├──■── └───┘┌─┴─┐ q_1: ─────┤ X ├ └───┘
>>> qasm2_code = ''' ... OPENQASM 2.0; ... qreg q[2]; ... h q[0]; ... cx q[0], q[1]; ... ''' >>> qcircuit5 = QCircuit.from_other_language(qasm2_code) >>> print(qcircuit5) ┌───┐ q_0: ┤ H ├──■── └───┘┌─┴─┐ q_1: ─────┤ X ├ └───┘ >>> qasm3_code = ''' ... OPENQASM 3.0; ... qubit[2] q; ... h q[0]; ... cx q[0], q[1]; ... ''' >>> qcircuit6 = QCircuit.from_other_language(qasm3_code) >>> print(qcircuit6) ┌───┐ q_0: ┤ H ├──■── └───┘┌─┴─┐ q_1: ─────┤ X ├ └───┘
- classmethod initializer(state)[source]
Initialize this circuit at a given state, given in parameter. This will imply adding gates at the beginning of the circuit.
- Parameters:
state (npt.NDArray[np.complex128]) – StateVector modeling the state for initializing the circuit.
- Returns:
A copy of the input circuit with additional instructions added before-hand to generate the right initial state.
- Return type:
Examples
>>> qc = QCircuit.initializer(np.array([1, 0, 0 ,1])/np.sqrt(2)) >>> print(qc) ┌────────────┐ q_0: ──┤ U(π/2,0,0) ├────■────────────────────────── ┌─┴────────────┴─┐┌─┴─┐┌──────────────────────┐ q_1: ┤ U(0,-π/4,-π/4) ├┤ X ├┤ U(0,-6.8934,0.61023) ├ └────────────────┘└───┘└──────────────────────┘ >>> pprint(run(qc, IBMDevice.AER_SIMULATOR_STATEVECTOR).amplitudes) [0.70711, 0, 0, 0.70711]
- add(components)[source]
Adds a
componentor a list ofcomponentat the end of the circuit.- Parameters:
components (TypeAliasForwardRef('Instruction') | TypeAliasForwardRef('NoiseModel') | Sequence[TypeAliasForwardRef('Instruction') | TypeAliasForwardRef('NoiseModel')]) – Instruction(s) or noise model(s) to append to the circuit.
Examples
>>> circuit = QCircuit(2) >>> circuit.add(X(0)) >>> circuit.add([CNOT(0, 1), BasisMeasure(shots=100)]) >>> circuit.pretty_print() QCircuit : Size (Qubits, Cbits) = (2, 2), Nb instructions = 3 ┌───┐ ┌─┐ q_0: ┤ X ├──■──┤M├─── └───┘┌─┴─┐└╥┘┌─┐ q_1: ─────┤ X ├─╫─┤M├ └───┘ ║ └╥┘ c: 2/═══════════╩══╩═ 0 1
>>> circuit.add(Depolarizing(0.3, dimension=2, gates=[CNOT])) >>> circuit.add([Depolarizing(0.02, [0])]) >>> circuit.pretty_print() QCircuit : Size (Qubits, Cbits) = (2, 2), Nb instructions = 3 Depolarizing noise: for gate CNOT with probability 0.3 and dimension 2 Depolarizing noise: on qubit 0 with probability 0.02 ┌───┐ ┌─┐ q_0: ┤ X ├──■──┤M├─── └───┘┌─┴─┐└╥┘┌─┐ q_1: ─────┤ X ├─╫─┤M├ └───┘ ║ └╥┘ c: 2/═══════════╩══╩═ 0 1
- append(other, qubits_offset=0)[source]
Appends the circuit at the end (right side) of this circuit, inplace.
If the size of the
otheris smaller than this circuit, the parameterqubits_offsetcan be used to indicate at which qubit theothercircuit must be added.This method can be shorthanded with the
+=operator (while+performs the same operation without the inplace factor.)- Parameters:
other (QCircuit) – The circuit to append at the end of this circuit.
qubits_offset (int) – If the circuit in parameter is smaller, this parameter determines at which qubit (vertically) the circuit will be added.
- Raises:
NumberQubitsError – If the circuit in parameter is larger than this circuit or if the
qubits_offsetis too big, such that theothercircuit would “stick out”.- Return type:
None
Examples
>>> c1 = QCircuit([CNOT(0,1),CNOT(1,2)]) >>> c2 = QCircuit([X(1),CNOT(1,2)]) >>> c1.append(c2) >>> print(c1) q_0: ──■───────────────── ┌─┴─┐ ┌───┐ q_1: ┤ X ├──■──┤ X ├──■── └───┘┌─┴─┐└───┘┌─┴─┐ q_2: ─────┤ X ├─────┤ X ├ └───┘ └───┘
>>> c1 = QCircuit([CNOT(0,1),CNOT(1,2)]) >>> c2 = QCircuit([X(1),CNOT(1,2)]) >>> c1 += c2 >>> print(c1) q_0: ──■───────────────── ┌─┴─┐ ┌───┐ q_1: ┤ X ├──■──┤ X ├──■── └───┘┌─┴─┐└───┘┌─┴─┐ q_2: ─────┤ X ├─────┤ X ├ └───┘ └───┘
>>> c1 = QCircuit([CNOT(0,1),CNOT(1,2)]) >>> c2 = QCircuit([X(1),CNOT(1,2)]) >>> print(c1 + c2) q_0: ──■───────────────── ┌─┴─┐ ┌───┐ q_1: ┤ X ├──■──┤ X ├──■── └───┘┌─┴─┐└───┘┌─┴─┐ q_2: ─────┤ X ├─────┤ X ├ └───┘ └───┘
- count_gates(gate=None)[source]
Returns the number of gates contained in the circuit. If a specific gate is given in the
gatearg, it returns the number of occurrences of this gate.- Parameters:
gate (Type[TypeAliasForwardRef('Gate')] | None) – The gate whose occurrence we want to determine in this circuit.
- Returns:
The number of gates (of a specific type) contained in the circuit.
- Return type:
int
Examples
>>> circuit = QCircuit( ... [X(0), Y(1), Z(2), CNOT(0, 1), SWAP(0, 1), CZ(1, 2), X(2), X(1), X(0)] ... ) >>> circuit.count_gates() 9 >>> circuit.count_gates(X) 4 >>> circuit.count_gates(Ry) 0
- depth()[source]
Computes the depth of the circuit.
- Returns:
Depth of the circuit.
- Return type:
int
Examples
>>> QCircuit([CNOT(0, 1), CNOT(1, 2), CNOT(0, 1), X(2)]).depth() 3 >>> QCircuit([CNOT(0, 1), CNOT(1, 2), CNOT(0, 1), Barrier(), X(2)]).depth() 4
- display(output='mpl', warn=True)[source]
Displays the circuit in the desired output format.
For now, this uses the qiskit circuit drawer, so all formats supported by qiskit are supported.
- Parameters:
output (str) – Format of the output, see docs.quantum.ibm.com/build/circuit-visualization for more information.
warn (bool) – Enable/Disable warnings for matplotlib figure. If \(True\) and we are not running headless (i.e. on Linux with an unset DISPLAY), issue warning when called on a non-GUI backend.
Examples
>>> theta = symbols("θ") >>> circ = QCircuit([P(theta, 0)]) >>> circ.display("text") ┌──────┐ q: ┤ P(θ) ├ └──────┘ >>> print(circ.display("latex_source")) \documentclass[border=2px]{standalone} \usepackage[braket, qm]{qcircuit} \usepackage{graphicx} \begin{document} \scalebox{1.0}{ \Qcircuit @C=1.0em @R=0.2em @!R { \\ \nghost{{q} : } & \lstick{{q} : } & \gate{\mathrm{P}\,(\mathrm{{\ensuremath{\theta}}})} & \qw & \qw\\ \\ }} \end{document}
- inverse()[source]
Generate the inverse (dagger) of this circuit.
- Returns:
The inverse circuit.
- Return type:
Examples
>>> c1 = QCircuit([T(0), CZ(0,1), H(1), Ry(4.56, 1)]) >>> print(c1) ┌───┐ q_0: ┤ T ├─■────────────────── └───┘ │ ┌───┐┌──────────┐ q_1: ──────■─┤ H ├┤ Ry(4.56) ├ └───┘└──────────┘ >>> print(c1.inverse()) ┌────┐ q_0: ───────────────────■─┤ T† ├ ┌───────────┐┌───┐ │ └────┘ q_1: ┤ Ry(-4.56) ├┤ H ├─■─────── └───────────┘└───┘ >>> c2 = QCircuit([T(0), CRk(2, 0, 1), Barrier(), H(1), Ry(4.56, 1)]) >>> print(c2) ┌───┐ ░ q_0: ┤ T ├─■────────░────────────────── └───┘ │P(π/2) ░ ┌───┐┌──────────┐ q_1: ──────■────────░─┤ H ├┤ Ry(4.56) ├ ░ └───┘└──────────┘ >>> print(c2.inverse()) ░ ┌────┐ q_0: ───────────────────░──■────────┤ T† ├ ┌───────────┐┌───┐ ░ │P(-π/2) └────┘ q_1: ┤ Ry(-4.56) ├┤ H ├─░──■────────────── └───────────┘└───┘ ░
- pretty_print()[source]
Provides a pretty print of the QCircuit.
Examples
>>> c = QCircuit([H(0), CNOT(0,1)]) >>> c.pretty_print() QCircuit : Size (Qubits, Cbits) = (2, 0), Nb instructions = 2 ┌───┐ q_0: ┤ H ├──■── └───┘┌─┴─┐ q_1: ─────┤ X ├ └───┘
- size()[source]
Provides the size of the circuit, in terms of the number of quantum and classical bits.
- Returns:
A couple
(q, c)of integers, withqthe number of qubits, andcthe number of cbits of this circuit.- Return type:
tuple[int, int]
Examples
>>> c1 = QCircuit([CNOT(0,1),CNOT(1,2)]) >>> c1.size() (3, 0) >>> c2 = QCircuit(3,nb_cbits=2) >>> c2.size() (3, 2) >>> c3 = QCircuit([CNOT(0,1),CNOT(1,2), BasisMeasure(shots=200)]) >>> c3.size() (3, 3)
- subs(values)[source]
Substitute the parameters of the circuit with values for each of the specified parameters. Optionally also remove all symbolic variables such as \(\pi\) (needed for example for circuit execution).
Since we use
sympyfor the gate parameters, thevaluescan in fact be anything thesubsmethod fromsympywould accept.- Parameters:
values (dict[Expr | str, Complex]) – Mapping between the variables and the replacing values.
- Returns:
The circuit with the replaced parameters.
- Return type:
Examples
>>> theta, k = symbols("θ k") >>> c = QCircuit( ... [Rx(theta, 0), CNOT(1,0), CNOT(1,2), X(2), Rk(2,1), H(0), CRk(k, 0, 1), ... BasisMeasure(shots=1000)] ... ) >>> print(c) ┌───────┐┌───┐┌───┐ ┌─┐ q_0: ┤ Rx(θ) ├┤ X ├┤ H ├───────────■─────────────────┤M├─── └───────┘└─┬─┘└───┘┌────────┐ │P(2**(1 - k)*pi) └╥┘┌─┐ q_1: ───────────■────■──┤ P(π/2) ├─■──────────────────╫─┤M├ ┌─┴─┐└─┬───┬──┘ ┌─┐ ║ └╥┘ q_2: ──────────────┤ X ├──┤ X ├───────────┤M├─────────╫──╫─ └───┘ └───┘ └╥┘ ║ ║ c: 3/══════════════════════════════════════╩══════════╩══╩═ 2 0 1 >>> print(c.subs({theta: np.pi, k: 1})) ┌───────┐┌───┐┌───┐ ┌─┐ q_0: ┤ Rx(π) ├┤ X ├┤ H ├───────────■─────┤M├─── └───────┘└─┬─┘└───┘┌────────┐ │P(π) └╥┘┌─┐ q_1: ───────────■────■──┤ P(π/2) ├─■──────╫─┤M├ ┌─┴─┐└─┬───┬──┘ ┌─┐ ║ └╥┘ q_2: ──────────────┤ X ├──┤ X ├─────┤M├───╫──╫─ └───┘ └───┘ └╥┘ ║ ║ c: 3/════════════════════════════════╩════╩══╩═ 2 0 1
- tensor(other)[source]
Computes the tensor product of this circuit with that in parameter.
In the circuit notation, the upper part of the output circuit will correspond to the first circuit, while the bottom part corresponds to that in parameter.
This method can be shorthanded with the
@operator.- Parameters:
other (QCircuit) – QCircuit being the second operand of the tensor product with this circuit.
other – QCircuit being the second operand of the tensor product with this circuit.
- Returns:
The QCircuit resulting from the tensor product of this circuit with that in parameter.
- Returns:
The QCircuit resulting from the tensor product of this circuit with that in parameter.
- Return type:
Examples
>>> c1 = QCircuit([CNOT(0,1),CNOT(1,2)]) >>> c2 = QCircuit([X(1),CNOT(1,2)]) >>> print(c1.tensor(c2)) q_0: ──■─────── ┌─┴─┐ q_1: ┤ X ├──■── └───┘┌─┴─┐ q_2: ─────┤ X ├ └───┘ q_3: ────────── ┌───┐ q_4: ┤ X ├──■── └───┘┌─┴─┐ q_5: ─────┤ X ├ └───┘
>>> c1 = QCircuit([CNOT(0,1),CNOT(1,2)]) >>> c2 = QCircuit([X(1),CNOT(1,2)]) >>> print(c1 @ c2) q_0: ──■─────── ┌─┴─┐ q_1: ┤ X ├──■── └───┘┌─┴─┐ q_2: ─────┤ X ├ └───┘ q_3: ────────── ┌───┐ q_4: ┤ X ├──■── └───┘┌─┴─┐ q_5: ─────┤ X ├ └───┘
- to_dict()[source]
Serialize the quantum circuit to a dictionary. :returns: A dictionary representation of the circuit. :rtype: dict
- Return type:
dict[str, int | str | list[str] | float | None]
- to_gate()[source]
Generate a gate from this entire circuit.
- Returns:
A gate representing this circuit.
- Return type:
Examples
>>> c = QCircuit([CNOT(0, 1), CNOT(1, 2), CNOT(0, 1), CNOT(2, 3)]) >>> pprint(c.to_gate().definition.matrix) [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]]
- to_matrix()[source]
Compute the unitary matrix associated to this circuit.
- Returns:
a unitary matrix representing this circuit
- Return type:
npt.NDArray[np.complex128]
Examples
>>> c = QCircuit([H(0), CNOT(0,1)]) >>> pprint(c.to_matrix()) [[0.70711, 0 , 0.70711 , 0 ], [0 , 0.70711, 0 , 0.70711 ], [0 , 0.70711, 0 , -0.70711], [0.70711, 0 , -0.70711, 0 ]]
- to_other_device(device: ATOSDevice, skip_pre_measure: bool = False) myQLM_Circuit[source]
- to_other_device(device: AWSDevice, skip_pre_measure: bool = False) braket_Circuit
- to_other_device(device: GOOGLEDevice, skip_pre_measure: bool = False) cirq_Circuit
- to_other_device(device: IBMDevice | StaticIBMSimulatedDevice, skip_pre_measure: bool = False, backend_sim: 'AerSimulator' | None = None) QuantumCircuit
Transforms this circuit into the corresponding device specified in the
devicearg.Some measurements require some adaptation between the user defined circuit and the measure. For instance if the targets are not given in a contiguous ordered list or if the basis measurement is in a basis other than the computational basis. We automatically add this adaptation as an intermediate circuit called
pre_measure.- Parameters:
device (AvailableDevice) – representing the target device.
skip_pre_measure (bool) – If true, the
pre_measurecircuit will not be added to the output.backend_sim (Optional['AerSimulator']) – Simulator backend for Qiskit devices.
- Returns:
The corresponding circuit in the target device.
- Return type:
QuantumCircuit | myQLM_Circuit | braket_Circuit | cirq_Circuit
Examples
>>> circuit = QCircuit([H(0), BasisMeasure()]) >>> qc = circuit.to_other_device(IBMDevice.AER_SIMULATOR) >>> type(qc) <class 'qiskit.circuit.quantumcircuit.QuantumCircuit'> >>> print(qc) ┌───┐┌─┐ q: ┤ H ├┤M├ └───┘└╥┘ c: 1/══════╩═ 0 >>> print(circuit.to_other_device(IBMDevice.IBM_BRISBANE)) global phase: π/4 ┌─────────┐┌────┐┌─────────┐┌─┐ q_0 -> 0 ┤ Rz(π/2) ├┤ √X ├┤ Rz(π/2) ├┤M├ └─────────┘└────┘└─────────┘└╥┘ ancilla_0 -> 1 ─────────────────────────────╫─ ... ║ ancilla_125 -> 126 ─────────────────────────────╫─ ║ c: 1/═════════════════════════════╩═ 0
Note
Most providers take noise into account at the job level. A notable exception is Braket, where the noise is contained in the circuit object. For this reason, you will find the noise included in the Braket circuits.
- to_other_language(language: Literal[Language.QASM2, Language.QASM3], skip_pre_measure: bool = False, skip_measurements: bool = False, printing: bool = False) str[source]
- to_other_language(language: Literal[Language.CIRQ], skip_pre_measure: bool = False, skip_measurements: bool = False, printing: bool = False) cirq_Circuit
- to_other_language(language: Literal[Language.BRAKET], skip_pre_measure: bool = False, skip_measurements: bool = False, printing: bool = False) braket_Circuit
- to_other_language(language: Literal[Language.MY_QLM], skip_pre_measure: bool = False, skip_measurements: bool = False, printing: bool = False) myQLM_Circuit
- to_other_language(language: Literal[Language.QISKIT], skip_pre_measure: bool = False, skip_measurements: bool = False, printing: bool = False) QuantumCircuit
- to_other_language(language: Language, skip_pre_measure: bool = False, skip_measurements: bool = False, printing: bool = False) QuantumCircuit | myQLM_Circuit | braket_Circuit | cirq_Circuit | str
Transforms this circuit into the corresponding circuit in the language specified in the
languagearg.Some measurements require some adaptation between the user defined circuit and the measure. For instance if the targets are not given in a contiguous ordered list or if the basis measurement is in a basis other than the computational basis. We automatically add this adaptation as an intermediate circuit called
pre_measure.By default, the circuit is translated to the corresponding
QuantumCircuitin Qiskit since this is the interface we use to generate the OpenQASM code.In the future, we will generate the OpenQASM code on our own, and this method will be used only for complex objects that are not tractable with OpenQASM (like hybrid structures).
- Parameters:
language (Language) – Enum representing the target language.
skip_pre_measure (bool) – If true, the
pre_measurewill not be added to the output.skip_measurements (bool) – If true, the
measurementswill not be added to the output.printing (bool) – If
Truedummy gates will replace custom gates (because qiskit’sOperatorscannot haveParametersin their definition.)
- Returns:
The corresponding circuit in the target language.
- Return type:
QuantumCircuit | myQLM_Circuit | braket_Circuit | cirq_Circuit | str
Examples
>>> circuit = QCircuit([X(0), CNOT(0, 1)]) >>> qc = circuit.to_other_language() >>> type(qc) <class 'qiskit.circuit.quantumcircuit.QuantumCircuit'> >>> circuit2 = QCircuit([H(0), CZ(0,1), Depolarizing(0.6, [0]), BasisMeasure()]) >>> print(circuit2.to_other_language(Language.BRAKET)) T : │ 0 │ 1 │ ┌───┐ ┌───────────┐ ┌───────────┐ q0 : ─┤ H ├─┤ DEPO(0.6) ├───●───┤ DEPO(0.6) ├─ └───┘ └───────────┘ │ └───────────┘ ┌─┴─┐ q1 : ─────────────────────┤ Z ├─────────────── └───┘ T : │ 0 │ 1 │ >>> print(circuit2.to_other_language(Language.QASM2)) OPENQASM 2.0; include "qelib1.inc"; qreg q[2]; creg c[2]; h q[0]; cz q[0],q[1]; measure q[0] -> c[0]; measure q[1] -> c[1]; >>> print(circuit2.to_other_language(Language.QASM3)) OPENQASM 3.0; include "stdgates.inc"; qubit[2] q; bit[2] c; h q[0]; cz q[0],q[1]; c[0] = measure q[0]; c[1] = measure q[1];
Note
Most providers take noise into account at the job level. A notable exception is Braket, where the noise is contained in the circuit object. For this reason, you will find the noise included in the Braket circuits.
- variables()[source]
Returns all the symbolic parameters involved in this circuit.
- Returns:
All the parameters of the circuit.
- Return type:
set[Basic]
Example
>>> circ = QCircuit([ ... Rx(theta, 0), CNOT(1,0), CNOT(1,2), X(2), Rk(2,1), ... H(0), CRk(k, 0, 1), ExpectationMeasure(obs, [1]) ... ]) >>> circ.variables() {θ, k}
- without_measurements(deep_copy=True)[source]
Provides a shallow copy of this circuit with all the measurements removed.
- Parameters:
deep_copy (bool) – If True, performs a deep copy of attribute values; otherwise, performs a shallow copy.
- Returns:
A QCircuit with all the measurements removed.
- Return type:
Example
>>> circuit = QCircuit([X(0), CNOT(0, 1), BasisMeasure(shots=100)]) >>> print(circuit) ┌───┐ ┌─┐ q_0: ┤ X ├──■──┤M├─── └───┘┌─┴─┐└╥┘┌─┐ q_1: ─────┤ X ├─╫─┤M├ └───┘ ║ └╥┘ c: 2/═══════════╩══╩═ 0 1 >>> print(circuit.without_measurements()) ┌───┐ q_0: ┤ X ├──■── └───┘┌─┴─┐ q_1: ─────┤ X ├ └───┘
- without_noises(deep_copy=True)[source]
Provides a shallow copy of this circuit with all the noise models removed.
- Parameters:
deep_copy (bool) – If True, performs a deep copy of attribute values; otherwise, performs a shallow copy.
- Returns:
A QCircuit with all the noise models removed.
- Return type:
Example
>>> circuit = QCircuit(2) >>> circuit.add([CNOT(0, 1), Depolarizing(prob=0.4, targets=[0, 1]), BasisMeasure(shots=100)]) >>> print(circuit) ┌─┐ q_0: ──■──┤M├─── ┌─┴─┐└╥┘┌─┐ q_1: ┤ X ├─╫─┤M├ └───┘ ║ └╥┘ c: 2/══════╩══╩═ 0 1 NoiseModel: Depolarizing(0.4, [0, 1]) >>> print(circuit.without_noises()) ┌─┐ q_0: ──■──┤M├─── ┌─┴─┐└╥┘┌─┐ q_1: ┤ X ├─╫─┤M├ └───┘ ║ └╥┘ c: 2/══════╩══╩═ 0 1
- property breakpoints: list[TypeAliasForwardRef('Breakpoint')]
Returns the breakpoints of the circuit in order.
- property gates: list[TypeAliasForwardRef('Gate')]
Returns a list of all gates in the circuit, ordered by their index.
- Returns:
Ordered list of gates in the circuit.
- input_g_phase: float
Stores the global phase (angle) arising from the Qiskit conversion of
CustomGatesto OpenQASM2. It is used to correct the global phase when the job type is \(STATE_VECTOR\), and when this circuit containsCustomGates.
- instructions: list[Instruction]
List of instructions with positions in the circuit.
- label
See parameter description.
- property measurements: list[TypeAliasForwardRef('Measure')]
Returns a list of all measurements in the circuit, ordered by their index.
- Returns:
Ordered list of measurements in the circuit.
- property nb_cbits: int
Number of cbits of the circuit.
- property nb_qubits: int
Number of qubits of the circuit.
- noises: list[NoiseModel]
List of noise models attached to the circuit.
- transpiled_circuit: braket_Circuit | cirq_Circuit | myQLM_Circuit | QuantumCircuit | None
A pre-transpiled circuit to skip repeated transpilation when running the circuit. Useful when working with a symbolic circuit that needs to be executed with different parameters.
- transpiled_noise_model
A pre-transpiled noise model that skips repeated transpilation when running the circuit. Currently, it is only useful in Qiskit when working with a symbolic circuit that needs to be executed with different parameters.