Quantum Gates
Snowflurry.AbstractGateSymbol — TypeAbstractGateSymbolA GateSymbol is an instantiation of an AbstractGateSymbol. It can be passed as an argument to a Gate constuctor, where a Gate is also associated with target qubits. A Gate will be placed on those target_qubits if it is added to a QuantumCircuit. AbstractGateSymbol is useful for dispatching all the GateSymbols to default implementations of functions such as get_connected_qubits(). Those functions can be specialized for GateSymbols requiring a different implementation.
AbstractGateSymbol is an abstract type, which means that it cannot be instantiated. Each concrete type of GateSymbols is a struct which is a subtype of AbstractGateSymbol. Each descendant of AbstractGateSymbol must implement at least the following methods:
get_operator(gate::AbstractGateSymbol, T::Type{<:Complex}=ComplexF64})::AbstractOperatorget_num_connected_qubits(gate::AbstractGateSymbol)::Integer
Examples
A struct must be defined for each new GateSymbol type. The following X_45 GateSymbol applies a $45°$ rotation about the $X$ axis:
julia> struct X45 <: AbstractGateSymbol
end;We need to define how many connected qubits are needed for our new GateSymbol:
julia> Snowflurry.get_num_connected_qubits(::X45) = 1
A Gate constructor must be defined as
julia> x_45(target::Integer) = Gate(X45(), [target]);along with an Operator constructor, with default precision ComplexF64, which is defined as
julia> x_45(T::Type{<:Complex} = ComplexF64) = rotation_x(π/4, T);
To simulate the effects of the gate in a QuantumCircuit or when applied to a Ket, the function get_operator must be extended:
julia> function Snowflurry.get_operator(gate::X45, T::Type{<:Complex} = ComplexF64)
return rotation_x(π/4, T)
end
The gate inverse can also be specified by extending the inv function:
julia> Base.inv(::X45) = Snowflurry.RotationX(-π/4);
An instance of the X_45 Gate can now be created, along with its inverse:
julia> x_45_gate = x_45(1)
Gate Object: X45
Connected_qubits : [1]
Operator:
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
0.9238795325112867 + 0.0im 0.0 - 0.3826834323650898im
0.0 - 0.3826834323650898im 0.9238795325112867 + 0.0im
julia> inv(x_45_gate)
Gate Object: Snowflurry.RotationX
Parameters:
theta : -0.7853981633974483
Connected_qubits : [1]
Operator:
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
0.9238795325112867 + 0.0im -0.0 + 0.3826834323650898im
-0.0 + 0.3826834323650898im 0.9238795325112867 + 0.0im
To enable the printing of a QuantumCircuit containing our new GateSymbol type, a display symbol must be defined as follows:
julia> Snowflurry.gates_display_symbols[X45] = ["X45"];
If this Gate will be sent as an instruction to a hardware QPU, an instruction String must be defined:
julia> Snowflurry.instruction_symbols[X45] = "x45";
A circuit containing this Gate can now be constructed:
julia> circuit = QuantumCircuit(qubit_count = 2, instructions = [x_45_gate])
Quantum Circuit Object:
qubit_count: 2
bit_count: 2
q[1]:──X45──
q[2]:───────
In addition, a Controlled{X45} gate can be constructed using:
julia> control = 1; target = 2;
julia> controlled(x_45(target), [control])
Gate Object: Controlled{X45}
Connected_qubits : [1, 2]
Operator:
(4, 4)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.9238795325112867 + 0.0im 0.0 - 0.3826834323650898im
0.0 + 0.0im 0.0 + 0.0im 0.0 - 0.3826834323650898im 0.9238795325112867 + 0.0im
Snowflurry.Controlled — TypeControlled{G<:AbstractGateSymbol}<:AbstractGateSymbolThe Controlled object allows the construction of a controlled AbstractGateSymbol using an Operator (the kernel) and the corresponding number of control qubits. A helper function, controlled can be used to easily create both controlled AbstractGateSymbols and controlled Gates. A call to apply_gate will be dispatched to the optimized routine if it exists. Otherwise, it will fall back to casting the operator into the equivalent DenseOperator and applying the created operator.
Examples
We can use the controlled function to create a controlled-Hadamard gate:
julia> controlled_hadamard = controlled(hadamard(2), [1])
Gate Object: Controlled{Snowflurry.Hadamard}
Connected_qubits : [1, 2]
Operator:
(4, 4)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.7071067811865475 + 0.0im 0.7071067811865475 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.7071067811865475 + 0.0im -0.7071067811865475 + 0.0im
It can then be used in a QuantumCircuit as any other Gate, and its display symbol is inherited from the display symbol of the single-target Hadamard Gate:
julia> circuit=QuantumCircuit(qubit_count=2,instructions = [controlled_hadamard])
Quantum Circuit Object:
qubit_count: 2
bit_count: 2
q[1]:──*──
|
q[2]:──H──
In general, a Controlled struct with an arbitraty number of targets and controls can be constructed. For instance, the following example constructs the equivalent of a Toffoli Gate, but as a ConnectedGate{SigmaX} with control_qubits=[1,2] and target_qubit=[3]:
julia> toffoli_as_controlled_gate = controlled(sigma_x(3), [1, 2])
Gate Object: Controlled{Snowflurry.SigmaX}
Connected_qubits : [1, 2, 3]
Operator:
(8, 8)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 1.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 1.0 + 0.0im 0.0 + 0.0imSnowflurry.Gate — TypeGate <: AbstractInstructionGate is an implementation of an AbstractInstruction that specifies an AbstractGateSymbol and its placement inside a QuantumCircuit. The placement corresponds to the target qubit (or qubits) on which the Gate operates.
Examples
julia> gate = iswap(1, 2)
Gate Object: Snowflurry.ISwap
Connected_qubits : [1, 2]
Operator:
(4, 4)-element Snowflurry.SwapLikeOperator:
Underlying data ComplexF64:
Equivalent DenseOperator:
1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.0 + 1.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 1.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 1.0 + 0.0imjulia> gate = universal(3, pi/2, -pi/2, pi/2)
Gate Object: Snowflurry.Universal
Parameters:
theta : 1.5707963267948966
phi : -1.5707963267948966
lambda : 1.5707963267948966
Connected_qubits : [3]
Operator:
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
0.7071067811865476 + 0.0im -4.329780281177466e-17 - 0.7071067811865475im
4.329780281177466e-17 - 0.7071067811865475im 0.7071067811865476 + 0.0imSnowflurry.eye — Functioneye(),
eye(size::Integer)Return the identity matrix as a DenseOperator, which is defined as:
\[I = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}.\]
Calling eye(size) will produce an identity matrix DenseOperator with dimensions (size,size).
Examples
julia> eye()
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
1.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 1.0 + 0.0im
julia> eye(4)
(4, 4)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 1.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 1.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 1.0 + 0.0im
Snowflurry.identity_gate — Functionidentity_gate(target)Return the Identity Gate, which applies the identity_gate() IdentityOperator to the target qubit.
Snowflurry.sigma_p — Functionsigma_p()Return the spin-$\frac{1}{2}$ raising Operator, which is defined as:
\[\sigma_+ = \begin{bmatrix} 0 & 1 \\ 0 & 0 \end{bmatrix}.\]
Snowflurry.sigma_m — Functionsigma_m()Return the spin-$\frac{1}{2}$ lowering Operator, which is defined as:
\[\sigma_- = \begin{bmatrix} 0 & 0 \\ 1 & 0 \end{bmatrix}.\]
Snowflurry.sigma_x — Functionsigma_x()Return the Pauli-X AntiDiagonalOperator, which is defined as:
\[\sigma_x = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}.\]
sigma_x(target)Return the Pauli-X Gate, which applies the sigma_x() AntiDiagonalOperator to the target qubit.
Snowflurry.sigma_y — Functionsigma_y()Return the Pauli-Y Operator, which is defined as:
\[\sigma_y = \begin{bmatrix} 0 & -i \\ i & 0 \end{bmatrix}.\]
sigma_y(target)Return the Pauli-Y Gate, which applies the sigma_y() Operator to the target qubit.
Snowflurry.sigma_z — Functionsigma_z()Return the Pauli-Z Operator, which is defined as:
\[\sigma_z = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}.\]
sigma_z(target)Return the Pauli-Z Gate, which applies the sigma_z() Operator to the target qubit.
Snowflurry.hadamard — Functionhadamard()Return the Hadamard Operator, which is defined as:
\[H = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix}.\]
hadamard(target)Return the Hadamard Gate, which applies the hadamard() Operator to the target qubit.
Snowflurry.pi_8 — Functionpi_8()Return the Operator for the $π/8$ gate, which is defined as:
\[T = \begin{bmatrix} 1 & 0 \\ 0 & e^{i\frac{\pi}{4}} \end{bmatrix}.\]
pi_8(target)Return a $π/8$ Gate (also known as a $T$ Gate), which applies the pi_8() DiagonalOperator to the target qubit.
Snowflurry.pi_8_dagger — Functionpi_8_dagger()Return the adjoint DiagonalOperator of the $π/8$ gate, which is defined as:
\[T^\dagger = \begin{bmatrix} 1 & 0 \\ 0 & e^{-i\frac{\pi}{4}} \end{bmatrix}.\]
pi_8_dagger(target)Return an adjoint $π/8$ Gate (also known as a $T^\dagger$ Gate), which applies the pi_8_dagger() Operator to the target qubit.
Snowflurry.x_90 — Functionx_90()Return the Operator which applies a $π/2$ rotation about the $X$ axis.
The Operator is defined as:
\[R_x\left(\frac{\pi}{2}\right) = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & -i \\ -i & 1 \end{bmatrix}.\]
x_90(target)Return a Gate that applies a $90°$ rotation about the $X$ axis as defined by the x_90() Operator.
Snowflurry.x_minus_90 — Functionx_minus_90()Return the Operator which applies a $-π/2$ rotation about the $X$ axis.
The Operator is defined as:
\[R_x\left(-\frac{\pi}{2}\right) = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & i \\ i & 1 \end{bmatrix}.\]
x_minus_90(target)Return a Gate that applies a $-90°$ rotation about the $X$ axis as defined by the x_minus_90() Operator.
Snowflurry.y_90 — Functiony_90()Return the Operator which applies a $π/2$ rotation about the $Y$ axis.
The Operator is defined as:
\[R_y\left(\frac{\pi}{2}\right) = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & -1 \\ 1 & 1 \end{bmatrix}.\]
y_90(target)Return a Gate that applies a $90°$ rotation about the $Y$ axis as defined by the y_90() Operator.
Snowflurry.y_minus_90 — Functiony_minus_90()Return the Operator which applies a $-π/2$ rotation about the $Y$ axis.
The Operator is defined as:
\[R_y\left(-\frac{\pi}{2}\right) = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \\ -1 & 1 \end{bmatrix}.\]
y_minus_90(target)Return a Gate that applies a $-90°$ rotation about the $Y$ axis as defined by the y_minus_90() Operator.
Snowflurry.z_90 — Functionz_90()Return the Operator which applies a $π/2$ rotation about the $Z$ axis.
The Operator is defined as:
\[R_z\left(\frac{\pi}{2}\right) = \begin{bmatrix} e^{-i\pi/4} & 0 \\[0.5em] 0 & e^{i\pi/4} \end{bmatrix}.\]
z_90(target)Return a Gate that applies a $90°$ rotation about the $Z$ axis as defined by the z_90() Operator.
Snowflurry.z_minus_90 — Functionz_minus_90()Return the Operator which applies a $-π/2$ rotation about the $Z$ axis. The Operator is defined as:
\[R_z\left(-\frac{\pi}{2}\right) = \begin{bmatrix} e^{i\pi/4} & 0 \\[0.5em] 0 & e^{-i\pi/4} \end{bmatrix}.\]
z_minus_90(target)Return a Gate that applies a $-90°$ rotation about the $Z$ axis as defined by the z_minus_90() Operator.
Snowflurry.rotation — Functionrotation(theta, phi)Return the Operator that applies a rotation theta about the axis $\vec{n}=\cos(\phi)~X+\sin(\phi)~Y$.
The Operator is defined as:
\[R(\theta, \phi) = \begin{bmatrix} \mathrm{cos}\left(\frac{\theta}{2}\right) & -i e^{-i\phi} \mathrm{sin}\left(\frac{\theta}{2}\right) \\[0.5em] -i e^{i\phi} \mathrm{sin}\left(\frac{\theta}{2}\right) & \mathrm{cos}\left(\frac{\theta}{2}\right) \end{bmatrix}.\]
rotation(target, theta, phi)Return a gate that applies a rotation theta to the target qubit about the axis $\vec{n}=\cos(\phi)~X+\sin(\phi)~Y$.
The corresponding Operator is rotation(theta, phi).
Snowflurry.rotation_x — Functionrotation_x(theta)Return the Operator which applies a rotation theta about the $X$ axis.
The Operator is defined as:
\[R_x(\theta) = \begin{bmatrix} \mathrm{cos}\left(\frac{\theta}{2}\right) & -i\mathrm{sin}\left(\frac{\theta}{2}\right) \\[0.5em] -i\mathrm{sin}\left(\frac{\theta}{2}\right) & \mathrm{cos}\left(\frac{\theta}{2}\right) \end{bmatrix}.\]
rotation_x(target, theta)Return a Gate that applies a rotation theta about the $X$ axis of the target qubit.
The corresponding Operator is rotation_x(theta).
Snowflurry.rotation_y — Functionrotation_y(theta)Return the Operator that applies a rotation theta about the $Y$ axis.
The Operator is defined as:
\[R_y(\theta) = \begin{bmatrix} \mathrm{cos}\left(\frac{\theta}{2}\right) & -\mathrm{sin}\left(\frac{\theta}{2}\right) \\[0.5em] \mathrm{sin}\left(\frac{\theta}{2}\right) & \mathrm{cos}\left(\frac{\theta}{2}\right) \end{bmatrix}.\]
rotation_y(target, theta)Return a Gate that applies a rotation theta about the $Y$ axis of the target qubit.
The corresponding Operator is rotation_y(theta).
Snowflurry.rotation_z — Functionrotation_z(lambda)Return the DiagonalOperator that applies a rotation about the $Z$ axis.
The DiagonalOperator is defined as:
\[R_z(\lambda) = \begin{bmatrix} e^{-i\lambda/2} & 0 \\[0.5em] 0 & e^{i\lambda/2} \end{bmatrix}.\]
rotation_z(target, lambda)Return a Gate that applies a rotation lambda about the $Z$ axis of the target qubit.
The corresponding Operator is rotation_z(lambda).
Snowflurry.root_zz — Functionroot_zz()Return the DiagonalOperator that, when applied twice in sequence, applies rotations about the $Z$ axes of $-\frac{\pi}{2}$ to the first qubit and $\frac{\pi}{2}$ to the second one.
The DiagonalOperator is defined as:
\[R_{ZZ} = \begin{bmatrix} 1-i & 0 & 0 & 0 \\ 0 & 1+i & 0 & 0 \\ 0 & 0 & 1+i & 0 \\ 0 & 0 & 0 & 1-i \\ \end{bmatrix}.\]
root_zz(qubit_1, qubit_2)Return the root of a ZZ Gate. The application of two ZZ gates in sequence is equivalent to the application of one rotation_z(-π/2) Operator to qubit_1 and one rotation_z(π/2) Operator to qubit_2.
The corresponding Operator is root_zz().
Snowflurry.root_zz_dagger — Functionroot_zz_dagger()Return the DiagonalOperator which is the complex conjugate of root_zz().
The DiagonalOperator is defined as:
\[R_{ZZ}^\dagger = \begin{bmatrix} 1+i & 0 & 0 & 0 \\ 0 & 1-i & 0 & 0 \\ 0 & 0 & 1-i & 0 \\ 0 & 0 & 0 & 1+i \\ \end{bmatrix}.\]
root_zz_dagger(qubit_1, qubit_2)Return the complex conjugate of a root of ZZ Gate.
The corresponding Operator is root_zz_dagger().
Snowflurry.phase_shift — Functionphase_shift(phi)Return the DiagonalOperator that applies a phase shift phi.
The DiagonalOperator is defined as:
\[P(\phi) = \begin{bmatrix} 1 & 0 \\[0.5em] 0 & e^{i\phi} \end{bmatrix}.\]
phase_shift(target, phi)Return a Gate that applies a phase shift phi to the target qubit as defined by the phase_shift(phi) DiagonalOperator.
Snowflurry.universal — Functionuniversal(theta, phi, lambda)Return the Operator which performs a rotation about the angles theta, phi, and lambda. See Theorem 4.1 in Quantum Computation and Quantum Information by Nielsen and Chuang.
The Operator is defined as:
\[U(\theta, \phi, \lambda) = \begin{bmatrix} \mathrm{cos}\left(\frac{\theta}{2}\right) & -e^{i\lambda}\mathrm{sin}\left(\frac{\theta}{2}\right) \\[0.5em] e^{i\phi}\mathrm{sin}\left(\frac{\theta}{2}\right) & e^{i\left(\phi+\lambda\right)}\mathrm{cos}\left(\frac{\theta}{2}\right) \end{bmatrix}.\]
universal(target, theta, phi, lambda)Return a gate which rotates the target qubit given the angles theta, phi, and lambda. See Theorem 4.1 in Quantum Computation and Quantum Information by Nielsen and Chuang.
The corresponding Operator is universal(theta, phi, lambda).
Snowflurry.control_z — Functioncontrol_z()Return the controlled-Z Operator, which is defined as:
\[CZ = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & -1 \end{bmatrix}.\]
control_z(control_qubit, target_qubit)Return a controlled-Z gate given a control_qubit and a target_qubit.
The corresponding Operator is control_z().
Snowflurry.control_x — Functioncontrol_x()Return the controlled-X (or controlled-NOT) Operator, which is defined as:
\[CX = CNOT = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \end{bmatrix}.\]
control_x(control_qubit, target_qubit)Return a controlled-X gate (also known as a controlled-NOT gate) given a control_qubit and a target_qubit.
The corresponding Operator is control_x().
Snowflurry.iswap — Functioniswap()Return the imaginary swap Operator, which is defined as:
\[iSWAP = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & i & 0 \\ 0 & i & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}.\]
iswap(qubit_1, qubit_2)Return the imaginary swap Gate which applies the imaginary swap Operator to qubit_1 and qubit_2.
The corresponding Operator is iswap().
Snowflurry.swap — Functionswap()Return the swap Operator, which is defined as:
\[iSWAP = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}.\]
swap(qubit_1, qubit_2)Return the swap Gate which applies the swap Operator to qubit_1 and qubit_2.
The corresponding Operator is swap().
Snowflurry.toffoli — Functiontoffoli()Return the Toffoli Operator, which is defined as:
\[CCX = CCNOT = \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}.\]
toffoli(control_qubit_1, control_qubit_2, target_qubit)Return a Toffoli gate (also known as a CCNOT gate) given two control qubits and a target_qubit.
The corresponding Operator is toffoli().
Snowflurry.iswap_dagger — Functioniswap_dagger()Return the adjoint of the imaginary swap Operator, which is defined as:
\[iSWAP^\dagger = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & -i & 0 \\ 0 & -i & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}.\]
iswap_dagger(qubit_1, qubit_2)Return the adjoint imaginary swap Gate which applies the adjoint imaginary swap Operator to qubit_1 and qubit_2.
The corresponding Operator is iswap_dagger().
Base.:* — MethodBase.:*(M::Gate, x::Ket)Return a Ket which results from applying Gate M to Ket x.
Examples
julia> ψ_0 = fock(0, 2)
2-element Ket{ComplexF64}:
1.0 + 0.0im
0.0 + 0.0im
julia> ψ_1 = sigma_x(1) * ψ_0
2-element Ket{ComplexF64}:
0.0 + 0.0im
1.0 + 0.0im
Snowflurry.apply_instruction! — Functionapply_instruction!(state::Ket, gate::Gate)Update the state by applying a gate to it.
Examples
julia> ψ_0 = fock(0, 2)
2-element Ket{ComplexF64}:
1.0 + 0.0im
0.0 + 0.0im
julia> apply_instruction!(ψ_0, sigma_x(1))
2-element Ket{ComplexF64}:
0.0 + 0.0im
1.0 + 0.0im
Snowflurry.get_operator — Functionget_operator(gate::Gate)Returns the Operator which is associated with a Gate.
Examples
julia> x = sigma_x(1);
julia> get_operator(get_gate_symbol(x))
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
. 1.0 + 0.0im
1.0 + 0.0im .
Base.inv — Methodinv(gate::AbstractGateSymbol)Return a Gate which is the inverse of the input gate.
Examples
julia> u = universal(1, -pi/2, pi/3, pi/4)
Gate Object: Snowflurry.Universal
Parameters:
theta : -1.5707963267948966
phi : 1.0471975511965976
lambda : 0.7853981633974483
Connected_qubits : [1]
Operator:
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
0.7071067811865476 + 0.0im 0.5 + 0.4999999999999999im
-0.3535533905932738 - 0.6123724356957945im -0.18301270189221924 + 0.6830127018922194im
julia> inv(u)
Gate Object: Snowflurry.Universal
Parameters:
theta : 1.5707963267948966
phi : -0.7853981633974483
lambda : -1.0471975511965976
Connected_qubits : [1]
Operator:
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
0.7071067811865476 + 0.0im -0.3535533905932738 + 0.6123724356957945im
0.5 - 0.4999999999999999im -0.18301270189221924 - 0.6830127018922194im
Snowflurry.move_instruction — Functionmove_instruction(gate::Gate,
qubit_mapping::AbstractDict{<:Integer,<:Integer})::AbstractGateSymbolReturns a copy of gate where the qubits on which the gate acts have been updated based on qubit_mapping.
The dictionary qubit_mapping contains key-value pairs describing how to update the target qubits. The key indicates which target qubit to change while the associated value specifies the new qubit.
Examples
julia> gate = sigma_x(1)
Gate Object: Snowflurry.SigmaX
Connected_qubits : [1]
Operator:
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
. 1.0 + 0.0im
1.0 + 0.0im .
julia> move_instruction(gate, Dict(1=>2))
Gate Object: Snowflurry.SigmaX
Connected_qubits : [2]
Operator:
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
. 1.0 + 0.0im
1.0 + 0.0im .
move_instruction(
original_readout::Readout,
qubit_mapping::AbstractDict{T,T},
)::AbstractInstruction where {T<:Integer}Returns a copy of original_readout where the qubits which the original_readout measures have been updated based on qubit_mapping.
The dictionary qubit_mapping contains key-value pairs describing how to update the target qubits. The key indicates which target qubit to change while the associated value specifies the new qubit.
Examples
julia> r = readout(1, 1)
Explicit Readout object:
connected_qubit: 1
destination_bit: 1
julia> move_instruction(r, Dict(1 => 2))
Explicit Readout object:
connected_qubit: 2
destination_bit: 1
Snowflurry.get_gate_symbol — Functionget_gate_symbol(gate::Gate)::AbstractGateSymbolReturns the symbol that is associated with a gate.
Examples
julia> gate = sigma_x(1);
julia> get_gate_symbol(gate)
Snowflurry.SigmaX()
Snowflurry.get_connected_qubits — Functionget_connected_qubits(instruction::AbstractInstruction)::AbstractVector{Int}Returns the indices of the qubits on which the instruction is applied.
Examples
julia> get_connected_qubits(control_z(1, 3))
2-element Vector{Int64}:
1
3
Snowflurry.get_num_connected_qubits — Functionget_num_connected_qubits(gate::AbstractGateSymbol)::IntReturns the number of qubits to which the gate is applied.
Examples
julia> get_num_connected_qubits(get_gate_symbol(control_z(1, 3)))
2
Snowflurry.get_control_qubits — Functionget_control_qubits(gate::Gate{<:AbstractControlledGateSymbol})Returns a list of the control qubits for a gate.
Examples
julia> get_control_qubits(toffoli(1, 4, 6))
2-element Vector{Int64}:
1
4
Snowflurry.get_target_qubits — Functionget_target_qubits(gate::Gate{<:AbstractControlledGateSymbol})Returns a list of the target qubits for a gate.
Examples
julia> get_target_qubits(toffoli(1, 4, 6))
1-element Vector{Int64}:
6
Snowflurry.get_destination_bit — Functionget_destination_bit(readout::Readout)::IntReturns the index of the classical bit to which the outcome of the readout is sent.
Examples
julia> get_destination_bit(readout(2, 3))
3
Snowflurry.get_gate_parameters — Functionget_gate_parameters(gate::AbstractGateSymbol)::Dict{String,Real}Returns a Dict containing the name and the value of each parameter in a gate.
Examples
julia> get_gate_parameters(get_gate_symbol(universal(1, π/2, π/4, -π/3)))
Dict{String, Float64} with 3 entries:
"theta" => 1.5708
"phi" => 0.785398
"lambda" => -1.0472