quairkit.circuit¶
The source file of the Circuit class.
-
class quairkit.circuit.Circuit(num_systems=
None
, system_dim=2
)¶ Quantum circuit.
- Parameters:¶
Note
when the number of system is unknown and system_dim is an int, the circuit is a dynamic quantum circuit.
- property num_qubits : int¶
Number of qubits.
- property num_qutrits : int¶
Number of qutrits.
- property isdynamic : bool¶
Whether the circuit is dynamic
- property num_systems : int¶
Number of systems.
- property system_dim : list[int] | int¶
Dimension of systems.
- unitary_matrix()¶
Get the unitary matrix form of the circuit.
- property gate_history : list[dict[str, str | list[int] | Tensor]]¶
List of gates information of circuit
- Returns:¶
history of quantum gates of circuit
- property depth : int¶
Depth of gate sequences.
- Returns:¶
depth of this circuit
Note
The measurement is omitted, and all gates are assumed to have depth 1. See Niel’s answer in the [StackExchange](https://quantumcomputing.stackexchange.com/a/5772).
- property system_history : list[list[tuple[dict[str, str | list[int] | Tensor], int]]]¶
gate information on each system
- Returns:¶
list of gate history on each system
Note
The entry
system_history[i][j][0/1]
returns the gate information / gate index of the j-th gate applied on the i-th system.
-
plot(save_path=
None
, dpi=100
, show=True
, output=False
, scale=1.0
, tex=False
)¶ display the circuit using matplotlib
- Parameters:¶
- save_path : str | None¶
the save path of image
- dpi : int | None¶
dots per inches, here is resolution ratio
- show : bool | None¶
whether execute
plt.show()
- output : bool | None¶
whether return the
matplotlib.figure.Figure
instance- scale : float | None¶
scale coefficient of figure, default to 1.0
- tex : bool | None¶
a bool flag which controls latex fonts of gate display, default to
False
.
- Returns:¶
a
matplotlib.figure.Figure
instance orNone
depends onoutput
- Return type:¶
None | Figure
Note
Using
plt.show()
may cause a distortion, but it will not happen in the figure saved. If the depth is too long, there will be some patches unable to display. Settingtex = True
requires that you have TeX and the other dependencies properly installed on your system. See https://matplotlib.org/stable/gallery/text_labels_and_annotations/tex_demo.html for more details.
-
h(qubits_idx=
'full'
)¶ Add single-qubit Hadamard gates.
The matrix form of such a gate is:
\[\begin{split}H = \frac{1}{\sqrt{2}} \begin{bmatrix} 1&1\\ 1&-1 \end{bmatrix}\end{split}\]
-
s(qubits_idx=
'full'
)¶ Add single-qubit S gates.
The matrix form of such a gate is:
\[\begin{split}S = \begin{bmatrix} 1&0\\ 0&i \end{bmatrix}\end{split}\]
-
sdg(qubits_idx=
'full'
)¶ Add single-qubit S dagger (S inverse) gates.
The matrix form of such a gate is:
\[\begin{split}S^\dagger = \begin{bmatrix} 1&0\\ 0&-i \end{bmatrix}\end{split}\]
-
t(qubits_idx=
'full'
)¶ Add single-qubit T gates.
The matrix form of such a gate is:
\[\begin{split}T = \begin{bmatrix} 1&0\\ 0&e^\frac{i\pi}{4} \end{bmatrix}\end{split}\]
-
tdg(qubits_idx=
'full'
)¶ Add single-qubit T dagger (T inverse) gates.
The matrix form of such a gate is:
\[\begin{split}T^\dagger = \begin{bmatrix} 1&0\\ 0&e^{-\frac{i\pi}{4}} \end{bmatrix}\end{split}\]
-
x(qubits_idx=
'full'
)¶ Add single-qubit X gates.
The matrix form of such a gate is:
\[\begin{split}X = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}\end{split}\]
-
y(qubits_idx=
'full'
)¶ Add single-qubit Y gates.
The matrix form of such a gate is:
\[\begin{split}Y = \begin{bmatrix} 0 & -i \\ i & 0 \end{bmatrix}\end{split}\]
-
z(qubits_idx=
'full'
)¶ Add single-qubit Z gates.
The matrix form of such a gate is:
\[\begin{split}Z = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}\end{split}\]
-
p(qubits_idx=
'full'
, param=None
, param_sharing=False
)¶ Add single-qubit P gates.
The matrix form of such a gate is:
\[\begin{split}P(\theta) = \begin{bmatrix} 1 & 0 \\ 0 & e^{i\theta} \end{bmatrix}\end{split}\]
-
rx(qubits_idx=
'full'
, param=None
, param_sharing=False
)¶ Add single-qubit rotation gates about the x-axis.
The matrix form of such a gate is:
\[\begin{split}R_X(\theta) = \begin{bmatrix} \cos\frac{\theta}{2} & -i\sin\frac{\theta}{2} \\ -i\sin\frac{\theta}{2} & \cos\frac{\theta}{2} \end{bmatrix}\end{split}\]
-
ry(qubits_idx=
'full'
, param=None
, param_sharing=False
)¶ Add single-qubit rotation gates about the y-axis.
The matrix form of such a gate is:
\[\begin{split}R_Y(\theta) = \begin{bmatrix} \cos\frac{\theta}{2} & -\sin\frac{\theta}{2} \\ \sin\frac{\theta}{2} & \cos\frac{\theta}{2} \end{bmatrix}\end{split}\]
-
rz(qubits_idx=
'full'
, param=None
, param_sharing=False
)¶ Add single-qubit rotation gates about the z-axis.
The matrix form of such a gate is:
\[\begin{split}R_Z(\theta) = \begin{bmatrix} e^{-i\frac{\theta}{2}} & 0 \\ 0 & e^{i\frac{\theta}{2}} \end{bmatrix}\end{split}\]
-
u3(qubits_idx=
'full'
, param=None
, param_sharing=False
)¶ Add single-qubit rotation gates.
The matrix form of such a gate is:
\[\begin{split}\begin{align} U_3(\theta, \phi, \lambda) = \begin{bmatrix} \cos\frac\theta2&-e^{i\lambda}\sin\frac\theta2\\ e^{i\phi}\sin\frac\theta2&e^{i(\phi+\lambda)}\cos\frac\theta2 \end{bmatrix} \end{align}\end{split}\]
-
cnot(qubits_idx=
'cycle'
)¶ Add CNOT gates.
For a 2-qubit quantum circuit, when qubits_idx is [0, 1], the matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{CNOT} &=|0\rangle \langle 0|\otimes I + |1 \rangle \langle 1|\otimes X\\ &= \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \end{bmatrix} \end{align}\end{split}\]
-
cy(qubits_idx=
'cycle'
)¶ Add controlled Y gates.
For a 2-qubit quantum circuit, when qubits_idx is [0, 1], the matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{CY} &=|0\rangle \langle 0|\otimes I + |1 \rangle \langle 1|\otimes Y\\ &= \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & -1j \\ 0 & 0 & 1j & 0 \end{bmatrix} \end{align}\end{split}\]
-
cz(qubits_idx=
'linear'
)¶ Add controlled Z gates.
For a 2-qubit quantum circuit, when qubits_idx is [0, 1], the matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{CZ} &=|0\rangle \langle 0|\otimes I + |1 \rangle \langle 1|\otimes Z\\ &= \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & -1 \end{bmatrix} \end{align}\end{split}\]
-
swap(qubits_idx=
'linear'
)¶ Add SWAP gates.
The matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{SWAP} = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \end{align}\end{split}\]
-
cp(qubits_idx=
'cycle'
, param=None
, param_sharing=False
)¶ Add controlled P gates.
For a 2-qubit quantum circuit, when qubits_idx is [0, 1], the matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{CP}(\theta) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & e^{i\theta} \end{bmatrix} \end{align}\end{split}\]
-
crx(qubits_idx=
'cycle'
, param=None
, param_sharing=False
)¶ Add controlled rotation gates about the x-axis.
For a 2-qubit quantum circuit, when qubits_idx is [0, 1], the matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{CR_X} &=|0\rangle \langle 0|\otimes I + |1 \rangle \langle 1|\otimes R_X\\ &= \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & \cos\frac{\theta}{2} & -i\sin\frac{\theta}{2} \\ 0 & 0 & -i\sin\frac{\theta}{2} & \cos\frac{\theta}{2} \end{bmatrix} \end{align}\end{split}\]
-
cry(qubits_idx=
'cycle'
, param=None
, param_sharing=False
)¶ Add controlled rotation gates about the y-axis.
For a 2-qubit quantum circuit, when qubits_idx is [0, 1], the matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{CR_Y} &=|0\rangle \langle 0|\otimes I + |1 \rangle \langle 1|\otimes R_Y\\ &= \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & \cos\frac{\theta}{2} & -\sin\frac{\theta}{2} \\ 0 & 0 & \sin\frac{\theta}{2} & \cos\frac{\theta}{2} \end{bmatrix} \end{align}\end{split}\]
-
crz(qubits_idx=
'cycle'
, param=None
, param_sharing=False
)¶ Add controlled rotation gates about the z-axis.
For a 2-qubit quantum circuit, when qubits_idx is [0, 1], the matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{CR_Z} &= |0\rangle \langle 0|\otimes I + |1 \rangle \langle 1|\otimes R_Z\\ &= \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & e^{-i\frac{\theta}{2}} & 0 \\ 0 & 0 & 0 & e^{i\frac{\theta}{2}} \end{bmatrix} \end{align}\end{split}\]
-
cu(qubits_idx=
'cycle'
, param=None
, param_sharing=False
)¶ Add controlled single-qubit rotation gates.
For a 2-qubit quantum circuit, when qubits_idx is [0, 1], the matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{CU} &= \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & \cos\frac\theta2 &-e^{i\lambda}\sin\frac\theta2 \\ 0 & 0 & e^{i\phi}\sin\frac\theta2&e^{i(\phi+\lambda)}\cos\frac\theta2 \end{bmatrix} \end{align}\end{split}\]
-
rxx(qubits_idx=
'linear'
, param=None
, param_sharing=False
)¶ Add RXX gates.
The matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{R_{XX}}(\theta) = \begin{bmatrix} \cos\frac{\theta}{2} & 0 & 0 & -i\sin\frac{\theta}{2} \\ 0 & \cos\frac{\theta}{2} & -i\sin\frac{\theta}{2} & 0 \\ 0 & -i\sin\frac{\theta}{2} & \cos\frac{\theta}{2} & 0 \\ -i\sin\frac{\theta}{2} & 0 & 0 & \cos\frac{\theta}{2} \end{bmatrix} \end{align}\end{split}\]
-
ryy(qubits_idx=
'linear'
, param=None
, param_sharing=False
)¶ Add RYY gates.
The matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{R_{YY}}(\theta) = \begin{bmatrix} \cos\frac{\theta}{2} & 0 & 0 & i\sin\frac{\theta}{2} \\ 0 & \cos\frac{\theta}{2} & -i\sin\frac{\theta}{2} & 0 \\ 0 & -i\sin\frac{\theta}{2} & \cos\frac{\theta}{2} & 0 \\ i\sin\frac{\theta}{2} & 0 & 0 & cos\frac{\theta}{2} \end{bmatrix} \end{align}\end{split}\]
-
rzz(qubits_idx=
'linear'
, param=None
, param_sharing=False
)¶ Add RZZ gates.
The matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{R_{ZZ}}(\theta) = \begin{bmatrix} e^{-i\frac{\theta}{2}} & 0 & 0 & 0 \\ 0 & e^{i\frac{\theta}{2}} & 0 & 0 \\ 0 & 0 & e^{i\frac{\theta}{2}} & 0 \\ 0 & 0 & 0 & e^{-i\frac{\theta}{2}} \end{bmatrix} \end{align}\end{split}\]
-
ms(qubits_idx=
'cycle'
)¶ Add Mølmer-Sørensen (MS) gates.
The matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{MS} = \mathit{R_{XX}}(-\frac{\pi}{2}) = \frac{1}{\sqrt{2}} \begin{bmatrix} 1 & 0 & 0 & i \\ 0 & 1 & i & 0 \\ 0 & i & 1 & 0 \\ i & 0 & 0 & 1 \end{bmatrix} \end{align}\end{split}\]
-
cswap(qubits_idx=
'cycle'
)¶ Add CSWAP (Fredkin) gates.
The matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{CSWAP} = \begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \end{bmatrix} \end{align}\end{split}\]
-
ccx(qubits_idx=
'cycle'
)¶ Add CCX (Toffoli) gates.
The matrix form of such a gate is:
\[\begin{split}\begin{align} \mathit{CCX} = \begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \end{bmatrix} \end{align}\end{split}\]
-
universal_two_qubits(qubits_idx=
'linear'
, param=None
, param_sharing=False
)¶ Add universal two-qubit gates. One of such a gate requires 15 parameters.
-
universal_three_qubits(qubits_idx=
'linear'
, param=None
, param_sharing=False
)¶ Add universal three-qubit gates. One of such a gate requires 81 parameters.
-
universal_qudits(system_idx, param=
None
, param_sharing=False
)¶ Add universal qudit gates. One of such a gate requires \(d^2 - 1\) parameters, where \(d\) is the gate dimension.
-
oracle(oracle, system_idx, gate_name=
'O'
, latex_name=None
, plot_width=None
)¶ Add an oracle gate.
- Parameters:¶
- oracle : Tensor¶
Unitary oracle to be implemented.
- system_idx : List[int] | int¶
Indices of the systems on which the gates are applied.
- gate_name : str | None¶
name of this oracle.
- latex_name : str | None¶
latex name of this oracle, default to be the gate name.
- plot_width : float | None¶
width of this gate in circuit plot, default to be proportional with the gate name.
-
control_oracle(oracle, system_idx, gate_name=
'O'
, latex_name=None
, plot_width=None
)¶ Add a controlled oracle gate.
- Parameters:¶
- oracle : Tensor¶
Unitary oracle to be implemented.
- system_idx : List[int]¶
Indices of the systems on which the gates are applied.
- gate_name : str | None¶
name of this oracle.
- latex_name : str | None¶
latex name of this oracle, default to be the gate name.
- plot_width : float | None¶
width of this gate in circuit plot, default to be proportional with the gate name.
-
param_oracle(generator, num_acted_param, system_idx, param=
None
, gate_name='P'
, latex_name=None
, plot_width=None
)¶ Add a parameterized oracle gate.
- Parameters:¶
- generator : Callable[[Tensor], Tensor]¶
function that generates the oracle.
- num_acted_param : int¶
the number of parameters required for a single operation.
- system_idx : List[int] | int¶
indices of the system on which this gate acts on.
- param : Tensor | float¶
input parameters of quantum parameterized gates. Defaults to
None
i.e. randomized.- gate_name : str | None¶
name of this oracle.
- latex_name : str | None¶
latex name of this oracle, default to be the gate name.
- plot_width : float | None¶
width of this gate in circuit plot, default to be proportional with the gate name.
-
collapse(system_idx=
None
, desired_result=None
, if_print=False
, measure_basis=None
)¶ - Parameters:¶
- system_idx : Iterable[int] | int | str | None¶
list of systems to be collapsed. Defaults to all qubits.
- desired_result : int | str | None¶
The desired result you want to collapse. Defaults to
None
meaning randomly choose one.- if_print : bool¶
whether print the information about the collapsed state. Defaults to
False
.- measure_basis : Tensor | None¶
The basis of the measurement. The quantum state will collapse to the corresponding eigenstate.
- Raises:¶
NotImplementedError – If the basis of measurement is not z. Other bases will be implemented in future.
TypeError – cannot get probability of state when the backend is unitary_matrix.
Note
When desired_result is None, Collapse does not support gradient calculation
-
superposition_layer(qubits_idx=
None
)¶ Add layers of Hadamard gates.
-
weak_superposition_layer(qubits_idx=
None
)¶ Add layers of Ry gates with a rotation angle \(\pi/4\).
-
linear_entangled_layer(qubits_idx=
None
, depth=1
)¶ Add linear entangled layers consisting of Ry gates, Rz gates, and CNOT gates.
-
real_entangled_layer(qubits_idx=
None
, depth=1
)¶ Add strongly entangled layers consisting of Ry gates and CNOT gates.
-
complex_entangled_layer(qubits_idx=
None
, depth=1
)¶ Add strongly entangled layers consisting of single-qubit rotation gates and CNOT gates.
-
real_block_layer(qubits_idx=
None
, depth=1
)¶ Add weakly entangled layers consisting of Ry gates and CNOT gates.
-
complex_block_layer(qubits_idx=
None
, depth=1
)¶ Add weakly entangled layers consisting of single-qubit rotation gates and CNOT gates.
-
bit_flip(prob, qubits_idx=
'full'
)¶ Add bit flip channels.
-
phase_flip(prob, qubits_idx=
'full'
)¶ Add phase flip channels.
-
bit_phase_flip(prob, qubits_idx=
'full'
)¶ Add bit phase flip channels.
-
amplitude_damping(gamma, qubits_idx=
'full'
)¶ Add amplitude damping channels.
-
generalized_amplitude_damping(gamma, prob, qubits_idx=
'full'
)¶ Add generalized amplitude damping channels.
- Parameters:¶
-
phase_damping(gamma, qubits_idx=
'full'
)¶ Add phase damping channels.
-
depolarizing(prob, qubits_idx=
'full'
)¶ Add depolarizing channels.
- generalized_depolarizing(prob, qubits_idx)¶
Add a general depolarizing channel.
-
pauli_channel(prob, qubits_idx=
'full'
)¶ Add Pauli channels.
-
reset_channel(prob, qubits_idx=
'full'
)¶ Add reset channels.
-
thermal_relaxation(const_t, exec_time, qubits_idx=
'full'
)¶ Add thermal relaxation channels.
- Parameters:¶
- const_t : Tensor | Iterable[float]¶
\(T_1\) and \(T_2\) relaxation time in microseconds.
- exec_time : Tensor | float¶
Quantum gate execution time in the process of relaxation in nanoseconds.
- qubits_idx : Iterable[int] | int | str¶
Indices of the qubits on which the channels are applied. Defaults to ‘full’.
- choi_channel(choi_repr, system_idx)¶
Add custom channels in the Choi representation.
- kraus_channel(kraus_oper, system_idx)¶
Add custom channels in the Kraus representation.
- stinespring_channel(stinespring_repr, system_idx)¶
Add custom channels in the Stinespring representation.