hqs_qorrelator_app.experimental_nmr_helpers

Experimental NMR helpers to run on simulators and hardware.

Functions

correlators_to_spectrum(m_avg_x, m_avg_y, ...)

Calculate the full spectrum from the computed correlators, and the corresponding ppm array.

fft_causal(f)

Performs the Fourier Transform of a causal signal separating its odd and even part.

hamiltonian_to_trotter_circuits(hamiltonian)

Create Trotter circuit for a given struqture Hamiltonian.

run_trotter_circuits(circuits, phi[, backend])

Run Trotter circuits with estimator and return expectation values.

Classes

Any(*args, **kwargs)

Special type indicating an unconstrained type.

BackendEstimatorV2(*, backend[, options])

Evaluates expectation values for provided quantum circuit and observable combinations.

LieTrotter([reps, insert_barriers, ...])

The Lie-Trotter product formula.

ParameterVector(name[, length, uuid])

A container of many related Parameter objects.

PauliEvolutionGate(operator[, time, label, ...])

Time-evolution of an operator consisting of Paulis.

PauliHamiltonian()

These are representations of systems of spins.

PrimitiveJob(function, *args, **kwargs)

Handle to a job from the reference implementations of the primitives in Qiskit.

QuantumCircuit(*regs[, name, global_phase, ...])

Core Qiskit representation of a quantum circuit.

SparsePauliOp(data[, coeffs, ...])

Sparse N-qubit operator in a Pauli basis representation.

StatevectorEstimator(*[, default_precision, ...])

Simple implementation of BaseEstimatorV2 with full state vector simulation.

combinations(iterable, r)

Return successive r-length combinations of elements in the iterable.

class hqs_qorrelator_app.experimental_nmr_helpers.Any(*args, **kwargs)[source]

Special type indicating an unconstrained type.

  • Any is compatible with every type.

  • Any assumed to have all methods.

  • All values assumed to be instances of Any.

Note that all the above statements are true from the point of view of static type checkers. At runtime, Any should not be used with instance checks.

class hqs_qorrelator_app.experimental_nmr_helpers.BackendEstimatorV2(*, backend: BackendV2, options: dict | None = None)[source]

Evaluates expectation values for provided quantum circuit and observable combinations.

The BackendEstimatorV2 class is a generic implementation of the BaseEstimatorV2 interface that is used to wrap a BackendV2 object in the BaseEstimatorV2 API. It facilitates using backends that do not provide a native BaseEstimatorV2 implementation in places that work with BaseEstimatorV2. However, if you're using a provider that has a native implementation of BaseEstimatorV2, it is a better choice to leverage that native implementation as it will likely include additional optimizations and be a more efficient implementation. The generic nature of this class precludes doing any provider- or backend-specific optimizations.

This class does not perform any measurement or gate mitigation, and, presently, is only compatible with Pauli-based observables. More formally, given an observable of the type \(O=\sum_{i=1}^Na_iP_i\), where \(a_i\) is a complex number and \(P_i\) is a Pauli operator, the estimator calculates the expectation \(\mathbb{E}(P_i)\) of each \(P_i\) and finally calculates the expectation value of \(O\) as \(\mathbb{E}(O)=\sum_{i=1}^Na_i\mathbb{E}(P_i)\). The reported std is calculated as

\[\frac{\sum_{i=1}^{n}|a_i|\sqrt{\textrm{Var}\big(P_i\big)}}{\sqrt{N}}\:,\]

where \(\textrm{Var}(P_i)\) is the variance of \(P_i\), \(N=O(\epsilon^{-2})\) is the number of shots, and \(\epsilon\) is the target precision [1].

Each tuple of (circuit, observables, <optional> parameter values, <optional> precision), called an estimator primitive unified bloc (PUB), produces its own array-based result. The run() method can be given a sequence of pubs to run in one call.

The options for BackendEstimatorV2 consist of the following items.

  • default_precision: The default precision to use if none are specified in run(). Default: 0.015625 (1 / sqrt(4096)).

  • abelian_grouping: Whether the observables should be grouped into sets of qubit-wise commuting observables. Default: True.

  • seed_simulator: The seed to use in the simulator. If None, a random seed will be used. Default: None.

Reference:

[1] O. Crawford, B. van Straaten, D. Wang, T. Parks, E. Campbell, St. Brierley, Efficient quantum measurement of Pauli operators in the presence of finite sampling error. Quantum 5, 385

property backend: BackendV2

Returns the backend which this estimator object is based on.

property options: Options

Return the options

run(pubs: Iterable[EstimatorPub | tuple[QuantumCircuit, str | Pauli | SparsePauliOp | SparseObservable | Mapping[str | Pauli, float] | ArrayLike] | tuple[QuantumCircuit, str | Pauli | SparsePauliOp | SparseObservable | Mapping[str | Pauli, float] | ArrayLike, Mapping[Parameter | str | tuple[Parameter | str, ...], ArrayLike]] | tuple[QuantumCircuit, str | Pauli | SparsePauliOp | SparseObservable | Mapping[str | Pauli, float] | ArrayLike, Mapping[Parameter | str | tuple[Parameter | str, ...], ArrayLike], Real]], *, precision: float | None = None) → PrimitiveJob[PrimitiveResult[PubResult]][source]
class hqs_qorrelator_app.experimental_nmr_helpers.LieTrotter(reps: int = 1, insert_barriers: bool = False, cx_structure: str = 'chain', atomic_evolution: Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None] | None = None, wrap: bool = False, preserve_order: bool = True, *, atomic_evolution_sparse_observable: bool = False)[source]

The Lie-Trotter product formula.

The Lie-Trotter formula approximates the exponential of two non-commuting operators with products of their exponentials up to a second order error:

\[e^{A + B} \approx e^{A}e^{B}.\]

In this implementation, the operators are provided as sum terms of a Pauli operator. For example, we approximate

\[e^{-it(XI + ZZ)} = e^{-it XI}e^{-it ZZ} + \mathcal{O}(t^2).\]

References

[1]: D. Berry, G. Ahokas, R. Cleve and B. Sanders, "Efficient quantum algorithms for simulating sparse Hamiltonians" (2006). arXiv:quant-ph/0508139 [2]: N. Hatano and M. Suzuki, "Finding Exponential Product Formulas of Higher Orders" (2005). arXiv:math-ph/0506007

property settings: dict[str, Any]

Return the settings in a dictionary, which can be used to reconstruct the object.

Returns:

A dictionary containing the settings of this product formula.

Raises:

NotImplementedError -- If a custom atomic evolution is set, which cannot be serialized.

class hqs_qorrelator_app.experimental_nmr_helpers.ParameterVector(name, length=0, uuid=None)

A container of many related Parameter objects.

This class is faster to construct than constructing many Parameter objects individually, and the individual names of the parameters will all share a common stem (the name of the vector). For a vector called v with length 3, the individual elements will have names v[0], v[1] and v[2].

The elements of a vector are sorted by the name of the vector, then the numeric value of their index.

This class fulfills the collections.abc.Sequence interface.

index(val)

Find the index of a ParameterVectorElement within the sequence.

This is an inefficient way of accessing the index field on the given value, which you should use instead.

name

The base name of the vector.

params

A sequence of the contained ParameterVectorElement instances.

Mutations to this object are not tracked.

resize(length)

Change the length of this vector.

Any references to ParameterVectorElement instances with lengths greater than length are invalidated by calling this.

The UUIDs of ParameterVectorElement instances that are deleted or created by this method are stable; the UUIDs are always derived as index offsets from the vector's UUID.

uuid

Get the root UUID of this vector.

class hqs_qorrelator_app.experimental_nmr_helpers.PauliEvolutionGate(operator: qiskit.quantum_info.Pauli | SparsePauliOp | SparseObservable | list[qiskit.quantum_info.Pauli | SparsePauliOp | SparseObservable], time: ParameterValueType = 1.0, label: str | None = None, synthesis: EvolutionSynthesis | None = None)[source]

Time-evolution of an operator consisting of Paulis.

For an Hermitian operator \(H\) consisting of Pauli terms and (real) evolution time \(t\) this gate represents the unitary

\[U(t) = e^{-itH}.\]

The evolution gates are related to the Pauli rotation gates by a factor of 2. For example the time evolution of the Pauli \(X\) operator is connected to the Pauli \(X\) rotation \(R_X\) by

\[U(t) = e^{-itX} = R_X(2t).\]

Compilation:

This gate represents the exact evolution \(U(t)\). Implementing this operation exactly, however, generally requires an exponential number of gates. The compiler therefore typically implements an approximation of the unitary \(U(t)\), e.g. using a product formula such as defined by LieTrotter. By passing the synthesis argument, you can specify which method the compiler should use, see qiskit.synthesis for the available options.

Note that the order in which the approximation and methods like control() and power() are called matters. Changing the order can lead to different unitaries.

Commutation checks:

Qiskit supports efficient commutation checks of PauliEvolutionGate instances with other Pauli-based gates, such as PauliGate or PauliProductMeasurement. However, these checks require conversion of the operator into SparseObservable format, hence we strongly suggest to build operators using this operator class if a large number of commutation checks are expected (e.g. if you have a circuit with a large number of sequential PauliEvolutionGates).

Examples:

The above will print (note that the -0.1 coefficient is not printed!):

     ┌──────────────────────────┐
q_0: ┤0                         ├
     │  exp(-it (ZZ + XI))(0.2) │
q_1: ┤1                         ├
     └──────────────────────────┘

References:

[1] G. Li et al. Paulihedral: A Generalized Block-Wise Compiler Optimization Framework For Quantum Simulation Kernels (2021). arXiv:2109.03371

control(num_ctrl_qubits: int = 1, label: str | None = None, ctrl_state: int | str | None = None, annotated: bool | None = None) → Gate[source]

Return the controlled version of itself.

The outcome is the specified controlled version of \(e^{-itH}\). The returned gate represents \(e^{-it H_C}\), where \(H_C\) is the original operator \(H\), tensored with \(|0\rangle\langle 0|\) and \(|1\rangle\langle 1|\) projectors (depending on the control state).

The controlled gate is implemented as PauliEvolutionGate, regardless of the value of annotated.

Parameters:
  • num_ctrl_qubits -- Number of controls to add. Defaults to 1.

  • label -- A label for the resulting Pauli evolution gate, to display in visualizations. Per default, the label is set to exp(-it <operators>) where <operators> is the sum of the Paulis. Note that the label does not include any coefficients of the Paulis. See the class docstring for an example.

  • ctrl_state -- The control state of the gate, specified either as an integer or a bitstring (e.g. "110"). If None, defaults to the all-ones state 2**num_ctrl_qubits - 1.

  • annotated -- Ignored.

Returns:

A controlled version of this gate.

inverse(annotated: bool = False)[source]

Return the inverse, which is obtained by flipping the sign of the evolution time.

power(exponent: float, annotated: bool = False) → Gate[source]

Raise this gate to the power of exponent.

The outcome represents \(e^{-i tp H}\) where \(p\) equals exponent.

Parameters:
  • exponent -- The power to raise the gate to.

  • annotated -- Not applicable to this class. Usually, when this is True we return an AnnotatedOperation with a power modifier set instead of a concrete Gate. However, we can efficiently represent powers of Pauli evolutions as PauliEvolutionGate, which is used here.

Returns:

An operation implementing gate^exponent.

property time: ParameterExpression | float

Return the evolution time as stored in the gate parameters.

Returns:

The evolution time.

to_matrix() → ndarray[source]

Return the matrix \(e^{-it H}\) as numpy.ndarray.

Returns:

The matrix this gate represents.

Raises:

ValueError -- If the time parameters is not numeric.

validate_parameter(parameter: ParameterExpression | float) → ParameterExpression | float[source]

Gate parameters should be int, float, or ParameterExpression

class hqs_qorrelator_app.experimental_nmr_helpers.PauliHamiltonian

These are representations of systems of spins.

PauliHamiltonians are characterized by a PauliOperator to represent the hamiltonian of the spin system and an optional number of spins.

Returns:

The new PauliHamiltonian.

Return type:

self

Examples

import numpy.testing as npt
import scipy.sparse as sp
from qoqo_calculator_pyo3 import CalculatorComplex
from struqture_py.spins import PauliHamiltonian, PauliProduct

system = PauliHamiltonian()
pp = PauliProduct().z(0)
system.add_operator_product(pp, 5.0)
npt.assert_equal(system.current_number_spins(), 1)
npt.assert_equal(system.get(pp), CalculatorComplex(5))
npt.assert_equal(system.keys(), [pp])
dimension = 4**system.current_number_spins()
matrix = sp.coo_matrix(system.sparse_matrix_superoperator_coo(system.current_number_spins()), shape=(dimension, dimension))
add_operator_product(key, value)

Add a new (key object, value Union[CalculatorComplex, CalculatorFloat]) pair to existing entries.

Parameters:
  • key (Product type) -- The key object

  • value (Union[CalculatorComplex, CalculatorFloat]) -- The value to add.

Raises:
  • TypeError -- Value is not CalculatorComplex or CalculatorFloat.

  • ValueError -- Product could not be constructed.

  • ValueError -- Error in add_operator_product function of self.

current_number_spins()

Return the current_number_spins input of self.

Returns:

The number of spins in self.

Return type:

int

static current_version()

Returns the current version of the struqture library.

Returns:

The current version of the library.

Return type:

str

empty_clone(capacity=None)

Return an instance of self that has no entries but clones all other properties, with the given capacity.

Parameters:

capacity (Optional[int]) -- The capacity of the new instance to create.

Returns:

An empty clone with the same properties as self, with the given capacity.

Return type:

self

static from_bincode(input)

Convert the bincode representation of self to an instance using the [bincode] crate.

Parameters:

input (bytearray) -- The serialized object (in [bincode] form).

Returns:

The deserialized object.

Raises:
  • TypeError -- Input cannot be converted to byte array.

  • ValueError -- Input cannot be deserialized.

static from_json(input)

Convert the json representation of self to an instance.

Parameters:

input (str) -- The serialized object in json form.

Returns:

The deserialized object.

Raises:

ValueError -- Input cannot be deserialized.

static from_json_struqture_1(input)

Convert a json corresponding to a struqture 1 object to the equivalent object in struqture 2.

Parameters:

input (Any) -- the json of the struqture 1 object to convert.

Returns:

the input object in struqture 2 form.

Return type:

Any

Raises:
  • ValueError -- Input could not be deserialised form json.

  • ValueError -- Struqture 1 object could not be converted to struqture 2.

get(key)

Get the coefficient corresponding to the key.

Parameters:

key -- Product to get the value of.

Returns:

Value at key (or 0.0).

Return type:

CalculatorComplex

Raises:

ValueError -- Product could not be constructed from key.

hermitian_conjugate()

Return the hermitian conjugate of self.

Returns:

The hermitian conjugate of self.

Return type:

self

is_empty()

Return true if self contains no values.

Returns:

Whether self is empty or not.

Return type:

bool

jordan_wigner()

Transform the given spin object into a fermionic object using the Jordan Wigner mapping.

static json_schema()

Return the JsonSchema for the json serialisation of the class.

Returns:

The json schema serialized to json

Return type:

str

keys()

Return a list of the unsorted keys in self.

Returns:

The sequence of keys of the self.

Return type:

List[OperatorProduct]

min_supported_version()

Return the minimum version of struqture that supports this object.

Returns:

The minimum version of the struqture library to deserialize this object.

Return type:

str

number_spins()

Return maximum index in self.

Returns:

Maximum index.

Return type:

int

pprint()
remove(key)

Remove the value of the input key.

Parameters:

key -- The key of the value to remove.

Raises:

ValueError -- Product could not be constructed.

set(key, value)

Overwrite an existing entry or set a new entry in self.

Parameters:
  • key (Product type) -- The key to set.

  • value (Union[CalculatorComplex, CalculatorFloat]) -- The value to set.

Returns:

Key existed if this is not None, and this is the value it had before it was overwritten.

Return type:

Optional[Union[CalculatorComplex, CalculatorFloat]]

Raises:

ValueError -- Product could not be constructed.

sparse_matrix_coo(number_spins)

Constructs the sparse matrix representation of self as a scipy COO matrix with a given number of spins.

Parameters:

number_spins (int) -- The number of spins in self.

Returns:

The little endian matrix representation of self.

Return type:

Tuple[np.ndarray, Tuple[np.ndarray, np.ndarray]]

Raises:
  • ValueError -- CalculatorError.

  • RuntimeError -- Could not convert to complex superoperator matrix.

sparse_matrix_superoperator_coo(number_spins)

Construct the sparse matrix representation of the superoperator in COO representation.

The superoperator for the operator O is defined as the Matrix S so that flatten(-i [O, p]) = S flatten(p) wher [,] is the commutator, p is a matrix and flatten flattens a matrix into a vector in row-major form.

Parameters:

number_spins (int) -- The number of spins to construct the matrix for.

Returns:

The little endian matrix representation of self.

Return type:

Tuple[np.ndarray, Tuple[np.ndarray, np.ndarray]]

Raises:
  • ValueError -- CalculatorError.

  • RuntimeError -- Could not convert to complex superoperator matrix.

to_bincode()

Return the bincode representation of self using the [bincode] crate.

Returns:

The serialized object (in [bincode] form).

Return type:

bytearray

Raises:

ValueError -- Cannot serialize object to bytes.

to_json()

Return the json representation of self.

Returns:

The serialized form of self.

Return type:

str

Raises:

ValueError -- Cannot serialize object to json.

truncate(threshold)

Truncate self by returning a copy without entries under a threshold.

Parameters:

threshold (float) -- The threshold for inclusion.

Returns:

The truncated version of self.

Return type:

self

values()

Return unsorted values in self.

Returns:

The sequence of values of self.

Return type:

List[Union[CalculatorComplex, CalculatorFloat]]

class hqs_qorrelator_app.experimental_nmr_helpers.PrimitiveJob(function, *args, **kwargs)[source]

Handle to a job from the reference implementations of the primitives in Qiskit.

This is a concrete implementation of the BasePrimitiveJob interface. See the documentation of that class for a discussion of the interface.

Primitives implementers looking to create their own job classes should not subclass this, but instead subclass the interface definition BasePrimitiveJob.

cancel()[source]
cancelled() → bool[source]
done() → bool[source]
in_final_state() → bool[source]
result() → ResultT[source]
running() → bool[source]
status() → JobStatus[source]
class hqs_qorrelator_app.experimental_nmr_helpers.QuantumCircuit(*regs: Register | int | Sequence[Bit], name: str | None = None, global_phase: ParameterExpression | float = 0, metadata: dict | None = None, inputs: Iterable[Var] = (), captures: Iterable[Var | Stretch] = (), declarations: Mapping[Var, Expr] | Iterable[tuple[Var, Expr]] = ())[source]

Core Qiskit representation of a quantum circuit.

Note

For more details setting the QuantumCircuit in context of all of the data structures that go with it, how it fits into the rest of the qiskit package, and the different regimes of quantum-circuit descriptions in Qiskit, see the module-level documentation of qiskit.circuit.

Example:

     ┌───┐
q_0: ┤ H ├──■──
     └───┘┌─┴─┐
q_1: ─────┤ X ├
          └───┘

Circuit attributes

QuantumCircuit has a small number of public attributes, which are mostly older functionality. Most of its functionality is accessed through methods.

A small handful of the attributes are intentionally mutable, the rest are data attributes that should be considered immutable.

Mutable attribute

Summary

global_phase

The global phase of the circuit, measured in radians.

metadata

Arbitrary user mapping, which Qiskit will preserve through the transpiler, but otherwise completely ignore.

name

An optional string name for the circuit.

Immutable data attribute

Summary

ancillas

List of AncillaQubits tracked by the circuit.

cregs

List of ClassicalRegisters tracked by the circuit.

clbits

List of Clbits tracked by the circuit.

data

List of individual CircuitInstructions that make up the circuit.

_data

Python-space handle to the C API QkCircuit object.

duration

Total duration of the circuit, added by scheduling transpiler passes. This attribute is deprecated and estimate_duration() should be used instead.

layout

Hardware layout and routing information added by the transpiler.

num_ancillas

The number of ancilla qubits in the circuit.

num_clbits

The number of clbits in the circuit.

num_captured_vars

Number of captured real-time classical variables.

num_captured_stretches

Number of captured stretches.

num_declared_vars

Number of locally declared real-time classical variables in the outer circuit scope.

num_declared_stretches

Number of locally declared stretches in the outer circuit scope.

num_input_vars

Number of input real-time classical variables.

num_parameters

Number of compile-time Parameters in the circuit.

num_qubits

Number of qubits in the circuit.

num_vars

Total number of real-time classical variables in the outer circuit scope.

num_stretches

Total number of stretches in the outer circuit scope.

num_identifiers

Total number of both variables and stretches in the outer circuit.

op_start_times

Start times of scheduled operations, added by scheduling transpiler passes.

parameters

Ordered set-like view of the compile-time Parameters tracked by the circuit.

qregs

List of QuantumRegisters tracked by the circuit.

qubits

List of Qubits tracked by the circuit.

unit

The unit of the duration field.

The core attribute is data. This is a sequence-like object that exposes the CircuitInstructions contained in an ordered form. You generally should not mutate this object directly; QuantumCircuit is only designed for append-only operations (which should use append()). Most operations that mutate circuits in place should be written as transpiler passes (qiskit.transpiler). The C API interacts with an internal object, called _data, which is not part of the public Python API, other than as a handle to pass to C-API calls.

data

The circuit data (instructions and context).

Example

[CircuitInstruction(operation=Instruction(name='measure', num_qubits=1,
num_clbits=1, params=[]), qubits=(Qubit(QuantumRegister(2, 'q'), 0),),
clbits=(Clbit(ClassicalRegister(2, 'c'), 1),))]
Returns:

A list-like object containing the CircuitInstruction instances in the circuit.

Alongside the data, the global_phase of a circuit can have some impact on its output, if the circuit is used to describe a Gate that may be controlled. This is measured in radians and is directly settable.

global_phase

The global phase of the current circuit scope in radians.

Example

0.0
0.7853981633974483

The name of a circuit becomes the name of the Instruction or Gate resulting from to_instruction() and to_gate() calls, which can be handy for visualizations.

name: str

A human-readable name for the circuit.

Example

my_circuit

You can attach arbitrary metadata to a circuit. No part of core Qiskit will inspect this or change its behavior based on metadata, but it will be faithfully passed through the transpiler, so you can tag your circuits yourself. When serializing a circuit with QPY (see qiskit.qpy), the metadata will be JSON-serialized and you may need to pass a custom serializer to handle non-JSON-compatible objects within it (see qpy.dump() for more detail). This field is ignored during export to OpenQASM 2 or 3.

metadata

Arbitrary user-defined dictionary of metadata for the circuit.

Qiskit will not examine the content of this mapping, but it will pass it through the transpiler and reattach it to the output, so you can track your own metadata.

Example

{'experiment_type': 'Bell state experiment'}

QuantumCircuit exposes data attributes tracking its internal quantum and classical bits and registers. These appear as Python lists, but you should treat them as immutable; changing them will at best have no effect, and more likely will simply corrupt the internal data of the QuantumCircuit.

qregs

A list of Qubits in the order that they were added. You should not mutate this.

cregs

A list of Clbits in the order that they were added. You should not mutate this.

qubits

A list of Qubits in the order that they were added. You should not mutate this.

ancillas

A list of AncillaQubits in the order that they were added. You should not mutate this.

clbits

A list of Clbits in the order that they were added. You should not mutate this.

Example

List the qubits in this circuit: [Qubit(QuantumRegister(2, 'q0'), 0),
Qubit(QuantumRegister(2, 'q0'), 1), Qubit(QuantumRegister(1, 'q1'), 0)]
List the classical bits in this circuit: [Clbit(ClassicalRegister(2, 'c0'), 0),
Clbit(ClassicalRegister(2, 'c0'), 1), Clbit(ClassicalRegister(1, 'c1'), 0)]

The compile-time parameters present in instructions on the circuit are available in parameters. This has a canonical order (mostly lexical, except in the case of ParameterVector), which matches the order that parameters will be assigned when using the list forms of assign_parameters(), but also supports set-like constant-time membership testing.

parameters

The parameters defined in the circuit.

This attribute returns the Parameter objects in the circuit sorted alphabetically. Note that parameters instantiated with a ParameterVector are still sorted numerically.

Examples

The snippet below shows that insertion order of parameters does not matter.

Bear in mind that alphabetical sorting might be unintuitive when it comes to numbers. The literal "10" comes before "2" in strict alphabetical sorting.

To respect numerical sorting, a ParameterVector can be used.

Returns:

The sorted Parameter objects in the circuit.

If you have transpiled your circuit, so you have a physical circuit, you can inspect the layout attribute for information stored by the transpiler about how the virtual qubits of the source circuit map to the hardware qubits of your physical circuit, both at the start and end of the circuit.

layout

Return any associated layout information about the circuit.

This attribute contains an optional TranspileLayout object. This is typically set on the output from transpile() or PassManager.run() to retain information about the permutations caused on the input circuit by transpilation.

There are two types of permutations caused by the transpile() function: an initial layout that permutes the qubits based on the selected physical qubits on the Target, and a final layout, which is an output permutation caused by SwapGates inserted during routing.

Example

[0, 1, 2]

If your circuit was also scheduled as part of a transpilation, it will expose the individual timings of each instruction, along with the total duration of the circuit.

duration

The total duration of the circuit, set by a scheduling transpiler pass. Its unit is specified by unit.

Deprecated since version 1.3.0: The property qiskit.circuit.quantumcircuit.QuantumCircuit.duration is deprecated as of Qiskit 1.3.0. It will be removed in Qiskit 3.0.0.

unit

The unit that duration is specified in.

Deprecated since version 1.3.0: The property qiskit.circuit.quantumcircuit.QuantumCircuit.unit is deprecated as of Qiskit 1.3.0. It will be removed in Qiskit 3.0.0.

op_start_times

Return a list of operation start times.

Note

This attribute computes the estimate starting time of the operations in the scheduled circuit and only works for simple circuits that have no control flow or other classical feed-forward operations.

This attribute is enabled once one of scheduling analysis passes runs on the quantum circuit.

Example

Original circuit:
        ┌───┐      ░ ┌─┐
q_0: ┤ H ├──■───░─┤M├───
        └───┘┌─┴─┐ ░ └╥┘┌─┐
q_1: ─────┤ X ├─░──╫─┤M├
            └───┘ ░  ║ └╥┘
meas: 2/══════════════╩══╩═
                    0  1

Transpiled circuit with basis gates ['u1', 'u2', 'u3', 'cx']:
            ┌─────────┐          ░ ┌─────────────────┐┌─┐
q_0 -> 0 ───┤ U2(0,π) ├──────■───░─┤ Delay(1255[dt]) ├┤M├
        ┌──┴─────────┴───┐┌─┴─┐ ░ └───────┬─┬───────┘└╥┘
q_1 -> 1 ┤ Delay(196[dt]) ├┤ X ├─░─────────┤M├─────────╫─
        └────────────────┘└───┘ ░         └╥┘         ║
meas: 2/═══════════════════════════════════╩══════════╩═
                                            1          0

Start times of instructions in the transpiled circuit:
u2: 0
delay: 0
cx: 196
barrier: 2098
delay: 2098
measure: 3353
measure: 2098
Returns:

List of integers representing instruction estimated start times. The index corresponds to the index of instruction in QuantumCircuit.data.

Raises:

AttributeError -- When circuit is not scheduled.

Finally, QuantumCircuit exposes several simple properties as dynamic read-only numeric attributes.

num_ancillas

Return the number of ancilla qubits.

Example

Number of ancilla qubits: 1
num_clbits

Return number of classical bits.

Example

Number of classical bits: 1
num_captured_vars

The number of real-time classical variables in the circuit marked as captured from an enclosing scope.

This is the length of the iter_captured_vars() iterable. If this is non-zero, num_input_vars must be zero.

num_captured_stretches

The number of stretches in the circuit marked as captured from an enclosing scope.

This is the length of the iter_captured_stretches() iterable. If this is non-zero, num_input_vars must be zero.

num_declared_vars

The number of real-time classical variables in the circuit that are declared by this circuit scope, excluding inputs or captures.

This is the length of the iter_declared_vars() iterable.

num_declared_stretches

The number of stretches in the circuit that are declared by this circuit scope, excluding captures.

This is the length of the iter_declared_stretches() iterable.

num_input_vars

The number of real-time classical variables in the circuit marked as circuit inputs.

This is the length of the iter_input_vars() iterable. If this is non-zero, num_captured_vars must be zero.

num_identifiers

The number of real-time classical variables and stretches in the circuit.

This is equal to num_vars() + num_stretches().

num_parameters

The number of parameter objects in the circuit.

num_qubits

Return number of qubits.

num_stretches

The number of stretches in the circuit.

This is the length of the iter_stretches() iterable.

num_vars

The number of real-time classical variables in the circuit.

This is the length of the iter_vars() iterable.

Creating new circuits

Method

Summary

__init__()

Default constructor of no-instruction circuits.

copy()

Make a complete copy of an existing circuit.

copy_empty_like()

Copy data objects from one circuit into a new one without any instructions.

from_instructions()

Infer data objects needed from a list of instructions.

from_qasm_file()

Legacy interface to qasm2.load().

from_qasm_str()

Legacy interface to qasm2.loads().

The default constructor (QuantumCircuit(...)) produces a circuit with no initial instructions. The arguments to the default constructor can be used to seed the circuit with quantum and classical data storage, and to provide a name, global phase and arbitrary metadata. All of these fields can be expanded later.

__init__(*regs: Register | int | Sequence[Bit], name: str | None = None, global_phase: ParameterExpression | float = 0, metadata: dict | None = None, inputs: Iterable[Var] = (), captures: Iterable[Var | Stretch] = (), declarations: Mapping[Var, Expr] | Iterable[tuple[Var, Expr]] = ())[source]

Default constructor of QuantumCircuit.

Parameters:
  • regs --

    The registers to be included in the circuit.

    • If a list of Register objects, represents the QuantumRegister and/or ClassicalRegister objects to include in the circuit.

      For example:

      • QuantumCircuit(QuantumRegister(4))

      • QuantumCircuit(QuantumRegister(4), ClassicalRegister(3))

      • QuantumCircuit(QuantumRegister(4, 'qr0'), QuantumRegister(2, 'qr1'))

    • If a list of int, the amount of qubits and/or classical bits to include in the circuit. It can either be a single int for just the number of quantum bits, or 2 ints for the number of quantum bits and classical bits, respectively.

      For example:

      • QuantumCircuit(4) # A QuantumCircuit with 4 qubits

      • QuantumCircuit(4, 3) # A QuantumCircuit with 4 qubits and 3 classical bits

    • If a list of python lists containing Bit objects, a collection of Bit s to be added to the circuit.

  • name -- the name of the quantum circuit. If not set, an automatically generated string will be assigned.

  • global_phase -- The global phase of the circuit in radians.

  • metadata -- Arbitrary key value metadata to associate with the circuit. This gets stored as free-form data in a dict in the metadata attribute. It will not be directly used in the circuit.

  • inputs -- any variables to declare as input runtime variables for this circuit. These should already be existing expr.Var nodes that you build from somewhere else; if you need to create the inputs as well, use QuantumCircuit.add_input(). The variables given in this argument will be passed directly to add_input(). A circuit cannot have both inputs and captures.

  • captures -- any variables that this circuit scope should capture from a containing scope. The variables given here will be passed directly to add_capture(). A circuit cannot have both inputs and captures.

  • declarations --

    any variables that this circuit should declare and initialize immediately. You can order this input so that later declarations depend on earlier ones (including inputs or captures). If you need to depend on values that will be computed later at runtime, use add_var() at an appropriate point in the circuit execution.

    This argument is intended for convenient circuit initialization when you already have a set of created variables. The variables used here will be directly passed to add_var(), which you can use directly if this is the first time you are creating the variable.

Raises:
  • CircuitError -- if the circuit name, if given, is not valid.

  • CircuitError -- if both inputs and captures are given.

If you have an existing circuit, you can produce a copy of it using copy(), including all its instructions. This is useful if you want to keep partial circuits while extending another, or to have a version you can mutate in-place while leaving the prior one intact.

copy(name: str | None = None) → Self[source]

Copy the circuit.

Parameters:

name (str) -- name to be given to the copied circuit. If None, then the name stays the same.

Returns:

a deepcopy of the current circuit, with the specified name

Return type:

QuantumCircuit

Similarly, if you want a circuit that contains all the same data objects (bits, registers, variables, etc) but with none of the instructions, you can use copy_empty_like(). This is quite common when you want to build up a new layer of a circuit to then apply onto the back with compose(), or to do a full rewrite of a circuit's instructions.

copy_empty_like(name: str | None = None, *, vars_mode: Literal['alike', 'captures', 'drop'] = 'alike') → Self[source]

Return a copy of self with the same structure but empty.

That structure includes:

  • name and other metadata

  • global phase

  • all the qubits and clbits, including the registers

  • the realtime variables defined in the circuit, handled according to the vars keyword argument.

Warning

If the circuit contains any local variable declarations (those added by the declarations argument to the circuit constructor, or using add_var()), they may be uninitialized in the output circuit. You will need to manually add store instructions for them (see Store and QuantumCircuit.store()) to initialize them.

Parameters:
  • name -- Name for the copied circuit. If None, then the name stays the same.

  • vars_mode --

    The mode to handle realtime variables in.

    alike

    The variables in the output circuit will have the same declaration semantics as in the original circuit. For example, input variables in the source will be input variables in the output circuit. Note that this causes the local variables to be uninitialised, because the stores are not copied. This can leave the circuit in a potentially dangerous state for users if they don't re-add initializer stores.

    captures

    All variables will be converted to captured variables. This is useful when you are building a new layer for an existing circuit that you will want to compose() onto the base, since compose() can inline captures onto the base circuit (but not other variables).

    drop

    The output circuit will have no variables defined.

Returns:

An empty copy of self.

Return type:

QuantumCircuit

In some cases, it is most convenient to generate a list of CircuitInstructions separately to an entire circuit context, and then to build a circuit from this. The from_instructions() constructor will automatically capture all Qubit and Clbit instances used in the instructions, and create a new QuantumCircuit object that has the correct resources and all the instructions.

static from_instructions(instructions: Iterable[CircuitInstruction | tuple[qiskit.circuit.Instruction] | tuple[qiskit.circuit.Instruction, Iterable[Qubit]] | tuple[qiskit.circuit.Instruction, Iterable[Qubit], Iterable[Clbit]]], *, qubits: Iterable[Qubit] = (), clbits: Iterable[Clbit] = (), name: str | None = None, global_phase: ParameterValueType = 0, metadata: dict | None = None) → QuantumCircuit[source]

Construct a circuit from an iterable of CircuitInstructions.

Parameters:
  • instructions -- The instructions to add to the circuit.

  • qubits -- Any qubits to add to the circuit. This argument can be used, for example, to enforce a particular ordering of qubits.

  • clbits -- Any classical bits to add to the circuit. This argument can be used, for example, to enforce a particular ordering of classical bits.

  • name -- The name of the circuit.

  • global_phase -- The global phase of the circuit in radians.

  • metadata -- Arbitrary key value metadata to associate with the circuit.

Returns:

The quantum circuit.

QuantumCircuit also still has two constructor methods that are legacy wrappers around the importers in qiskit.qasm2. These automatically apply the legacy compatibility settings of load() and loads().

static from_qasm_file(path: str | PathLike) → QuantumCircuit[source]

Read an OpenQASM 2.0 program from a file and convert to an instance of QuantumCircuit.

Parameters:

path -- Path to the file for an OpenQASM 2 program

Returns:

The QuantumCircuit object for the input OpenQASM 2.

Return type:

QuantumCircuit

See also

qasm2.load(): the complete interface to the OpenQASM 2 importer.

static from_qasm_str(qasm_str: str) → QuantumCircuit[source]

Convert a string containing an OpenQASM 2.0 program to a QuantumCircuit.

Parameters:

qasm_str (str) -- A string containing an OpenQASM 2.0 program.

Returns:

The QuantumCircuit object for the input OpenQASM 2

Return type:

QuantumCircuit

See also

qasm2.loads(): the complete interface to the OpenQASM 2 importer.

Data objects on circuits

Adding data objects

Method

Adds this kind of data

add_bits()

Qubits and Clbits.

add_register()

QuantumRegister and ClassicalRegister.

add_var()

Var nodes with local scope and initializers.

add_stretch()

Stretch nodes with local scope.

add_input()

Var nodes that are treated as circuit inputs.

add_capture()

Var or Stretch nodes captured from containing scopes.

add_uninitialized_var()

Var nodes with local scope and undefined state.

Typically you add most of the data objects (Qubit, Clbit, ClassicalRegister, etc) to the circuit as part of using the __init__() default constructor, or copy_empty_like(). However, it is also possible to add these afterwards. Typed classical data, such as standalone Var nodes (see circuit-repr-real-time-classical), can be both constructed and added with separate methods.

New registerless Qubit and Clbit objects are added using add_bits(). These objects must not already be present in the circuit. You can check if a bit exists in the circuit already using find_bit().

add_bits(bits: Iterable[Bit]) → None[source]

Add Bits to the circuit.

Warning

If the quantum circuit has an existing layout attribute, adding a Qubit will only increase the number of qubits. It will not update the layout.

Registers are added to the circuit with add_register(). In this method, it is not an error if some of the bits are already present in the circuit. In this case, the register will be an "alias" over the bits. This is not generally well-supported by hardware backends; it is probably best to stay away from relying on it. The registers a given bit is in are part of the return of find_bit().

add_register(*regs: Register | int | Sequence[Bit]) → None[source]

Add registers.

Warning

If the quantum circuit has an existing layout attribute, adding a QuantumRegister will only increase the number of qubits. It will not update the layout.

Real-time, typed classical data is represented on the circuit by Var nodes with a well-defined Type. It is possible to instantiate these separately to a circuit (see Var.new()), but it is often more convenient to use circuit methods that will automatically manage the types and expression initialization for you. The two most common methods are add_var() (locally scoped variables) and add_input() (inputs to the circuit). Additionally, the method add_stretch() can be used to add stretches to the circuit.

add_var(name_or_var: str | Var, /, initial: Any) → Var[source]

Add a classical variable with automatic storage and scope to this circuit.

The variable is considered to have been "declared" at the beginning of the circuit, but it only becomes initialized at the point of the circuit that you call this method, so it can depend on variables defined before it.

Parameters:
  • name_or_var -- either a string of the variable name, or an existing instance of Var to re-use. Variables cannot shadow names that are already in use within the circuit.

  • initial --

    the value to initialize this variable with. If the first argument was given as a string name, the type of the resulting variable is inferred from the initial expression; to control this more manually, either use Var.new() to manually construct a new variable with the desired type, or use expr.cast() to cast the initializer to the desired type.

    This must be either a Expr node, or a value that can be lifted to one using expr.lift.

Returns:

The created variable. If a Var instance was given, the exact same object will be returned.

Raises:

CircuitError -- if the variable cannot be created due to shadowing an existing identifier.

Examples

Define a new variable given just a name and an initializer expression:

from qiskit.circuit import QuantumCircuit

qc = QuantumCircuit(2)
my_var = qc.add_var("my_var", False)

Reuse a variable that may have been taken from a related circuit, or otherwise constructed manually, and initialize it to some more complicated expression:

from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.circuit.classical import expr, types

my_var = expr.Var.new("my_var", types.Uint(8))

cr1 = ClassicalRegister(8, "cr1")
cr2 = ClassicalRegister(8, "cr2")
qc = QuantumCircuit(QuantumRegister(8), cr1, cr2)

# Get some measurement results into each register.
qc.h(0)
for i in range(1, 8):
    qc.cx(0, i)
qc.measure(range(8), cr1)

qc.reset(range(8))
qc.h(0)
for i in range(1, 8):
    qc.cx(0, i)
qc.measure(range(8), cr2)

# Now when we add the variable, it is initialized using the real-time state of the
# two classical registers we measured into above.
qc.add_var(my_var, expr.bit_and(cr1, cr2))
add_input(name_or_var: str, type_: Type, /) → Var[source]
add_input(name_or_var: Var, type_: None = None, /) → Var

Register a variable as an input to the circuit.

Parameters:
  • name_or_var -- either a string name, or an existing Var node to use as the input variable.

  • type -- if the name is given as a string, then this must be a Type to use for the variable. If the variable is given as an existing Var, then this must not be given, and will instead be read from the object itself.

Returns:

the variable created, or the same variable as was passed in.

Raises:

CircuitError -- if the variable cannot be created due to shadowing an existing variable.

add_stretch(name_or_stretch: str | Stretch) → Stretch[source]

Declares a new stretch scoped to this circuit.

Parameters:

name_or_stretch -- either a string of the stretch name, or an existing instance of Stretch to re-use. Stretches cannot shadow names that are already in use within the circuit.

Returns:

The created stretch. If a Stretch instance was given, the exact same object will be returned.

Raises:

CircuitError -- if the stretch cannot be created due to shadowing an existing identifier.

Examples

Define and use a new stretch given just a name:

from qiskit.circuit import QuantumCircuit, Duration
from qiskit.circuit.classical import expr

qc = QuantumCircuit(2)
my_stretch = qc.add_stretch("my_stretch")

qc.delay(expr.add(Duration.dt(200), my_stretch), 1)

In addition, there are two lower-level methods that can be useful for programmatic generation of circuits. When working interactively, you will most likely not need these; most uses of add_uninitialized_var() are part of copy_empty_like(), and most uses of add_capture() would be better off using the control-flow builder interface.

add_uninitialized_var(var: Var, /)[source]

Add a variable with no initializer.

In most cases, you should use add_var() to initialize the variable. To use this function, you must already hold a Var instance, as the use of the function typically only makes sense in copying contexts.

Warning

Qiskit makes no assertions about what an uninitialized variable will evaluate to at runtime, and some hardware may reject this as an error.

You should treat this function with caution, and as a low-level primitive that is useful only in special cases of programmatically rebuilding two like circuits.

Parameters:

var -- the variable to add.

add_capture(var: Var)[source]
add_capture(stretch: Stretch)

Add an identifier to the circuit that it should capture from a scope it will be contained within.

This method requires a Var or Stretch node to enforce that you've got a handle to an identifier, because you will need to declare the same identifier using the same object in the outer circuit.

This is a low-level method, which is only really useful if you are manually constructing control-flow operations. You typically will not need to call this method, assuming you are using the builder interface for control-flow scopes (with context-manager statements for if_test() and the other scoping constructs). The builder interface will automatically make the inner scopes closures on your behalf by capturing any identifiers that are used within them.

Parameters:

var (Union[expr.Var, expr.Stretch]) -- the variable or stretch to capture from an enclosing scope.

Raises:

CircuitError -- if the identifier cannot be created due to shadowing an existing identifier.

Working with bits and registers

A Bit instance is, on its own, just a unique handle for circuits to use in their own contexts. If you have got a Bit instance and a circuit, you can find the contexts that the bit exists in using find_bit(), such as its integer index in the circuit and any registers it is contained in.

find_bit(bit: Bit) → BitLocations[source]

Find locations in the circuit which can be used to reference a given Bit.

In particular, this function can find the integer index of a qubit, which corresponds to its hardware index for a transpiled circuit.

Note

The circuit index of a AncillaQubit will be its index in qubits, not ancillas.

Parameters:

bit (Bit) -- The bit to locate.

Returns:

A 2-tuple. The first element (index) contains the index at which the Bit can be found (in either qubits, clbits, depending on its type). The second element (registers) is a list of (register, index) pairs with an entry for each Register in the circuit which contains the Bit (and the index in the Register at which it can be found).

Return type:

namedtuple(int, List[Tuple(Register, int)])

Raises:
  • CircuitError -- If the supplied Bit was of an unknown type.

  • CircuitError -- If the supplied Bit could not be found on the circuit.

Examples

Loop through a circuit, getting the qubit and clbit indices of each operation:

from qiskit.circuit import QuantumCircuit, Qubit

qc = QuantumCircuit(3, 3)
qc.h(0)
qc.cx(0, 1)
qc.cx(1, 2)
qc.measure([0, 1, 2], [0, 1, 2])

# The `.qubits` and `.clbits` fields are not integers.
assert isinstance(qc.data[0].qubits[0], Qubit)
# ... but we can use `find_bit` to retrieve them.
assert qc.find_bit(qc.data[0].qubits[0]).index == 0

simple = [
    (
        instruction.operation.name,
        [qc.find_bit(bit).index for bit in instruction.qubits],
        [qc.find_bit(bit).index for bit in instruction.clbits],
    )
    for instruction in qc.data
]

Similarly, you can query a circuit to see if a register has already been added to it by using has_register().

has_register(register: Register) → bool[source]

Test if this circuit has the register r.

Parameters:

register (Register) -- a quantum or classical register.

Returns:

True if the register is contained in this circuit.

Return type:

bool

Working with compile-time parameters

See also

circuit-compile-time-parameters

A more complete discussion of what compile-time parametrization is, and how it fits into Qiskit's data model.

Unlike bits, registers, and real-time typed classical data, compile-time symbolic parameters are not manually added to a circuit. Their presence is inferred by being contained in operations added to circuits and the global phase. An ordered list of all parameters currently in a circuit is at QuantumCircuit.parameters.

The most common operation on Parameter instances is to replace them in symbolic operations with some numeric value, or another symbolic expression. This is done with assign_parameters().

assign_parameters(parameters: Mapping[Parameter, ParameterExpression | float] | Iterable[ParameterExpression | float], inplace: Literal[False] = False, *, flat_input: bool = False, strict: bool = True) → QuantumCircuit[source]
assign_parameters(parameters: Mapping[Parameter, ParameterExpression | float] | Iterable[ParameterExpression | float], inplace: Literal[True] = False, *, flat_input: bool = False, strict: bool = True) → None

Assign parameters to new parameters or values.

If parameters is passed as a dictionary, the keys should be Parameter instances in the current circuit. The values of the dictionary can either be numeric values or new parameter objects.

If parameters is passed as a list or array, the elements are assigned to the current parameters in the order of parameters which is sorted alphabetically (while respecting the ordering in ParameterVector objects).

The values can be assigned to the current circuit object or to a copy of it.

Note

When parameters is given as a mapping, it is permissible to have keys that are strings of the parameter names; these will be looked up using get_parameter(). You can also have keys that are ParameterVector instances, and in this case, the dictionary value should be a sequence of values of the same length as the vector.

If you use either of these cases, you must leave the setting flat_input=False; changing this to True enables the fast path, where all keys must be Parameter instances.

Parameters:
  • parameters -- Either a dictionary or iterable specifying the new parameter values.

  • inplace -- If False, a copy of the circuit with the bound parameters is returned. If True the circuit instance itself is modified.

  • flat_input -- If True and parameters is a mapping type, it is assumed to be exactly a mapping of {parameter: value}. By default (False), the mapping may also contain ParameterVector keys that point to a corresponding sequence of values, and these will be unrolled during the mapping, or string keys, which will be converted to Parameter instances using get_parameter().

  • strict -- If False, any parameters given in the mapping that are not used in the circuit will be ignored. If True (the default), an error will be raised indicating a logic error.

Raises:
  • CircuitError -- If parameters is a dict and contains parameters not present in the circuit.

  • ValueError -- If parameters is a list/array and the length mismatches the number of free parameters in the circuit.

Returns:

A copy of the circuit with bound parameters if inplace is False, otherwise None.

Examples

Create a parameterized circuit and assign the parameters in-place.

Bind the values out-of-place by list and get a copy of the original circuit.

The circuit tracks parameters by Parameter instances themselves, and forbids having multiple parameters of the same name to avoid some problems when interoperating with OpenQASM or other external formats. You can use has_parameter() and get_parameter() to query the circuit for a parameter with the given string name.

has_parameter(name_or_param: str | Parameter, /) → bool[source]

Check whether a parameter object exists in this circuit.

Parameters:

name_or_param -- the parameter, or name of a parameter to check. If this is a Parameter node, the parameter must be exactly the given one for this function to return True.

Returns:

whether a matching parameter is assignable in this circuit.

See also

QuantumCircuit.get_parameter()

Retrieve the Parameter instance from this circuit by name.

QuantumCircuit.has_var()

A similar method to this, but for run-time expr.Var variables instead of compile-time Parameters.

get_parameter(name: str, default: T) → Parameter | T[source]
get_parameter(name: str, default: builtin_types.EllipsisType = Ellipsis) → Parameter

Retrieve a compile-time parameter that is accessible in this circuit scope by name.

Parameters:
  • name -- the name of the parameter to retrieve.

  • default -- if given, this value will be returned if the parameter is not present. If it is not given, a KeyError is raised instead.

Returns:

The corresponding parameter.

Raises:

KeyError -- if no default is given, but the parameter does not exist in the circuit.

Examples

Retrieve a parameter by name from a circuit:

from qiskit.circuit import QuantumCircuit, Parameter

my_param = Parameter("my_param")

# Create a parametrized circuit.
qc = QuantumCircuit(1)
qc.rx(my_param, 0)

# We can use 'my_param' as a parameter, but let's say we've lost the Python object
# and need to retrieve it.
my_param_again = qc.get_parameter("my_param")

assert my_param == my_param_again

Get a variable from a circuit by name, returning some default if it is not present:

assert qc.get_parameter("my_param", None) == my_param
assert qc.get_parameter("unknown_param", None) is None

See also

get_var()

A similar method, but for expr.Var run-time variables instead of Parameter compile-time parameters.

Working with real-time typed classical data

See also

qiskit.circuit.classical

Module-level documentation for how the variable-, expression- and type-systems work, the objects used to represent them, and the classical operations available.

circuit-repr-real-time-classical

A discussion of how real-time data fits into the entire qiskit.circuit data model as a whole.

Adding data objects

The methods for adding new Var or Stretch identifiers to a circuit after initialization.

You can retrieve identifiers attached to a circuit (e.g. a Var or Stretch) by name with methods get_var(), get_stretch(), or get_identifier(). You can also check if a circuit contains a given identifier with has_var(), has_stretch(), or has_identifier().

get_var(name: str, default: T) → Var | T[source]
get_var(name: str, default: builtin_types.EllipsisType = Ellipsis) → Var

Retrieve a variable that is accessible in this circuit scope by name.

Parameters:
  • name -- the name of the variable to retrieve.

  • default -- if given, this value will be returned if the variable is not present. If it is not given, a KeyError is raised instead.

Returns:

The corresponding variable.

Raises:

KeyError -- if no default is given, but the variable does not exist.

Examples

Retrieve a variable by name from a circuit:

from qiskit.circuit import QuantumCircuit

# Create a circuit and create a variable in it.
qc = QuantumCircuit()
my_var = qc.add_var("my_var", False)

# We can use 'my_var' as a variable, but let's say we've lost the Python object and
# need to retrieve it.
my_var_again = qc.get_var("my_var")

assert my_var == my_var_again

Get a variable from a circuit by name, returning some default if it is not present:

assert qc.get_var("my_var", None) == my_var
assert qc.get_var("unknown_variable", None) is None

See also

get_parameter()

A similar method, but for Parameter compile-time parameters instead of expr.Var run-time variables.

get_stretch(name: str, default: T) → Stretch | T[source]
get_stretch(name: str, default: builtin_types.EllipsisType = Ellipsis) → Stretch

Retrieve a stretch that is accessible in this circuit scope by name.

Parameters:
  • name -- the name of the stretch to retrieve.

  • default -- if given, this value will be returned if the variable is not present. If it is not given, a KeyError is raised instead.

Returns:

The corresponding stretch.

Raises:

KeyError -- if no default is given, but the variable does not exist.

Examples

Retrieve a stretch by name from a circuit:

from qiskit.circuit import QuantumCircuit

# Create a circuit and create a variable in it.
qc = QuantumCircuit()
my_stretch = qc.add_stretch("my_stretch")

# We can use 'my_stretch' as a variable, but let's say we've lost the Python object and
# need to retrieve it.
my_stretch_again = qc.get_stretch("my_stretch")

assert my_stretch == my_stretch_again

Get a variable from a circuit by name, returning some default if it is not present:

assert qc.get_stretch("my_stretch", None) == my_stretch
assert qc.get_stretch("unknown_stretch", None) is None
get_identifier(name: str, default: T) → Var | Stretch | T[source]
get_identifier(name: str, default: builtin_types.EllipsisType = Ellipsis) → Var | Stretch

Retrieve an identifier that is accessible in this circuit scope by name.

This currently includes both real-time classical variables and stretches.

Parameters:
  • name -- the name of the identifier to retrieve.

  • default -- if given, this value will be returned if the variable is not present. If it is not given, a KeyError is raised instead.

Returns:

The corresponding variable.

Raises:

KeyError -- if no default is given, but the identifier does not exist.

See also

get_var()

Gets an identifier known to be a expr.Var instance.

get_stretch()

Gets an identifier known to be a expr.Stretch instance.

get_parameter()

A similar method, but for Parameter compile-time parameters instead of expr.Var run-time variables.

has_var(name_or_var: str | Var, /) → bool[source]

Check whether a variable is accessible in this scope.

Parameters:

name_or_var -- the variable, or name of a variable to check. If this is a expr.Var node, the variable must be exactly the given one for this function to return True.

Returns:

whether a matching variable is accessible.

See also

QuantumCircuit.get_var()

Retrieve the expr.Var instance from this circuit by name.

QuantumCircuit.has_parameter()

A similar method to this, but for compile-time Parameters instead of run-time expr.Var variables.

has_stretch(name_or_stretch: str | Stretch, /) → bool[source]

Check whether a stretch is accessible in this scope.

Parameters:

name_or_stretch -- the stretch, or name of a stretch to check. If this is a expr.Stretch node, the stretch must be exactly the given one for this function to return True.

Returns:

whether a matching stretch is accessible.

See also

QuantumCircuit.get_stretch()

Retrieve the expr.Stretch instance from this circuit by name.

has_identifier(name_or_ident: str | Var | Stretch, /) → bool[source]

Check whether an identifier is accessible in this scope.

Parameters:

name_or_ident -- the instance, or name of the identifier to check. If this is a expr.Var or expr.Stretch node, the matched instance must be exactly the given one for this function to return True.

Returns:

whether a matching identifier is accessible.

See also

QuantumCircuit.get_identifier()

Retrieve the expr.Var or expr.Stretch instance from this circuit by name.

QuantumCircuit.has_var()

The same as this method, but ignoring anything that isn't a run-time expr.Var variable.

QuantumCircuit.has_stretch()

The same as this method, but ignoring anything that isn't a run-time expr.Stretch variable.

QuantumCircuit.has_parameter()

A similar method to this, but for compile-time Parameters instead of run-time expr.Var variables.

There are also several iterator methods that you can use to get the full set of identifiers tracked by a circuit. At least one of iter_input_vars() and iter_captured_vars() will be empty, as inputs and captures are mutually exclusive. All of the iterators have corresponding dynamic properties on QuantumCircuit that contain their length: num_vars, num_stretches, num_input_vars, num_captured_vars, num_captured_stretches, num_declared_vars, or num_declared_stretches.

iter_vars() → Iterable[Var][source]

Get an iterable over all real-time classical variables in scope within this circuit.

This method will iterate over all variables in scope. For more fine-grained iterators, see iter_declared_vars(), iter_input_vars() and iter_captured_vars().

iter_stretches() → Iterable[Stretch][source]

Get an iterable over all stretches in scope within this circuit.

This method will iterate over all stretches in scope. For more fine-grained iterators, see iter_declared_stretches() and iter_captured_stretches().

iter_input_vars() → Iterable[Var][source]

Get an iterable over all real-time classical variables that are declared as inputs to this circuit scope. This excludes locally declared variables (see iter_declared_vars()) and captured variables (see iter_captured_vars()).

iter_captured_vars() → Iterable[Var][source]

Get an iterable over all real-time classical variables that are captured by this circuit scope from a containing scope. This excludes input variables (see iter_input_vars()) and locally declared variables (see iter_declared_vars()).

iter_captured_stretches() → Iterable[Stretch][source]

Get an iterable over stretches that are captured by this circuit scope from a containing scope. This excludes locally declared stretches (see iter_declared_stretches()).

iter_declared_vars() → Iterable[Var][source]

Get an iterable over all real-time classical variables that are declared with automatic storage duration in this scope. This excludes input variables (see iter_input_vars()) and captured variables (see iter_captured_vars()).

iter_declared_stretches() → Iterable[Stretch][source]

Get an iterable over all stretches that are declared in this scope. This excludes captured stretches (see iter_captured_stretches()).

Adding operations to circuits

You can add anything that implements the Operation interface to a circuit as a single instruction, though most things you will want to add will be Instruction or Gate instances.

See also

circuit-operations-instructions

The qiskit.circuit-level documentation on the different interfaces that Qiskit uses to define circuit-level instructions.

Methods to add general operations

These are the base methods that handle adding any object, including user-defined ones, onto circuits.

Method

When to use it

append()

Add an instruction as a single object onto a circuit.

_append()

Same as append(), but a low-level interface that elides almost all error checking.

compose()

Inline the instructions from one circuit onto another.

tensor()

Like compose(), but strictly for joining circuits that act on disjoint qubits.

QuantumCircuit has two main ways that you will add more operations onto a circuit. Which to use depends on whether you want to add your object as a single "instruction" (append()), or whether you want to join the instructions from two circuits together (compose()).

A single instruction or operation appears as a single entry in the data of the circuit, and as a single box when drawn in the circuit visualizers (see draw()). A single instruction is the "unit" that a hardware backend might be defined in terms of (see Target). An Instruction can come with a definition, which is one rule the transpiler (see qiskit.transpiler) will be able to fall back on to decompose it for hardware, if needed. An Operation that is not also an Instruction can only be decomposed if it has some associated high-level synthesis method registered for it (see qiskit.transpiler.passes.synthesis.plugin).

A QuantumCircuit alone is not a single Instruction; it is rather more complicated, since it can, in general, represent a complete program with typed classical memory inputs and outputs, and control flow. Qiskit's (and most hardware's) data model does not yet have the concept of re-usable callable subroutines with virtual quantum operands. You can convert simple circuits that act only on qubits with unitary operations into a Gate using to_gate(), and simple circuits acting only on qubits and clbits into a Instruction with to_instruction().

When you have an Operation, Instruction, or Gate, add it to the circuit, specifying the qubit and clbit arguments with append().

append(instruction: Operation | CircuitInstruction, qargs: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]] | None = None, cargs: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]] | None = None, *, copy: bool = True) → InstructionSet[source]

Append one or more instructions to the end of the circuit, modifying the circuit in place.

The qargs and cargs will be expanded and broadcast according to the rules of the given Instruction, and any non-Bit specifiers (such as integer indices) will be resolved into the relevant instances.

If a CircuitInstruction is given, it will be unwrapped, verified in the context of this circuit, and a new object will be appended to the circuit. In this case, you may not pass qargs or cargs separately.

Parameters:
  • instruction -- Instruction instance to append, or a CircuitInstruction with all its context. Objects implementing to_instruction are also supported, but passing an Instruction directly is generally preferred, since that avoids the repeated conversion cost.

  • qargs -- specifiers of the Qubits to attach instruction to.

  • cargs -- specifiers of the Clbits to attach instruction to.

  • copy -- if True (the default), then the incoming instruction is copied before adding it to the circuit if it contains symbolic parameters, so it can be safely mutated without affecting other circuits the same instruction might be in. If you are sure this instruction will not be in other circuits, you can set this False for a small speedup.

Returns:

a handle to the CircuitInstructions that were actually added to the circuit.

Return type:

qiskit.circuit.InstructionSet

Raises:

CircuitError -- if the operation passed is not an instance of Instruction, or cannot be converted to one by calling to_instruction on it.

append() does quite substantial error checking to ensure that you cannot accidentally break the data model of QuantumCircuit. If you are programmatically generating a circuit from known-good data, you can elide much of this error checking by using the fast-path appender _append(), but at the risk that the caller is responsible for ensuring they are passing only valid data.

_append(instruction: CircuitInstruction, *, _standard_gate: bool) → CircuitInstruction[source]
_append(instruction: Operation, qargs: Sequence[Qubit], cargs: Sequence[Clbit]) → Operation

Append an instruction to the end of the circuit, modifying the circuit in place.

Warning

This is an internal fast-path function, and it is the responsibility of the caller to ensure that all the arguments are valid; there is no error checking here. In particular:

  • all the qubits and clbits must already exist in the circuit and there can be no duplicates in the list.

  • any control-flow operations instructions must act only on variables present in the circuit.

  • the circuit must not be within a control-flow builder context.

Note

This function may be used by callers other than QuantumCircuit when the caller is sure that all error-checking, broadcasting and scoping has already been performed, and the only reference to the circuit the instructions are being appended to is within that same function. In particular, it is not safe to call QuantumCircuit._append() on a circuit that is received by a function argument. This is because QuantumCircuit._append() will not recognize the scoping constructs of the control-flow builder interface.

Parameters:
  • instruction --

    A complete well-formed CircuitInstruction of the operation and its context to be added.

    In the legacy compatibility form, this can be a bare Operation, in which case qargs and cargs must be explicitly given.

  • qargs -- Legacy argument for qubits to attach the bare Operation to. Ignored if the first argument is in the preferential CircuitInstruction form.

  • cargs -- Legacy argument for clbits to attach the bare Operation to. Ignored if the first argument is in the preferential CircuitInstruction form.

Returns:

a handle to the instruction that was just added.

Return type:

CircuitInstruction

In other cases, you may want to join two circuits together, applying the instructions from one circuit onto specified qubits and clbits on another circuit. This "inlining" operation is called compose() in Qiskit. compose() is, in general, more powerful than a to_instruction()-plus-append() combination for joining two circuits, because it can also link typed classical data together, and allows for circuit control-flow operations to be joined onto another circuit.

The downsides to compose() are that it is a more complex operation that can involve more rewriting of the operand, and that it necessarily must move data from one circuit object to another. If you are building up a circuit for yourself and raw performance is a core goal, consider passing around your base circuit and having different parts of your algorithm write directly to the base circuit, rather than building a temporary layer circuit.

compose(other: QuantumCircuit | Instruction, qubits: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int] | Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]] | None = None, clbits: Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int] | Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]] | None = None, front: bool = False, inplace: Literal[True] = True, wrap: bool = False, *, copy: bool = True, var_remap: Mapping[str | Var | Stretch, str | Var | Stretch] | None = None, inline_captures: bool = False) → None[source]
compose(other: QuantumCircuit | Instruction, qubits: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int] | Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]] | None = None, clbits: Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int] | Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]] | None = None, front: bool = False, inplace: Literal[False] = False, wrap: bool = False, *, copy: bool = True, var_remap: Mapping[str | Var | Stretch, str | Var | Stretch] | None = None, inline_captures: bool = False) → QuantumCircuit

Apply the instructions from one circuit onto specified qubits and/or clbits on another.

Note

By default, this creates a new circuit object, leaving self untouched. For most uses of this function, it is far more efficient to set inplace=True and modify the base circuit in-place.

When dealing with realtime variables (expr.Var and expr.Stretch instances), there are two principal strategies for using compose():

  1. The other circuit is treated as entirely additive, including its variables. The variables in other must be entirely distinct from those in self (use var_remap to help with this), and all variables in other will be declared anew in the output with matching input/capture/local scoping to how they are in other. This is generally what you want if you're joining two unrelated circuits.

  2. The other circuit was created as an exact extension to self to be inlined onto it, including acting on the existing variables in their states at the end of self. In this case, other should be created with all these variables to be inlined declared as "captures", and then you can use inline_captures=True in this method to link them. This is generally what you want if you're building up a circuit by defining layers on-the-fly, or rebuilding a circuit using layers taken from itself. You might find the vars_mode="captures" argument to copy_empty_like() useful to create each layer's base, in this case.

Parameters:
  • other (qiskit.circuit.Instruction or QuantumCircuit) -- (sub)circuit or instruction to compose onto self. If not a QuantumCircuit, this can be anything that append will accept.

  • qubits (list[Qubit|int]) -- qubits of self to compose onto.

  • clbits (list[Clbit|int]) -- clbits of self to compose onto.

  • front (bool) -- If True, front composition will be performed. This is not possible within control-flow builder context managers.

  • inplace (bool) -- If True, modify the object. Otherwise, return composed circuit.

  • copy (bool) -- If True (the default), then the input is treated as shared, and any contained instructions will be copied, if they might need to be mutated in the future. You can set this to False if the input should be considered owned by the base circuit, in order to avoid unnecessary copies; in this case, it is not valid to use other afterward, and some instructions may have been mutated in place.

  • var_remap (Mapping) --

    mapping to use to rewrite expr.Var and expr.Stretch nodes in other as they are inlined into self. This can be used to avoid naming conflicts.

    Both keys and values can be given as strings or direct identifier instances. If a key is a string, it matches any Var or Stretch with the same name. If a value is a string, whenever a new key matches it, a new Var or Stretch is created with the correct type. If a value is a Var, its type must exactly match that of the variable it is replacing.

  • inline_captures (bool) --

    if True, then all "captured" identifier nodes in the other QuantumCircuit are assumed to refer to identifiers already declared in self (as any input/capture/local type), and the uses in other will apply to the existing identifiers. If you want to build up a layer for an existing circuit to use with compose(), you might find the vars_mode="captures" argument to copy_empty_like() useful. Any remapping in vars_remap occurs before evaluating this variable inlining.

    If this is False (the default), then all identifiers in other will be required to be distinct from those in self, and new declarations will be made for them.

  • wrap (bool) -- If True, wraps the other circuit into a gate (or instruction, depending on whether it contains only unitary instructions) before composing it onto self. Rather than using this option, it is almost always better to manually control this yourself by using to_instruction() or to_gate(), and then call append().

Returns:

the composed circuit (returns None if inplace==True).

Return type:

QuantumCircuit

Raises:
  • CircuitError -- if no correct wire mapping can be made between the two circuits, such as if other is wider than self.

  • CircuitError -- if trying to emit a new circuit while self has a partially built control-flow context active, such as the context-manager forms of if_test(), for_loop() and while_loop().

  • CircuitError -- if trying to compose to the front of a circuit when a control-flow builder block is active; there is no clear meaning to this action.

Examples

>>> lhs.compose(rhs, qubits=[3, 2], inplace=True)
            ┌───┐                   ┌─────┐                ┌───┐
lqr_1_0: ───┤ H ├───    rqr_0: ──■──┤ Tdg ├    lqr_1_0: ───┤ H ├───────────────
            ├───┤              ┌─┴─┐└─────┘                ├───┤
lqr_1_1: ───┤ X ├───    rqr_1: ┤ X ├───────    lqr_1_1: ───┤ X ├───────────────
         ┌──┴───┴──┐           └───┘                    ┌──┴───┴──┐┌───┐
lqr_1_2: ┤ U1(0.1) ├  +                     =  lqr_1_2: ┤ U1(0.1) ├┤ X ├───────
         └─────────┘                                    └─────────┘└─┬─┘┌─────┐
lqr_2_0: ─────■─────                           lqr_2_0: ─────■───────■──┤ Tdg ├
            ┌─┴─┐                                          ┌─┴─┐        └─────┘
lqr_2_1: ───┤ X ├───                           lqr_2_1: ───┤ X ├───────────────
            └───┘                                          └───┘
lcr_0: 0 ═══════════                           lcr_0: 0 ═══════════════════════

lcr_1: 0 ═══════════                           lcr_1: 0 ═══════════════════════

If you are trying to join two circuits that will apply to completely disjoint qubits and clbits, tensor() is a convenient wrapper around manually adding bit objects and calling compose().

tensor(other: QuantumCircuit, inplace: bool = False) → QuantumCircuit | None[source]

Tensor self with other.

Remember that in the little-endian convention the leftmost operation will be at the bottom of the circuit. See also the docs for more information.

     ┌────────┐        ┌─────┐          ┌─────┐
q_0: ┤ bottom ├ ⊗ q_0: ┤ top ├  = q_0: ─┤ top ├──
     └────────┘        └─────┘         ┌┴─────┴─┐
                                  q_1: ┤ bottom ├
                                       └────────┘
Parameters:
  • other (QuantumCircuit) -- The other circuit to tensor this circuit with.

  • inplace (bool) -- If True, modify the object. Otherwise return composed circuit.

Examples

Returns:

The tensored circuit (returns None if inplace=True).

Return type:

QuantumCircuit

As some rules of thumb:

  • If you have a single Operation, Instruction or Gate, you should definitely use append() or _append().

  • If you have a QuantumCircuit that represents a single atomic instruction for a larger circuit that you want to re-use, you probably want to call to_instruction() or to_gate(), and then apply the result of that to the circuit using append().

  • If you have a QuantumCircuit that represents a larger "layer" of another circuit, or contains typed classical variables or control flow, you should use compose() to merge it onto another circuit.

  • tensor() is wanted far more rarely than either append() or compose(). Internally, it is mostly a wrapper around add_bits() and compose().

Some potential pitfalls to beware of:

  • Even if you re-use a custom Instruction during circuit construction, the transpiler will generally have to "unroll" each invocation of it to its inner decomposition before beginning work on it. This should not prevent you from using the to_instruction()-plus-append() pattern, as the transpiler will improve in this regard over time.

  • compose() will, by default, produce a new circuit for backwards compatibility. This is more expensive, and not usually what you want, so you should set inplace=True.

  • Both append() and compose() (but not _append()) have a copy keyword argument that defaults to True. In these cases, the incoming Operation instances will be copied if Qiskit detects that the objects have mutability about them (such as taking gate parameters). If you are sure that you will not re-use the objects again in other places, you should set copy=False to prevent this copying, which can be a substantial speed-up for large objects.

Methods to add standard instructions

The QuantumCircuit class has helper methods to add many of the Qiskit standard-library instructions and gates onto a circuit. These are generally equivalent to manually constructing an instance of the relevant qiskit.circuit.library object, then passing that to append() with the remaining arguments placed into the qargs and cargs fields as appropriate.

The following methods apply special non-unitary Instruction operations to the circuit:

QuantumCircuit method

qiskit.circuit Instruction

barrier()

Barrier

delay()

Delay

initialize()

Initialize

measure()

Measure

reset()

Reset

store()

Store

These methods apply uncontrolled unitary Gate instances to the circuit:

QuantumCircuit method

qiskit.circuit.library Gate

dcx()

DCXGate

ecr()

ECRGate

h()

HGate

id()

IGate

iswap()

iSwapGate

ms()

MSGate

p()

PhaseGate

pauli()

PauliGate

prepare_state()

StatePreparation

r()

RGate

rcccx()

RC3XGate

rccx()

RCCXGate

rv()

RVGate

rx()

RXGate

rxx()

RXXGate

ry()

RYGate

ryy()

RYYGate

rz()

RZGate

rzx()

RZXGate

rzz()

RZZGate

s()

SGate

sdg()

SdgGate

swap()

SwapGate

sx()

SXGate

sxdg()

SXdgGate

t()

TGate

tdg()

TdgGate

u()

UGate

unitary()

UnitaryGate

x()

XGate

y()

YGate

z()

ZGate

The following methods apply Gate instances that are also controlled gates, so are direct subclasses of ControlledGate:

QuantumCircuit method

qiskit.circuit.library ControlledGate

ccx()

CCXGate

ccz()

CCZGate

ch()

CHGate

cp()

CPhaseGate

crx()

CRXGate

cry()

CRYGate

crz()

CRZGate

cs()

CSGate

csdg()

CSdgGate

cswap()

CSwapGate

csx()

CSXGate

cu()

CUGate

cx()

CXGate

cy()

CYGate

cz()

CZGate

Finally, these methods apply particular generalized multiply controlled gates to the circuit, often with eager syntheses. They are listed in terms of the base gate they are controlling, since their exact output is often a synthesized version of a gate.

QuantumCircuit method

Base qiskit.circuit.library Gate

mcp()

PhaseGate

mcrx()

RXGate

mcry()

RYGate

mcrz()

RZGate

mcx()

XGate

The rest of this section is the API listing of all the individual methods; the tables above are summaries whose links will jump you to the correct place.

barrier(*qargs: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label=None) → InstructionSet[source]

Apply Barrier. If qargs is empty, applies to all qubits in the circuit.

Parameters:
  • qargs (QubitSpecifier) -- Specification for one or more qubit arguments.

  • label (str) -- The string label of the barrier.

Returns:

handle to the added instructions.

Return type:

qiskit.circuit.InstructionSet

ccx(control_qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], control_qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CCXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit1 -- The qubit(s) used as the first control.

  • control_qubit2 -- The qubit(s) used as the second control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

ccz(control_qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], control_qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CCZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit1 -- The qubit(s) used as the first control.

  • control_qubit2 -- The qubit(s) used as the second control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '10'). Defaults to controlling on the '11' state.

Returns:

A handle to the instructions created.

ch(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CHGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cp(theta: ParameterExpression | float, control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CPhaseGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

crx(theta: ParameterExpression | float, control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CRXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cry(theta: ParameterExpression | float, control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CRYGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

crz(theta: ParameterExpression | float, control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CRZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cs(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CSGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

csdg(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CSdgGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cswap(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CSwapGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit1 -- The qubit(s) targeted by the gate.

  • target_qubit2 -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

csx(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CSXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cu(theta: ParameterExpression | float, phi: ParameterExpression | float, lam: ParameterExpression | float, gamma: ParameterExpression | float, control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CUGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The \(\theta\) rotation angle of the gate.

  • phi -- The \(\phi\) rotation angle of the gate.

  • lam -- The \(\lambda\) rotation angle of the gate.

  • gamma -- The global phase applied of the U gate, if applied.

  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cx(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cy(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CYGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the controls.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cz(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the controls.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

dcx(qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply DCXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • qubit1 -- The qubit(s) to apply the gate to.

  • qubit2 -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

delay(duration: ParameterExpression | float | Expr, qarg: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int] | None = None, unit: str | None = None) → InstructionSet[source]

Apply Delay. If qarg is None, applies to all qubits. When applying to multiple qubits, delays with the same duration will be created.

Parameters:
  • duration (Object) -- duration of the delay. If this is an Expr, it must be a constant expression of type Duration.

  • qarg (Object) -- qubit argument to apply this delay.

  • unit (str | None) -- unit of the duration, unless duration is an Expr in which case it must not be specified. Supported units: 's', 'ms', 'us', 'ns', 'ps', and 'dt'. Default is 'dt', i.e. integer time unit depending on the target backend.

Returns:

handle to the added instructions.

Return type:

qiskit.circuit.InstructionSet

Raises:

CircuitError -- if arguments have bad format.

ecr(qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply ECRGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • qubit1 -- The first qubit to apply the gate to.

  • qubit2 -- The second qubit to apply the gate to.

Returns:

A handle to the instructions created.

h(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply HGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

id(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply IGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

initialize(params: Statevector | Sequence[complex] | str | int, qubits: Sequence[QubitSpecifier] | None = None, normalize: bool = False)[source]

Initialize qubits in a specific state.

Qubit initialization is done by first resetting the qubits to \(|0\rangle\) followed by calling StatePreparation class to prepare the qubits in a specified state. Both these steps are included in the Initialize instruction.

Parameters:
  • params --

    The state to initialize to, can be either of the following.

    • Statevector or vector of complex amplitudes to initialize to.

    • Labels of basis states of the Pauli eigenstates Z, X, Y. See Statevector.from_label(). Notice the order of the labels is reversed with respect to the qubit index to be applied to. Example label '01' initializes the qubit zero to \(|1\rangle\) and the qubit one to \(|0\rangle\).

    • An integer that is used as a bitmap indicating which qubits to initialize to \(|1\rangle\). Example: setting params to 5 would initialize qubit 0 and qubit 2 to \(|1\rangle\) and qubit 1 to \(|0\rangle\).

  • qubits -- Qubits to initialize. If None the initialization is applied to all qubits in the circuit.

  • normalize -- Whether to normalize an input array to a unit vector.

Returns:

A handle to the instructions created.

Examples

Prepare a qubit in the state \((|0\rangle - |1\rangle) / \sqrt{2}\).

output:

     ┌──────────────────────────────┐
q_0: ┤ Initialize(0.70711,-0.70711) ├
     └──────────────────────────────┘

Initialize from a string two qubits in the state \(|10\rangle\). The order of the labels is reversed with respect to qubit index. More information about labels for basis states are in Statevector.from_label().

output:

     ┌──────────────────┐
q_0: ┤0                 ├
     │  Initialize(0,1) │
q_1: ┤1                 ├
     └──────────────────┘

Initialize two qubits from an array of complex amplitudes.

output:

     ┌────────────────────────────────────┐
q_0: ┤0                                   ├
     │  Initialize(0,0.70711,-0.70711j,0) │
q_1: ┤1                                   ├
     └────────────────────────────────────┘
iswap(qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply iSwapGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • qubit1 -- The first qubit to apply the gate to.

  • qubit2 -- The second qubit to apply the gate to.

Returns:

A handle to the instructions created.

mcp(lam: ParameterExpression | float, control_qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], ctrl_state: str | int | None = None) → InstructionSet[source]

Apply MCPhaseGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • lam -- The angle of the rotation.

  • control_qubits -- The qubits used as the controls.

  • target_qubit -- The qubit(s) targeted by the gate.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

mcrx(theta: ParameterExpression | float, q_controls: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], q_target: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], use_basis_gates: bool = False)[source]

Apply Multiple-Controlled X rotation gate

Parameters:
  • theta -- The angle of the rotation.

  • q_controls -- The qubits used as the controls.

  • q_target -- The qubit targeted by the gate.

  • use_basis_gates -- use p, u, cx basis gates.

mcry(theta: ParameterExpression | float, q_controls: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], q_target: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], q_ancillae: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int] | Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]] | None = None, mode: str | None = None, use_basis_gates: bool = False)[source]

Apply Multiple-Controlled Y rotation gate

Parameters:
  • theta -- The angle of the rotation.

  • q_controls -- The qubits used as the controls.

  • q_target -- The qubit targeted by the gate.

  • q_ancillae -- The list of ancillary qubits.

  • mode -- The implementation mode to use.

  • use_basis_gates -- use p, u, cx basis gates

mcrz(lam: ParameterExpression | float, q_controls: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], q_target: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], use_basis_gates: bool = False)[source]

Apply Multiple-Controlled Z rotation gate

Parameters:
  • lam -- The angle of the rotation.

  • q_controls -- The qubits used as the controls.

  • q_target -- The qubit targeted by the gate.

  • use_basis_gates -- use p, u, cx basis gates.

mcx(control_qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], ancilla_qubits: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int] | Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]] | None = None, mode: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply MCXGate.

The multi-cX gate can be implemented using different techniques, which use different numbers of ancilla qubits and have varying circuit depth. These modes are:

  • 'noancilla': Requires 0 ancilla qubits.

  • 'recursion': Requires 1 ancilla qubit if more than 4 controls are used, otherwise 0.

  • 'v-chain': Requires 2 less ancillas than the number of control qubits.

  • 'v-chain-dirty': Same as for the clean ancillas (but the circuit will be longer).

For the full matrix form of this gate, see the underlying gate documentation.

Deprecated since version 2.1: qiskit.circuit.quantumcircuit.QuantumCircuit.mcx()'s argument mode is deprecated as of Qiskit 2.1. It will be removed no earlier than 3 months after the release date. Instead, add a generic MCXGate to the circuit and specify the synthesis method via the hls_config in the transpilation. Alternatively, specific decompositions are available at https://qisk.it/mcx.

Parameters:
  • control_qubits -- The qubits used as the controls.

  • target_qubit -- The qubit(s) targeted by the gate.

  • ancilla_qubits -- The qubits used as the ancillae, if the mode requires them.

  • mode -- The choice of mode, explained further above.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

Raises:
  • ValueError -- if the given mode is not known, or if too few ancilla qubits are passed.

  • AttributeError -- if no ancilla qubits are passed, but some are needed.

measure(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], cbit: Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]) → InstructionSet[source]

Measure a quantum bit (qubit) in the Z basis into a classical bit (cbit).

When a quantum state is measured, a qubit is projected in the computational (Pauli Z) basis to either \(\lvert 0 \rangle\) or \(\lvert 1 \rangle\). The classical bit cbit indicates the result of that projection as a 0 or a 1 respectively. This operation is non-reversible.

Parameters:
  • qubit -- qubit(s) to measure.

  • cbit -- classical bit(s) to place the measurement result(s) in, or a expr.Var of types.Uint type indexing the target clbit.

Returns:

handle to the added instructions.

Return type:

qiskit.circuit.InstructionSet

Raises:

CircuitError -- if arguments have bad format.

Examples

In this example, a qubit is measured and the result of that measurement is stored in the classical bit (usually expressed in diagrams as a double line):

     ┌───┐┌─┐
  q: ┤ H ├┤M├
     └───┘└╥┘
c: 1/══════╩═
           0

It is possible to call measure with lists of qubits and cbits as a shortcut for one-to-one measurement. These two forms produce identical results:

Instead of lists, you can use QuantumRegister and ClassicalRegister under the same logic.

This is equivalent to:

ms(theta: ParameterExpression | float, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]]) → InstructionSet[source]

Apply MSGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • qubits -- The qubits to apply the gate to.

Returns:

A handle to the instructions created.

p(theta: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply PhaseGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

pauli(pauli_string: str, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]]) → InstructionSet[source]

Apply PauliGate.

Parameters:
  • pauli_string -- A string representing the Pauli operator to apply, e.g. 'XX'.

  • qubits -- The qubits to apply this gate to.

Returns:

A handle to the instructions created.

prepare_state(state: Statevector | Sequence[complex] | str | int, qubits: Sequence[QubitSpecifier] | None = None, label: str | None = None, normalize: bool = False) → InstructionSet[source]

Prepare qubits in a specific state.

This class implements a state preparing unitary. Unlike initialize() it does not reset the qubits first.

Parameters:
  • state --

    The state to initialize to, can be either of the following.

    • Statevector or vector of complex amplitudes to initialize to.

    • Labels of basis states of the Pauli eigenstates Z, X, Y. See Statevector.from_label(). Notice the order of the labels is reversed with respect to the qubit index to be applied to. Example label '01' initializes the qubit zero to \(|1\rangle\) and the qubit one to \(|0\rangle\).

    • An integer that is used as a bitmap indicating which qubits to initialize to \(|1\rangle\). Example: setting params to 5 would initialize qubit 0 and qubit 2 to \(|1\rangle\) and qubit 1 to \(|0\rangle\).

  • qubits -- Qubits to initialize. If None the initialization is applied to all qubits in the circuit.

  • label -- An optional label for the gate

  • normalize -- Whether to normalize an input array to a unit vector.

Returns:

A handle to the instruction that was just initialized

Examples

Prepare a qubit in the state \((|0\rangle - |1\rangle) / \sqrt{2}\).

output:

     ┌─────────────────────────────────────┐
q_0: ┤ State Preparation(0.70711,-0.70711) ├
     └─────────────────────────────────────┘

Prepare from a string two qubits in the state \(|10\rangle\). The order of the labels is reversed with respect to qubit index. More information about labels for basis states are in Statevector.from_label().

output:

     ┌─────────────────────────┐
q_0: ┤0                        ├
     │  State Preparation(0,1) │
q_1: ┤1                        ├
     └─────────────────────────┘

Initialize two qubits from an array of complex amplitudes

output:

     ┌───────────────────────────────────────────┐
q_0: ┤0                                          ├
     │  State Preparation(0,0.70711,-0.70711j,0) │
q_1: ┤1                                          ├
     └───────────────────────────────────────────┘
r(theta: ParameterExpression | float, phi: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • phi -- The angle of the axis of rotation in the x-y plane.

  • qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

rcccx(control_qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], control_qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], control_qubit3: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RC3XGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit1 -- The qubit(s) used as the first control.

  • control_qubit2 -- The qubit(s) used as the second control.

  • control_qubit3 -- The qubit(s) used as the third control.

  • target_qubit -- The qubit(s) targeted by the gate.

Returns:

A handle to the instructions created.

rccx(control_qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], control_qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RCCXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit1 -- The qubit(s) used as the first control.

  • control_qubit2 -- The qubit(s) used as the second control.

  • target_qubit -- The qubit(s) targeted by the gate.

Returns:

A handle to the instructions created.

reset(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Reset the quantum bit(s) to their default state.

Parameters:

qubit -- qubit(s) to reset.

Returns:

handle to the added instruction.

Return type:

qiskit.circuit.InstructionSet

rv(vx: ParameterExpression | float, vy: ParameterExpression | float, vz: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RVGate.

For the full matrix form of this gate, see the underlying gate documentation.

Rotation around an arbitrary rotation axis \(v\), where \(|v|\) is the angle of rotation in radians.

Parameters:
  • vx -- x-component of the rotation axis.

  • vy -- y-component of the rotation axis.

  • vz -- z-component of the rotation axis.

  • qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

rx(theta: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None) → InstructionSet[source]

Apply RXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The rotation angle of the gate.

  • qubit -- The qubit(s) to apply the gate to.

  • label -- The string label of the gate in the circuit.

Returns:

A handle to the instructions created.

rxx(theta: ParameterExpression | float, qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RXXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • qubit1 -- The qubit(s) to apply the gate to.

  • qubit2 -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

ry(theta: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None) → InstructionSet[source]

Apply RYGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The rotation angle of the gate.

  • qubit -- The qubit(s) to apply the gate to.

  • label -- The string label of the gate in the circuit.

Returns:

A handle to the instructions created.

ryy(theta: ParameterExpression | float, qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RYYGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The rotation angle of the gate.

  • qubit1 -- The qubit(s) to apply the gate to.

  • qubit2 -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

rz(phi: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • phi -- The rotation angle of the gate.

  • qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

rzx(theta: ParameterExpression | float, qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RZXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The rotation angle of the gate.

  • qubit1 -- The qubit(s) to apply the gate to.

  • qubit2 -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

rzz(theta: ParameterExpression | float, qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RZZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The rotation angle of the gate.

  • qubit1 -- The qubit(s) to apply the gate to.

  • qubit2 -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

s(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply SGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

sdg(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply SdgGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

store(lvalue: Any, rvalue: Any, /) → InstructionSet[source]

Store the result of the given real-time classical expression rvalue in the memory location defined by lvalue.

Typically lvalue will be a Var node and rvalue will be some Expr to write into it, but anything that expr.lift() can raise to an Expr is permissible in both places, and it will be called on them.

Parameters:
  • lvalue -- a valid specifier for a memory location in the circuit. This will typically be a Var node, but you can also write to Clbit or ClassicalRegister memory locations if your hardware supports it. The memory location must already be present in the circuit.

  • rvalue -- a real-time classical expression whose result should be written into the given memory location.

See also

Store

The backing Instruction class that represents this operation.

add_var()

Create a new variable in the circuit that can be written to with this method.

swap(qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply SwapGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • qubit1 -- The first qubit to apply the gate to.

  • qubit2 -- The second qubit to apply the gate to.

Returns:

A handle to the instructions created.

sx(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply SXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

sxdg(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply SXdgGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

t(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply TGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

tdg(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply TdgGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

u(theta: ParameterExpression | float, phi: ParameterExpression | float, lam: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply UGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The \(\theta\) rotation angle of the gate.

  • phi -- The \(\phi\) rotation angle of the gate.

  • lam -- The \(\lambda\) rotation angle of the gate.

  • qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

unitary(obj: np.ndarray | Gate | BaseOperator, qubits: Sequence[QubitSpecifier], label: str | None = None)[source]

Apply unitary gate specified by obj to qubits.

Parameters:
  • obj -- Unitary operator.

  • qubits -- The circuit qubits to apply the transformation to.

  • label -- Unitary name for backend [Default: None].

Returns:

The quantum circuit.

Return type:

QuantumCircuit

Example

Apply a gate specified by a unitary matrix to a quantum circuit

x(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None) → InstructionSet[source]

Apply XGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • qubit -- The qubit(s) to apply the gate to.

  • label -- The string label of the gate in the circuit.

Returns:

A handle to the instructions created.

y(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply YGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

z(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply ZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

Adding control flow to circuits

See also

circuit-control-flow-repr

Discussion of how control-flow operations are represented in the whole qiskit.circuit context.

QuantumCircuit method

Control-flow instruction

if_test()

IfElseOp with only a True body

if_else()

IfElseOp with both True and False bodies

while_loop()

WhileLoopOp

switch()

SwitchCaseOp

for_loop()

ForLoopOp

box()

BoxOp

break_loop()

BreakLoopOp

continue_loop()

ContinueLoopOp

QuantumCircuit has corresponding methods for all of the control-flow operations that are supported by Qiskit. These have two forms for calling them. The first is a very straightforward convenience wrapper that takes in the block bodies of the instructions as QuantumCircuit arguments, and simply constructs and appends the corresponding ControlFlowOp.

The second form, which we strongly recommend you use for constructing control flow, is called the builder interface. Here, the methods take only the real-time discriminant of the operation, and return context managers that you enter using with. You can then use regular QuantumCircuit methods within those blocks to build up the control-flow bodies, and Qiskit will automatically track which of the data resources are needed for the inner blocks, building the complete ControlFlowOp as you leave the with statement. It is far simpler and less error-prone to build control flow programmatically this way.

When using the control-flow builder interface, you may sometimes want a qubit to be included in a block, even though it has no operations defined. In this case, you can use the noop() method.

To check whether a circuit contains a ControlFlowOp you can use the helper method QuantumCircuit.has_control_flow_op().

box(body_or_annotations: QuantumCircuit | Iterable[Annotation] = Ellipsis, /, qubits: Sequence[QubitSpecifier] | None = None, clbits: Sequence[ClbitSpecifier] | None = None, *, label: str | None = None, duration: None = None, unit: Literal['dt', 's', 'ms', 'us', 'ns', 'ps', 'expr'] | None = None, annotations: Iterable[Annotation] = Ellipsis)[source]

Create a box of operations on this circuit that are treated atomically in the greater context.

A "box" is a control-flow construct that is entered unconditionally. The contents of the box behave somewhat as if the start and end of the box were barriers (see barrier()), except it is permissible to commute operations "all the way" through the box. The box is also an explicit scope for the purposes of variables, stretches and compiler passes.

There are two forms for calling this function:

  • Pass a QuantumCircuit positionally, and the qubits and clbits it acts on. In this form, a BoxOp is immediately created and appended using the circuit as the body.

  • Use in a with statement with no body, qubits or clbits. This is the "builder-interface form", where you then use other QuantumCircuit methods within the Python with scope to add instructions to the box. This is the preferred form, and much less error prone.

Examples

Using the builder interface to add two boxes in sequence. The two boxes in this circuit can execute concurrently, and the second explicitly inserts a data-flow dependency on qubit 8 for the duration of the box, even though the qubit is idle.

from qiskit.circuit import QuantumCircuit, Annotation

class MyAnnotation(Annotation):
    namespace = "my.namespace"

qc = QuantumCircuit(9)
with qc.box():
    qc.cz(0, 1)
    qc.cz(2, 3)
with qc.box([MyAnnotation()]):
    qc.cz(4, 5)
    qc.cz(6, 7)
    qc.noop(8)

Using the explicit construction of box. This creates the same circuit as above, and should give an indication why the previous form is preferred for interactive use.

from qiskit.circuit import QuantumCircuit, BoxOp

body_0 = QuantumCircuit(4)
body_0.cz(0, 1)
body_0.cz(2, 3)

# Note that the qubit indices inside a body related only to the body.  The
# association with qubits in the containing circuit is made by the ``qubits``
# argument to `QuantumCircuit.box`.
body_1 = QuantumCircuit(5)
body_1.cz(0, 1)
body_1.cz(2, 3)

qc = QuantumCircuit(9)
qc.box(body_0, [0, 1, 2, 3], [])
qc.box(body_1, [4, 5, 6, 7, 8], [])
Parameters:
  • body_or_annotations -- the first positional argument is unnamed. If a QuantumCircuit is passed positionally, it is immediately used as the body of the box, and qubits and clbits must also be specified. If not given, or if given an iterable of Annotation objects, the context-manager form of this method is triggered.

  • qubits -- the qubits to apply the BoxOp to, in the explicit form.

  • clbits -- the clbits to apply the BoxOp to, in the explicit form.

  • label -- an optional string label for the instruction.

  • duration -- an optional explicit duration for the BoxOp. Scheduling passes are constrained to schedule the contained scope to match a given duration, including delay insertion if required.

  • unit -- the unit of the duration.

  • annotations -- any Annotation objects the box should have. When this method is used in context-manager form, this argument can instead be passed as the only positional argument.

break_loop() → InstructionSet[source]

Apply BreakLoopOp.

Warning

If you are using the context-manager "builder" forms of if_test(), for_loop() or while_loop(), you can only call this method if you are within a loop context, because otherwise the "resource width" of the operation cannot be determined. This would quickly lead to invalid circuits, and so if you are trying to construct a reusable loop body (without the context managers), you must also use the non-context-manager form of if_test() and if_else(). Take care that the BreakLoopOp instruction must span all the resources of its containing loop, not just the immediate scope.

Returns:

A handle to the instruction created.

Raises:

CircuitError -- if this method was called within a builder context, but not contained within a loop.

continue_loop() → InstructionSet[source]

Apply ContinueLoopOp.

Warning

If you are using the context-manager "builder" forms of if_test(), for_loop() or while_loop(), you can only call this method if you are within a loop context, because otherwise the "resource width" of the operation cannot be determined. This would quickly lead to invalid circuits, and so if you are trying to construct a reusable loop body (without the context managers), you must also use the non-context-manager form of if_test() and if_else(). Take care that the ContinueLoopOp instruction must span all the resources of its containing loop, not just the immediate scope.

Returns:

A handle to the instruction created.

Raises:

CircuitError -- if this method was called within a builder context, but not contained within a loop.

for_loop(indexset: Iterable[int], loop_parameter: Parameter | Var | None, body: None, qubits: None, clbits: None, *, label: str | None) → ForLoopContext[source]
for_loop(indexset: Iterable[int], loop_parameter: Parameter | Var | None, body: QuantumCircuit, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], clbits: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]], *, label: str | None) → InstructionSet

Create a for loop on this circuit.

There are two forms for calling this function. If called with all its arguments (with the possible exception of label), it will create a ForLoopOp with the given body. If body (and qubits and clbits) are not passed, then this acts as a context manager, which, when entered, provides a loop variable (unless one is given, in which case it will be reused) and will automatically build a ForLoopOp when the scope finishes. In this form, you do not need to keep track of the qubits or clbits you are using, because the scope will handle it for you.

For example:

from qiskit import QuantumCircuit
qc = QuantumCircuit(2, 1)

with qc.for_loop(range(5)) as i:
    qc.h(0)
    qc.cx(0, 1)
    qc.measure(0, 0)
    with qc.if_test((0, True)):
        qc.break_loop()
Parameters:
  • indexset (Iterable[int]) -- A collection of integers to loop over. Always necessary.

  • loop_parameter (Optional[Parameter|expr.Var]) --

    The parameter used within body to which the values from indexset will be assigned. In the context-manager form, if this argument is not supplied, then a loop parameter will be allocated for you and returned as the value of the with statement. This will only be bound into the circuit if it is used within the body.

    If this argument is None in the manual form of this method, body will be repeated once for each of the items in indexset but their values will be ignored.

  • body (Optional[QuantumCircuit]) -- The loop body to be repeatedly executed. Omit this to use the context-manager mode.

  • qubits (Optional[Sequence[QubitSpecifier]]) -- The circuit qubits over which the loop body should be run. Omit this to use the context-manager mode.

  • clbits (Optional[Sequence[ClbitSpecifier]]) -- The circuit clbits over which the loop body should be run. Omit this to use the context-manager mode.

  • label (Optional[str]) -- The string label of the instruction in the circuit.

Returns:

depending on the call signature, either a context manager for creating the for loop (it will automatically be added to the circuit at the end of the block), or an InstructionSet handle to the appended loop operation.

Return type:

InstructionSet or ForLoopContext

Raises:

CircuitError -- if an incorrect calling convention is used.

if_else(condition: tuple[ClassicalRegister, int] | tuple[Clbit, int] | tuple[Clbit, bool], true_body: QuantumCircuit, false_body: QuantumCircuit, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], clbits: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]], label: str | None = None) → InstructionSet[source]

Apply IfElseOp.

Note

This method does not have an associated context-manager form, because it is already handled by the if_test() method. You can use the else part of that with something such as:

from qiskit.circuit import QuantumCircuit, Qubit, Clbit
bits = [Qubit(), Qubit(), Clbit()]
qc = QuantumCircuit(bits)
qc.h(0)
qc.cx(0, 1)
qc.measure(0, 0)
with qc.if_test((bits[2], 0)) as else_:
    qc.h(0)
with else_:
    qc.x(0)
Parameters:
  • condition -- A condition to be evaluated in real time at circuit execution, which, if true, will trigger the evaluation of true_body. Can be specified as either a tuple of a ClassicalRegister to be tested for equality with a given int, or as a tuple of a Clbit to be compared to either a bool or an int.

  • true_body -- The circuit body to be run if condition is true.

  • false_body -- The circuit to be run if condition is false.

  • qubits -- The circuit qubits over which the if/else should be run.

  • clbits -- The circuit clbits over which the if/else should be run.

  • label -- The string label of the instruction in the circuit.

Raises:

CircuitError -- If the provided condition references Clbits outside the enclosing circuit.

Returns:

A handle to the instruction created.

if_test(condition: tuple[ClassicalRegister | Clbit, int]) → IfContext[source]
if_test(condition: tuple[ClassicalRegister | Clbit, int], true_body: QuantumCircuit, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], clbits: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]], *, label: str | None = None) → InstructionSet

Create an if statement on this circuit.

There are two forms for calling this function. If called with all its arguments (with the possible exception of label), it will create a IfElseOp with the given true_body, and there will be no branch for the false condition (see also the if_else() method). However, if true_body (and qubits and clbits) are not passed, then this acts as a context manager, which can be used to build if statements. The return value of the with statement is a chainable context manager, which can be used to create subsequent else blocks. In this form, you do not need to keep track of the qubits or clbits you are using, because the scope will handle it for you.

For example:

from qiskit.circuit import QuantumCircuit, Qubit, Clbit
bits = [Qubit(), Qubit(), Qubit(), Clbit(), Clbit()]
qc = QuantumCircuit(bits)

qc.h(0)
qc.cx(0, 1)
qc.measure(0, 0)
qc.h(0)
qc.cx(0, 1)
qc.measure(0, 1)

with qc.if_test((bits[3], 0)) as else_:
    qc.x(2)
with else_:
    qc.h(2)
    qc.z(2)
Parameters:
  • condition (Tuple[Union[ClassicalRegister, Clbit], int]) -- A condition to be evaluated in real time during circuit execution, which, if true, will trigger the evaluation of true_body. Can be specified as either a tuple of a ClassicalRegister to be tested for equality with a given int, or as a tuple of a Clbit to be compared to either a bool or an int.

  • true_body (Optional[QuantumCircuit]) -- The circuit body to be run if condition is true.

  • qubits (Optional[Sequence[QubitSpecifier]]) -- The circuit qubits over which the if/else should be run.

  • clbits (Optional[Sequence[ClbitSpecifier]]) -- The circuit clbits over which the if/else should be run.

  • label (Optional[str]) -- The string label of the instruction in the circuit.

Returns:

depending on the call signature, either a context manager for creating the if block (it will automatically be added to the circuit at the end of the block), or an InstructionSet handle to the appended conditional operation.

Return type:

InstructionSet or IfContext

Raises:
  • CircuitError -- If the provided condition references Clbits outside the enclosing circuit.

  • CircuitError -- if an incorrect calling convention is used.

Returns:

A handle to the instruction created.

switch(target: Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int], cases: None, qubits: None, clbits: None, *, label: str | None) → SwitchContext[source]
switch(target: Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int], cases: Iterable[tuple[Any, QuantumCircuit]], qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], clbits: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]], *, label: str | None) → InstructionSet

Create a switch/case structure on this circuit.

There are two forms for calling this function. If called with all its arguments (with the possible exception of label), it will create a SwitchCaseOp with the given case structure. If cases (and qubits and clbits) are not passed, then this acts as a context manager, which will automatically build a SwitchCaseOp when the scope finishes. In this form, you do not need to keep track of the qubits or clbits you are using, because the scope will handle it for you.

Example usage:

from qiskit.circuit import QuantumCircuit, ClassicalRegister, QuantumRegister
qreg = QuantumRegister(3)
creg = ClassicalRegister(3)
qc = QuantumCircuit(qreg, creg)
qc.h([0, 1, 2])
qc.measure([0, 1, 2], [0, 1, 2])

with qc.switch(creg) as case:
    with case(0):
        qc.x(0)
    with case(1, 2):
        qc.z(1)
    with case(case.DEFAULT):
        qc.cx(0, 1)
Parameters:
  • target (Union[ClassicalRegister, Clbit]) -- The classical value to switch one. This must be integer-like.

  • cases (Iterable[Tuple[Any, QuantumCircuit]]) -- A sequence of case specifiers. Each tuple defines one case body (the second item). The first item of the tuple can be either a single integer value, the special value CASE_DEFAULT, or a tuple of several integer values. Each of the integer values will be tried in turn; control will then pass to the body corresponding to the first match. CASE_DEFAULT matches all possible values. Omit in context-manager form.

  • qubits (Sequence[Qubit]) -- The circuit qubits over which all case bodies execute. Omit in context-manager form.

  • clbits (Sequence[Clbit]) -- The circuit clbits over which all case bodies execute. Omit in context-manager form.

  • label (Optional[str]) -- The string label of the instruction in the circuit.

Returns:

If used in context-manager mode, then this should be used as a with resource, which will return an object that can be repeatedly entered to produce cases for the switch statement. If the full form is used, then this returns a handle to the instructions created.

Return type:

InstructionSet or SwitchCaseContext

Raises:

CircuitError -- if an incorrect calling convention is used.

while_loop(condition: tuple[ClassicalRegister | Clbit, int] | Expr, body: None, qubits: None, clbits: None, *, label: str | None) → WhileLoopContext[source]
while_loop(condition: tuple[ClassicalRegister | Clbit, int] | Expr, body: QuantumCircuit, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], clbits: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]], *, label: str | None) → InstructionSet

Create a while loop on this circuit.

There are two forms for calling this function. If called with all its arguments (with the possible exception of label), it will create a WhileLoopOp with the given body. If body (and qubits and clbits) are not passed, then this acts as a context manager, which will automatically build a WhileLoopOp when the scope finishes. In this form, you do not need to keep track of the qubits or clbits you are using, because the scope will handle it for you.

Example usage:

from qiskit.circuit import QuantumCircuit, Clbit, Qubit
bits = [Qubit(), Qubit(), Clbit()]
qc = QuantumCircuit(bits)

with qc.while_loop((bits[2], 0)):
    qc.h(0)
    qc.cx(0, 1)
    qc.measure(0, 0)
Parameters:
  • condition (Tuple[Union[ClassicalRegister, Clbit], int]) -- An equality condition to be checked prior to executing body. The left-hand side of the condition must be a ClassicalRegister or a Clbit, and the right-hand side must be an integer or boolean.

  • body (Optional[QuantumCircuit]) -- The loop body to be repeatedly executed. Omit this to use the context-manager mode.

  • qubits (Optional[Sequence[Qubit]]) -- The circuit qubits over which the loop body should be run. Omit this to use the context-manager mode.

  • clbits (Optional[Sequence[Clbit]]) -- The circuit clbits over which the loop body should be run. Omit this to use the context-manager mode.

  • label (Optional[str]) -- The string label of the instruction in the circuit.

Returns:

If used in context-manager mode, then this should be used as a with resource, which will infer the block content and operands on exit. If the full form is used, then this returns a handle to the instructions created.

Return type:

InstructionSet or WhileLoopContext

Raises:

CircuitError -- if an incorrect calling convention is used.

noop(*qargs: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int])[source]

Mark the given qubit(s) as used within the current scope, without adding an operation.

This has no effect (other than raising an exception on invalid input) when called in the top scope of a QuantumCircuit. Within a control-flow builder, this causes the qubit to be "used" by the control-flow block, if it wouldn't already be used, without adding any additional operations on it.

For example:

from qiskit.circuit import QuantumCircuit

qc = QuantumCircuit(3)
with qc.box():
    # This control-flow block will only use qubits 0 and 1.
    qc.cx(0, 1)
with qc.box():
    # This control-flow block will contain only the same operation as the previous
    # block, but it will also mark qubit 2 as "used" by the box.
    qc.cx(0, 1)
    qc.noop(2)
Parameters:

*qargs -- variadic list of valid qubit specifiers. Anything that can be passed as a qubit or collection of qubits is valid for each argument here.

Raises:

CircuitError -- if any requested qubit is not valid for the circuit.

has_control_flow_op() → bool[source]

Checks whether the circuit has an instance of ControlFlowOp present amongst its operations.

Converting circuits to other objects

As discussed in Methods to add general operations, you can convert a circuit to either an Instruction or a Gate using two helper methods.

to_instruction(parameter_map: dict[Parameter, ParameterExpression | float] | None = None, label: str | None = None) → Instruction[source]

Create an Instruction out of this circuit.

See also

circuit_to_instruction()

The underlying driver of this method.

Parameters:
  • parameter_map -- For parameterized circuits, a mapping from parameters in the circuit to parameters to be used in the instruction. If None, existing circuit parameters will also parameterize the instruction.

  • label -- Optional gate label.

Returns:

a composite instruction encapsulating this circuit (can be

decomposed back).

Return type:

qiskit.circuit.Instruction

to_gate(parameter_map: dict[Parameter, ParameterExpression | float] | None = None, label: str | None = None) → Gate[source]

Create a Gate out of this circuit. The circuit must act only on qubits and contain only unitary operations.

See also

circuit_to_gate()

The underlying driver of this method.

Parameters:
  • parameter_map -- For parameterized circuits, a mapping from parameters in the circuit to parameters to be used in the gate. If None, existing circuit parameters will also parameterize the gate.

  • label -- Optional gate label.

Returns:

a composite gate encapsulating this circuit (can be decomposed back).

Return type:

Gate

In addition, you can convert the entire circuit into the DAGCircuit representation:

to_dag(*, copy_operations: bool = True) → qiskit.dagcircuit.DAGCircuit[source]

Convert this circuit to a DAGCircuit.

This is a simple wrapper around circuit_to_dag().

Parameters:

copy_operations -- whether to deep copy the individual instructions. If set to False, the operation is cheaper but mutations to the instructions in the DAG will affect the original circuit.

Returns:

a DAG representing this same circuit.

Helper mutation methods

There are two higher-level methods on QuantumCircuit for appending measurements to the end of a circuit. Note that by default, these also add an extra register.

measure_active(inplace: bool = True) → QuantumCircuit | None[source]

Adds measurement to all non-idle qubits. Creates a new ClassicalRegister with a size equal to the number of non-idle qubits being measured.

Returns a new circuit with measurements if inplace=False.

Parameters:

inplace (bool) -- All measurements inplace or return new circuit.

Returns:

Returns circuit with measurements when inplace = False.

Return type:

QuantumCircuit

measure_all(inplace: bool = True, add_bits: bool = True) → QuantumCircuit | None[source]

Adds measurement to all qubits.

By default, adds new classical bits in a ClassicalRegister to store these measurements. If add_bits=False, the results of the measurements will instead be stored in the already existing classical bits, with qubit n being measured into classical bit n.

Returns a new circuit with measurements if inplace=False.

Parameters:
  • inplace (bool) -- All measurements inplace or return new circuit.

  • add_bits (bool) -- Whether to add new bits to store the results.

Returns:

Returns circuit with measurements when inplace=False.

Return type:

QuantumCircuit

Raises:

CircuitError -- if add_bits=False but there are not enough classical bits.

There are two "subtractive" methods on QuantumCircuit as well. This is not a use-case that QuantumCircuit is designed for; typically you should just look to use copy_empty_like() in place of clear(), and run remove_final_measurements() as its transpiler-pass form RemoveFinalMeasurements.

clear() → None[source]

Clear all instructions in self.

Clearing the circuits will keep the metadata.

See also

copy_empty_like()

A method to produce a new circuit with no instructions and all the same tracking of quantum and classical typed data, but without mutating the original circuit.

remove_final_measurements(inplace: bool = True) → QuantumCircuit | None[source]

Removes final measurements and barriers on all qubits if they are present. Deletes the classical registers that were used to store the values from these measurements that become idle as a result of this operation, and deletes classical bits that are referenced only by removed registers, or that aren't referenced at all but have become idle as a result of this operation.

Measurements and barriers are considered final if they are followed by no other operations (aside from other measurements or barriers.)

Note

This method has rather complex behavior, particularly around the removal of newly idle classical bits and registers. It is much more efficient to avoid adding unnecessary classical data in the first place, rather than trying to remove it later.

See also

RemoveFinalMeasurements

A transpiler pass that removes final measurements and barriers. This does not remove the classical data. If this is your goal, you can call that with:

from qiskit.circuit import QuantumCircuit
from qiskit.transpiler.passes import RemoveFinalMeasurements

qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.barrier()
qc.measure([0, 1], [0, 1])

pass_ = RemoveFinalMeasurements()
just_bell = pass_(qc)
Parameters:

inplace (bool) -- All measurements removed inplace or return new circuit.

Returns:

Returns the resulting circuit when inplace=False, else None.

Return type:

QuantumCircuit

Circuit properties

Simple circuit metrics

When constructing quantum circuits, there are several properties that help quantify the "size" of the circuits, and their ability to be run on a noisy quantum device. Some of these, like number of qubits, are straightforward to understand, while others like depth and number of tensor components require a bit more explanation. Here we will explain all of these properties, and, in preparation for understanding how circuits change when run on actual devices, highlight the conditions under which they change.

Consider the following circuit:

From the plot, it is easy to see that this circuit has 12 qubits, and a collection of Hadamard, CNOT, X, and SWAP gates. But how to quantify this programmatically? Because we can do single-qubit gates on all the qubits simultaneously, the number of qubits in this circuit is equal to the width() of the circuit:

assert qc.width() == 12

We can also just get the number of qubits directly using num_qubits:

assert qc.num_qubits == 12

Important

For a quantum circuit composed from just qubits, the circuit width is equal to the number of qubits. This is the definition used in quantum computing. However, for more complicated circuits with classical registers, and classically controlled gates, this equivalence breaks down. As such, from now on we will not refer to the number of qubits in a quantum circuit as the width.

It is also straightforward to get the number and type of the gates in a circuit using count_ops():

qc.count_ops()
OrderedDict([('cx', 8), ('h', 5), ('x', 3), ('swap', 3)])

We can also get just the raw count of operations by computing the circuits size():

assert qc.size() == 19
count_ops() → OrderedDict[str, int][source]

Count each operation kind in the circuit.

Returns:

A breakdown of how many operations of each kind, sorted by amount.

depth(filter_function: ~collections.abc.Callable[[~qiskit._accelerate.circuit.CircuitInstruction], bool] = <function QuantumCircuit.<lambda>>) → int[source]

Return circuit depth (i.e., length of critical path).

The depth of a quantum circuit is a measure of how many "layers" of quantum gates, executed in parallel, it takes to complete the computation defined by the circuit. Because quantum gates take time to implement, the depth of a circuit roughly corresponds to the amount of time it takes the quantum computer to execute the circuit.

Warning

This operation is not well defined if the circuit contains control-flow operations.

Parameters:

filter_function -- A function to decide which instructions count to increase depth. Should take as a single positional input a CircuitInstruction. Instructions for which the function returns False are ignored in the computation of the circuit depth. By default, filters out "directives", such as Barrier.

Returns:

Depth of circuit.

Return type:

int

Examples

Simple calculation of total circuit depth:

from qiskit.circuit import QuantumCircuit
qc = QuantumCircuit(4)
qc.h(0)
qc.cx(0, 1)
qc.h(2)
qc.cx(2, 3)
assert qc.depth() == 2

Modifying the previous example to only calculate the depth of multi-qubit gates:

assert qc.depth(lambda instr: len(instr.qubits) > 1) == 1
get_instructions(name: str) → list[CircuitInstruction][source]

Get instructions matching name.

Parameters:

name (str) -- The name of instruction to get.

Returns:

list of (instruction, qargs, cargs).

Return type:

list(tuple)

num_connected_components(unitary_only: bool = False) → int[source]

How many non-entangled subcircuits can the circuit be factored to.

Parameters:

unitary_only (bool) -- Compute only unitary part of graph.

Returns:

Number of connected components in circuit.

Return type:

int

num_nonlocal_gates() → int[source]

Return number of non-local gates (i.e. involving 2+ qubits).

Conditional nonlocal gates are also included.

num_tensor_factors() → int[source]

Computes the number of tensor factors in the unitary (quantum) part of the circuit only.

Notes

This is here for backwards compatibility, and will be removed in a future release of Qiskit. You should call num_unitary_factors instead.

num_unitary_factors() → int[source]

Computes the number of tensor factors in the unitary (quantum) part of the circuit only.

size(filter_function: ~collections.abc.Callable[[...], int] = <function QuantumCircuit.<lambda>>) → int[source]

Returns total number of instructions in circuit.

Parameters:

filter_function (callable) -- a function to filter out some instructions. Should take as input a tuple of (Instruction, list(Qubit), list(Clbit)). By default, filters out "directives", such as barrier or snapshot.

Returns:

Total number of gate operations.

Return type:

int

width() → int[source]

Return number of qubits plus clbits in circuit.

Returns:

Width of circuit.

Return type:

int

Accessing scheduling information

If a QuantumCircuit has been scheduled as part of a transpilation pipeline, the timing information for individual qubits can be accessed. The whole-circuit timing information is available through the estimate_duration() method and op_start_times attribute.

estimate_duration(target, unit: str = 's') → int | float[source]

Estimate the duration of a scheduled circuit

This method computes the estimate of the circuit duration by finding the longest duration path in the circuit based on the durations provided by a given target. This method only works for simple circuits that have no control flow or other classical feed-forward operations.

Parameters:
  • target (Target) -- The Target instance that contains durations for the instructions if the target is missing duration data for any of the instructions in the circuit an QiskitError will be raised. This should be the same target object used as the target for transpilation.

  • unit -- The unit to return the duration in. This defaults to "s" for seconds but this can be a supported SI prefix for seconds returns. For example setting this to "n" will return in unit of nanoseconds. Supported values of this type are "f", "p", "n", "u", "µ", "m", "k", "M", "G", "T", and "P". Additionally, a value of "dt" is also accepted to output an integer in units of "dt". For this to function "dt" must be specified in the target.

Returns:

The estimated duration for the execution of a single shot of the circuit in the specified unit.

Raises:

QiskitError -- If the circuit is not scheduled or contains other details that prevent computing an estimated duration from (such as parameterized delay).

qubit_duration(*qubits: Qubit | int) → float[source]

Return the duration between the start and stop time of the first and last instructions, excluding delays, over the supplied qubits. Its time unit is self.unit.

Parameters:

*qubits -- Qubits within self to include.

Returns:

Return the duration between the first start and last stop time of non-delay instructions

qubit_start_time(*qubits: Qubit | int) → float[source]

Return the start time of the first instruction, excluding delays, over the supplied qubits. Its time unit is self.unit.

Return 0 if there are no instructions over qubits

Parameters:
  • *qubits -- Qubits within self to include. Integers are allowed for qubits, indicating

  • self.qubits. (indices of)

Returns:

Return the start time of the first instruction, excluding delays, over the qubits

Raises:

CircuitError -- if self is a not-yet scheduled circuit.

qubit_stop_time(*qubits: Qubit | int) → float[source]

Return the stop time of the last instruction, excluding delays, over the supplied qubits. Its time unit is self.unit.

Return 0 if there are no instructions over qubits

Parameters:
  • *qubits -- Qubits within self to include. Integers are allowed for qubits, indicating

  • self.qubits. (indices of)

Returns:

Return the stop time of the last instruction, excluding delays, over the qubits

Raises:

CircuitError -- if self is a not-yet scheduled circuit.

Abstract and physical circuits

Circuits are a fairly low-level abstraction of quantum algorithms. However, even within this, there are distinctions. Quantum programmers often want to use a wide array of gates and instructions, and work in a regime where all qubits and interact with all others. Quantum hardware, however, typically has a restrictive set of native gates, and only certain pairs of hardware qubits can interact. We term these two regimes "abstract circuits" and "physical circuits", respectively.

Qiskit has two ways of distinguishing a circuit that is intended to be physical. This is a fuzzy check, for historical reasons; originally, Qiskit never made the distinction at all (which is why transpile() is called that, and not called compile!). The most explicit way is through the layout attribute of circuits; if this is set, the circuit is certainly intended to be physical. The older, more implicit, way is the metadata of the Qubit objects and QuantumRegister instances in the circuit. A circuit can only be considered (as judged by several transpiler passes) as physical if it contains exactly one quantum register, which is called q and owns all the circuit qubits in index order. Again for historical reasons, this is the default for the QuantumCircuit(int [, int]) form of the default constructor.

Normally, you create a QuantumCircuit and build it in the abstract sense (regardless of the qubit metadata). You then call transpile() to compile the circuit into a hardware-supported circuit. However, in cases where you want to write a hardware efficient circuit from the beginning, you can short-circuit the full compilation infrastructure using the ensure_physical() method. This will ensure that, no matter how you defined the initial qubit metadata, all requirements for the circuit to be considered physical will be satisfied, with the qubit indices mapped to the hardware qubits.

For more complete control over choosing a virtual-to-physical mapping and routing, see the layout and routing <transpiler-preset-stage-routing> stages of the preset compilation pipelines.

ensure_physical(num_qubits: int | None = None, *, apply_layout: bool = True) → bool[source]

Put this circuit into canonical physical form, with the given number of qubits, if it is not already.

Several Qiskit transpiler passes only make sense when applied to circuits defined in terms of physical qubits. If you have manually constructed a circuit where the qubit indices correspond to physical qubits, use this function to ensure that the metadata of the circuit matches the canonical physical form. This means replacing the qubit data with a single owning register called "q", and (optionally) setting the layout field of the circuit to link these physical qubits with the original virtual ones.

If the circuit does not already have a layout, this method (with apply_layout=True) is equivalent to applying the full trivial layout method of the preset compilation pipeline.

If the circuit is already canonically physical, nothing happens to it. This method cannot change the number of qubits in the circuit if it already has a layout set.

Parameters:
  • num_qubits -- if given, expand the circuit with ancillas up to this size. The ancillas will always be the highest qubit indices of the circuit. If not given (the default), the circuit stays the same width. This option cannot be set if the circuit already as a layout.

  • apply_layout -- if true (the default), set the layout attribute of the circuit appropriately so that the circuit appears to have been laid out with the "trivial" layout, including ancilla expansion, for a backend of width num_qubits. This has no effect if the circuit already had a layout.

Returns:

whether the circuit was modified in order to make it physical.

Raises:
  • ValueError -- if num_qubits is too small for the circuit.

  • CircuitError -- if num_qubits is set to attempt to expand the circuit, but the circuit already has a layout set.

estimate_fidelity(target) → float | None[source]

Estimate the fidelity of a physical circuit.

This function will compute the product of the error rates for each gate in the circuit to estimate the fidelity of the circuit:

..math::
label:

estimated circuit fidelity

prod_{g in text{gates}} bigl(1 - operatorname{error}(g)bigr)

where \(\operatorname{error}(g)\) is the error rate in the target for the instruction \(g\) from the circuit in the target. If the circuit is not physical, meaning any instruction in the circuit (as in operation and qargs) is not found in the target, this will return None. This method is not intended to compute a realistic simulation of the fidelity of execution on real hardware. It is designed to provide an estimate of how the transpiler would work with the fidelity for various heuristics in its operation. It is typically only useful for comparing different compilation outputs against each other to estimate which one would produce a better quality execution on hardware.

Parameters:

target (Target) -- The Target instance that the circuit will be executed on and used to get the error rates for the instructions in the circuit.

Returns:

The estimated fidelity of executing the circuit on the given target. If any instruction in the circuit is not present in target

Raises:

QiskitError -- If the circuit contains any control flow operations.

Instruction-like methods

QuantumCircuit also contains a small number of methods that are very Instruction-like in detail. You may well find better integration and more API support if you first convert your circuit to an Instruction (to_instruction()) or Gate (to_gate()) as appropriate, then call the corresponding method.

control(num_ctrl_qubits: int = 1, label: str | None = None, ctrl_state: str | int | None = None, annotated: bool | None = None) → QuantumCircuit[source]

Return the controlled version of this circuit.

The original circuit is converted into a gate, and the resulting circuit contains the controlled version of this gate. This controlled gate is implemented as ControlledGate when annotated is False, and as AnnotatedOperation when annotated is True.

Deprecated since version 2.3: qiskit.circuit.quantumcircuit.QuantumCircuit.control()'s argument annotated is deprecated as of Qiskit 2.3. It will be removed in Qiskit 3.0. The method QuantumCircuit.control() no longer accepts annotated=None. The new default is annotated=True, which represents the controlled gate in the new quantum circuit as an AnnotatedOperation (unless a dedicated controlled-gate class already exists). You can explicitly set annotated=False to preserve the previous behavior. However, using annotated=True is recommended, as it defers construction of the controlled circuit to transpiler, and furthermore enables additional controlled-gate optimizations (typically leading to higher-quality circuits).

Parameters:
  • num_ctrl_qubits -- Number of controls to add. Defaults to 1.

  • label -- An optional label to give the controlled gate for visualization. Defaults to None. Ignored if the controlled gate is implemented as an annotated operation.

  • ctrl_state -- The control state of the gate, specified either as an integer or a bitstring (e.g. "110"). If None, defaults to the all-ones state 2**num_ctrl_qubits - 1.

  • annotated -- Indicates whether the controlled gate should be implemented as a controlled gate or as an annotated operation.

Returns:

The controlled version of this circuit.

Return type:

QuantumCircuit

Raises:

CircuitError -- If the circuit contains a non-unitary operation and cannot be controlled.

inverse(annotated: bool = False) → QuantumCircuit[source]

Invert (take adjoint of) this circuit.

This is done by recursively inverting all gates.

Parameters:

annotated -- indicates whether the inverse gate can be implemented as an annotated gate.

Returns:

the inverted circuit

Return type:

QuantumCircuit

Raises:

CircuitError -- if the circuit cannot be inverted.

Examples

input:

     ┌───┐
q_0: ┤ H ├─────■──────
     └───┘┌────┴─────┐
q_1: ─────┤ RX(1.57) ├
          └──────────┘

output:

                  ┌───┐
q_0: ──────■──────┤ H ├
     ┌─────┴─────┐└───┘
q_1: ┤ RX(-1.57) ├─────
     └───────────┘
power(power: float, matrix_power: bool = False, annotated: bool = False) → QuantumCircuit[source]

Raise this circuit to the power of power.

If power is a positive integer and both matrix_power and annotated are False, this implementation defaults to calling repeat. Otherwise, the circuit is converted into a gate, and a new circuit, containing this gate raised to the given power, is returned. The gate raised to the given power is implemented either as a unitary gate if annotated is False or as an annotated operation if annotated is True.

Parameters:
  • power (float) -- The power to raise this circuit to.

  • matrix_power (bool) -- indicates whether the inner power gate can be implemented as a unitary gate.

  • annotated (bool) -- indicates whether the inner power gate can be implemented as an annotated operation.

Raises:

CircuitError -- If the circuit needs to be converted to a unitary gate, but is not unitary.

Returns:

A circuit implementing this circuit raised to the power of power.

Return type:

QuantumCircuit

repeat(reps: int, *, insert_barriers: bool = False) → QuantumCircuit[source]

Repeat this circuit reps times.

Parameters:
  • reps (int) -- How often this circuit should be repeated.

  • insert_barriers (bool) -- Whether to include barriers between circuit repetitions.

Returns:

A circuit containing reps repetitions of this circuit.

Return type:

QuantumCircuit

reverse_ops() → QuantumCircuit[source]

Reverse the circuit by reversing the order of instructions.

This is done by recursively reversing all instructions. It does not invert (adjoint) any gate.

Returns:

the reversed circuit.

Return type:

QuantumCircuit

Examples

input:

     ┌───┐
q_0: ┤ H ├─────■──────
     └───┘┌────┴─────┐
q_1: ─────┤ RX(1.57) ├
          └──────────┘

output:

                 ┌───┐
q_0: ─────■──────┤ H ├
     ┌────┴─────┐└───┘
q_1: ┤ RX(1.57) ├─────
     └──────────┘

Visualization

Qiskit includes some drawing tools to give you a quick feel for what your circuit looks like. This tooling is primarily targeted at producing either a Matplotlib- or text-based drawing. There is also a lesser-featured LaTeX backend for drawing, but this is only for simple circuits, and is not as actively maintained.

See also

qiskit.visualization

The primary documentation for all of Qiskit's visualization tooling.

draw(output: str | None = None, scale: float | None = None, filename: str | None = None, style: dict | str | None = None, interactive: bool = False, plot_barriers: bool = True, reverse_bits: bool | None = None, justify: str | None = None, vertical_compression: str | None = 'medium', idle_wires: bool | str | None = None, with_layout: bool = True, fold: int | None = None, ax: Any | None = None, initial_state: bool = False, cregbundle: bool | None = None, wire_order: list[int] | None = None, expr_len: int = 30, measure_arrows: bool | None = None, barrier_label_len: int = 16)[source]

Draw the quantum circuit. Use the output parameter to choose the drawing format:

text

ASCII art TextDrawing that can be printed in the console.

mpl

Images with color rendered purely in Python using matplotlib.

latex

High-quality images compiled via LaTeX.

Warning

This will call an installed system version of pdflatex on arbitrary user input by design (such as to render custom code in Instruction.label), so should only be used on trusted input.

latex_source

Raw uncompiled LaTeX output. This is the source of what would be rendered by the latex drawer.

Warning

Support for Expr nodes in conditions and SwitchCaseOp.target fields is preliminary and incomplete. The text and mpl drawers will make a best-effort attempt to show data dependencies, but the LaTeX-based drawers will skip these completely.

Parameters:
  • output -- Select the output method to use for drawing the circuit. Valid choices are text, mpl, latex, latex_source. By default, the text drawer is used unless the user config file (usually ~/.qiskit/settings.conf) has an alternative backend set as the default. For example, circuit_drawer = latex. If the output kwarg is set, that backend will always be used over the default in the user config file.

  • scale -- Scale of image to draw (shrink if < 1.0). Only used by the mpl, latex and latex_source outputs. Defaults to 1.0.

  • filename -- File path to save image to. Defaults to None (result not saved in a file).

  • style --

    Style name, file name of style JSON file, or a dictionary specifying the style.

    • The supported style names are "iqp" (default), "iqp-dark", "clifford", "textbook" and "bw".

    • If given a JSON file, e.g. my_style.json or my_style (the .json extension may be omitted), this function attempts to load the style dictionary from that location. Note, that the JSON file must completely specify the visualization specifications. The file is searched for in qiskit/visualization/circuit/styles, the current working directory, and the location specified in ~/.qiskit/settings.conf.

    • If a dictionary, every entry overrides the default configuration. If the "name" key is given, the default configuration is given by that style. For example, {"name": "textbook", "subfontsize": 5} loads the "textbook" style and sets the subfontsize (e.g. the gate angles) to 5.

    • If None the default style "iqp" is used or, if given, the default style specified in ~/.qiskit/settings.conf.

  • interactive -- When set to True, show the circuit in a new window (for mpl this depends on the matplotlib backend being used supporting this). Note when used with either the text or the latex_source output type this has no effect and will be silently ignored. Defaults to False.

  • reverse_bits -- When set to True, reverse the bit order inside registers for the output visualization. Defaults to False unless the user config file (usually ~/.qiskit/settings.conf) has an alternative value set. For example, circuit_reverse_bits = True.

  • plot_barriers -- Enable/disable drawing barriers in the output circuit. Defaults to True.

  • justify -- Options are "left", "right" or "none" (str). If anything else is supplied, left justified will be used instead. It refers to where gates should be placed in the output circuit if there is an option. none results in each gate being placed in its own column. Defaults to left.

  • vertical_compression -- high, medium or low. It merges the lines generated by the text output so the drawing will take less vertical room. Default is medium. Only used by the text output, will be silently ignored otherwise.

  • idle_wires -- Include (or not) idle wires (wires with no circuit elements) in output visualization. The string "auto" is also possible, in which case idle wires are shown except when the circuit has a layout attached. Default is "auto" unless the user config file (usually ~/.qiskit/settings.conf) has an alternative value set. For example, circuit_idle_wires = False.

  • with_layout -- Include layout information, with labels on the physical layout. Default is True.

  • fold -- Sets pagination. It can be disabled using -1. In text, sets the length of the lines. This is useful when the drawing does not fit in the console. If None (default), it will try to guess the console width using shutil.get_terminal_size(). However, if running in jupyter, the default line length is set to 80 characters. In mpl, it is the number of (visual) layers before folding. Default is 25.

  • ax -- Only used by the mpl backend. An optional matplotlib.axes.Axes object to be used for the visualization output. If none is specified, a new matplotlib Figure will be created and used. Additionally, if specified there will be no returned Figure since it is redundant.

  • initial_state -- Adds \(|0\rangle\) in the beginning of the qubit wires and \(0\) to classical wires. Default is False.

  • cregbundle -- If set to True, bundle classical registers. Default is True, except for when output is set to "text".

  • wire_order -- A list of integers used to reorder the display of the bits. The list must have an entry for every bit with the bits in the range 0 to (num_qubits + num_clbits).

  • expr_len -- The number of characters to display if an Expr is used for the condition in a ControlFlowOp. If this number is exceeded, the string will be truncated at that number and '...' added to the end.

  • measure_arrows -- If True, draw an arrow from each measure box down to the classical bit or register where the measure value is placed. If False, do not draw arrow, but instead place the name of the bit or register in the measure box. Default is True unless the user config file (usually ~/.qiskit/settings.conf) has an alternative value set. For example, circuit_measure_arrows = False.

  • barrier_label_len -- The number of characters to display for Barrier labels in the output circuit. If this number is exceeded, the string will be truncated at that number and '...' added to the end.

Returns:

TextDrawing or matplotlib.figure or PIL.Image or str:

  • TextDrawing (if output='text')

    A drawing that can be printed as ascii art.

  • matplotlib.figure.Figure (if output='mpl')

    A matplotlib figure object for the circuit diagram.

  • PIL.Image (if output='latex')

    An in-memory representation of the image of the circuit diagram.

  • str (if output='latex_source')

    The LaTeX source code for visualizing the circuit diagram.

Raises:
  • VisualizationError -- when an invalid output method is selected

  • ImportError -- when the output methods requires non-installed libraries.

Example

In addition to the core draw() driver, there are two visualization-related helper methods, which are mostly useful for quickly unwrapping some inner instructions or reversing the qubit-labelling conventions in the drawing. For more general mutation, including basis-gate rewriting, you should use the transpiler (qiskit.transpiler).

decompose(gates_to_decompose: str | type[Instruction] | Sequence[str | type[Instruction]] | None = None, reps: int = 1) → Self[source]

Call a decomposition pass on this circuit, to decompose one level (shallow decompose).

Parameters:
  • gates_to_decompose -- Optional subset of gates to decompose. Can be a gate type, such as HGate, or a gate name, such as "h", or a gate label, such as "My H Gate", or a list of any combination of these. If a gate name is entered, it will decompose all gates with that name, whether the gates have labels or not. Defaults to all gates in the circuit.

  • reps -- Optional number of times the circuit should be decomposed. For instance, reps=2 equals calling circuit.decompose().decompose().

Returns:

a circuit one level decomposed

Return type:

QuantumCircuit

reverse_bits() → QuantumCircuit[source]

Return a circuit with the opposite order of wires.

The circuit is "vertically" flipped. If a circuit is defined over multiple registers, the resulting circuit will have the same registers but with their order flipped.

This method is useful for converting a circuit written in little-endian convention to the big-endian equivalent, and vice versa.

Returns:

the circuit with reversed bit order.

Return type:

QuantumCircuit

Examples

input:

     ┌───┐
a_0: ┤ H ├──■─────────────────
     └───┘┌─┴─┐
a_1: ─────┤ X ├──■────────────
          └───┘┌─┴─┐
a_2: ──────────┤ X ├──■───────
               └───┘┌─┴─┐
b_0: ───────────────┤ X ├──■──
                    └───┘┌─┴─┐
b_1: ────────────────────┤ X ├
                         └───┘

output:

                         ┌───┐
b_0: ────────────────────┤ X ├
                    ┌───┐└─┬─┘
b_1: ───────────────┤ X ├──■──
               ┌───┐└─┬─┘
a_0: ──────────┤ X ├──■───────
          ┌───┐└─┬─┘
a_1: ─────┤ X ├──■────────────
     ┌───┐└─┬─┘
a_2: ┤ H ├──■─────────────────
     └───┘
_append(instruction: CircuitInstruction, *, _standard_gate: bool) → CircuitInstruction[source]
_append(instruction: Operation, qargs: Sequence[Qubit], cargs: Sequence[Clbit]) → Operation

Append an instruction to the end of the circuit, modifying the circuit in place.

Warning

This is an internal fast-path function, and it is the responsibility of the caller to ensure that all the arguments are valid; there is no error checking here. In particular:

  • all the qubits and clbits must already exist in the circuit and there can be no duplicates in the list.

  • any control-flow operations instructions must act only on variables present in the circuit.

  • the circuit must not be within a control-flow builder context.

Note

This function may be used by callers other than QuantumCircuit when the caller is sure that all error-checking, broadcasting and scoping has already been performed, and the only reference to the circuit the instructions are being appended to is within that same function. In particular, it is not safe to call QuantumCircuit._append() on a circuit that is received by a function argument. This is because QuantumCircuit._append() will not recognize the scoping constructs of the control-flow builder interface.

Parameters:
  • instruction --

    A complete well-formed CircuitInstruction of the operation and its context to be added.

    In the legacy compatibility form, this can be a bare Operation, in which case qargs and cargs must be explicitly given.

  • qargs -- Legacy argument for qubits to attach the bare Operation to. Ignored if the first argument is in the preferential CircuitInstruction form.

  • cargs -- Legacy argument for clbits to attach the bare Operation to. Ignored if the first argument is in the preferential CircuitInstruction form.

Returns:

a handle to the instruction that was just added.

Return type:

CircuitInstruction

add_bits(bits: Iterable[Bit]) → None[source]

Add Bits to the circuit.

Warning

If the quantum circuit has an existing layout attribute, adding a Qubit will only increase the number of qubits. It will not update the layout.

add_capture(var: Var)[source]
add_capture(stretch: Stretch)

Add an identifier to the circuit that it should capture from a scope it will be contained within.

This method requires a Var or Stretch node to enforce that you've got a handle to an identifier, because you will need to declare the same identifier using the same object in the outer circuit.

This is a low-level method, which is only really useful if you are manually constructing control-flow operations. You typically will not need to call this method, assuming you are using the builder interface for control-flow scopes (with context-manager statements for if_test() and the other scoping constructs). The builder interface will automatically make the inner scopes closures on your behalf by capturing any identifiers that are used within them.

Parameters:

var (Union[expr.Var, expr.Stretch]) -- the variable or stretch to capture from an enclosing scope.

Raises:

CircuitError -- if the identifier cannot be created due to shadowing an existing identifier.

add_input(name_or_var: str, type_: Type, /) → Var[source]
add_input(name_or_var: Var, type_: None = None, /) → Var

Register a variable as an input to the circuit.

Parameters:
  • name_or_var -- either a string name, or an existing Var node to use as the input variable.

  • type -- if the name is given as a string, then this must be a Type to use for the variable. If the variable is given as an existing Var, then this must not be given, and will instead be read from the object itself.

Returns:

the variable created, or the same variable as was passed in.

Raises:

CircuitError -- if the variable cannot be created due to shadowing an existing variable.

add_register(*regs: Register | int | Sequence[Bit]) → None[source]

Add registers.

Warning

If the quantum circuit has an existing layout attribute, adding a QuantumRegister will only increase the number of qubits. It will not update the layout.

add_stretch(name_or_stretch: str | Stretch) → Stretch[source]

Declares a new stretch scoped to this circuit.

Parameters:

name_or_stretch -- either a string of the stretch name, or an existing instance of Stretch to re-use. Stretches cannot shadow names that are already in use within the circuit.

Returns:

The created stretch. If a Stretch instance was given, the exact same object will be returned.

Raises:

CircuitError -- if the stretch cannot be created due to shadowing an existing identifier.

Examples

Define and use a new stretch given just a name:

from qiskit.circuit import QuantumCircuit, Duration
from qiskit.circuit.classical import expr

qc = QuantumCircuit(2)
my_stretch = qc.add_stretch("my_stretch")

qc.delay(expr.add(Duration.dt(200), my_stretch), 1)
add_uninitialized_var(var: Var, /)[source]

Add a variable with no initializer.

In most cases, you should use add_var() to initialize the variable. To use this function, you must already hold a Var instance, as the use of the function typically only makes sense in copying contexts.

Warning

Qiskit makes no assertions about what an uninitialized variable will evaluate to at runtime, and some hardware may reject this as an error.

You should treat this function with caution, and as a low-level primitive that is useful only in special cases of programmatically rebuilding two like circuits.

Parameters:

var -- the variable to add.

add_var(name_or_var: str | Var, /, initial: Any) → Var[source]

Add a classical variable with automatic storage and scope to this circuit.

The variable is considered to have been "declared" at the beginning of the circuit, but it only becomes initialized at the point of the circuit that you call this method, so it can depend on variables defined before it.

Parameters:
  • name_or_var -- either a string of the variable name, or an existing instance of Var to re-use. Variables cannot shadow names that are already in use within the circuit.

  • initial --

    the value to initialize this variable with. If the first argument was given as a string name, the type of the resulting variable is inferred from the initial expression; to control this more manually, either use Var.new() to manually construct a new variable with the desired type, or use expr.cast() to cast the initializer to the desired type.

    This must be either a Expr node, or a value that can be lifted to one using expr.lift.

Returns:

The created variable. If a Var instance was given, the exact same object will be returned.

Raises:

CircuitError -- if the variable cannot be created due to shadowing an existing identifier.

Examples

Define a new variable given just a name and an initializer expression:

from qiskit.circuit import QuantumCircuit

qc = QuantumCircuit(2)
my_var = qc.add_var("my_var", False)

Reuse a variable that may have been taken from a related circuit, or otherwise constructed manually, and initialize it to some more complicated expression:

from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.circuit.classical import expr, types

my_var = expr.Var.new("my_var", types.Uint(8))

cr1 = ClassicalRegister(8, "cr1")
cr2 = ClassicalRegister(8, "cr2")
qc = QuantumCircuit(QuantumRegister(8), cr1, cr2)

# Get some measurement results into each register.
qc.h(0)
for i in range(1, 8):
    qc.cx(0, i)
qc.measure(range(8), cr1)

qc.reset(range(8))
qc.h(0)
for i in range(1, 8):
    qc.cx(0, i)
qc.measure(range(8), cr2)

# Now when we add the variable, it is initialized using the real-time state of the
# two classical registers we measured into above.
qc.add_var(my_var, expr.bit_and(cr1, cr2))
property ancillas: list[AncillaQubit]

A list of AncillaQubits in the order that they were added. You should not mutate this.

append(instruction: Operation | CircuitInstruction, qargs: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]] | None = None, cargs: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]] | None = None, *, copy: bool = True) → InstructionSet[source]

Append one or more instructions to the end of the circuit, modifying the circuit in place.

The qargs and cargs will be expanded and broadcast according to the rules of the given Instruction, and any non-Bit specifiers (such as integer indices) will be resolved into the relevant instances.

If a CircuitInstruction is given, it will be unwrapped, verified in the context of this circuit, and a new object will be appended to the circuit. In this case, you may not pass qargs or cargs separately.

Parameters:
  • instruction -- Instruction instance to append, or a CircuitInstruction with all its context. Objects implementing to_instruction are also supported, but passing an Instruction directly is generally preferred, since that avoids the repeated conversion cost.

  • qargs -- specifiers of the Qubits to attach instruction to.

  • cargs -- specifiers of the Clbits to attach instruction to.

  • copy -- if True (the default), then the incoming instruction is copied before adding it to the circuit if it contains symbolic parameters, so it can be safely mutated without affecting other circuits the same instruction might be in. If you are sure this instruction will not be in other circuits, you can set this False for a small speedup.

Returns:

a handle to the CircuitInstructions that were actually added to the circuit.

Return type:

qiskit.circuit.InstructionSet

Raises:

CircuitError -- if the operation passed is not an instance of Instruction, or cannot be converted to one by calling to_instruction on it.

assign_parameters(parameters: Mapping[Parameter, ParameterExpression | float] | Iterable[ParameterExpression | float], inplace: Literal[False] = False, *, flat_input: bool = False, strict: bool = True) → QuantumCircuit[source]
assign_parameters(parameters: Mapping[Parameter, ParameterExpression | float] | Iterable[ParameterExpression | float], inplace: Literal[True] = False, *, flat_input: bool = False, strict: bool = True) → None

Assign parameters to new parameters or values.

If parameters is passed as a dictionary, the keys should be Parameter instances in the current circuit. The values of the dictionary can either be numeric values or new parameter objects.

If parameters is passed as a list or array, the elements are assigned to the current parameters in the order of parameters which is sorted alphabetically (while respecting the ordering in ParameterVector objects).

The values can be assigned to the current circuit object or to a copy of it.

Note

When parameters is given as a mapping, it is permissible to have keys that are strings of the parameter names; these will be looked up using get_parameter(). You can also have keys that are ParameterVector instances, and in this case, the dictionary value should be a sequence of values of the same length as the vector.

If you use either of these cases, you must leave the setting flat_input=False; changing this to True enables the fast path, where all keys must be Parameter instances.

Parameters:
  • parameters -- Either a dictionary or iterable specifying the new parameter values.

  • inplace -- If False, a copy of the circuit with the bound parameters is returned. If True the circuit instance itself is modified.

  • flat_input -- If True and parameters is a mapping type, it is assumed to be exactly a mapping of {parameter: value}. By default (False), the mapping may also contain ParameterVector keys that point to a corresponding sequence of values, and these will be unrolled during the mapping, or string keys, which will be converted to Parameter instances using get_parameter().

  • strict -- If False, any parameters given in the mapping that are not used in the circuit will be ignored. If True (the default), an error will be raised indicating a logic error.

Raises:
  • CircuitError -- If parameters is a dict and contains parameters not present in the circuit.

  • ValueError -- If parameters is a list/array and the length mismatches the number of free parameters in the circuit.

Returns:

A copy of the circuit with bound parameters if inplace is False, otherwise None.

Examples

Create a parameterized circuit and assign the parameters in-place.

Bind the values out-of-place by list and get a copy of the original circuit.

barrier(*qargs: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label=None) → InstructionSet[source]

Apply Barrier. If qargs is empty, applies to all qubits in the circuit.

Parameters:
  • qargs (QubitSpecifier) -- Specification for one or more qubit arguments.

  • label (str) -- The string label of the barrier.

Returns:

handle to the added instructions.

Return type:

qiskit.circuit.InstructionSet

box(body_or_annotations: QuantumCircuit | Iterable[Annotation] = Ellipsis, /, qubits: Sequence[QubitSpecifier] | None = None, clbits: Sequence[ClbitSpecifier] | None = None, *, label: str | None = None, duration: None = None, unit: Literal['dt', 's', 'ms', 'us', 'ns', 'ps', 'expr'] | None = None, annotations: Iterable[Annotation] = Ellipsis)[source]

Create a box of operations on this circuit that are treated atomically in the greater context.

A "box" is a control-flow construct that is entered unconditionally. The contents of the box behave somewhat as if the start and end of the box were barriers (see barrier()), except it is permissible to commute operations "all the way" through the box. The box is also an explicit scope for the purposes of variables, stretches and compiler passes.

There are two forms for calling this function:

  • Pass a QuantumCircuit positionally, and the qubits and clbits it acts on. In this form, a BoxOp is immediately created and appended using the circuit as the body.

  • Use in a with statement with no body, qubits or clbits. This is the "builder-interface form", where you then use other QuantumCircuit methods within the Python with scope to add instructions to the box. This is the preferred form, and much less error prone.

Examples

Using the builder interface to add two boxes in sequence. The two boxes in this circuit can execute concurrently, and the second explicitly inserts a data-flow dependency on qubit 8 for the duration of the box, even though the qubit is idle.

from qiskit.circuit import QuantumCircuit, Annotation

class MyAnnotation(Annotation):
    namespace = "my.namespace"

qc = QuantumCircuit(9)
with qc.box():
    qc.cz(0, 1)
    qc.cz(2, 3)
with qc.box([MyAnnotation()]):
    qc.cz(4, 5)
    qc.cz(6, 7)
    qc.noop(8)

Using the explicit construction of box. This creates the same circuit as above, and should give an indication why the previous form is preferred for interactive use.

from qiskit.circuit import QuantumCircuit, BoxOp

body_0 = QuantumCircuit(4)
body_0.cz(0, 1)
body_0.cz(2, 3)

# Note that the qubit indices inside a body related only to the body.  The
# association with qubits in the containing circuit is made by the ``qubits``
# argument to `QuantumCircuit.box`.
body_1 = QuantumCircuit(5)
body_1.cz(0, 1)
body_1.cz(2, 3)

qc = QuantumCircuit(9)
qc.box(body_0, [0, 1, 2, 3], [])
qc.box(body_1, [4, 5, 6, 7, 8], [])
Parameters:
  • body_or_annotations -- the first positional argument is unnamed. If a QuantumCircuit is passed positionally, it is immediately used as the body of the box, and qubits and clbits must also be specified. If not given, or if given an iterable of Annotation objects, the context-manager form of this method is triggered.

  • qubits -- the qubits to apply the BoxOp to, in the explicit form.

  • clbits -- the clbits to apply the BoxOp to, in the explicit form.

  • label -- an optional string label for the instruction.

  • duration -- an optional explicit duration for the BoxOp. Scheduling passes are constrained to schedule the contained scope to match a given duration, including delay insertion if required.

  • unit -- the unit of the duration.

  • annotations -- any Annotation objects the box should have. When this method is used in context-manager form, this argument can instead be passed as the only positional argument.

break_loop() → InstructionSet[source]

Apply BreakLoopOp.

Warning

If you are using the context-manager "builder" forms of if_test(), for_loop() or while_loop(), you can only call this method if you are within a loop context, because otherwise the "resource width" of the operation cannot be determined. This would quickly lead to invalid circuits, and so if you are trying to construct a reusable loop body (without the context managers), you must also use the non-context-manager form of if_test() and if_else(). Take care that the BreakLoopOp instruction must span all the resources of its containing loop, not just the immediate scope.

Returns:

A handle to the instruction created.

Raises:

CircuitError -- if this method was called within a builder context, but not contained within a loop.

ccx(control_qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], control_qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CCXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit1 -- The qubit(s) used as the first control.

  • control_qubit2 -- The qubit(s) used as the second control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

ccz(control_qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], control_qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CCZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit1 -- The qubit(s) used as the first control.

  • control_qubit2 -- The qubit(s) used as the second control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '10'). Defaults to controlling on the '11' state.

Returns:

A handle to the instructions created.

ch(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CHGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

property clbits: list[Clbit]

A list of Clbits in the order that they were added. You should not mutate this.

Example

List the qubits in this circuit: [Qubit(QuantumRegister(2, 'q0'), 0),
Qubit(QuantumRegister(2, 'q0'), 1), Qubit(QuantumRegister(1, 'q1'), 0)]
List the classical bits in this circuit: [Clbit(ClassicalRegister(2, 'c0'), 0),
Clbit(ClassicalRegister(2, 'c0'), 1), Clbit(ClassicalRegister(1, 'c1'), 0)]
clear() → None[source]

Clear all instructions in self.

Clearing the circuits will keep the metadata.

See also

copy_empty_like()

A method to produce a new circuit with no instructions and all the same tracking of quantum and classical typed data, but without mutating the original circuit.

compose(other: QuantumCircuit | Instruction, qubits: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int] | Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]] | None = None, clbits: Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int] | Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]] | None = None, front: bool = False, inplace: Literal[True] = True, wrap: bool = False, *, copy: bool = True, var_remap: Mapping[str | Var | Stretch, str | Var | Stretch] | None = None, inline_captures: bool = False) → None[source]
compose(other: QuantumCircuit | Instruction, qubits: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int] | Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]] | None = None, clbits: Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int] | Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]] | None = None, front: bool = False, inplace: Literal[False] = False, wrap: bool = False, *, copy: bool = True, var_remap: Mapping[str | Var | Stretch, str | Var | Stretch] | None = None, inline_captures: bool = False) → QuantumCircuit

Apply the instructions from one circuit onto specified qubits and/or clbits on another.

Note

By default, this creates a new circuit object, leaving self untouched. For most uses of this function, it is far more efficient to set inplace=True and modify the base circuit in-place.

When dealing with realtime variables (expr.Var and expr.Stretch instances), there are two principal strategies for using compose():

  1. The other circuit is treated as entirely additive, including its variables. The variables in other must be entirely distinct from those in self (use var_remap to help with this), and all variables in other will be declared anew in the output with matching input/capture/local scoping to how they are in other. This is generally what you want if you're joining two unrelated circuits.

  2. The other circuit was created as an exact extension to self to be inlined onto it, including acting on the existing variables in their states at the end of self. In this case, other should be created with all these variables to be inlined declared as "captures", and then you can use inline_captures=True in this method to link them. This is generally what you want if you're building up a circuit by defining layers on-the-fly, or rebuilding a circuit using layers taken from itself. You might find the vars_mode="captures" argument to copy_empty_like() useful to create each layer's base, in this case.

Parameters:
  • other (qiskit.circuit.Instruction or QuantumCircuit) -- (sub)circuit or instruction to compose onto self. If not a QuantumCircuit, this can be anything that append will accept.

  • qubits (list[Qubit|int]) -- qubits of self to compose onto.

  • clbits (list[Clbit|int]) -- clbits of self to compose onto.

  • front (bool) -- If True, front composition will be performed. This is not possible within control-flow builder context managers.

  • inplace (bool) -- If True, modify the object. Otherwise, return composed circuit.

  • copy (bool) -- If True (the default), then the input is treated as shared, and any contained instructions will be copied, if they might need to be mutated in the future. You can set this to False if the input should be considered owned by the base circuit, in order to avoid unnecessary copies; in this case, it is not valid to use other afterward, and some instructions may have been mutated in place.

  • var_remap (Mapping) --

    mapping to use to rewrite expr.Var and expr.Stretch nodes in other as they are inlined into self. This can be used to avoid naming conflicts.

    Both keys and values can be given as strings or direct identifier instances. If a key is a string, it matches any Var or Stretch with the same name. If a value is a string, whenever a new key matches it, a new Var or Stretch is created with the correct type. If a value is a Var, its type must exactly match that of the variable it is replacing.

  • inline_captures (bool) --

    if True, then all "captured" identifier nodes in the other QuantumCircuit are assumed to refer to identifiers already declared in self (as any input/capture/local type), and the uses in other will apply to the existing identifiers. If you want to build up a layer for an existing circuit to use with compose(), you might find the vars_mode="captures" argument to copy_empty_like() useful. Any remapping in vars_remap occurs before evaluating this variable inlining.

    If this is False (the default), then all identifiers in other will be required to be distinct from those in self, and new declarations will be made for them.

  • wrap (bool) -- If True, wraps the other circuit into a gate (or instruction, depending on whether it contains only unitary instructions) before composing it onto self. Rather than using this option, it is almost always better to manually control this yourself by using to_instruction() or to_gate(), and then call append().

Returns:

the composed circuit (returns None if inplace==True).

Return type:

QuantumCircuit

Raises:
  • CircuitError -- if no correct wire mapping can be made between the two circuits, such as if other is wider than self.

  • CircuitError -- if trying to emit a new circuit while self has a partially built control-flow context active, such as the context-manager forms of if_test(), for_loop() and while_loop().

  • CircuitError -- if trying to compose to the front of a circuit when a control-flow builder block is active; there is no clear meaning to this action.

Examples

>>> lhs.compose(rhs, qubits=[3, 2], inplace=True)
            ┌───┐                   ┌─────┐                ┌───┐
lqr_1_0: ───┤ H ├───    rqr_0: ──■──┤ Tdg ├    lqr_1_0: ───┤ H ├───────────────
            ├───┤              ┌─┴─┐└─────┘                ├───┤
lqr_1_1: ───┤ X ├───    rqr_1: ┤ X ├───────    lqr_1_1: ───┤ X ├───────────────
         ┌──┴───┴──┐           └───┘                    ┌──┴───┴──┐┌───┐
lqr_1_2: ┤ U1(0.1) ├  +                     =  lqr_1_2: ┤ U1(0.1) ├┤ X ├───────
         └─────────┘                                    └─────────┘└─┬─┘┌─────┐
lqr_2_0: ─────■─────                           lqr_2_0: ─────■───────■──┤ Tdg ├
            ┌─┴─┐                                          ┌─┴─┐        └─────┘
lqr_2_1: ───┤ X ├───                           lqr_2_1: ───┤ X ├───────────────
            └───┘                                          └───┘
lcr_0: 0 ═══════════                           lcr_0: 0 ═══════════════════════

lcr_1: 0 ═══════════                           lcr_1: 0 ═══════════════════════
continue_loop() → InstructionSet[source]

Apply ContinueLoopOp.

Warning

If you are using the context-manager "builder" forms of if_test(), for_loop() or while_loop(), you can only call this method if you are within a loop context, because otherwise the "resource width" of the operation cannot be determined. This would quickly lead to invalid circuits, and so if you are trying to construct a reusable loop body (without the context managers), you must also use the non-context-manager form of if_test() and if_else(). Take care that the ContinueLoopOp instruction must span all the resources of its containing loop, not just the immediate scope.

Returns:

A handle to the instruction created.

Raises:

CircuitError -- if this method was called within a builder context, but not contained within a loop.

control(num_ctrl_qubits: int = 1, label: str | None = None, ctrl_state: str | int | None = None, annotated: bool | None = None) → QuantumCircuit[source]

Return the controlled version of this circuit.

The original circuit is converted into a gate, and the resulting circuit contains the controlled version of this gate. This controlled gate is implemented as ControlledGate when annotated is False, and as AnnotatedOperation when annotated is True.

Deprecated since version 2.3: qiskit.circuit.quantumcircuit.QuantumCircuit.control()'s argument annotated is deprecated as of Qiskit 2.3. It will be removed in Qiskit 3.0. The method QuantumCircuit.control() no longer accepts annotated=None. The new default is annotated=True, which represents the controlled gate in the new quantum circuit as an AnnotatedOperation (unless a dedicated controlled-gate class already exists). You can explicitly set annotated=False to preserve the previous behavior. However, using annotated=True is recommended, as it defers construction of the controlled circuit to transpiler, and furthermore enables additional controlled-gate optimizations (typically leading to higher-quality circuits).

Parameters:
  • num_ctrl_qubits -- Number of controls to add. Defaults to 1.

  • label -- An optional label to give the controlled gate for visualization. Defaults to None. Ignored if the controlled gate is implemented as an annotated operation.

  • ctrl_state -- The control state of the gate, specified either as an integer or a bitstring (e.g. "110"). If None, defaults to the all-ones state 2**num_ctrl_qubits - 1.

  • annotated -- Indicates whether the controlled gate should be implemented as a controlled gate or as an annotated operation.

Returns:

The controlled version of this circuit.

Return type:

QuantumCircuit

Raises:

CircuitError -- If the circuit contains a non-unitary operation and cannot be controlled.

copy(name: str | None = None) → Self[source]

Copy the circuit.

Parameters:

name (str) -- name to be given to the copied circuit. If None, then the name stays the same.

Returns:

a deepcopy of the current circuit, with the specified name

Return type:

QuantumCircuit

copy_empty_like(name: str | None = None, *, vars_mode: Literal['alike', 'captures', 'drop'] = 'alike') → Self[source]

Return a copy of self with the same structure but empty.

That structure includes:

  • name and other metadata

  • global phase

  • all the qubits and clbits, including the registers

  • the realtime variables defined in the circuit, handled according to the vars keyword argument.

Warning

If the circuit contains any local variable declarations (those added by the declarations argument to the circuit constructor, or using add_var()), they may be uninitialized in the output circuit. You will need to manually add store instructions for them (see Store and QuantumCircuit.store()) to initialize them.

Parameters:
  • name -- Name for the copied circuit. If None, then the name stays the same.

  • vars_mode --

    The mode to handle realtime variables in.

    alike

    The variables in the output circuit will have the same declaration semantics as in the original circuit. For example, input variables in the source will be input variables in the output circuit. Note that this causes the local variables to be uninitialised, because the stores are not copied. This can leave the circuit in a potentially dangerous state for users if they don't re-add initializer stores.

    captures

    All variables will be converted to captured variables. This is useful when you are building a new layer for an existing circuit that you will want to compose() onto the base, since compose() can inline captures onto the base circuit (but not other variables).

    drop

    The output circuit will have no variables defined.

Returns:

An empty copy of self.

Return type:

QuantumCircuit

count_ops() → OrderedDict[str, int][source]

Count each operation kind in the circuit.

Returns:

A breakdown of how many operations of each kind, sorted by amount.

cp(theta: ParameterExpression | float, control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CPhaseGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

property cregs: list[ClassicalRegister]

A list of Clbits in the order that they were added. You should not mutate this.

crx(theta: ParameterExpression | float, control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CRXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cry(theta: ParameterExpression | float, control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CRYGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

crz(theta: ParameterExpression | float, control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CRZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cs(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CSGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

csdg(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CSdgGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cswap(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CSwapGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit1 -- The qubit(s) targeted by the gate.

  • target_qubit2 -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

csx(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CSXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cu(theta: ParameterExpression | float, phi: ParameterExpression | float, lam: ParameterExpression | float, gamma: ParameterExpression | float, control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CUGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The \(\theta\) rotation angle of the gate.

  • phi -- The \(\phi\) rotation angle of the gate.

  • lam -- The \(\lambda\) rotation angle of the gate.

  • gamma -- The global phase applied of the U gate, if applied.

  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cx(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the control.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cy(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CYGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the controls.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

cz(control_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply CZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit -- The qubit(s) used as the controls.

  • target_qubit -- The qubit(s) targeted by the gate.

  • label -- The string label of the gate in the circuit.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

property data: QuantumCircuitData

The circuit data (instructions and context).

Example

[CircuitInstruction(operation=Instruction(name='measure', num_qubits=1,
num_clbits=1, params=[]), qubits=(Qubit(QuantumRegister(2, 'q'), 0),),
clbits=(Clbit(ClassicalRegister(2, 'c'), 1),))]
Returns:

A list-like object containing the CircuitInstruction instances in the circuit.

dcx(qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply DCXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • qubit1 -- The qubit(s) to apply the gate to.

  • qubit2 -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

decompose(gates_to_decompose: str | type[Instruction] | Sequence[str | type[Instruction]] | None = None, reps: int = 1) → Self[source]

Call a decomposition pass on this circuit, to decompose one level (shallow decompose).

Parameters:
  • gates_to_decompose -- Optional subset of gates to decompose. Can be a gate type, such as HGate, or a gate name, such as "h", or a gate label, such as "My H Gate", or a list of any combination of these. If a gate name is entered, it will decompose all gates with that name, whether the gates have labels or not. Defaults to all gates in the circuit.

  • reps -- Optional number of times the circuit should be decomposed. For instance, reps=2 equals calling circuit.decompose().decompose().

Returns:

a circuit one level decomposed

Return type:

QuantumCircuit

delay(duration: ParameterExpression | float | Expr, qarg: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int] | None = None, unit: str | None = None) → InstructionSet[source]

Apply Delay. If qarg is None, applies to all qubits. When applying to multiple qubits, delays with the same duration will be created.

Parameters:
  • duration (Object) -- duration of the delay. If this is an Expr, it must be a constant expression of type Duration.

  • qarg (Object) -- qubit argument to apply this delay.

  • unit (str | None) -- unit of the duration, unless duration is an Expr in which case it must not be specified. Supported units: 's', 'ms', 'us', 'ns', 'ps', and 'dt'. Default is 'dt', i.e. integer time unit depending on the target backend.

Returns:

handle to the added instructions.

Return type:

qiskit.circuit.InstructionSet

Raises:

CircuitError -- if arguments have bad format.

depth(filter_function: ~collections.abc.Callable[[~qiskit._accelerate.circuit.CircuitInstruction], bool] = <function QuantumCircuit.<lambda>>) → int[source]

Return circuit depth (i.e., length of critical path).

The depth of a quantum circuit is a measure of how many "layers" of quantum gates, executed in parallel, it takes to complete the computation defined by the circuit. Because quantum gates take time to implement, the depth of a circuit roughly corresponds to the amount of time it takes the quantum computer to execute the circuit.

Warning

This operation is not well defined if the circuit contains control-flow operations.

Parameters:

filter_function -- A function to decide which instructions count to increase depth. Should take as a single positional input a CircuitInstruction. Instructions for which the function returns False are ignored in the computation of the circuit depth. By default, filters out "directives", such as Barrier.

Returns:

Depth of circuit.

Return type:

int

Examples

Simple calculation of total circuit depth:

from qiskit.circuit import QuantumCircuit
qc = QuantumCircuit(4)
qc.h(0)
qc.cx(0, 1)
qc.h(2)
qc.cx(2, 3)
assert qc.depth() == 2

Modifying the previous example to only calculate the depth of multi-qubit gates:

assert qc.depth(lambda instr: len(instr.qubits) > 1) == 1
draw(output: str | None = None, scale: float | None = None, filename: str | None = None, style: dict | str | None = None, interactive: bool = False, plot_barriers: bool = True, reverse_bits: bool | None = None, justify: str | None = None, vertical_compression: str | None = 'medium', idle_wires: bool | str | None = None, with_layout: bool = True, fold: int | None = None, ax: Any | None = None, initial_state: bool = False, cregbundle: bool | None = None, wire_order: list[int] | None = None, expr_len: int = 30, measure_arrows: bool | None = None, barrier_label_len: int = 16)[source]

Draw the quantum circuit. Use the output parameter to choose the drawing format:

text

ASCII art TextDrawing that can be printed in the console.

mpl

Images with color rendered purely in Python using matplotlib.

latex

High-quality images compiled via LaTeX.

Warning

This will call an installed system version of pdflatex on arbitrary user input by design (such as to render custom code in Instruction.label), so should only be used on trusted input.

latex_source

Raw uncompiled LaTeX output. This is the source of what would be rendered by the latex drawer.

Warning

Support for Expr nodes in conditions and SwitchCaseOp.target fields is preliminary and incomplete. The text and mpl drawers will make a best-effort attempt to show data dependencies, but the LaTeX-based drawers will skip these completely.

Parameters:
  • output -- Select the output method to use for drawing the circuit. Valid choices are text, mpl, latex, latex_source. By default, the text drawer is used unless the user config file (usually ~/.qiskit/settings.conf) has an alternative backend set as the default. For example, circuit_drawer = latex. If the output kwarg is set, that backend will always be used over the default in the user config file.

  • scale -- Scale of image to draw (shrink if < 1.0). Only used by the mpl, latex and latex_source outputs. Defaults to 1.0.

  • filename -- File path to save image to. Defaults to None (result not saved in a file).

  • style --

    Style name, file name of style JSON file, or a dictionary specifying the style.

    • The supported style names are "iqp" (default), "iqp-dark", "clifford", "textbook" and "bw".

    • If given a JSON file, e.g. my_style.json or my_style (the .json extension may be omitted), this function attempts to load the style dictionary from that location. Note, that the JSON file must completely specify the visualization specifications. The file is searched for in qiskit/visualization/circuit/styles, the current working directory, and the location specified in ~/.qiskit/settings.conf.

    • If a dictionary, every entry overrides the default configuration. If the "name" key is given, the default configuration is given by that style. For example, {"name": "textbook", "subfontsize": 5} loads the "textbook" style and sets the subfontsize (e.g. the gate angles) to 5.

    • If None the default style "iqp" is used or, if given, the default style specified in ~/.qiskit/settings.conf.

  • interactive -- When set to True, show the circuit in a new window (for mpl this depends on the matplotlib backend being used supporting this). Note when used with either the text or the latex_source output type this has no effect and will be silently ignored. Defaults to False.

  • reverse_bits -- When set to True, reverse the bit order inside registers for the output visualization. Defaults to False unless the user config file (usually ~/.qiskit/settings.conf) has an alternative value set. For example, circuit_reverse_bits = True.

  • plot_barriers -- Enable/disable drawing barriers in the output circuit. Defaults to True.

  • justify -- Options are "left", "right" or "none" (str). If anything else is supplied, left justified will be used instead. It refers to where gates should be placed in the output circuit if there is an option. none results in each gate being placed in its own column. Defaults to left.

  • vertical_compression -- high, medium or low. It merges the lines generated by the text output so the drawing will take less vertical room. Default is medium. Only used by the text output, will be silently ignored otherwise.

  • idle_wires -- Include (or not) idle wires (wires with no circuit elements) in output visualization. The string "auto" is also possible, in which case idle wires are shown except when the circuit has a layout attached. Default is "auto" unless the user config file (usually ~/.qiskit/settings.conf) has an alternative value set. For example, circuit_idle_wires = False.

  • with_layout -- Include layout information, with labels on the physical layout. Default is True.

  • fold -- Sets pagination. It can be disabled using -1. In text, sets the length of the lines. This is useful when the drawing does not fit in the console. If None (default), it will try to guess the console width using shutil.get_terminal_size(). However, if running in jupyter, the default line length is set to 80 characters. In mpl, it is the number of (visual) layers before folding. Default is 25.

  • ax -- Only used by the mpl backend. An optional matplotlib.axes.Axes object to be used for the visualization output. If none is specified, a new matplotlib Figure will be created and used. Additionally, if specified there will be no returned Figure since it is redundant.

  • initial_state -- Adds \(|0\rangle\) in the beginning of the qubit wires and \(0\) to classical wires. Default is False.

  • cregbundle -- If set to True, bundle classical registers. Default is True, except for when output is set to "text".

  • wire_order -- A list of integers used to reorder the display of the bits. The list must have an entry for every bit with the bits in the range 0 to (num_qubits + num_clbits).

  • expr_len -- The number of characters to display if an Expr is used for the condition in a ControlFlowOp. If this number is exceeded, the string will be truncated at that number and '...' added to the end.

  • measure_arrows -- If True, draw an arrow from each measure box down to the classical bit or register where the measure value is placed. If False, do not draw arrow, but instead place the name of the bit or register in the measure box. Default is True unless the user config file (usually ~/.qiskit/settings.conf) has an alternative value set. For example, circuit_measure_arrows = False.

  • barrier_label_len -- The number of characters to display for Barrier labels in the output circuit. If this number is exceeded, the string will be truncated at that number and '...' added to the end.

Returns:

TextDrawing or matplotlib.figure or PIL.Image or str:

  • TextDrawing (if output='text')

    A drawing that can be printed as ascii art.

  • matplotlib.figure.Figure (if output='mpl')

    A matplotlib figure object for the circuit diagram.

  • PIL.Image (if output='latex')

    An in-memory representation of the image of the circuit diagram.

  • str (if output='latex_source')

    The LaTeX source code for visualizing the circuit diagram.

Raises:
  • VisualizationError -- when an invalid output method is selected

  • ImportError -- when the output methods requires non-installed libraries.

Example

property duration

The total duration of the circuit, set by a scheduling transpiler pass. Its unit is specified by unit.

Deprecated since version 1.3.0: The property qiskit.circuit.quantumcircuit.QuantumCircuit.duration is deprecated as of Qiskit 1.3.0. It will be removed in Qiskit 3.0.0.

ecr(qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply ECRGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • qubit1 -- The first qubit to apply the gate to.

  • qubit2 -- The second qubit to apply the gate to.

Returns:

A handle to the instructions created.

ensure_physical(num_qubits: int | None = None, *, apply_layout: bool = True) → bool[source]

Put this circuit into canonical physical form, with the given number of qubits, if it is not already.

Several Qiskit transpiler passes only make sense when applied to circuits defined in terms of physical qubits. If you have manually constructed a circuit where the qubit indices correspond to physical qubits, use this function to ensure that the metadata of the circuit matches the canonical physical form. This means replacing the qubit data with a single owning register called "q", and (optionally) setting the layout field of the circuit to link these physical qubits with the original virtual ones.

If the circuit does not already have a layout, this method (with apply_layout=True) is equivalent to applying the full trivial layout method of the preset compilation pipeline.

If the circuit is already canonically physical, nothing happens to it. This method cannot change the number of qubits in the circuit if it already has a layout set.

Parameters:
  • num_qubits -- if given, expand the circuit with ancillas up to this size. The ancillas will always be the highest qubit indices of the circuit. If not given (the default), the circuit stays the same width. This option cannot be set if the circuit already as a layout.

  • apply_layout -- if true (the default), set the layout attribute of the circuit appropriately so that the circuit appears to have been laid out with the "trivial" layout, including ancilla expansion, for a backend of width num_qubits. This has no effect if the circuit already had a layout.

Returns:

whether the circuit was modified in order to make it physical.

Raises:
  • ValueError -- if num_qubits is too small for the circuit.

  • CircuitError -- if num_qubits is set to attempt to expand the circuit, but the circuit already has a layout set.

estimate_duration(target, unit: str = 's') → int | float[source]

Estimate the duration of a scheduled circuit

This method computes the estimate of the circuit duration by finding the longest duration path in the circuit based on the durations provided by a given target. This method only works for simple circuits that have no control flow or other classical feed-forward operations.

Parameters:
  • target (Target) -- The Target instance that contains durations for the instructions if the target is missing duration data for any of the instructions in the circuit an QiskitError will be raised. This should be the same target object used as the target for transpilation.

  • unit -- The unit to return the duration in. This defaults to "s" for seconds but this can be a supported SI prefix for seconds returns. For example setting this to "n" will return in unit of nanoseconds. Supported values of this type are "f", "p", "n", "u", "µ", "m", "k", "M", "G", "T", and "P". Additionally, a value of "dt" is also accepted to output an integer in units of "dt". For this to function "dt" must be specified in the target.

Returns:

The estimated duration for the execution of a single shot of the circuit in the specified unit.

Raises:

QiskitError -- If the circuit is not scheduled or contains other details that prevent computing an estimated duration from (such as parameterized delay).

estimate_fidelity(target) → float | None[source]

Estimate the fidelity of a physical circuit.

This function will compute the product of the error rates for each gate in the circuit to estimate the fidelity of the circuit:

..math::
label:

estimated circuit fidelity

prod_{g in text{gates}} bigl(1 - operatorname{error}(g)bigr)

where \(\operatorname{error}(g)\) is the error rate in the target for the instruction \(g\) from the circuit in the target. If the circuit is not physical, meaning any instruction in the circuit (as in operation and qargs) is not found in the target, this will return None. This method is not intended to compute a realistic simulation of the fidelity of execution on real hardware. It is designed to provide an estimate of how the transpiler would work with the fidelity for various heuristics in its operation. It is typically only useful for comparing different compilation outputs against each other to estimate which one would produce a better quality execution on hardware.

Parameters:

target (Target) -- The Target instance that the circuit will be executed on and used to get the error rates for the instructions in the circuit.

Returns:

The estimated fidelity of executing the circuit on the given target. If any instruction in the circuit is not present in target

Raises:

QiskitError -- If the circuit contains any control flow operations.

find_bit(bit: Bit) → BitLocations[source]

Find locations in the circuit which can be used to reference a given Bit.

In particular, this function can find the integer index of a qubit, which corresponds to its hardware index for a transpiled circuit.

Note

The circuit index of a AncillaQubit will be its index in qubits, not ancillas.

Parameters:

bit (Bit) -- The bit to locate.

Returns:

A 2-tuple. The first element (index) contains the index at which the Bit can be found (in either qubits, clbits, depending on its type). The second element (registers) is a list of (register, index) pairs with an entry for each Register in the circuit which contains the Bit (and the index in the Register at which it can be found).

Return type:

namedtuple(int, List[Tuple(Register, int)])

Raises:
  • CircuitError -- If the supplied Bit was of an unknown type.

  • CircuitError -- If the supplied Bit could not be found on the circuit.

Examples

Loop through a circuit, getting the qubit and clbit indices of each operation:

from qiskit.circuit import QuantumCircuit, Qubit

qc = QuantumCircuit(3, 3)
qc.h(0)
qc.cx(0, 1)
qc.cx(1, 2)
qc.measure([0, 1, 2], [0, 1, 2])

# The `.qubits` and `.clbits` fields are not integers.
assert isinstance(qc.data[0].qubits[0], Qubit)
# ... but we can use `find_bit` to retrieve them.
assert qc.find_bit(qc.data[0].qubits[0]).index == 0

simple = [
    (
        instruction.operation.name,
        [qc.find_bit(bit).index for bit in instruction.qubits],
        [qc.find_bit(bit).index for bit in instruction.clbits],
    )
    for instruction in qc.data
]
for_loop(indexset: Iterable[int], loop_parameter: Parameter | Var | None, body: None, qubits: None, clbits: None, *, label: str | None) → ForLoopContext[source]
for_loop(indexset: Iterable[int], loop_parameter: Parameter | Var | None, body: QuantumCircuit, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], clbits: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]], *, label: str | None) → InstructionSet

Create a for loop on this circuit.

There are two forms for calling this function. If called with all its arguments (with the possible exception of label), it will create a ForLoopOp with the given body. If body (and qubits and clbits) are not passed, then this acts as a context manager, which, when entered, provides a loop variable (unless one is given, in which case it will be reused) and will automatically build a ForLoopOp when the scope finishes. In this form, you do not need to keep track of the qubits or clbits you are using, because the scope will handle it for you.

For example:

from qiskit import QuantumCircuit
qc = QuantumCircuit(2, 1)

with qc.for_loop(range(5)) as i:
    qc.h(0)
    qc.cx(0, 1)
    qc.measure(0, 0)
    with qc.if_test((0, True)):
        qc.break_loop()
Parameters:
  • indexset (Iterable[int]) -- A collection of integers to loop over. Always necessary.

  • loop_parameter (Optional[Parameter|expr.Var]) --

    The parameter used within body to which the values from indexset will be assigned. In the context-manager form, if this argument is not supplied, then a loop parameter will be allocated for you and returned as the value of the with statement. This will only be bound into the circuit if it is used within the body.

    If this argument is None in the manual form of this method, body will be repeated once for each of the items in indexset but their values will be ignored.

  • body (Optional[QuantumCircuit]) -- The loop body to be repeatedly executed. Omit this to use the context-manager mode.

  • qubits (Optional[Sequence[QubitSpecifier]]) -- The circuit qubits over which the loop body should be run. Omit this to use the context-manager mode.

  • clbits (Optional[Sequence[ClbitSpecifier]]) -- The circuit clbits over which the loop body should be run. Omit this to use the context-manager mode.

  • label (Optional[str]) -- The string label of the instruction in the circuit.

Returns:

depending on the call signature, either a context manager for creating the for loop (it will automatically be added to the circuit at the end of the block), or an InstructionSet handle to the appended loop operation.

Return type:

InstructionSet or ForLoopContext

Raises:

CircuitError -- if an incorrect calling convention is used.

static from_instructions(instructions: Iterable[CircuitInstruction | tuple[qiskit.circuit.Instruction] | tuple[qiskit.circuit.Instruction, Iterable[Qubit]] | tuple[qiskit.circuit.Instruction, Iterable[Qubit], Iterable[Clbit]]], *, qubits: Iterable[Qubit] = (), clbits: Iterable[Clbit] = (), name: str | None = None, global_phase: ParameterValueType = 0, metadata: dict | None = None) → QuantumCircuit[source]

Construct a circuit from an iterable of CircuitInstructions.

Parameters:
  • instructions -- The instructions to add to the circuit.

  • qubits -- Any qubits to add to the circuit. This argument can be used, for example, to enforce a particular ordering of qubits.

  • clbits -- Any classical bits to add to the circuit. This argument can be used, for example, to enforce a particular ordering of classical bits.

  • name -- The name of the circuit.

  • global_phase -- The global phase of the circuit in radians.

  • metadata -- Arbitrary key value metadata to associate with the circuit.

Returns:

The quantum circuit.

static from_qasm_file(path: str | PathLike) → QuantumCircuit[source]

Read an OpenQASM 2.0 program from a file and convert to an instance of QuantumCircuit.

Parameters:

path -- Path to the file for an OpenQASM 2 program

Returns:

The QuantumCircuit object for the input OpenQASM 2.

Return type:

QuantumCircuit

See also

qasm2.load(): the complete interface to the OpenQASM 2 importer.

static from_qasm_str(qasm_str: str) → QuantumCircuit[source]

Convert a string containing an OpenQASM 2.0 program to a QuantumCircuit.

Parameters:

qasm_str (str) -- A string containing an OpenQASM 2.0 program.

Returns:

The QuantumCircuit object for the input OpenQASM 2

Return type:

QuantumCircuit

See also

qasm2.loads(): the complete interface to the OpenQASM 2 importer.

get_identifier(name: str, default: T) → Var | Stretch | T[source]
get_identifier(name: str, default: builtin_types.EllipsisType = Ellipsis) → Var | Stretch

Retrieve an identifier that is accessible in this circuit scope by name.

This currently includes both real-time classical variables and stretches.

Parameters:
  • name -- the name of the identifier to retrieve.

  • default -- if given, this value will be returned if the variable is not present. If it is not given, a KeyError is raised instead.

Returns:

The corresponding variable.

Raises:

KeyError -- if no default is given, but the identifier does not exist.

See also

get_var()

Gets an identifier known to be a expr.Var instance.

get_stretch()

Gets an identifier known to be a expr.Stretch instance.

get_parameter()

A similar method, but for Parameter compile-time parameters instead of expr.Var run-time variables.

get_instructions(name: str) → list[CircuitInstruction][source]

Get instructions matching name.

Parameters:

name (str) -- The name of instruction to get.

Returns:

list of (instruction, qargs, cargs).

Return type:

list(tuple)

get_parameter(name: str, default: T) → Parameter | T[source]
get_parameter(name: str, default: builtin_types.EllipsisType = Ellipsis) → Parameter

Retrieve a compile-time parameter that is accessible in this circuit scope by name.

Parameters:
  • name -- the name of the parameter to retrieve.

  • default -- if given, this value will be returned if the parameter is not present. If it is not given, a KeyError is raised instead.

Returns:

The corresponding parameter.

Raises:

KeyError -- if no default is given, but the parameter does not exist in the circuit.

Examples

Retrieve a parameter by name from a circuit:

from qiskit.circuit import QuantumCircuit, Parameter

my_param = Parameter("my_param")

# Create a parametrized circuit.
qc = QuantumCircuit(1)
qc.rx(my_param, 0)

# We can use 'my_param' as a parameter, but let's say we've lost the Python object
# and need to retrieve it.
my_param_again = qc.get_parameter("my_param")

assert my_param == my_param_again

Get a variable from a circuit by name, returning some default if it is not present:

assert qc.get_parameter("my_param", None) == my_param
assert qc.get_parameter("unknown_param", None) is None

See also

get_var()

A similar method, but for expr.Var run-time variables instead of Parameter compile-time parameters.

get_stretch(name: str, default: T) → Stretch | T[source]
get_stretch(name: str, default: builtin_types.EllipsisType = Ellipsis) → Stretch

Retrieve a stretch that is accessible in this circuit scope by name.

Parameters:
  • name -- the name of the stretch to retrieve.

  • default -- if given, this value will be returned if the variable is not present. If it is not given, a KeyError is raised instead.

Returns:

The corresponding stretch.

Raises:

KeyError -- if no default is given, but the variable does not exist.

Examples

Retrieve a stretch by name from a circuit:

from qiskit.circuit import QuantumCircuit

# Create a circuit and create a variable in it.
qc = QuantumCircuit()
my_stretch = qc.add_stretch("my_stretch")

# We can use 'my_stretch' as a variable, but let's say we've lost the Python object and
# need to retrieve it.
my_stretch_again = qc.get_stretch("my_stretch")

assert my_stretch == my_stretch_again

Get a variable from a circuit by name, returning some default if it is not present:

assert qc.get_stretch("my_stretch", None) == my_stretch
assert qc.get_stretch("unknown_stretch", None) is None
get_var(name: str, default: T) → Var | T[source]
get_var(name: str, default: builtin_types.EllipsisType = Ellipsis) → Var

Retrieve a variable that is accessible in this circuit scope by name.

Parameters:
  • name -- the name of the variable to retrieve.

  • default -- if given, this value will be returned if the variable is not present. If it is not given, a KeyError is raised instead.

Returns:

The corresponding variable.

Raises:

KeyError -- if no default is given, but the variable does not exist.

Examples

Retrieve a variable by name from a circuit:

from qiskit.circuit import QuantumCircuit

# Create a circuit and create a variable in it.
qc = QuantumCircuit()
my_var = qc.add_var("my_var", False)

# We can use 'my_var' as a variable, but let's say we've lost the Python object and
# need to retrieve it.
my_var_again = qc.get_var("my_var")

assert my_var == my_var_again

Get a variable from a circuit by name, returning some default if it is not present:

assert qc.get_var("my_var", None) == my_var
assert qc.get_var("unknown_variable", None) is None

See also

get_parameter()

A similar method, but for Parameter compile-time parameters instead of expr.Var run-time variables.

property global_phase: ParameterExpression | float

The global phase of the current circuit scope in radians.

Example

0.0
0.7853981633974483
h(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply HGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

has_control_flow_op() → bool[source]

Checks whether the circuit has an instance of ControlFlowOp present amongst its operations.

has_identifier(name_or_ident: str | Var | Stretch, /) → bool[source]

Check whether an identifier is accessible in this scope.

Parameters:

name_or_ident -- the instance, or name of the identifier to check. If this is a expr.Var or expr.Stretch node, the matched instance must be exactly the given one for this function to return True.

Returns:

whether a matching identifier is accessible.

See also

QuantumCircuit.get_identifier()

Retrieve the expr.Var or expr.Stretch instance from this circuit by name.

QuantumCircuit.has_var()

The same as this method, but ignoring anything that isn't a run-time expr.Var variable.

QuantumCircuit.has_stretch()

The same as this method, but ignoring anything that isn't a run-time expr.Stretch variable.

QuantumCircuit.has_parameter()

A similar method to this, but for compile-time Parameters instead of run-time expr.Var variables.

has_parameter(name_or_param: str | Parameter, /) → bool[source]

Check whether a parameter object exists in this circuit.

Parameters:

name_or_param -- the parameter, or name of a parameter to check. If this is a Parameter node, the parameter must be exactly the given one for this function to return True.

Returns:

whether a matching parameter is assignable in this circuit.

See also

QuantumCircuit.get_parameter()

Retrieve the Parameter instance from this circuit by name.

QuantumCircuit.has_var()

A similar method to this, but for run-time expr.Var variables instead of compile-time Parameters.

has_register(register: Register) → bool[source]

Test if this circuit has the register r.

Parameters:

register (Register) -- a quantum or classical register.

Returns:

True if the register is contained in this circuit.

Return type:

bool

has_stretch(name_or_stretch: str | Stretch, /) → bool[source]

Check whether a stretch is accessible in this scope.

Parameters:

name_or_stretch -- the stretch, or name of a stretch to check. If this is a expr.Stretch node, the stretch must be exactly the given one for this function to return True.

Returns:

whether a matching stretch is accessible.

See also

QuantumCircuit.get_stretch()

Retrieve the expr.Stretch instance from this circuit by name.

has_var(name_or_var: str | Var, /) → bool[source]

Check whether a variable is accessible in this scope.

Parameters:

name_or_var -- the variable, or name of a variable to check. If this is a expr.Var node, the variable must be exactly the given one for this function to return True.

Returns:

whether a matching variable is accessible.

See also

QuantumCircuit.get_var()

Retrieve the expr.Var instance from this circuit by name.

QuantumCircuit.has_parameter()

A similar method to this, but for compile-time Parameters instead of run-time expr.Var variables.

id(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply IGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

if_else(condition: tuple[ClassicalRegister, int] | tuple[Clbit, int] | tuple[Clbit, bool], true_body: QuantumCircuit, false_body: QuantumCircuit, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], clbits: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]], label: str | None = None) → InstructionSet[source]

Apply IfElseOp.

Note

This method does not have an associated context-manager form, because it is already handled by the if_test() method. You can use the else part of that with something such as:

from qiskit.circuit import QuantumCircuit, Qubit, Clbit
bits = [Qubit(), Qubit(), Clbit()]
qc = QuantumCircuit(bits)
qc.h(0)
qc.cx(0, 1)
qc.measure(0, 0)
with qc.if_test((bits[2], 0)) as else_:
    qc.h(0)
with else_:
    qc.x(0)
Parameters:
  • condition -- A condition to be evaluated in real time at circuit execution, which, if true, will trigger the evaluation of true_body. Can be specified as either a tuple of a ClassicalRegister to be tested for equality with a given int, or as a tuple of a Clbit to be compared to either a bool or an int.

  • true_body -- The circuit body to be run if condition is true.

  • false_body -- The circuit to be run if condition is false.

  • qubits -- The circuit qubits over which the if/else should be run.

  • clbits -- The circuit clbits over which the if/else should be run.

  • label -- The string label of the instruction in the circuit.

Raises:

CircuitError -- If the provided condition references Clbits outside the enclosing circuit.

Returns:

A handle to the instruction created.

if_test(condition: tuple[ClassicalRegister | Clbit, int]) → IfContext[source]
if_test(condition: tuple[ClassicalRegister | Clbit, int], true_body: QuantumCircuit, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], clbits: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]], *, label: str | None = None) → InstructionSet

Create an if statement on this circuit.

There are two forms for calling this function. If called with all its arguments (with the possible exception of label), it will create a IfElseOp with the given true_body, and there will be no branch for the false condition (see also the if_else() method). However, if true_body (and qubits and clbits) are not passed, then this acts as a context manager, which can be used to build if statements. The return value of the with statement is a chainable context manager, which can be used to create subsequent else blocks. In this form, you do not need to keep track of the qubits or clbits you are using, because the scope will handle it for you.

For example:

from qiskit.circuit import QuantumCircuit, Qubit, Clbit
bits = [Qubit(), Qubit(), Qubit(), Clbit(), Clbit()]
qc = QuantumCircuit(bits)

qc.h(0)
qc.cx(0, 1)
qc.measure(0, 0)
qc.h(0)
qc.cx(0, 1)
qc.measure(0, 1)

with qc.if_test((bits[3], 0)) as else_:
    qc.x(2)
with else_:
    qc.h(2)
    qc.z(2)
Parameters:
  • condition (Tuple[Union[ClassicalRegister, Clbit], int]) -- A condition to be evaluated in real time during circuit execution, which, if true, will trigger the evaluation of true_body. Can be specified as either a tuple of a ClassicalRegister to be tested for equality with a given int, or as a tuple of a Clbit to be compared to either a bool or an int.

  • true_body (Optional[QuantumCircuit]) -- The circuit body to be run if condition is true.

  • qubits (Optional[Sequence[QubitSpecifier]]) -- The circuit qubits over which the if/else should be run.

  • clbits (Optional[Sequence[ClbitSpecifier]]) -- The circuit clbits over which the if/else should be run.

  • label (Optional[str]) -- The string label of the instruction in the circuit.

Returns:

depending on the call signature, either a context manager for creating the if block (it will automatically be added to the circuit at the end of the block), or an InstructionSet handle to the appended conditional operation.

Return type:

InstructionSet or IfContext

Raises:
  • CircuitError -- If the provided condition references Clbits outside the enclosing circuit.

  • CircuitError -- if an incorrect calling convention is used.

Returns:

A handle to the instruction created.

initialize(params: Statevector | Sequence[complex] | str | int, qubits: Sequence[QubitSpecifier] | None = None, normalize: bool = False)[source]

Initialize qubits in a specific state.

Qubit initialization is done by first resetting the qubits to \(|0\rangle\) followed by calling StatePreparation class to prepare the qubits in a specified state. Both these steps are included in the Initialize instruction.

Parameters:
  • params --

    The state to initialize to, can be either of the following.

    • Statevector or vector of complex amplitudes to initialize to.

    • Labels of basis states of the Pauli eigenstates Z, X, Y. See Statevector.from_label(). Notice the order of the labels is reversed with respect to the qubit index to be applied to. Example label '01' initializes the qubit zero to \(|1\rangle\) and the qubit one to \(|0\rangle\).

    • An integer that is used as a bitmap indicating which qubits to initialize to \(|1\rangle\). Example: setting params to 5 would initialize qubit 0 and qubit 2 to \(|1\rangle\) and qubit 1 to \(|0\rangle\).

  • qubits -- Qubits to initialize. If None the initialization is applied to all qubits in the circuit.

  • normalize -- Whether to normalize an input array to a unit vector.

Returns:

A handle to the instructions created.

Examples

Prepare a qubit in the state \((|0\rangle - |1\rangle) / \sqrt{2}\).

output:

     ┌──────────────────────────────┐
q_0: ┤ Initialize(0.70711,-0.70711) ├
     └──────────────────────────────┘

Initialize from a string two qubits in the state \(|10\rangle\). The order of the labels is reversed with respect to qubit index. More information about labels for basis states are in Statevector.from_label().

output:

     ┌──────────────────┐
q_0: ┤0                 ├
     │  Initialize(0,1) │
q_1: ┤1                 ├
     └──────────────────┘

Initialize two qubits from an array of complex amplitudes.

output:

     ┌────────────────────────────────────┐
q_0: ┤0                                   ├
     │  Initialize(0,0.70711,-0.70711j,0) │
q_1: ┤1                                   ├
     └────────────────────────────────────┘
instances = 41
inverse(annotated: bool = False) → QuantumCircuit[source]

Invert (take adjoint of) this circuit.

This is done by recursively inverting all gates.

Parameters:

annotated -- indicates whether the inverse gate can be implemented as an annotated gate.

Returns:

the inverted circuit

Return type:

QuantumCircuit

Raises:

CircuitError -- if the circuit cannot be inverted.

Examples

input:

     ┌───┐
q_0: ┤ H ├─────■──────
     └───┘┌────┴─────┐
q_1: ─────┤ RX(1.57) ├
          └──────────┘

output:

                  ┌───┐
q_0: ──────■──────┤ H ├
     ┌─────┴─────┐└───┘
q_1: ┤ RX(-1.57) ├─────
     └───────────┘
iswap(qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply iSwapGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • qubit1 -- The first qubit to apply the gate to.

  • qubit2 -- The second qubit to apply the gate to.

Returns:

A handle to the instructions created.

iter_captured_stretches() → Iterable[Stretch][source]

Get an iterable over stretches that are captured by this circuit scope from a containing scope. This excludes locally declared stretches (see iter_declared_stretches()).

iter_captured_vars() → Iterable[Var][source]

Get an iterable over all real-time classical variables that are captured by this circuit scope from a containing scope. This excludes input variables (see iter_input_vars()) and locally declared variables (see iter_declared_vars()).

iter_captures() → Iterable[Var | Stretch][source]

Get an iterable over all identifiers are captured by this circuit scope from a containing scope. This excludes input variables (see iter_input_vars()) and locally declared variables and stretches (see iter_declared_vars() and iter_declared_stretches()).

iter_declared_stretches() → Iterable[Stretch][source]

Get an iterable over all stretches that are declared in this scope. This excludes captured stretches (see iter_captured_stretches()).

iter_declared_vars() → Iterable[Var][source]

Get an iterable over all real-time classical variables that are declared with automatic storage duration in this scope. This excludes input variables (see iter_input_vars()) and captured variables (see iter_captured_vars()).

iter_input_vars() → Iterable[Var][source]

Get an iterable over all real-time classical variables that are declared as inputs to this circuit scope. This excludes locally declared variables (see iter_declared_vars()) and captured variables (see iter_captured_vars()).

iter_stretches() → Iterable[Stretch][source]

Get an iterable over all stretches in scope within this circuit.

This method will iterate over all stretches in scope. For more fine-grained iterators, see iter_declared_stretches() and iter_captured_stretches().

iter_vars() → Iterable[Var][source]

Get an iterable over all real-time classical variables in scope within this circuit.

This method will iterate over all variables in scope. For more fine-grained iterators, see iter_declared_vars(), iter_input_vars() and iter_captured_vars().

property layout: TranspileLayout | None

Return any associated layout information about the circuit.

This attribute contains an optional TranspileLayout object. This is typically set on the output from transpile() or PassManager.run() to retain information about the permutations caused on the input circuit by transpilation.

There are two types of permutations caused by the transpile() function: an initial layout that permutes the qubits based on the selected physical qubits on the Target, and a final layout, which is an output permutation caused by SwapGates inserted during routing.

Example

[0, 1, 2]
mcp(lam: ParameterExpression | float, control_qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], ctrl_state: str | int | None = None) → InstructionSet[source]

Apply MCPhaseGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • lam -- The angle of the rotation.

  • control_qubits -- The qubits used as the controls.

  • target_qubit -- The qubit(s) targeted by the gate.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

mcrx(theta: ParameterExpression | float, q_controls: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], q_target: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], use_basis_gates: bool = False)[source]

Apply Multiple-Controlled X rotation gate

Parameters:
  • theta -- The angle of the rotation.

  • q_controls -- The qubits used as the controls.

  • q_target -- The qubit targeted by the gate.

  • use_basis_gates -- use p, u, cx basis gates.

mcry(theta: ParameterExpression | float, q_controls: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], q_target: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], q_ancillae: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int] | Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]] | None = None, mode: str | None = None, use_basis_gates: bool = False)[source]

Apply Multiple-Controlled Y rotation gate

Parameters:
  • theta -- The angle of the rotation.

  • q_controls -- The qubits used as the controls.

  • q_target -- The qubit targeted by the gate.

  • q_ancillae -- The list of ancillary qubits.

  • mode -- The implementation mode to use.

  • use_basis_gates -- use p, u, cx basis gates

mcrz(lam: ParameterExpression | float, q_controls: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], q_target: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], use_basis_gates: bool = False)[source]

Apply Multiple-Controlled Z rotation gate

Parameters:
  • lam -- The angle of the rotation.

  • q_controls -- The qubits used as the controls.

  • q_target -- The qubit targeted by the gate.

  • use_basis_gates -- use p, u, cx basis gates.

mcx(control_qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], ancilla_qubits: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int] | Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]] | None = None, mode: str | None = None, ctrl_state: str | int | None = None) → InstructionSet[source]

Apply MCXGate.

The multi-cX gate can be implemented using different techniques, which use different numbers of ancilla qubits and have varying circuit depth. These modes are:

  • 'noancilla': Requires 0 ancilla qubits.

  • 'recursion': Requires 1 ancilla qubit if more than 4 controls are used, otherwise 0.

  • 'v-chain': Requires 2 less ancillas than the number of control qubits.

  • 'v-chain-dirty': Same as for the clean ancillas (but the circuit will be longer).

For the full matrix form of this gate, see the underlying gate documentation.

Deprecated since version 2.1: qiskit.circuit.quantumcircuit.QuantumCircuit.mcx()'s argument mode is deprecated as of Qiskit 2.1. It will be removed no earlier than 3 months after the release date. Instead, add a generic MCXGate to the circuit and specify the synthesis method via the hls_config in the transpilation. Alternatively, specific decompositions are available at https://qisk.it/mcx.

Parameters:
  • control_qubits -- The qubits used as the controls.

  • target_qubit -- The qubit(s) targeted by the gate.

  • ancilla_qubits -- The qubits used as the ancillae, if the mode requires them.

  • mode -- The choice of mode, explained further above.

  • ctrl_state -- The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling on the '1' state.

Returns:

A handle to the instructions created.

Raises:
  • ValueError -- if the given mode is not known, or if too few ancilla qubits are passed.

  • AttributeError -- if no ancilla qubits are passed, but some are needed.

measure(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], cbit: Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]) → InstructionSet[source]

Measure a quantum bit (qubit) in the Z basis into a classical bit (cbit).

When a quantum state is measured, a qubit is projected in the computational (Pauli Z) basis to either \(\lvert 0 \rangle\) or \(\lvert 1 \rangle\). The classical bit cbit indicates the result of that projection as a 0 or a 1 respectively. This operation is non-reversible.

Parameters:
  • qubit -- qubit(s) to measure.

  • cbit -- classical bit(s) to place the measurement result(s) in, or a expr.Var of types.Uint type indexing the target clbit.

Returns:

handle to the added instructions.

Return type:

qiskit.circuit.InstructionSet

Raises:

CircuitError -- if arguments have bad format.

Examples

In this example, a qubit is measured and the result of that measurement is stored in the classical bit (usually expressed in diagrams as a double line):

     ┌───┐┌─┐
  q: ┤ H ├┤M├
     └───┘└╥┘
c: 1/══════╩═
           0

It is possible to call measure with lists of qubits and cbits as a shortcut for one-to-one measurement. These two forms produce identical results:

Instead of lists, you can use QuantumRegister and ClassicalRegister under the same logic.

This is equivalent to:

measure_active(inplace: bool = True) → QuantumCircuit | None[source]

Adds measurement to all non-idle qubits. Creates a new ClassicalRegister with a size equal to the number of non-idle qubits being measured.

Returns a new circuit with measurements if inplace=False.

Parameters:

inplace (bool) -- All measurements inplace or return new circuit.

Returns:

Returns circuit with measurements when inplace = False.

Return type:

QuantumCircuit

measure_all(inplace: bool = True, add_bits: bool = True) → QuantumCircuit | None[source]

Adds measurement to all qubits.

By default, adds new classical bits in a ClassicalRegister to store these measurements. If add_bits=False, the results of the measurements will instead be stored in the already existing classical bits, with qubit n being measured into classical bit n.

Returns a new circuit with measurements if inplace=False.

Parameters:
  • inplace (bool) -- All measurements inplace or return new circuit.

  • add_bits (bool) -- Whether to add new bits to store the results.

Returns:

Returns circuit with measurements when inplace=False.

Return type:

QuantumCircuit

Raises:

CircuitError -- if add_bits=False but there are not enough classical bits.

property metadata: dict

Arbitrary user-defined dictionary of metadata for the circuit.

Qiskit will not examine the content of this mapping, but it will pass it through the transpiler and reattach it to the output, so you can track your own metadata.

Example

{'experiment_type': 'Bell state experiment'}
ms(theta: ParameterExpression | float, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]]) → InstructionSet[source]

Apply MSGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • qubits -- The qubits to apply the gate to.

Returns:

A handle to the instructions created.

name: str

A human-readable name for the circuit.

Example

my_circuit
noop(*qargs: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int])[source]

Mark the given qubit(s) as used within the current scope, without adding an operation.

This has no effect (other than raising an exception on invalid input) when called in the top scope of a QuantumCircuit. Within a control-flow builder, this causes the qubit to be "used" by the control-flow block, if it wouldn't already be used, without adding any additional operations on it.

For example:

from qiskit.circuit import QuantumCircuit

qc = QuantumCircuit(3)
with qc.box():
    # This control-flow block will only use qubits 0 and 1.
    qc.cx(0, 1)
with qc.box():
    # This control-flow block will contain only the same operation as the previous
    # block, but it will also mark qubit 2 as "used" by the box.
    qc.cx(0, 1)
    qc.noop(2)
Parameters:

*qargs -- variadic list of valid qubit specifiers. Anything that can be passed as a qubit or collection of qubits is valid for each argument here.

Raises:

CircuitError -- if any requested qubit is not valid for the circuit.

property num_ancillas: int

Return the number of ancilla qubits.

Example

Number of ancilla qubits: 1
property num_captured_stretches: int

The number of stretches in the circuit marked as captured from an enclosing scope.

This is the length of the iter_captured_stretches() iterable. If this is non-zero, num_input_vars must be zero.

property num_captured_vars: int

The number of real-time classical variables in the circuit marked as captured from an enclosing scope.

This is the length of the iter_captured_vars() iterable. If this is non-zero, num_input_vars must be zero.

property num_clbits: int

Return number of classical bits.

Example

Number of classical bits: 1
num_connected_components(unitary_only: bool = False) → int[source]

How many non-entangled subcircuits can the circuit be factored to.

Parameters:

unitary_only (bool) -- Compute only unitary part of graph.

Returns:

Number of connected components in circuit.

Return type:

int

property num_declared_stretches: int

The number of stretches in the circuit that are declared by this circuit scope, excluding captures.

This is the length of the iter_declared_stretches() iterable.

property num_declared_vars: int

The number of real-time classical variables in the circuit that are declared by this circuit scope, excluding inputs or captures.

This is the length of the iter_declared_vars() iterable.

property num_identifiers: int

The number of real-time classical variables and stretches in the circuit.

This is equal to num_vars() + num_stretches().

property num_input_vars: int

The number of real-time classical variables in the circuit marked as circuit inputs.

This is the length of the iter_input_vars() iterable. If this is non-zero, num_captured_vars must be zero.

num_nonlocal_gates() → int[source]

Return number of non-local gates (i.e. involving 2+ qubits).

Conditional nonlocal gates are also included.

property num_parameters: int

The number of parameter objects in the circuit.

property num_qubits: int

Return number of qubits.

property num_stretches: int

The number of stretches in the circuit.

This is the length of the iter_stretches() iterable.

num_tensor_factors() → int[source]

Computes the number of tensor factors in the unitary (quantum) part of the circuit only.

Notes

This is here for backwards compatibility, and will be removed in a future release of Qiskit. You should call num_unitary_factors instead.

num_unitary_factors() → int[source]

Computes the number of tensor factors in the unitary (quantum) part of the circuit only.

property num_vars: int

The number of real-time classical variables in the circuit.

This is the length of the iter_vars() iterable.

property op_start_times: list[int]

Return a list of operation start times.

Note

This attribute computes the estimate starting time of the operations in the scheduled circuit and only works for simple circuits that have no control flow or other classical feed-forward operations.

This attribute is enabled once one of scheduling analysis passes runs on the quantum circuit.

Example

Original circuit:
        ┌───┐      ░ ┌─┐
q_0: ┤ H ├──■───░─┤M├───
        └───┘┌─┴─┐ ░ └╥┘┌─┐
q_1: ─────┤ X ├─░──╫─┤M├
            └───┘ ░  ║ └╥┘
meas: 2/══════════════╩══╩═
                    0  1

Transpiled circuit with basis gates ['u1', 'u2', 'u3', 'cx']:
            ┌─────────┐          ░ ┌─────────────────┐┌─┐
q_0 -> 0 ───┤ U2(0,π) ├──────■───░─┤ Delay(1255[dt]) ├┤M├
        ┌──┴─────────┴───┐┌─┴─┐ ░ └───────┬─┬───────┘└╥┘
q_1 -> 1 ┤ Delay(196[dt]) ├┤ X ├─░─────────┤M├─────────╫─
        └────────────────┘└───┘ ░         └╥┘         ║
meas: 2/═══════════════════════════════════╩══════════╩═
                                            1          0

Start times of instructions in the transpiled circuit:
u2: 0
delay: 0
cx: 196
barrier: 2098
delay: 2098
measure: 3353
measure: 2098
Returns:

List of integers representing instruction estimated start times. The index corresponds to the index of instruction in QuantumCircuit.data.

Raises:

AttributeError -- When circuit is not scheduled.

p(theta: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply PhaseGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

property parameters: ParameterView

The parameters defined in the circuit.

This attribute returns the Parameter objects in the circuit sorted alphabetically. Note that parameters instantiated with a ParameterVector are still sorted numerically.

Examples

The snippet below shows that insertion order of parameters does not matter.

Bear in mind that alphabetical sorting might be unintuitive when it comes to numbers. The literal "10" comes before "2" in strict alphabetical sorting.

To respect numerical sorting, a ParameterVector can be used.

Returns:

The sorted Parameter objects in the circuit.

pauli(pauli_string: str, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]]) → InstructionSet[source]

Apply PauliGate.

Parameters:
  • pauli_string -- A string representing the Pauli operator to apply, e.g. 'XX'.

  • qubits -- The qubits to apply this gate to.

Returns:

A handle to the instructions created.

power(power: float, matrix_power: bool = False, annotated: bool = False) → QuantumCircuit[source]

Raise this circuit to the power of power.

If power is a positive integer and both matrix_power and annotated are False, this implementation defaults to calling repeat. Otherwise, the circuit is converted into a gate, and a new circuit, containing this gate raised to the given power, is returned. The gate raised to the given power is implemented either as a unitary gate if annotated is False or as an annotated operation if annotated is True.

Parameters:
  • power (float) -- The power to raise this circuit to.

  • matrix_power (bool) -- indicates whether the inner power gate can be implemented as a unitary gate.

  • annotated (bool) -- indicates whether the inner power gate can be implemented as an annotated operation.

Raises:

CircuitError -- If the circuit needs to be converted to a unitary gate, but is not unitary.

Returns:

A circuit implementing this circuit raised to the power of power.

Return type:

QuantumCircuit

prefix = 'circuit'
prepare_state(state: Statevector | Sequence[complex] | str | int, qubits: Sequence[QubitSpecifier] | None = None, label: str | None = None, normalize: bool = False) → InstructionSet[source]

Prepare qubits in a specific state.

This class implements a state preparing unitary. Unlike initialize() it does not reset the qubits first.

Parameters:
  • state --

    The state to initialize to, can be either of the following.

    • Statevector or vector of complex amplitudes to initialize to.

    • Labels of basis states of the Pauli eigenstates Z, X, Y. See Statevector.from_label(). Notice the order of the labels is reversed with respect to the qubit index to be applied to. Example label '01' initializes the qubit zero to \(|1\rangle\) and the qubit one to \(|0\rangle\).

    • An integer that is used as a bitmap indicating which qubits to initialize to \(|1\rangle\). Example: setting params to 5 would initialize qubit 0 and qubit 2 to \(|1\rangle\) and qubit 1 to \(|0\rangle\).

  • qubits -- Qubits to initialize. If None the initialization is applied to all qubits in the circuit.

  • label -- An optional label for the gate

  • normalize -- Whether to normalize an input array to a unit vector.

Returns:

A handle to the instruction that was just initialized

Examples

Prepare a qubit in the state \((|0\rangle - |1\rangle) / \sqrt{2}\).

output:

     ┌─────────────────────────────────────┐
q_0: ┤ State Preparation(0.70711,-0.70711) ├
     └─────────────────────────────────────┘

Prepare from a string two qubits in the state \(|10\rangle\). The order of the labels is reversed with respect to qubit index. More information about labels for basis states are in Statevector.from_label().

output:

     ┌─────────────────────────┐
q_0: ┤0                        ├
     │  State Preparation(0,1) │
q_1: ┤1                        ├
     └─────────────────────────┘

Initialize two qubits from an array of complex amplitudes

output:

     ┌───────────────────────────────────────────┐
q_0: ┤0                                          ├
     │  State Preparation(0,0.70711,-0.70711j,0) │
q_1: ┤1                                          ├
     └───────────────────────────────────────────┘
property qregs: list[QuantumRegister]

A list of Qubits in the order that they were added. You should not mutate this.

qubit_duration(*qubits: Qubit | int) → float[source]

Return the duration between the start and stop time of the first and last instructions, excluding delays, over the supplied qubits. Its time unit is self.unit.

Parameters:

*qubits -- Qubits within self to include.

Returns:

Return the duration between the first start and last stop time of non-delay instructions

qubit_start_time(*qubits: Qubit | int) → float[source]

Return the start time of the first instruction, excluding delays, over the supplied qubits. Its time unit is self.unit.

Return 0 if there are no instructions over qubits

Parameters:
  • *qubits -- Qubits within self to include. Integers are allowed for qubits, indicating

  • self.qubits. (indices of)

Returns:

Return the start time of the first instruction, excluding delays, over the qubits

Raises:

CircuitError -- if self is a not-yet scheduled circuit.

qubit_stop_time(*qubits: Qubit | int) → float[source]

Return the stop time of the last instruction, excluding delays, over the supplied qubits. Its time unit is self.unit.

Return 0 if there are no instructions over qubits

Parameters:
  • *qubits -- Qubits within self to include. Integers are allowed for qubits, indicating

  • self.qubits. (indices of)

Returns:

Return the stop time of the last instruction, excluding delays, over the qubits

Raises:

CircuitError -- if self is a not-yet scheduled circuit.

property qubits: list[Qubit]

A list of Qubits in the order that they were added. You should not mutate this.

r(theta: ParameterExpression | float, phi: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • phi -- The angle of the axis of rotation in the x-y plane.

  • qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

rcccx(control_qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], control_qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], control_qubit3: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RC3XGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit1 -- The qubit(s) used as the first control.

  • control_qubit2 -- The qubit(s) used as the second control.

  • control_qubit3 -- The qubit(s) used as the third control.

  • target_qubit -- The qubit(s) targeted by the gate.

Returns:

A handle to the instructions created.

rccx(control_qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], control_qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], target_qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RCCXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • control_qubit1 -- The qubit(s) used as the first control.

  • control_qubit2 -- The qubit(s) used as the second control.

  • target_qubit -- The qubit(s) targeted by the gate.

Returns:

A handle to the instructions created.

remove_final_measurements(inplace: bool = True) → QuantumCircuit | None[source]

Removes final measurements and barriers on all qubits if they are present. Deletes the classical registers that were used to store the values from these measurements that become idle as a result of this operation, and deletes classical bits that are referenced only by removed registers, or that aren't referenced at all but have become idle as a result of this operation.

Measurements and barriers are considered final if they are followed by no other operations (aside from other measurements or barriers.)

Note

This method has rather complex behavior, particularly around the removal of newly idle classical bits and registers. It is much more efficient to avoid adding unnecessary classical data in the first place, rather than trying to remove it later.

See also

RemoveFinalMeasurements

A transpiler pass that removes final measurements and barriers. This does not remove the classical data. If this is your goal, you can call that with:

from qiskit.circuit import QuantumCircuit
from qiskit.transpiler.passes import RemoveFinalMeasurements

qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.barrier()
qc.measure([0, 1], [0, 1])

pass_ = RemoveFinalMeasurements()
just_bell = pass_(qc)
Parameters:

inplace (bool) -- All measurements removed inplace or return new circuit.

Returns:

Returns the resulting circuit when inplace=False, else None.

Return type:

QuantumCircuit

repeat(reps: int, *, insert_barriers: bool = False) → QuantumCircuit[source]

Repeat this circuit reps times.

Parameters:
  • reps (int) -- How often this circuit should be repeated.

  • insert_barriers (bool) -- Whether to include barriers between circuit repetitions.

Returns:

A circuit containing reps repetitions of this circuit.

Return type:

QuantumCircuit

reset(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Reset the quantum bit(s) to their default state.

Parameters:

qubit -- qubit(s) to reset.

Returns:

handle to the added instruction.

Return type:

qiskit.circuit.InstructionSet

reverse_bits() → QuantumCircuit[source]

Return a circuit with the opposite order of wires.

The circuit is "vertically" flipped. If a circuit is defined over multiple registers, the resulting circuit will have the same registers but with their order flipped.

This method is useful for converting a circuit written in little-endian convention to the big-endian equivalent, and vice versa.

Returns:

the circuit with reversed bit order.

Return type:

QuantumCircuit

Examples

input:

     ┌───┐
a_0: ┤ H ├──■─────────────────
     └───┘┌─┴─┐
a_1: ─────┤ X ├──■────────────
          └───┘┌─┴─┐
a_2: ──────────┤ X ├──■───────
               └───┘┌─┴─┐
b_0: ───────────────┤ X ├──■──
                    └───┘┌─┴─┐
b_1: ────────────────────┤ X ├
                         └───┘

output:

                         ┌───┐
b_0: ────────────────────┤ X ├
                    ┌───┐└─┬─┘
b_1: ───────────────┤ X ├──■──
               ┌───┐└─┬─┘
a_0: ──────────┤ X ├──■───────
          ┌───┐└─┬─┘
a_1: ─────┤ X ├──■────────────
     ┌───┐└─┬─┘
a_2: ┤ H ├──■─────────────────
     └───┘
reverse_ops() → QuantumCircuit[source]

Reverse the circuit by reversing the order of instructions.

This is done by recursively reversing all instructions. It does not invert (adjoint) any gate.

Returns:

the reversed circuit.

Return type:

QuantumCircuit

Examples

input:

     ┌───┐
q_0: ┤ H ├─────■──────
     └───┘┌────┴─────┐
q_1: ─────┤ RX(1.57) ├
          └──────────┘

output:

                 ┌───┐
q_0: ─────■──────┤ H ├
     ┌────┴─────┐└───┘
q_1: ┤ RX(1.57) ├─────
     └──────────┘
rv(vx: ParameterExpression | float, vy: ParameterExpression | float, vz: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RVGate.

For the full matrix form of this gate, see the underlying gate documentation.

Rotation around an arbitrary rotation axis \(v\), where \(|v|\) is the angle of rotation in radians.

Parameters:
  • vx -- x-component of the rotation axis.

  • vy -- y-component of the rotation axis.

  • vz -- z-component of the rotation axis.

  • qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

rx(theta: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None) → InstructionSet[source]

Apply RXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The rotation angle of the gate.

  • qubit -- The qubit(s) to apply the gate to.

  • label -- The string label of the gate in the circuit.

Returns:

A handle to the instructions created.

rxx(theta: ParameterExpression | float, qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RXXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The angle of the rotation.

  • qubit1 -- The qubit(s) to apply the gate to.

  • qubit2 -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

ry(theta: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None) → InstructionSet[source]

Apply RYGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The rotation angle of the gate.

  • qubit -- The qubit(s) to apply the gate to.

  • label -- The string label of the gate in the circuit.

Returns:

A handle to the instructions created.

ryy(theta: ParameterExpression | float, qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RYYGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The rotation angle of the gate.

  • qubit1 -- The qubit(s) to apply the gate to.

  • qubit2 -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

rz(phi: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • phi -- The rotation angle of the gate.

  • qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

rzx(theta: ParameterExpression | float, qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RZXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The rotation angle of the gate.

  • qubit1 -- The qubit(s) to apply the gate to.

  • qubit2 -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

rzz(theta: ParameterExpression | float, qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply RZZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The rotation angle of the gate.

  • qubit1 -- The qubit(s) to apply the gate to.

  • qubit2 -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

s(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply SGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

sdg(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply SdgGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

size(filter_function: ~collections.abc.Callable[[...], int] = <function QuantumCircuit.<lambda>>) → int[source]

Returns total number of instructions in circuit.

Parameters:

filter_function (callable) -- a function to filter out some instructions. Should take as input a tuple of (Instruction, list(Qubit), list(Clbit)). By default, filters out "directives", such as barrier or snapshot.

Returns:

Total number of gate operations.

Return type:

int

store(lvalue: Any, rvalue: Any, /) → InstructionSet[source]

Store the result of the given real-time classical expression rvalue in the memory location defined by lvalue.

Typically lvalue will be a Var node and rvalue will be some Expr to write into it, but anything that expr.lift() can raise to an Expr is permissible in both places, and it will be called on them.

Parameters:
  • lvalue -- a valid specifier for a memory location in the circuit. This will typically be a Var node, but you can also write to Clbit or ClassicalRegister memory locations if your hardware supports it. The memory location must already be present in the circuit.

  • rvalue -- a real-time classical expression whose result should be written into the given memory location.

See also

Store

The backing Instruction class that represents this operation.

add_var()

Create a new variable in the circuit that can be written to with this method.

swap(qubit1: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], qubit2: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply SwapGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • qubit1 -- The first qubit to apply the gate to.

  • qubit2 -- The second qubit to apply the gate to.

Returns:

A handle to the instructions created.

switch(target: Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int], cases: None, qubits: None, clbits: None, *, label: str | None) → SwitchContext[source]
switch(target: Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int], cases: Iterable[tuple[Any, QuantumCircuit]], qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], clbits: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]], *, label: str | None) → InstructionSet

Create a switch/case structure on this circuit.

There are two forms for calling this function. If called with all its arguments (with the possible exception of label), it will create a SwitchCaseOp with the given case structure. If cases (and qubits and clbits) are not passed, then this acts as a context manager, which will automatically build a SwitchCaseOp when the scope finishes. In this form, you do not need to keep track of the qubits or clbits you are using, because the scope will handle it for you.

Example usage:

from qiskit.circuit import QuantumCircuit, ClassicalRegister, QuantumRegister
qreg = QuantumRegister(3)
creg = ClassicalRegister(3)
qc = QuantumCircuit(qreg, creg)
qc.h([0, 1, 2])
qc.measure([0, 1, 2], [0, 1, 2])

with qc.switch(creg) as case:
    with case(0):
        qc.x(0)
    with case(1, 2):
        qc.z(1)
    with case(case.DEFAULT):
        qc.cx(0, 1)
Parameters:
  • target (Union[ClassicalRegister, Clbit]) -- The classical value to switch one. This must be integer-like.

  • cases (Iterable[Tuple[Any, QuantumCircuit]]) -- A sequence of case specifiers. Each tuple defines one case body (the second item). The first item of the tuple can be either a single integer value, the special value CASE_DEFAULT, or a tuple of several integer values. Each of the integer values will be tried in turn; control will then pass to the body corresponding to the first match. CASE_DEFAULT matches all possible values. Omit in context-manager form.

  • qubits (Sequence[Qubit]) -- The circuit qubits over which all case bodies execute. Omit in context-manager form.

  • clbits (Sequence[Clbit]) -- The circuit clbits over which all case bodies execute. Omit in context-manager form.

  • label (Optional[str]) -- The string label of the instruction in the circuit.

Returns:

If used in context-manager mode, then this should be used as a with resource, which will return an object that can be repeatedly entered to produce cases for the switch statement. If the full form is used, then this returns a handle to the instructions created.

Return type:

InstructionSet or SwitchCaseContext

Raises:

CircuitError -- if an incorrect calling convention is used.

sx(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply SXGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

sxdg(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply SXdgGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

t(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply TGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

tdg(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply TdgGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

tensor(other: QuantumCircuit, inplace: bool = False) → QuantumCircuit | None[source]

Tensor self with other.

Remember that in the little-endian convention the leftmost operation will be at the bottom of the circuit. See also the docs for more information.

     ┌────────┐        ┌─────┐          ┌─────┐
q_0: ┤ bottom ├ ⊗ q_0: ┤ top ├  = q_0: ─┤ top ├──
     └────────┘        └─────┘         ┌┴─────┴─┐
                                  q_1: ┤ bottom ├
                                       └────────┘
Parameters:
  • other (QuantumCircuit) -- The other circuit to tensor this circuit with.

  • inplace (bool) -- If True, modify the object. Otherwise return composed circuit.

Examples

Returns:

The tensored circuit (returns None if inplace=True).

Return type:

QuantumCircuit

to_dag(*, copy_operations: bool = True) → qiskit.dagcircuit.DAGCircuit[source]

Convert this circuit to a DAGCircuit.

This is a simple wrapper around circuit_to_dag().

Parameters:

copy_operations -- whether to deep copy the individual instructions. If set to False, the operation is cheaper but mutations to the instructions in the DAG will affect the original circuit.

Returns:

a DAG representing this same circuit.

to_gate(parameter_map: dict[Parameter, ParameterExpression | float] | None = None, label: str | None = None) → Gate[source]

Create a Gate out of this circuit. The circuit must act only on qubits and contain only unitary operations.

See also

circuit_to_gate()

The underlying driver of this method.

Parameters:
  • parameter_map -- For parameterized circuits, a mapping from parameters in the circuit to parameters to be used in the gate. If None, existing circuit parameters will also parameterize the gate.

  • label -- Optional gate label.

Returns:

a composite gate encapsulating this circuit (can be decomposed back).

Return type:

Gate

to_instruction(parameter_map: dict[Parameter, ParameterExpression | float] | None = None, label: str | None = None) → Instruction[source]

Create an Instruction out of this circuit.

See also

circuit_to_instruction()

The underlying driver of this method.

Parameters:
  • parameter_map -- For parameterized circuits, a mapping from parameters in the circuit to parameters to be used in the instruction. If None, existing circuit parameters will also parameterize the instruction.

  • label -- Optional gate label.

Returns:

a composite instruction encapsulating this circuit (can be

decomposed back).

Return type:

qiskit.circuit.Instruction

u(theta: ParameterExpression | float, phi: ParameterExpression | float, lam: ParameterExpression | float, qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply UGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • theta -- The \(\theta\) rotation angle of the gate.

  • phi -- The \(\phi\) rotation angle of the gate.

  • lam -- The \(\lambda\) rotation angle of the gate.

  • qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

property unit

The unit that duration is specified in.

Deprecated since version 1.3.0: The property qiskit.circuit.quantumcircuit.QuantumCircuit.unit is deprecated as of Qiskit 1.3.0. It will be removed in Qiskit 3.0.0.

unitary(obj: np.ndarray | Gate | BaseOperator, qubits: Sequence[QubitSpecifier], label: str | None = None)[source]

Apply unitary gate specified by obj to qubits.

Parameters:
  • obj -- Unitary operator.

  • qubits -- The circuit qubits to apply the transformation to.

  • label -- Unitary name for backend [Default: None].

Returns:

The quantum circuit.

Return type:

QuantumCircuit

Example

Apply a gate specified by a unitary matrix to a quantum circuit

while_loop(condition: tuple[ClassicalRegister | Clbit, int] | Expr, body: None, qubits: None, clbits: None, *, label: str | None) → WhileLoopContext[source]
while_loop(condition: tuple[ClassicalRegister | Clbit, int] | Expr, body: QuantumCircuit, qubits: Sequence[Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]], clbits: Sequence[Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int]], *, label: str | None) → InstructionSet

Create a while loop on this circuit.

There are two forms for calling this function. If called with all its arguments (with the possible exception of label), it will create a WhileLoopOp with the given body. If body (and qubits and clbits) are not passed, then this acts as a context manager, which will automatically build a WhileLoopOp when the scope finishes. In this form, you do not need to keep track of the qubits or clbits you are using, because the scope will handle it for you.

Example usage:

from qiskit.circuit import QuantumCircuit, Clbit, Qubit
bits = [Qubit(), Qubit(), Clbit()]
qc = QuantumCircuit(bits)

with qc.while_loop((bits[2], 0)):
    qc.h(0)
    qc.cx(0, 1)
    qc.measure(0, 0)
Parameters:
  • condition (Tuple[Union[ClassicalRegister, Clbit], int]) -- An equality condition to be checked prior to executing body. The left-hand side of the condition must be a ClassicalRegister or a Clbit, and the right-hand side must be an integer or boolean.

  • body (Optional[QuantumCircuit]) -- The loop body to be repeatedly executed. Omit this to use the context-manager mode.

  • qubits (Optional[Sequence[Qubit]]) -- The circuit qubits over which the loop body should be run. Omit this to use the context-manager mode.

  • clbits (Optional[Sequence[Clbit]]) -- The circuit clbits over which the loop body should be run. Omit this to use the context-manager mode.

  • label (Optional[str]) -- The string label of the instruction in the circuit.

Returns:

If used in context-manager mode, then this should be used as a with resource, which will infer the block content and operands on exit. If the full form is used, then this returns a handle to the instructions created.

Return type:

InstructionSet or WhileLoopContext

Raises:

CircuitError -- if an incorrect calling convention is used.

width() → int[source]

Return number of qubits plus clbits in circuit.

Returns:

Width of circuit.

Return type:

int

x(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int], label: str | None = None) → InstructionSet[source]

Apply XGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:
  • qubit -- The qubit(s) to apply the gate to.

  • label -- The string label of the gate in the circuit.

Returns:

A handle to the instructions created.

y(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply YGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

z(qubit: Qubit | QuantumRegister | int | slice | Sequence[Qubit | int]) → InstructionSet[source]

Apply ZGate.

For the full matrix form of this gate, see the underlying gate documentation.

Parameters:

qubit -- The qubit(s) to apply the gate to.

Returns:

A handle to the instructions created.

class hqs_qorrelator_app.experimental_nmr_helpers.SparsePauliOp(data: PauliList | SparsePauliOp | Pauli | list | str, coeffs: ndarray | None = None, *, ignore_pauli_phase: bool = False, copy: bool = True)[source]

Sparse N-qubit operator in a Pauli basis representation.

This is a sparse representation of an N-qubit matrix Operator in terms of N-qubit PauliList and complex coefficients.

It can be used for performing operator arithmetic for hundreds of qubits if the number of non-zero Pauli basis terms is sufficiently small.

The Pauli basis components are stored as a PauliList object and can be accessed using the paulis attribute. The coefficients are stored as a complex Numpy array vector and can be accessed using the coeffs attribute.

Data type of coefficients

The default dtype of the internal coeffs Numpy array is complex128. Users can configure this by passing np.ndarray with a different dtype. For example, a parameterized SparsePauliOp can be made as follows:

Note

Parameterized SparsePauliOp does not support the following methods:

  • to_matrix(sparse=True) since scipy.sparse cannot have objects as elements.

  • to_operator() since Operator does not support objects.

  • sort, argsort since ParameterExpression does not support comparison.

  • equiv since ParameterExpression cannot be converted into complex.

  • chop since ParameterExpression does not support absolute value.

adjoint()[source]

Return the adjoint of the Operator.

apply_layout(layout: TranspileLayout | list[int] | None, num_qubits: int | None = None) → SparsePauliOp[source]

Apply a transpiler layout to this SparsePauliOp

Parameters:
  • layout -- Either a TranspileLayout, a list of integers or None. If both layout and num_qubits are none, a copy of the operator is returned.

  • num_qubits -- The number of qubits to expand the operator to. If not provided then if layout is a TranspileLayout the number of the transpiler output circuit qubits will be used by default. If layout is a list of integers the permutation specified will be applied without any expansion. If layout is None, the operator will be expanded to the given number of qubits.

Returns:

A new SparsePauliOp with the provided layout applied

argsort(weight: bool = False)[source]

Return indices for sorting the rows of the table.

Returns the composition of permutations in the order of sorting by coefficient and sorting by Pauli. By using the weight kwarg the output can additionally be sorted by the number of non-identity terms in the Pauli, where the set of all Pauli's of a given weight are still ordered lexicographically.

Example

Here is an example of how to use SparsePauliOp argsort.

Initial Ordering
SparsePauliOp(['XX', 'XX', 'XX', 'YI', 'II', 'XZ', 'XY', 'XI'],
              coeffs=[2.+1.j, 2.+2.j, 3.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j, 7.+0.j])
Lexicographically sorted
[4 7 0 1 2 6 5 3]
Lexicographically sorted
[4 7 0 1 2 6 5 3]
Weight sorted
[4 7 3 0 1 2 6 5]
Parameters:
  • weight (bool) -- optionally sort by weight if True (Default: False).

  • sorted (By using the weight kwarg the output can additionally be)

  • Pauli. (by the number of non-identity terms in the)

Returns:

the indices for sorting the table.

Return type:

array

assign_parameters(parameters: Mapping[Parameter, complex | ParameterExpression] | Sequence[complex | ParameterExpression], inplace: bool = False) → SparsePauliOp | None[source]

Bind the free Parameters in the coefficients to provided values.

Note

If all the parameters in the circuit are bound to numeric values, the coefficients array will be returned with a complex dtype.

Parameters:
  • parameters -- The values to bind the parameters to.

  • inplace -- If False, a copy of the operator with the bound parameters is returned. If True the operator itself is modified.

Returns:

A copy of the operator with bound parameters, if inplace is False, otherwise None.

chop(tol: float = 1e-14) → SparsePauliOp[source]

Set real and imaginary parts of the coefficients to 0 if < tol in magnitude.

For example, the operator representing 1+1e-17j X + 1e-17 Y with a tolerance larger than 1e-17 will be reduced to 1 X whereas SparsePauliOp.simplify() would return 1+1e-17j X.

If both the real and imaginary part of a coefficient is 0 after chopping, the corresponding Pauli is removed from the operator.

Parameters:

tol (float) -- The absolute tolerance to check whether a real or imaginary part should be set to 0.

Returns:

This operator with chopped coefficients.

Return type:

SparsePauliOp

property coeffs

Return the Pauli coefficients.

compose(other: SparsePauliOp, qargs: list | None = None, front: bool = False) → SparsePauliOp[source]

Return the operator composition with another SparsePauliOp.

Parameters:
  • other (SparsePauliOp) -- a SparsePauliOp object.

  • qargs (list or None) -- a list of subsystem positions to apply other on. If None apply on all subsystems (default: None).

  • front (bool) -- If True compose using right operator multiplication, instead of left multiplication [default: False].

Returns:

The composed SparsePauliOp.

Return type:

SparsePauliOp

Raises:

QiskitError -- if other cannot be converted to an operator, or has incompatible dimensions for specified subsystems.

Note

Composition (&) by default is defined as left matrix multiplication for matrix operators, while @ (equivalent to dot()) is defined as right matrix multiplication. That is that A & B == A.compose(B) is equivalent to B @ A == B.dot(A) when A and B are of the same type.

Setting the front=True kwarg changes this to right matrix multiplication and is equivalent to the dot() method A.dot(B) == A.compose(B, front=True).

conjugate()[source]

Return the conjugate of the SparsePauliOp.

equiv(other: SparsePauliOp, atol: float | None = None) → bool[source]

Check if two SparsePauliOp operators are equivalent.

Parameters:
  • other (SparsePauliOp) -- an operator object.

  • atol -- Absolute numerical tolerance for checking equivalence.

Returns:

True if the operator is equivalent to self.

Return type:

bool

expand(other: SparsePauliOp) → SparsePauliOp[source]

Return the reverse-order tensor product with another SparsePauliOp.

Parameters:

other (SparsePauliOp) -- a SparsePauliOp object.

Returns:

the tensor product \(b \otimes a\), where \(a\)

is the current SparsePauliOp, and \(b\) is the other SparsePauliOp.

Return type:

SparsePauliOp

static from_list(obj: Iterable[tuple[str, complex]], dtype: type | None = None, *, num_qubits: int | None = None) → SparsePauliOp[source]

Construct from a list of Pauli strings and coefficients.

For example, the 5-qubit Hamiltonian

\[H = Z_1 X_4 + 2 Y_0 Y_3\]

can be constructed as

Parameters:
  • obj (Iterable[Tuple[str, complex]]) -- The list of 2-tuples specifying the Pauli terms.

  • dtype (type | None) -- Data type for the coefficients. If None (default), the dtype is automatically inferred.

  • num_qubits (int) -- The number of qubits of the operator (Default: None).

Returns:

The SparsePauliOp representation of the Pauli terms.

Return type:

SparsePauliOp

Raises:
  • QiskitError -- If an empty list is passed and num_qubits is None.

  • QiskitError -- If num_qubits and the objects in the input list do not match.

static from_operator(obj: Operator, atol: float | None = None, rtol: float | None = None) → SparsePauliOp[source]

Construct from an Operator object.

Note that the cost of this construction is exponential in general because the number of possible Pauli terms in the decomposition is exponential in the number of qubits.

Internally this uses an implementation of the "tensorized Pauli decomposition" presented in Hantzko, Binkowski and Gupta (2023).

Parameters:
  • obj (Operator) -- an N-qubit operator.

  • atol (float) -- Optional. Absolute tolerance for checking if coefficients are zero (Default: 1e-8). Since the comparison is to zero, in effect the tolerance used is the maximum of atol and rtol.

  • rtol (float) -- Optional. relative tolerance for checking if coefficients are zero (Default: 1e-5). Since the comparison is to zero, in effect the tolerance used is the maximum of atol and rtol.

Returns:

the SparsePauliOp representation of the operator.

Return type:

SparsePauliOp

Raises:

QiskitError -- if the input operator is not an N-qubit operator.

static from_sparse_list(obj: Iterable[tuple[str, list[int], complex]], num_qubits: int, do_checks: bool = True, dtype: type | None = None) → SparsePauliOp[source]

Construct from a list of local Pauli strings and coefficients.

Each list element is a 3-tuple of a local Pauli string, indices where to apply it, and a coefficient.

For example, the 5-qubit Hamiltonian

\[H = Z_1 X_4 + 2 Y_0 Y_3\]

can be constructed as

Parameters:
  • obj (Iterable[tuple[str, list[int], complex]]) -- The list 3-tuples specifying the Paulis.

  • num_qubits (int) -- The number of qubits of the operator.

  • do_checks (bool) -- Whether to perform validity checks on the input indices.

  • dtype (type | None) -- Data type for the coefficients. If None (default), the dtype is automatically inferred.

Returns:

The SparsePauliOp representation of the Pauli terms.

Return type:

SparsePauliOp

Raises:
  • QiskitError -- If the number of qubits is incompatible with the indices of the Pauli terms.

  • QiskitError -- If the designated qubit is already assigned.

static from_sparse_observable(obs: SparseObservable) → SparsePauliOp[source]

Initialize from a SparseObservable.

Warning

A SparseObservable can efficiently represent eigenstate projectors (such as \(|0\langle\rangle 0|\)), but a SparsePauliOp cannot. If the input obs has \(n\) single-qubit projectors, the resulting SparsePauliOp will use \(2^n\) terms, which is an exponentially expensive representation that can quickly run out of memory.

Parameters:

obs -- The SparseObservable to convert.

Returns:

A SparsePauliOp version of the observable.

group_commuting(qubit_wise: bool = False) → list[SparsePauliOp][source]

Partition a SparsePauliOp into sets of commuting Pauli strings.

Parameters:

qubit_wise (bool) -- whether the commutation rule is applied to the whole operator, or on a per-qubit basis. For example:

Returns:

List of SparsePauliOp where each SparsePauliOp contains

commuting Pauli operators.

Return type:

list[SparsePauliOp]

is_unitary(atol: float | None = None, rtol: float | None = None) → bool[source]

Return True if operator is a unitary matrix.

This method checks whether the operator composed with its adjoint equals the identity, up to the provided tolerance. The tolerance is used when simplifying the composed operator and checking if the result is the identity.

Parameters:
  • atol (float) -- Optional. Absolute tolerance for checking if coefficients are zero (Default: 1e-8).

  • rtol (float) -- Optional. Relative tolerance for checking if coefficients are zero (Default: 1e-5).

Returns:

True if the operator is unitary, False otherwise.

Return type:

bool

label_iter()[source]

Return a label representation iterator.

This is a lazy iterator that converts each term in the SparsePauliOp into a tuple (label, coeff). To convert the entire table to labels use the to_labels() method.

Returns:

label iterator object for the SparsePauliOp.

Return type:

LabelIterator

matrix_iter(sparse: bool = False)[source]

Return a matrix representation iterator.

This is a lazy iterator that converts each term in the SparsePauliOp into a matrix as it is used. To convert to a single matrix use the to_matrix() method.

Parameters:

sparse (bool) -- optionally return sparse CSR matrices if True, otherwise return Numpy array matrices (Default: False)

Returns:

matrix iterator object for the PauliList.

Return type:

MatrixIterator

noncommutation_graph(qubit_wise: bool) → PyGraph[source]

Create the non-commutation graph of this SparsePauliOp.

This transforms the measurement operator grouping problem into graph coloring problem. The constructed graph contains one node for each Pauli. The nodes will be connecting for any two Pauli terms that do _not_ commute.

Parameters:

qubit_wise (bool) -- whether the commutation rule is applied to the whole operator, or on a per-qubit basis.

Returns:

the non-commutation graph with nodes for each Pauli and edges

indicating a non-commutation relation. Each node will hold the index of the Pauli term it corresponds to in its data. The edges of the graph hold no data.

Return type:

rustworkx.PyGraph

property parameters: ParameterView

Return the free Parameters in the coefficients.

property paulis

Return the PauliList.

property settings: dict

Return settings.

simplify(atol: float | None = None, rtol: float | None = None) → SparsePauliOp[source]

Simplify PauliList by combining duplicates and removing zeros.

Parameters:
  • atol (float) -- Optional. Absolute tolerance for checking if coefficients are zero (Default: 1e-8).

  • rtol (float) -- Optional. relative tolerance for checking if coefficients are zero (Default: 1e-5).

Returns:

the simplified SparsePauliOp operator.

Return type:

SparsePauliOp

property size

The number of Pauli of Pauli terms in the operator.

sort(weight: bool = False)[source]

Sort the rows of the table.

After sorting the coefficients using numpy's argsort, sort by Pauli. Pauli sort takes precedence. If Pauli is the same, it will be sorted by coefficient. By using the weight kwarg the output can additionally be sorted by the number of non-identity terms in the Pauli, where the set of all Pauli's of a given weight are still ordered lexicographically.

Example

Here is an example of how to use SparsePauliOp sort.

Initial Ordering
SparsePauliOp(['XX', 'XX', 'XX', 'YI', 'II', 'XZ', 'XY', 'XI'],
              coeffs=[2.+1.j, 2.+2.j, 3.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j, 7.+0.j])
Lexicographically sorted
SparsePauliOp(['II', 'XI', 'XX', 'XX', 'XX', 'XY', 'XZ', 'YI'],
              coeffs=[4.+0.j, 7.+0.j, 2.+1.j, 2.+2.j, 3.+0.j, 6.+0.j, 5.+0.j, 3.+0.j])
Lexicographically sorted
SparsePauliOp(['II', 'XI', 'XX', 'XX', 'XX', 'XY', 'XZ', 'YI'],
              coeffs=[4.+0.j, 7.+0.j, 2.+1.j, 2.+2.j, 3.+0.j, 6.+0.j, 5.+0.j, 3.+0.j])
Weight sorted
SparsePauliOp(['II', 'XI', 'YI', 'XX', 'XX', 'XX', 'XY', 'XZ'],
              coeffs=[4.+0.j, 7.+0.j, 3.+0.j, 2.+1.j, 2.+2.j, 3.+0.j, 6.+0.j, 5.+0.j])
Parameters:
  • weight (bool) -- optionally sort by weight if True (Default: False).

  • sorted (By using the weight kwarg the output can additionally be)

  • Pauli. (by the number of non-identity terms in the)

Returns:

a sorted copy of the original table.

Return type:

SparsePauliOp

static sum(ops: list[SparsePauliOp]) → SparsePauliOp[source]

Sum of SparsePauliOps.

This is a specialized version of the builtin sum function for SparsePauliOp with smaller overhead.

Parameters:

ops (list[SparsePauliOp]) -- a list of SparsePauliOps.

Returns:

the SparsePauliOp representing the sum of the input list.

Return type:

SparsePauliOp

Raises:
  • QiskitError -- if the input list is empty.

  • QiskitError -- if the input list includes an object that is not SparsePauliOp.

  • QiskitError -- if the numbers of qubits of the objects in the input list do not match.

tensor(other: SparsePauliOp) → SparsePauliOp[source]

Return the tensor product with another SparsePauliOp.

Parameters:

other (SparsePauliOp) -- a SparsePauliOp object.

Returns:

the tensor product \(a \otimes b\), where \(a\)

is the current SparsePauliOp, and \(b\) is the other SparsePauliOp.

Return type:

SparsePauliOp

Note

The tensor product can be obtained using the ^ binary operator. Hence a.tensor(b) is equivalent to a ^ b.

to_list(array: bool = False)[source]

Convert to a list Pauli string labels and coefficients.

For operators with a lot of terms converting using the array=True kwarg will be more efficient since it allocates memory for the full Numpy array of labels in advance.

Parameters:

array (bool) -- return a Numpy array if True, otherwise return a list (Default: False).

Returns:

List of pairs (label, coeff) for rows of the PauliList.

Return type:

list or array

to_matrix(sparse: bool = False, force_serial: bool = False) → ndarray[source]

Convert to a dense or sparse matrix.

Parameters:
  • sparse -- if True return a sparse CSR matrix, otherwise return dense Numpy array (the default).

  • force_serial -- if True, use an unthreaded implementation, regardless of the state of the Qiskit threading-control environment variables. By default, this will use threaded parallelism over the available CPUs.

Returns:

A dense matrix if sparse=False. csr_matrix: A sparse matrix in CSR format if sparse=True.

Return type:

array

to_operator() → Operator[source]

Convert to a matrix Operator object

to_sparse_list()[source]

Convert to a sparse Pauli list format with elements (pauli, qubits, coefficient).

transpose()[source]

Return the transpose of the SparsePauliOp.

class hqs_qorrelator_app.experimental_nmr_helpers.StatevectorEstimator(*, default_precision: float = 0.0, seed: Generator | int | None = None)[source]

Simple implementation of BaseEstimatorV2 with full state vector simulation.

This class is implemented via Statevector which turns provided circuits into pure state vectors. These states are subsequently acted on by SparsePauliOp, which implies that, at present, this implementation is only compatible with Pauli-based observables.

Each tuple of (circuit, observables, <optional> parameter values, <optional> precision), called an estimator primitive unified bloc (PUB), produces its own array-based result. The run() method can be given a sequence of pubs to run in one call.

Note

The result of this class is exact if the circuit contains only unitary operations. On the other hand, the result could be stochastic if the circuit contains a non-unitary operation such as a reset for some subsystems. The stochastic result can be made reproducible by setting seed, e.g., StatevectorEstimator(seed=123).

property default_precision: float

Return the default precision

run(pubs: Iterable[EstimatorPub | tuple[QuantumCircuit, str | Pauli | SparsePauliOp | SparseObservable | Mapping[str | Pauli, float] | ArrayLike] | tuple[QuantumCircuit, str | Pauli | SparsePauliOp | SparseObservable | Mapping[str | Pauli, float] | ArrayLike, Mapping[Parameter | str | tuple[Parameter | str, ...], ArrayLike]] | tuple[QuantumCircuit, str | Pauli | SparsePauliOp | SparseObservable | Mapping[str | Pauli, float] | ArrayLike, Mapping[Parameter | str | tuple[Parameter | str, ...], ArrayLike], Real]], *, precision: float | None = None) → PrimitiveJob[PrimitiveResult[PubResult]][source]
property seed: Generator | int | None

Return the seed or Generator object for random number generation.

class hqs_qorrelator_app.experimental_nmr_helpers.combinations(iterable, r)

Return successive r-length combinations of elements in the iterable.

combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)

hqs_qorrelator_app.experimental_nmr_helpers.correlators_to_spectrum(m_avg_x: list[float], m_avg_y: list[float], n_max: int, trotter_timestep: float, b_field: float, chem_shift_hz: float, noise_strength: float, gyromagnetic_ratio: float = 267522128.0) → tuple[Any, Any][source]

Calculate the full spectrum from the computed correlators, and the corresponding ppm array.

Note: The correlators are computed via a Fourier Transform.

Please note that this experimental function defines the external magnetic field to be in the z-direction, meaning that the full spectrum is represented by x.real + y.imag. If you have defined the external magnetic field to be in the x-direction, this function will not work, as you will need to use x.real - y.imag.

Parameters:
  • m_avg_x -- The first correlator, e.g. the ZZ correlator if the field is in the x-direction.

  • m_avg_y -- The second correlator, e.g. the YZ correlator if the field is in the x-direction.

  • n_max -- The total number of data points, which is greater than or equal to the number of trotter steps.

  • trotter_timestep -- The trotter timestep.

  • b_field -- strength of the constant magnetic field in the z-direction in Tesla.

  • chem_shift_hz -- The chemical shift of the input Hamiltonian.

  • noise_strength -- strength of the noise (gamma) used to decay the correlators.

  • gyromagnetic_ratio -- The gyromagnetic ratio of the isotope in rad/(s*T). If None is specified, will default to the one for 1H (267522128.0)

Returns:

The calculated spectrum. ppm: The ppm array to plot the full spectrum against.

Return type:

spectrum_full

hqs_qorrelator_app.experimental_nmr_helpers.fft_causal(f: ndarray) → ndarray[source]

Performs the Fourier Transform of a causal signal separating its odd and even part.

This way of transforming is necessary for causal signals or any signal that does not start and end at the same value. This is because the fft replicates the signal to be able to calculate the coefficients, leading to sudden jumps if the function itself is not periodic. These jumps introduce a shift in the FT at all frequencies, being equivalent to a delta within the sampled time frame. By (anti-)symmetrizing the signal one can circumvent this problem and obtain the correct Fourier Transform.

Parameters:

f (np.ndarray) -- Function to transform.

Returns:

The complex Fourier Transform.

Return type:

np.ndarray

hqs_qorrelator_app.experimental_nmr_helpers.hamiltonian_to_trotter_circuits(hamiltonian: PauliHamiltonian, number_of_trottersteps: int = 100, trotter_timestep: float = 0.01) → Tuple[List[QuantumCircuit], ParameterVector][source]

Create Trotter circuit for a given struqture Hamiltonian.

Parameters:
  • hamiltonian (PauliHamiltonian) -- Hamiltonian to create Trotter circuits for

  • number_of_trottersteps (int) -- Number of Trotter steps to apply

  • trotter_timestep (float) -- Time step for the Trotter steps

Returns:

A list of Trotter circuits for the given Hamiltonian

Return type:

List[QuantumCircuit]

hqs_qorrelator_app.experimental_nmr_helpers.run_trotter_circuits(circuits: List[QuantumCircuit], phi: ParameterVector, backend: Any = None) → Tuple[ndarray, Any][source]

Run Trotter circuits with estimator and return expectation values.

A qiskit EstimatorBackendV2 is used here. The argument backend should be an instance of qiskit BackendV2 or a qoqo_for_braket BraketBackend or None. If backend is None, a StatevectorEstimator will be used. If backend is an instance of BraketBackend, the AWS device and session will be extracted and used to create a BraketAwsBackend. Otherwise, the provided backend will be used.

Parameters:
  • circuits (List[QuantumCircuit]) -- List of Trotter circuits

  • phi (ParameterVector) -- Parameter vector for the X-sum eigenstate template

  • backend (Backend) -- backend to run the circuits on. Please note that the number of shots is converted to a precision, where precision = 1 / sqrt(number_shots).

Returns:

A tuple containing the X and Y expectation values for the given circuits and parameters

Return type:

Tuple[np.ndarray, np.ndarray]