Quantum Gates

Snowflurry.AbstractGateSymbolType
AbstractGateSymbol

A GateSymbol is an instantiation of an AbstractGateSymbol, which, when used inside a Gate (specifing placement) can be added to a QuantumCircuit to apply an operator to one or more target qubits. AbstractGateSymbol is useful to dispatch all GateSymbols to default implementation of functions such as getconnectedqubits(). Those functions are then specialized for GateSymbols requiring a different implementation.

AbstractGateSymbol is an abstract type, which means that it cannot be instantiated. Instead, 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})::AbstractOperator
  • get_num_connected_qubits(gate::AbstractGateSymbol)::Integer

Examples

A struct must be defined for each new GateSymbol type, such as the following X_45 GateSymbol which applies a $45°$ rotation about the $X$ axis:

julia> struct X45 <: AbstractGateSymbol
       end;

We need to define how many connected qubits our new GateSymbol has.

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, defined as:

julia> x_45(T::Type{<:Complex} = ComplexF64) = rotation_x(π/4, T);

To simulate the effect of the gate in a QuantumCircuit or when applied to a Ket, the function get_operator must be extended.

julia> Snowflurry.get_operator(gate::X45, T::Type{<:Complex} = ComplexF64) = rotation_x(π/4, T);

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 printout 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 is to 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
source
Snowflurry.ControlledType
Controlled{G<:AbstractGateSymbol}<:AbstractGateSymbol

The 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. The apply_gate will call into the optimized routine, and if no such routine is present, 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 with an arbitraty number of targets and controls can be constructed. For instance, the following 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.0im
source
Snowflurry.GateType
Gate <: AbstractInstruction

Gate 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.0im
julia> 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.0im
source
Snowflurry.eyeFunction
eye(),
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 of 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
source
Snowflurry.sigma_pFunction
sigma_p()

Return the spin-$\frac{1}{2}$ raising Operator, which is defined as:

\[\sigma_+ = \begin{bmatrix} 0 & 1 \\ 0 & 0 \end{bmatrix}.\]

source
Snowflurry.sigma_mFunction
sigma_m()

Return the spin-$\frac{1}{2}$ lowering Operator, which is defined as:

\[\sigma_- = \begin{bmatrix} 0 & 0 \\ 1 & 0 \end{bmatrix}.\]

source
Snowflurry.sigma_xFunction
sigma_x()

Return the Pauli-X AntiDiagonalOperator, which is defined as:

\[\sigma_x = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}.\]

source
sigma_x(target)

Return the Pauli-X Gate, which applies the sigma_x() AntiDiagonalOperator to the target qubit.

source
Snowflurry.sigma_yFunction
sigma_y()

Return the Pauli-Y Operator, which is defined as:

\[\sigma_y = \begin{bmatrix} 0 & -i \\ i & 0 \end{bmatrix}.\]

source
sigma_y(target)

Return the Pauli-Y Gate, which applies the sigma_y() Operator to the target qubit.

source
Snowflurry.sigma_zFunction
sigma_z()

Return the Pauli-Z Operator, which is defined as:

\[\sigma_z = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}.\]

source
sigma_z(target)

Return the Pauli-Z Gate, which applies the sigma_z() Operator to the target qubit.

source
Snowflurry.hadamardFunction
hadamard()

Return the Hadamard Operator, which is defined as:

\[H = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix}.\]

source
hadamard(target)

Return the Hadamard Gate, which applies the hadamard() Operator to the target qubit.

source
Snowflurry.pi_8Function
pi_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}.\]

source
pi_8(target)

Return a $π/8$ Gate (also known as a $T$ Gate), which applies the pi_8() DiagonalOperator to the target qubit.

source
Snowflurry.pi_8_daggerFunction
pi_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}.\]

source
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.

source
Snowflurry.x_90Function
x_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}.\]

source
x_90(target)

Return a Gate that applies a $90°$ rotation about the $X$ axis as defined by the x_90() Operator.

source
Snowflurry.x_minus_90Function
x_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}.\]

source
x_minus_90(target)

Return a Gate that applies a $-90°$ rotation about the $X$ axis as defined by the x_minus_90() Operator.

source
Snowflurry.y_90Function
y_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}.\]

source
y_90(target)

Return a Gate that applies a $90°$ rotation about the $Y$ axis as defined by the y_90() Operator.

source
Snowflurry.y_minus_90Function
y_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}.\]

source
y_minus_90(target)

Return a Gate that applies a $-90°$ rotation about the $Y$ axis as defined by the y_minus_90() Operator.

source
Snowflurry.z_90Function
z_90()

Return the Operator which applies a $π/2$ rotation about the $Z$ axis.

The Operator is defined as: ```math R_z\left(\frac{\pi}{2}\right) = \begin{bmatrix} e^{-i\frac{pi}{4} & 0 \[0.5em] 0 & e^{i\frac{pi}{4}} \end{bmatrix}.

source
z_90(target)

Return a Gate that applies a $90°$ rotation about the $Z$ axis as defined by the z_90() Operator.

source
Snowflurry.z_minus_90Function
z_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\frac{pi}{4} & 0 \\[0.5em] 0 & e^{-i\frac{pi}{4}} \end{bmatrix}.\]

source
z_minus_90(target)

Return a Gate that applies a $-90°$ rotation about the $Z$ axis as defined by the z_minus_90() Operator.

source
Snowflurry.rotationFunction
rotation(theta, phi)

Return the Operator which applies a rotation theta about an axis $\vec{n}$ defined by: $\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}.\]

source
rotation(target, theta, phi)

Return a gate that applies a rotation theta to the target qubit about an axis $\vec{n}$ defined by: $\vec{n}=\cos(\phi)~X+\sin(\phi)~Y$.

The corresponding Operator is rotation(theta, phi).

source
Snowflurry.rotation_xFunction
rotation_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}.\]

source
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).

source
Snowflurry.rotation_yFunction
rotation_y(theta)

Return the Operator that applies a rotation theta about the $Y$ axis of the target qubit.

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}.\]

source
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).

source
Snowflurry.rotation_zFunction
rotation_z(lambda)

Return the DiagonalOperator that applies a rotation of z.

The DiagonalOperator is defined as:

\[R_z(\lambda) = \begin{bmatrix} e^{-i\frac{\lambda}{2} & 0 \\[0.5em] 0 & e^{i\frac{\lambda}{2}} \end{bmatrix}.\]

source
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).

source
Snowflurry.root_zzFunction
root_zz()

Return the DiagonalOperator that, when applied twice in sequence, applies a rotation of z by -pi/2 on the first qubit and pi/2 on the second.

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}.\]

source
root_zz(qubit_1, qubit_2)

Return the root of a ZZ Gate which, when two are applied in sequence, are equivalent to one rotationz(-pi/2) Operator to `qubit1and one rotation_z(pi/2) toqubit_2.`

The corresponding Operator is root_zz().

source
Snowflurry.root_zz_daggerFunction
root_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}.\]

source
root_zz_dagger(qubit_1, qubit_2)

Return the complex conjugate of a root of ZZ Gate.

The corresponding Operator is root_zz_dagger().

source
Snowflurry.phase_shiftFunction
phase_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}.\]

source
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.

source
Snowflurry.universalFunction
universal(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}.\]

source
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).

source
Snowflurry.control_zFunction
control_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}.\]

source
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().

source
Snowflurry.control_xFunction
control_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}.\]

source
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().

source
Snowflurry.iswapFunction
iswap()

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}.\]

source
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().

source
Snowflurry.swapFunction
swap()

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}.\]

source
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().

source
Snowflurry.toffoliFunction
toffoli()

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}.\]

source
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().

source
Snowflurry.iswap_daggerFunction
iswap_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}.\]

source
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().

source
Base.:*Method
Base.:*(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

source
Snowflurry.apply_instruction!Function
apply_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
source
Snowflurry.get_operatorFunction
get_operator(gate::Gate)

Returns the Operator which is associated to 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    .

source
Base.invMethod
inv(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

source
Snowflurry.move_instructionFunction
move_instruction(gate::Gate,
    qubit_mapping::AbstractDict{<:Integer,<:Integer})::AbstractGateSymbol

Returns 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    .

source
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 
source