QuantumCircuit
class
class qiskit.circuit.QuantumCircuit(*regs, name=None, global_phase=0, metadata=None, inputs=(), captures=(), declarations=())
Core Qiskit representation of a quantum circuit.
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
.
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 AncillaQubit s tracked by the circuit. |
calibrations | Custom user-supplied pulse calibrations for individual instructions. |
cregs | List of ClassicalRegister s tracked by the circuit. |
clbits | List of Clbit s tracked by the circuit. |
data | List of individual CircuitInstruction s that make up the circuit. |
duration | Total duration of the circuit, added by scheduling transpiler passes. |
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_declared_vars | Number of locally declared real-time classical variables in the outer circuit scope. |
num_input_vars | Number of input real-time classical variables. |
num_parameters | Number of compile-time Parameter s 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. |
op_start_times | Start times of scheduled operations, added by scheduling transpiler passes. |
parameters | Ordered set-like view of the compile-time Parameter s tracked by the circuit. |
qregs | List of QuantumRegister s tracked by the circuit. |
qubits | List of Qubit s 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 CircuitInstruction
s 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
).
data
The circuit data (instructions and context).
Returns
a list-like object containing the CircuitInstruction
s for each instruction.
Return type
QuantumCircuitData
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.
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
Type: str
A human-readable name for the 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 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.
QuantumCircuit
exposes data attributes tracking its internal quantum and classical bits and registers. These appear as Python list
s, 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
Type: list[QuantumRegister]
A list of the QuantumRegister
s in this circuit. You should not mutate this.
cregs
Type: list[ClassicalRegister]
A list of the ClassicalRegister
s in this circuit. You should not mutate this.
qubits
A list of Qubit
s in the order that they were added. You should not mutate this.
ancillas
A list of AncillaQubit
s in the order that they were added. You should not mutate this.
clbits
A list of Clbit
s in the order that they were added. You should not mutate this.
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.
>>> from qiskit.circuit import QuantumCircuit, Parameter
>>> a, b, elephant = Parameter("a"), Parameter("b"), Parameter("elephant")
>>> circuit = QuantumCircuit(1)
>>> circuit.rx(b, 0)
>>> circuit.rz(elephant, 0)
>>> circuit.ry(a, 0)
>>> circuit.parameters # sorted alphabetically!
ParameterView([Parameter(a), Parameter(b), Parameter(elephant)])
Bear in mind that alphabetical sorting might be unintuitive when it comes to numbers. The literal “10” comes before “2” in strict alphabetical sorting.
>>> from qiskit.circuit import QuantumCircuit, Parameter
>>> angles = [Parameter("angle_1"), Parameter("angle_2"), Parameter("angle_10")]
>>> circuit = QuantumCircuit(1)
>>> circuit.u(*angles, 0)
>>> circuit.draw()
┌─────────────────────────────┐
q: ┤ U(angle_1,angle_2,angle_10) ├
└─────────────────────────────┘
>>> circuit.parameters
ParameterView([Parameter(angle_1), Parameter(angle_10), Parameter(angle_2)])
To respect numerical sorting, a ParameterVector
can be used.
>>> from qiskit.circuit import QuantumCircuit, Parameter, ParameterVector
>>> x = ParameterVector("x", 12)
>>> circuit = QuantumCircuit(1)
>>> for x_i in x:
... circuit.rx(x_i, 0)
>>> circuit.parameters
ParameterView([
ParameterVectorElement(x[0]), ParameterVectorElement(x[1]),
ParameterVectorElement(x[2]), ParameterVectorElement(x[3]),
..., ParameterVectorElement(x[11])
])
Returns
The sorted Parameter
objects in the circuit.
The storage of any manual pulse-level calibrations for individual instructions on the circuit is in calibrations
. This presents as a dict
, but should not be mutated directly; use the methods discussed in Manual calibration of instructions.
calibrations
Return calibration dictionary.
The custom pulse definition of a given gate is of the form {'gate_name': {(qubits, params): schedule}}
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 which permutes the qubits based on the selected physical qubits on the Target
, and a final layout which is an output permutation caused by SwapGate
s inserted during routing.
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
Type: int | float | None
The total duration of the circuit, set by a scheduling transpiler pass. Its unit is specified by unit
.
unit
The unit that duration
is specified in.
op_start_times
Return a list of operation start times.
This attribute is enabled once one of scheduling analysis passes runs on the quantum circuit.
Returns
List of integers representing instruction 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.
num_clbits
Return number of classical bits.
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_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_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_parameters
The number of parameter objects in the circuit.
num_qubits
Return number of qubits.
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__
__init__(*regs, name=None, global_phase=0, metadata=None, inputs=(), captures=(), declarations=())
Default constructor of QuantumCircuit
.
Parameters
-
regs (Register |int | Sequence[Bit]) –
The registers to be included in the circuit.
-
If a list of
Register
objects, represents theQuantumRegister
and/orClassicalRegister
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 ofBit
s to be added to the circuit.
-
-
name (str | None) – the name of the quantum circuit. If not set, an automatically generated string will be assigned.
-
global_phase (ParameterValueType) – The global phase of the circuit in radians.
-
metadata (dict | None) – 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 (Iterable[expr.Var]) – any variables to declare as
input
runtime variables for this circuit. These should already be existingexpr.Var
nodes that you build from somewhere else; if you need to create the inputs as well, useQuantumCircuit.add_input()
. The variables given in this argument will be passed directly toadd_input()
. A circuit cannot have bothinputs
andcaptures
. -
captures (Iterable[expr.Var]) – any variables that 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 bothinputs
andcaptures
. -
declarations (Mapping[expr.Var, expr.Expr] | Iterable[Tuple[expr.Var, expr.Expr]]) –
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
andcaptures
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
copy(name=None)
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
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 use apply onto the back with compose()
, or to do a full rewrite of a circuit’s instructions.
copy_empty_like
copy_empty_like(name=None, *, vars_mode='alike')
Return a copy of self with the same structure but empty.
That structure includes:
- name, calibrations 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.
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 (str | None) – Name for the copied circuit. If None, then the name stays the same.
-
vars_mode (Literal['alike', 'captures', 'drop']) –
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 beinput
variables in the output circuit.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, sincecompose()
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
In some cases, it is most convenient to generate a list of CircuitInstruction
s 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.
from_instructions
static from_instructions(instructions, *, qubits=(), clbits=(), name=None, global_phase=0, metadata=None)
Construct a circuit from an iterable of CircuitInstruction
s.
Parameters
- instructions (Iterable[CircuitInstruction |tuple[qiskit.circuit.Instruction] | tuple[qiskit.circuit.Instruction, Iterable[Qubit]] | tuple[qiskit.circuit.Instruction, Iterable[Qubit], Iterable[Clbit]]]) – The instructions to add to the circuit.
- qubits (Iterable[Qubit]) – Any qubits to add to the circuit. This argument can be used, for example, to enforce a particular ordering of qubits.
- clbits (Iterable[Clbit]) – Any classical bits to add to the circuit. This argument can be used, for example, to enforce a particular ordering of classical bits.
- name (str | None) – The name of the circuit.
- global_phase (ParameterValueType) – The global phase of the circuit in radians.
- metadata (dict | None) – Arbitrary key value metadata to associate with the circuit.
Returns
The quantum circuit.
Return type
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()
.
from_qasm_file
static from_qasm_file(path)
Read an OpenQASM 2.0 program from a file and convert to an instance of QuantumCircuit
.
Parameters
path (str) – Path to the file for an OpenQASM 2 program
Returns
The QuantumCircuit object for the input OpenQASM 2.
Return type
qasm2.load()
: the complete interface to the OpenQASM 2 importer.
from_qasm_str
static from_qasm_str(qasm_str)
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
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() | Qubit s and Clbit s. |
add_register() | QuantumRegister and ClassicalRegister . |
add_var() | Var nodes with local scope and initializers. |
add_input() | Var nodes that are treated as circuit inputs. |
add_capture() | Var 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 Real-time classical computation), 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
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
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).
add_var
add_var(name_or_var, /, initial)
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 (str |expr.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 (Any) –
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 useexpr.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 usingexpr.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 variable.
Return type
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
add_input(name_or_var: str, type_: Type, /) → Var
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 existingVar
, 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.
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
add_uninitialized_var(var, /)
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.
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 (Var) – the variable to add.
add_capture
add_capture(var)
Add a variable to the circuit that it should capture from a scope it will be contained within.
This method requires a Var
node to enforce that you’ve got a handle to one, because you will need to declare the same variable using the same object into 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 variables that are used within them.
Parameters
var (Var) – the variable to capture from an enclosing scope.
Raises
CircuitError – if the variable cannot be created due to shadowing an existing variable.
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, just 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
find_bit(bit)
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.
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
has_register(register)
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
Working with 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
assign_parameters(parameters: Mapping[Parameter, ParameterExpression | float] | Iterable[ParameterExpression | float], inplace: Literal[False] = False, *, flat_input: bool = False, strict: bool = True) → QuantumCircuit
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.
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
andparameters
is a mapping type, it is assumed to be exactly a mapping of{parameter: value}
. By default (False
), the mapping may also containParameterVector
keys that point to a corresponding sequence of values, and these will be unrolled during the mapping, or string keys, which will be converted toParameter
instances usingget_parameter()
. - strict – If
False
, any parameters given in the mapping that are not used in the circuit will be ignored. IfTrue
(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.
from qiskit.circuit import QuantumCircuit, Parameter
circuit = QuantumCircuit(2)
params = [Parameter('A'), Parameter('B'), Parameter('C')]
circuit.ry(params[0], 0)
circuit.crx(params[1], 0, 1)
circuit.draw('mpl')
circuit.assign_parameters({params[0]: params[2]}, inplace=True)
circuit.draw('mpl')
Bind the values out-of-place by list and get a copy of the original circuit.
from qiskit.circuit import QuantumCircuit, ParameterVector
circuit = QuantumCircuit(2)
params = ParameterVector('P', 2)
circuit.ry(params[0], 0)
circuit.crx(params[1], 0, 1)
bound_circuit = circuit.assign_parameters([1, 2])
bound_circuit.draw('mpl')
circuit.draw('mpl')
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
has_parameter(name_or_param, /)
Check whether a parameter object exists in this circuit.
Parameters
name_or_param (str |Parameter) – 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.
Return type
QuantumCircuit.get_parameter()
Retrieve the Parameter
instance from this circuit by name.
A similar method to this, but for run-time expr.Var
variables instead of compile-time Parameter
s.
get_parameter
get_parameter(name: str, default: T) → Parameter | T
get_parameter(name: str, default: ellipsis = 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 is 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) is my_param
assert qc.get_parameter("unknown_param", None) is None
Working with real-time typed classical data
Module-level documentation for how the variable-, expression- and type-systems work, the objects used to represent them, and the classical operations available.
Real-time classical computation
A discussion of how real-time data fits into the entire qiskit.circuit
data model as a whole.
The methods for adding new Var
variables to a circuit after initialization.
You can retrive a Var
instance attached to a circuit by using its variable name using get_var()
, or check if a circuit contains a given variable with has_var()
.
get_var
get_var(name: str, default: T) → Var | T
get_var(name: str, default: ellipsis = 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 is 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) is my_var
assert qc.get_var("unknown_variable", None) is None
has_var
has_var(name_or_var, /)
Check whether a variable is accessible in this scope.
Parameters
name_or_var (str |expr.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.
Return type
Retrieve the expr.Var
instance from this circuit by name.
QuantumCircuit.has_parameter()
A similar method to this, but for compile-time Parameter
s instead of run-time expr.Var
variables.
There are also several iterator methods that you can use to get the full set of variables 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_input_vars
, num_captured_vars
and num_declared_vars
.
iter_vars
iter_vars()
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()
.
Return type
iter_input_vars
iter_input_vars()
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()
).
Return type
iter_captured_vars
iter_captured_vars()
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()
).
Return type
iter_declared_vars
iter_declared_vars()
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()
).
Return type
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.
Operations, instructions and gates
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
append(instruction, qargs=None, cargs=None, *, copy=True)
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 (Operation |CircuitInstruction) –
Instruction
instance to append, or aCircuitInstruction
with all its context. - qargs (Sequence[QubitSpecifier] | None) – specifiers of the
Qubit
s to attach instruction to. - cargs (Sequence[ClbitSpecifier] | None) – specifiers of the
Clbit
s to attach instruction to. - copy (bool) – if
True
(the default), then the incominginstruction
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 thisFalse
for a small speedup.
Returns
a handle to the CircuitInstruction
s that were actually added to the circuit.
Return type
Raises
CircuitError – if the operation passed is not an instance of Instruction
.
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
_append(instruction: CircuitInstruction, *, _standard_gate: bool) → CircuitInstruction
_append(instruction: Operation, qargs: Sequence[Qubit], cargs: Sequence[Clbit]) → Operation
Append an instruction to the end of the circuit, modifying the circuit in place.
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 or classically conditioned instructions must act only on variables present in the circuit.
- the circuit must not be within a control-flow builder context.
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 caseqargs
andcargs
must be explicitly given. -
qargs – Legacy argument for qubits to attach the bare
Operation
to. Ignored if the first argument is in the preferentialCircuitInstruction
form. -
cargs – Legacy argument for clbits to attach the bare
Operation
to. Ignored if the first argument is in the preferentialCircuitInstruction
form.
Returns
a handle to the instruction that was just added.
Return type
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
compose(other, qubits=None, clbits=None, front=False, inplace=False, wrap=False, *, copy=True, var_remap=None, inline_captures=False)
Apply the instructions from one circuit onto specified qubits and/or clbits on another.
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
instances), there are two principal strategies for using compose()
:
- The
other
circuit is treated as entirely additive, including its variables. The variables inother
must be entirely distinct from those inself
(usevar_remap
to help with this), and all variables inother
will be declared anew in the output with matching input/capture/local scoping to how they are inother
. This is generally what you want if you’re joining two unrelated circuits. - The
other
circuit was created as an exact extension toself
to be inlined onto it, including acting on the existing variables in their states at the end ofself
. In this case,other
should be created with all these variables to be inlined declared as “captures”, and then you can useinline_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 thevars_mode="captures"
argument tocopy_empty_like()
useful to create each layer’s base, in this case.
Parameters
-
other (qiskit.circuit.Instruction orQuantumCircuit) – (sub)circuit or instruction to compose onto self. If not a
QuantumCircuit
, this can be anything thatappend
will accept. -
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 toFalse
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 useother
afterward, and some instructions may have been mutated in place. -
var_remap (Mapping) –
mapping to use to rewrite
expr.Var
nodes inother
as they are inlined intoself
. This can be used to avoid naming conflicts.Both keys and values can be given as strings or direct
expr.Var
instances. If a key is a string, it matches anyVar
with the same name. If a value is a string, whenever a new key matches a it, a newVar
is created with the correct type. If a value is aVar
, itstype
must exactly match that of the variable it is replacing. -
inline_captures (bool) –
if
True
, then all “captured”Var
nodes in theother
QuantumCircuit
are assumed to refer to variables already declared inself
(as any input/capture/local type), and the uses inother
will apply to the existing variables. If you want to build up a layer for an existing circuit to use withcompose()
, you might find thevars_mode="captures"
argument tocopy_empty_like()
useful. Any remapping invars_remap
occurs before evaluating this variable inlining.If this is
False
(the default), then all variables inother
will be required to be distinct from those inself
, 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()
orto_gate()
, and then callappend()
.
Returns
the composed circuit (returns None if inplace==True).
Return type
Raises
- CircuitError – if no correct wire mapping can be made between the two circuits, such as if
other
is wider thanself
. - CircuitError – if trying to emit a new circuit while
self
has a partially built control-flow context active, such as the context-manager forms ofif_test()
,for_loop()
andwhile_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
tensor(other, inplace=False)
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.
Return type
QuantumCircuit | None
Examples
from qiskit import QuantumCircuit
top = QuantumCircuit(1)
top.x(0);
bottom = QuantumCircuit(2)
bottom.cry(0.2, 0, 1);
tensored = bottom.tensor(top)
tensored.draw('mpl')
Returns
The tensored circuit (returns None
if inplace=True
).
Return type
As some rules of thumb:
- If you have a single
Operation
,Instruction
orGate
, you should definitely useappend()
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 callto_instruction()
orto_gate()
, and then apply the result of that to the circuit usingappend()
. - If you have a
QuantumCircuit
that represents a larger “layer” of another circuit, or contains typed classical variables or control flow, you should usecompose()
to merge it onto another circuit. tensor()
is wanted far more rarely than eitherappend()
orcompose()
. Internally, it is mostly a wrapper aroundadd_bits()
andcompose()
.
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 theto_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 setinplace=True
.- Both
append()
andcompose()
(but not_append()
) have acopy
keyword argument that defaults toTrue
. In these cases, the incomingOperation
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 setcopy=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 relevent 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:
The following methods apply Gate
instances that are also controlled gates, so are direct subclasses of ControlledGate
:
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
barrier(*qargs, label=None)
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
ccx
ccx(control_qubit1, control_qubit2, target_qubit, ctrl_state=None)
Apply CCXGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit1 (QubitSpecifier) – The qubit(s) used as the first control.
- control_qubit2 (QubitSpecifier) – The qubit(s) used as the second control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- ctrl_state (str |int | None) – 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.
Return type
ccz
ccz(control_qubit1, control_qubit2, target_qubit, label=None, ctrl_state=None)
Apply CCZGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit1 (QubitSpecifier) – The qubit(s) used as the first control.
- control_qubit2 (QubitSpecifier) – The qubit(s) used as the second control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
ch
ch(control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CHGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit (QubitSpecifier) – The qubit(s) used as the control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
cp
cp(theta, control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CPhaseGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterValueType) – The angle of the rotation.
- control_qubit (QubitSpecifier) – The qubit(s) used as the control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
crx
crx(theta, control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CRXGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterValueType) – The angle of the rotation.
- control_qubit (QubitSpecifier) – The qubit(s) used as the control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
cry
cry(theta, control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CRYGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterValueType) – The angle of the rotation.
- control_qubit (QubitSpecifier) – The qubit(s) used as the control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
crz
crz(theta, control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CRZGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterValueType) – The angle of the rotation.
- control_qubit (QubitSpecifier) – The qubit(s) used as the control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
cs
cs(control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CSGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit (QubitSpecifier) – The qubit(s) used as the control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
csdg
csdg(control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CSdgGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit (QubitSpecifier) – The qubit(s) used as the control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
cswap
cswap(control_qubit, target_qubit1, target_qubit2, label=None, ctrl_state=None)
Apply CSwapGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit (QubitSpecifier) – The qubit(s) used as the control.
- target_qubit1 (QubitSpecifier) – The qubit(s) targeted by the gate.
- target_qubit2 (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
csx
csx(control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CSXGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit (QubitSpecifier) – The qubit(s) used as the control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
cu
cu(theta, phi, lam, gamma, control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CUGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterValueType) – The rotation angle of the gate.
- phi (ParameterValueType) – The rotation angle of the gate.
- lam (ParameterValueType) – The rotation angle of the gate.
- gamma (ParameterValueType) – The global phase applied of the U gate, if applied.
- control_qubit (QubitSpecifier) – The qubit(s) used as the control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
cx
cx(control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CXGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit (QubitSpecifier) – The qubit(s) used as the control.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
cy
cy(control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CYGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit (QubitSpecifier) – The qubit(s) used as the controls.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
cz
cz(control_qubit, target_qubit, label=None, ctrl_state=None)
Apply CZGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit (QubitSpecifier) – The qubit(s) used as the controls.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- label (str | None) – The string label of the gate in the circuit.
- ctrl_state (str |int | None) – 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.
Return type
dcx
dcx(qubit1, qubit2)
Apply DCXGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- qubit1 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
- qubit2 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
delay
delay(duration, qarg=None, unit='dt')
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 (int orfloat orParameterExpression) – duration of the delay.
- qarg (Object) – qubit argument to apply this delay.
- unit (str) – unit of the duration. 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
Raises
CircuitError – if arguments have bad format.
ecr
ecr(qubit1, qubit2)
Apply ECRGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- qubit1 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubits to apply the gate to.
- qubit2 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubits to apply the gate to.
Returns
A handle to the instructions created.
Return type
h
h(qubit)
Apply HGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
id
id(qubit)
Apply IGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
initialize
initialize(params, qubits=None, normalize=False)
Initialize qubits in a specific state.
Qubit initialization is done by first resetting the qubits to followed by calling StatePreparation
class to prepare the qubits in a specified state. Both these steps are included in the Initialize
instruction.
Parameters
-
params (Statevector | Sequence[complex] | str |int) –
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 and the qubit one to . - An integer that is used as a bitmap indicating which qubits to initialize to . Example: setting params to 5 would initialize qubit 0 and qubit 2 to and qubit 1 to .
-
qubits (Sequence[QubitSpecifier] | None) – Qubits to initialize. If
None
the initialization is applied to all qubits in the circuit. -
normalize (bool) – Whether to normalize an input array to a unit vector.
Returns
A handle to the instructions created.
Examples
Prepare a qubit in the state .
import numpy as np
from qiskit import QuantumCircuit
circuit = QuantumCircuit(1)
circuit.initialize([1/np.sqrt(2), -1/np.sqrt(2)], 0)
circuit.draw()
output:
┌──────────────────────────────┐
q_0: ┤ Initialize(0.70711,-0.70711) ├
└──────────────────────────────┘
Initialize from a string two qubits in the state . The order of the labels is reversed with respect to qubit index. More information about labels for basis states are in Statevector.from_label()
.
import numpy as np
from qiskit import QuantumCircuit
circuit = QuantumCircuit(2)
circuit.initialize('01', circuit.qubits)
circuit.draw()
output:
┌──────────────────┐
q_0: ┤0 ├
│ Initialize(0,1) │
q_1: ┤1 ├
└──────────────────┘
Initialize two qubits from an array of complex amplitudes.
import numpy as np
from qiskit import QuantumCircuit
circuit = QuantumCircuit(2)
circuit.initialize([0, 1/np.sqrt(2), -1.j/np.sqrt(2), 0], circuit.qubits)
circuit.draw()
output:
┌────────────────────────────────────┐
q_0: ┤0 ├
│ Initialize(0,0.70711,-0.70711j,0) │
q_1: ┤1 ├
└────────────────────────────────────┘
iswap
iswap(qubit1, qubit2)
Apply iSwapGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- qubit1 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubits to apply the gate to.
- qubit2 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubits to apply the gate to.
Returns
A handle to the instructions created.
Return type
mcp
mcp(lam, control_qubits, target_qubit, ctrl_state=None)
Apply MCPhaseGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- lam (ParameterValueType) – The angle of the rotation.
- control_qubits (Sequence[QubitSpecifier]) – The qubits used as the controls.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- ctrl_state (str |int | None) – 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.
Return type
mcrx
mcrx(theta, q_controls, q_target, use_basis_gates=False)
Apply Multiple-Controlled X rotation gate
Parameters
- self (QuantumCircuit) – The QuantumCircuit object to apply the mcrx gate on.
- theta (float) – angle theta
- q_controls (QuantumRegister orlist(Qubit)) – The list of control qubits
- q_target (Qubit) – The target qubit
- use_basis_gates (bool) – use p, u, cx
Raises
QiskitError – parameter errors
mcry
mcry(theta, q_controls, q_target, q_ancillae=None, mode=None, use_basis_gates=False)
Apply Multiple-Controlled Y rotation gate
Parameters
- self (QuantumCircuit) – The QuantumCircuit object to apply the mcry gate on.
- theta (float) – angle theta
- q_controls (list(Qubit)) – The list of control qubits
- q_target (Qubit) – The target qubit
- q_ancillae (QuantumRegister ortuple(QuantumRegister, int)) – The list of ancillary qubits.
- mode (string) – The implementation mode to use
- use_basis_gates (bool) – use p, u, cx
Raises
QiskitError – parameter errors
mcrz
mcrz(lam, q_controls, q_target, use_basis_gates=False)
Apply Multiple-Controlled Z rotation gate
Parameters
- self (QuantumCircuit) – The QuantumCircuit object to apply the mcrz gate on.
- lam (float) – angle lambda
- q_controls (list(Qubit)) – The list of control qubits
- q_target (Qubit) – The target qubit
- use_basis_gates (bool) – use p, u, cx
Raises
QiskitError – parameter errors
mcx
mcx(control_qubits, target_qubit, ancilla_qubits=None, mode='noancilla', ctrl_state=None)
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.
Parameters
- control_qubits (Sequence[QubitSpecifier]) – The qubits used as the controls.
- target_qubit (QubitSpecifier) – The qubit(s) targeted by the gate.
- ancilla_qubits (QubitSpecifier | Sequence[QubitSpecifier] | None) – The qubits used as the ancillae, if the mode requires them.
- mode (str) – The choice of mode, explained further above.
- ctrl_state (str |int | None) – 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.
Return type
measure
measure(qubit, cbit)
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 or . 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 |QuantumRegister |int |slice |Sequence[Qubit |int]) – qubit(s) to measure.
- cbit (Clbit |ClassicalRegister |int |slice |Sequence[Clbit |int]) – classical bit(s) to place the measurement result(s) in.
Returns
handle to the added instructions.
Return type
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):
from qiskit import QuantumCircuit
circuit = QuantumCircuit(1, 1)
circuit.h(0)
circuit.measure(0, 0)
circuit.draw()
┌───┐┌─┐
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:
circuit = QuantumCircuit(2, 2)
circuit.measure([0,1], [0,1])
circuit = QuantumCircuit(2, 2)
circuit.measure(0, 0)
circuit.measure(1, 1)
Instead of lists, you can use QuantumRegister
and ClassicalRegister
under the same logic.
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
qreg = QuantumRegister(2, "qreg")
creg = ClassicalRegister(2, "creg")
circuit = QuantumCircuit(qreg, creg)
circuit.measure(qreg, creg)
This is equivalent to:
circuit = QuantumCircuit(qreg, creg)
circuit.measure(qreg[0], creg[0])
circuit.measure(qreg[1], creg[1])
ms
ms(theta, qubits)
Apply MSGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterExpression |float) – The angle of the rotation.
- qubits (Sequence[Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]]) – The qubits to apply the gate to.
Returns
A handle to the instructions created.
Return type
p
p(theta, qubit)
Apply PhaseGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterExpression |float) – THe angle of the rotation.
- qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
pauli
pauli(pauli_string, qubits)
Apply PauliGate
.
Parameters
- pauli_string (str) – A string representing the Pauli operator to apply, e.g. ‘XX’.
- qubits (Sequence[Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]]) – The qubits to apply this gate to.
Returns
A handle to the instructions created.
Return type
prepare_state
prepare_state(state, qubits=None, label=None, normalize=False)
Prepare qubits in a specific state.
This class implements a state preparing unitary. Unlike initialize()
it does not reset the qubits first.
Parameters
-
state (Statevector | Sequence[complex] | str |int) –
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 and the qubit one to . - An integer that is used as a bitmap indicating which qubits to initialize to . Example: setting params to 5 would initialize qubit 0 and qubit 2 to and qubit 1 to .
-
qubits (Sequence[QubitSpecifier] | None) – Qubits to initialize. If
None
the initialization is applied to all qubits in the circuit. -
label (str | None) – An optional label for the gate
-
normalize (bool) – Whether to normalize an input array to a unit vector.
Returns
A handle to the instruction that was just initialized
Return type
Examples
Prepare a qubit in the state .
import numpy as np
from qiskit import QuantumCircuit
circuit = QuantumCircuit(1)
circuit.prepare_state([1/np.sqrt(2), -1/np.sqrt(2)], 0)
circuit.draw()
output:
┌─────────────────────────────────────┐
q_0: ┤ State Preparation(0.70711,-0.70711) ├
└─────────────────────────────────────┘
Prepare from a string two qubits in the state . The order of the labels is reversed with respect to qubit index. More information about labels for basis states are in Statevector.from_label()
.
import numpy as np
from qiskit import QuantumCircuit
circuit = QuantumCircuit(2)
circuit.prepare_state('01', circuit.qubits)
circuit.draw()
output:
┌─────────────────────────┐
q_0: ┤0 ├
│ State Preparation(0,1) │
q_1: ┤1 ├
└─────────────────────────┘
Initialize two qubits from an array of complex amplitudes .. code-block:
import numpy as np
from qiskit import QuantumCircuit
circuit = QuantumCircuit(2)
circuit.prepare_state([0, 1/np.sqrt(2), -1.j/np.sqrt(2), 0], circuit.qubits)
circuit.draw()
output:
┌───────────────────────────────────────────┐
q_0: ┤0 ├
│ State Preparation(0,0.70711,-0.70711j,0) │
q_1: ┤1 ├
└───────────────────────────────────────────┘
r
r(theta, phi, qubit)
Apply RGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterExpression |float) – The angle of the rotation.
- phi (ParameterExpression |float) – The angle of the axis of rotation in the x-y plane.
- qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
rcccx
rcccx(control_qubit1, control_qubit2, control_qubit3, target_qubit)
Apply RC3XGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit1 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) used as the first control.
- control_qubit2 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) used as the second control.
- control_qubit3 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) used as the third control.
- target_qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) targeted by the gate.
Returns
A handle to the instructions created.
Return type
rccx
rccx(control_qubit1, control_qubit2, target_qubit)
Apply RCCXGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- control_qubit1 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) used as the first control.
- control_qubit2 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) used as the second control.
- target_qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) targeted by the gate.
Returns
A handle to the instructions created.
Return type
reset
reset(qubit)
Reset the quantum bit(s) to their default state.
Parameters
qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – qubit(s) to reset.
Returns
handle to the added instruction.
Return type
rv
rv(vx, vy, vz, qubit)
Apply RVGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Rotation around an arbitrary rotation axis , where is the angle of rotation in radians.
Parameters
- vx (ParameterExpression |float) – x-component of the rotation axis.
- vy (ParameterExpression |float) – y-component of the rotation axis.
- vz (ParameterExpression |float) – z-component of the rotation axis.
- qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
rx
rx(theta, qubit, label=None)
Apply RXGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterValueType) – The rotation angle of the gate.
- qubit (QubitSpecifier) – The qubit(s) to apply the gate to.
- label (str | None) – The string label of the gate in the circuit.
Returns
A handle to the instructions created.
Return type
rxx
rxx(theta, qubit1, qubit2)
Apply RXXGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterExpression |float) – The angle of the rotation.
- qubit1 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
- qubit2 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
ry
ry(theta, qubit, label=None)
Apply RYGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterValueType) – The rotation angle of the gate.
- qubit (QubitSpecifier) – The qubit(s) to apply the gate to.
- label (str | None) – The string label of the gate in the circuit.
Returns
A handle to the instructions created.
Return type
ryy
ryy(theta, qubit1, qubit2)
Apply RYYGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterExpression |float) – The rotation angle of the gate.
- qubit1 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
- qubit2 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
rz
rz(phi, qubit)
Apply RZGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- phi (ParameterExpression |float) – The rotation angle of the gate.
- qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
rzx
rzx(theta, qubit1, qubit2)
Apply RZXGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterExpression |float) – The rotation angle of the gate.
- qubit1 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
- qubit2 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
rzz
rzz(theta, qubit1, qubit2)
Apply RZZGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterExpression |float) – The rotation angle of the gate.
- qubit1 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
- qubit2 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
s
s(qubit)
Apply SGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
sdg
sdg(qubit)
Apply SdgGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
store
store(lvalue, rvalue, /)
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 (Any) – a valid specifier for a memory location in the circuit. This will typically be a
Var
node, but you can also write toClbit
orClassicalRegister
memory locations if your hardware supports it. The memory location must already be present in the circuit. - rvalue (Any) – a real-time classical expression whose result should be written into the given memory location.
Return type
The backing Instruction
class that represents this operation.
Create a new variable in the circuit that can be written to with this method.
swap
swap(qubit1, qubit2)
Apply SwapGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- qubit1 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubits to apply the gate to.
- qubit2 (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubits to apply the gate to.
Returns
A handle to the instructions created.
Return type
sx
sx(qubit)
Apply SXGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
sxdg
sxdg(qubit)
Apply SXdgGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
t
t(qubit)
Apply TGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
tdg
tdg(qubit)
Apply TdgGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
u
u(theta, phi, lam, qubit)
Apply UGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- theta (ParameterExpression |float) – The rotation angle of the gate.
- phi (ParameterExpression |float) – The rotation angle of the gate.
- lam (ParameterExpression |float) – The rotation angle of the gate.
- qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
unitary
unitary(obj, qubits, label=None)
Apply unitary gate specified by obj
to qubits
.
Parameters
- obj (np.ndarray | Gate | BaseOperator) – Unitary operator.
- qubits (Sequence[QubitSpecifier]) – The circuit qubits to apply the transformation to.
- label (str | None) – Unitary name for backend [Default: None].
Returns
The quantum circuit.
Return type
Example
Apply a gate specified by a unitary matrix to a quantum circuit
from qiskit import QuantumCircuit
matrix = [[0, 0, 0, 1],
[0, 0, 1, 0],
[1, 0, 0, 0],
[0, 1, 0, 0]]
circuit = QuantumCircuit(2)
circuit.unitary(matrix, [0, 1])
x
x(qubit, label=None)
Apply XGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
- qubit (QubitSpecifier) – The qubit(s) to apply the gate to.
- label (str | None) – The string label of the gate in the circuit.
Returns
A handle to the instructions created.
Return type
y
y(qubit)
Apply YGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
z
z(qubit)
Apply ZGate
.
For the full matrix form of this gate, see the underlying gate documentation.
Parameters
qubit (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – The qubit(s) to apply the gate to.
Returns
A handle to the instructions created.
Return type
Adding control flow to circuits
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 . |
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 straightfowards 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.
break_loop
break_loop()
Apply BreakLoopOp
.
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.
Return type
continue_loop
continue_loop()
Apply ContinueLoopOp
.
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.
Return type
for_loop
for_loop(indexset: Iterable[int], loop_parameter: Parameter | None, body: None, qubits: None, clbits: None, *, label: str | None) → ForLoopContext
for_loop(indexset: Iterable[int], loop_parameter: Parameter | 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)
qc.break_loop().c_if(0, True)
Parameters
-
indexset (Iterable[int]) – A collection of integers to loop over. Always necessary.
-
loop_parameter (Optional[Parameter]) –
The parameter used within
body
to which the values fromindexset
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 thewith
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 inindexset
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
if_else(condition, true_body, false_body, qubits, clbits, label=None)
Apply IfElseOp
.
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 (tuple[ClassicalRegister, int] | tuple[Clbit, int] | tuple[Clbit, bool]) – 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 aClassicalRegister
to be tested for equality with a givenint
, or as a tuple of aClbit
to be compared to either abool
or anint
. - true_body (QuantumCircuit) – The circuit body to be run if
condition
is true. - false_body (QuantumCircuit) – The circuit to be run if
condition
is false. - qubits (Sequence[QubitSpecifier]) – The circuit qubits over which the if/else should be run.
- clbits (Sequence[ClbitSpecifier]) – The circuit clbits over which the if/else should be run.
- label (str | None) – 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.
Return type
if_test
if_test(condition: tuple[ClassicalRegister | Clbit, int]) → IfContext
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 aClassicalRegister
to be tested for equality with a givenint
, or as a tuple of aClbit
to be compared to either abool
or anint
. - 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
switch(target: Clbit | ClassicalRegister | int | slice | Sequence[Clbit | int], cases: None, qubits: None, clbits: None, *, label: str | None) → SwitchContext
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
while_loop(condition: tuple[ClassicalRegister | Clbit, int] | expr.Expr, body: None, qubits: None, clbits: None, *, label: str | None) → WhileLoopContext
while_loop(condition: tuple[ClassicalRegister | Clbit, int] | expr.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 aClassicalRegister
or aClbit
, 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.
Converting circuits to single 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
to_instruction(parameter_map=None, label=None)
Create an Instruction
out of this circuit.
circuit_to_instruction()
The underlying driver of this method.
Parameters
- parameter_map (dict[Parameter, ParameterValueType] | None) – 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 (str | None) – Optional gate label.
Returns
a composite instruction encapsulating this circuit (can be
decomposed back).
Return type
to_gate
to_gate(parameter_map=None, label=None)
Create a Gate
out of this circuit. The circuit must act only qubits and contain only unitary operations.
circuit_to_gate()
The underlying driver of this method.
Parameters
- parameter_map (dict[Parameter, ParameterValueType] | None) – 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 (str | None) – Optional gate label.
Returns
a composite gate encapsulating this circuit (can be decomposed back).
Return type
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
measure_active(inplace=True)
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
measure_all
measure_all(inplace=True, add_bits=True)
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
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
clear()
Clear all instructions in self.
Clearing the circuits will keep the metadata and calibrations.
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
remove_final_measurements(inplace=True)
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.)
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.
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
Manual calibration of instructions
QuantumCircuit
can store calibrations
of instructions that define the pulses used to run them on one particular hardware backend. You can
add_calibration
add_calibration(gate, qubits, schedule, params=None)
Register a low-level, custom pulse definition for the given gate.
Parameters
- gate (Union[Gate, str]) – Gate information.
- qubits (Union[int, Tuple[int]]) – List of qubits to be measured.
- schedule (Schedule) – Schedule information.
- params (Optional[List[Union[float, Parameter]]]) – A list of parameters.
Raises
Exception – if the gate is of type string and params is None.
has_calibration_for
has_calibration_for(instruction)
Return True if the circuit has a calibration defined for the instruction context. In this case, the operation does not need to be translated to the device basis.
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 qiskit import QuantumCircuit
qc = QuantumCircuit(12)
for idx in range(5):
qc.h(idx)
qc.cx(idx, idx+5)
qc.cx(1, 7)
qc.x(8)
qc.cx(1, 9)
qc.x(7)
qc.cx(1, 11)
qc.swap(6, 11)
qc.swap(6, 9)
qc.swap(6, 10)
qc.x(6)
qc.draw('mpl')
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
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
A particularly important circuit property is known as the circuit depth()
. 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. Thus, the depth of a circuit is one important quantity used to measure if a quantum circuit can be run on a device.
The depth of a quantum circuit has a mathematical definition as the longest path in a directed acyclic graph (DAG). However, such a definition is a bit hard to grasp, even for experts. Fortunately, the depth of a circuit can be easily understood by anyone familiar with playing Tetris. Lets see how to compute this graphically:
We can verify our graphical result using QuantumCircuit.depth()
:
assert qc.depth() == 9
count_ops
count_ops()
Count each operation kind in the circuit.
Returns
a breakdown of how many operations of each kind, sorted by amount.
Return type
OrderedDict
depth
depth(filter_function=<function QuantumCircuit.<lambda>>)
Return circuit depth (i.e., length of critical path).
This operation is not well defined if the circuit contains control-flow operations.
Parameters
filter_function (Callable[[CircuitInstruction], bool]) – 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
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
get_instructions(name)
Get instructions matching name.
Parameters
name (str) – The name of instruction to.
Returns
list of (instruction, qargs, cargs).
Return type
num_connected_components
num_connected_components(unitary_only=False)
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
num_nonlocal_gates
num_nonlocal_gates()
Return number of non-local gates (i.e. involving 2+ qubits).
Conditional nonlocal gates are also included.
Return type
num_tensor_factors
num_tensor_factors()
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.
Return type
num_unitary_factors
num_unitary_factors()
Computes the number of tensor factors in the unitary (quantum) part of the circuit only.
Return type
size
size(filter_function=<function QuantumCircuit.<lambda>>)
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
width
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 duration
, unit
and op_start_times
attributes.
qubit_duration
qubit_duration(*qubits)
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 (Qubit |int) – Qubits within self
to include.
Returns
Return the duration between the first start and last stop time of non-delay instructions
Return type
qubit_start_time
qubit_start_time(*qubits)
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 (Qubit |int) – 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.
Return type
qubit_stop_time
qubit_stop_time(*qubits)
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 (Qubit |int) – 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.
Return type
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
control(num_ctrl_qubits=1, label=None, ctrl_state=None, annotated=False)
Control this circuit on num_ctrl_qubits
qubits.
Parameters
- num_ctrl_qubits (int) – The number of control qubits.
- label (str) – An optional label to give the controlled operation for visualization.
- ctrl_state (str orint) – The control state in decimal or as a bitstring (e.g. ‘111’). If None, use
2**num_ctrl_qubits - 1
. - annotated (bool) – indicates whether the controlled gate should be implemented as an annotated gate.
Returns
The controlled version of this circuit.
Return type
Raises
CircuitError – If the circuit contains a non-unitary operation and cannot be controlled.
inverse
inverse(annotated=False)
Invert (take adjoint of) this circuit.
This is done by recursively inverting all gates.
Parameters
annotated (bool) – indicates whether the inverse gate can be implemented as an annotated gate.
Returns
the inverted circuit
Return type
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(power, matrix_power=False, annotated=False)
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
repeat
repeat(reps, *, insert_barriers=False)
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
reverse_ops
reverse_ops()
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
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.
The primary documentation for all of Qiskit’s visualization tooling.
draw
draw(output=None, scale=None, filename=None, style=None, interactive=False, plot_barriers=True, reverse_bits=None, justify=None, vertical_compression='medium', idle_wires=None, with_layout=True, fold=None, ax=None, initial_state=False, cregbundle=None, wire_order=None, expr_len=30)
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.
latex_source: raw uncompiled latex output.
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 (str | None) – Select the output method to use for drawing the circuit. Valid choices are
text
,mpl
,latex
,latex_source
. By default, thetext
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 (float | None) – Scale of image to draw (shrink if
< 1.0
). Only used by thempl
,latex
andlatex_source
outputs. Defaults to1.0
. -
filename (str | None) – File path to save image to. Defaults to
None
(result not saved in a file). -
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
ormy_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 inqiskit/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"texbook"
style and sets the subfontsize (e.g. the gate angles) to5
. - If
None
the default style"iqp"
is used or, if given, the default style specified in~/.qiskit/settings.conf
.
- The supported style names are
-
interactive (bool) – When set to
True
, show the circuit in a new window (formpl
this depends on the matplotlib backend being used supporting this). Note when used with either the text or thelatex_source
output type this has no effect and will be silently ignored. Defaults toFalse
. -
reverse_bits (bool | None) – When set to
True
, reverse the bit order inside registers for the output visualization. Defaults toFalse
unless the user config file (usually~/.qiskit/settings.conf
) has an alternative value set. For example,circuit_reverse_bits = True
. -
plot_barriers (bool) – Enable/disable drawing barriers in the output circuit. Defaults to
True
. -
justify (str | None) – 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 toleft
. -
vertical_compression (str | None) –
high
,medium
orlow
. It merges the lines generated by the text output so the drawing will take less vertical room. Default ismedium
. Only used by thetext
output, will be silently ignored otherwise. -
idle_wires (bool | None) – Include idle wires (wires with no circuit elements) in output visualization. Default is
True
unless the user config file (usually~/.qiskit/settings.conf
) has an alternative value set. For example,circuit_idle_wires = False
. -
with_layout (bool) – Include layout information, with labels on the physical layout. Default is
True
. -
fold (int | None) – 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 usingshutil.get_terminal_size()
. However, if running in jupyter, the default line length is set to 80 characters. Inmpl
, it is the number of (visual) layers before folding. Default is 25. -
ax (Any | None) – 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 (bool) – Adds in the beginning of the qubit wires and to classical wires. Default is
False
. -
cregbundle (bool | None) – If set to
True
, bundle classical registers. Default isTrue
, except for whenoutput
is set to"text"
. -
wire_order (list[int] | None) – 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 (int) – The number of characters to display if an
Expr
is used for the condition in aControlFlowOp
. 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
(ifoutput='text'
)A drawing that can be printed as ascii art.
-
matplotlib.figure.Figure
(ifoutput='mpl'
)A matplotlib figure object for the circuit diagram.
-
PIL.Image
(ifoutput='latex
’)An in-memory representation of the image of the circuit diagram.
-
str
(ifoutput='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
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
qc = QuantumCircuit(1, 1)
qc.h(0)
qc.measure(0, 0)
qc.draw(output='mpl', style={'backgroundcolor': '#EEEEEE'})
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
decompose(gates_to_decompose=None, reps=1)
Call a decomposition pass on this circuit, to decompose one level (shallow decompose).
Parameters
- gates_to_decompose (type orstr orlist(type, str)) – 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 circuit. - reps (int) – Optional number of times the circuit should be decomposed. For instance,
reps=2
equals callingcircuit.decompose().decompose()
. can decompose specific gates specific time
Returns
a circuit one level decomposed
Return type
reverse_bits
reverse_bits()
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
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 ├──■─────────────────
└───┘
Internal utilities
These functions are not intended for public use, but were accidentally left documented in the public API during the 1.0 release. They will be removed in Qiskit 2.0, but will be supported until then.
cast
static cast(value, type_)
Best effort to cast value to type. Otherwise, returns the value.
The method qiskit.circuit.quantumcircuit.QuantumCircuit.cast()
is deprecated as of qiskit 1.2. It will be removed in the 2.0 release. This method is only used as an internal helper and will be removed with no replacement.
Return type
S | T
cbit_argument_conversion
cbit_argument_conversion(clbit_representation)
Converts several classical bit representations (such as indexes, range, etc.) into a list of classical bits.
The method qiskit.circuit.quantumcircuit.QuantumCircuit.cbit_argument_conversion()
is deprecated as of qiskit 1.2. It will be removed in the 2.0 release. This method is only used as an internal helper and will be removed with no replacement.
Parameters
clbit_representation (Clbit |ClassicalRegister |int |slice |Sequence[Clbit |int]) – Representation to expand.
Returns
A list of tuples where each tuple is a classical bit.
Return type
cls_instances
classmethod cls_instances()
Return the current number of instances of this class, useful for auto naming.
The method qiskit.circuit.quantumcircuit.QuantumCircuit.cls_instances()
is deprecated as of qiskit 1.2. It will be removed in the 2.0 release. This method is only used as an internal helper and will be removed with no replacement.
Return type
cls_prefix
classmethod cls_prefix()
Return the prefix to use for auto naming.
The method qiskit.circuit.quantumcircuit.QuantumCircuit.cls_prefix()
is deprecated as of qiskit 1.2. It will be removed in the 2.0 release. This method is only used as an internal helper and will be removed with no replacement.
Return type
qbit_argument_conversion
qbit_argument_conversion(qubit_representation)
Converts several qubit representations (such as indexes, range, etc.) into a list of qubits.
The method qiskit.circuit.quantumcircuit.QuantumCircuit.qbit_argument_conversion()
is deprecated as of qiskit 1.2. It will be removed in the 2.0 release. This method is only used as an internal helper and will be removed with no replacement.
Parameters
qubit_representation (Qubit |QuantumRegister |int |slice |Sequence[Qubit |int]) – Representation to expand.
Returns
The resolved instances of the qubits.
Return type