Library reference
Quantum Gates
Snowflurry.AbstractGateSymbol
— Type.
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
Snowflurry.Controlled
— Type.
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 AbstractGateSymbol
s and controlled Gate
s. 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
Snowflurry.Gate
— Type.
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
Snowflurry.eye
— Function.
eye(),
eye(size::Integer)
Return the identity matrix as a DenseOperator
, which is defined as:
$$ I = \begin{bmatrix} 1 & 0 \newline 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
Snowflurry.identity_gate
— Function.
identity_gate(target)
Return the Identity Gate
, which applies the identity_gate()
IdentityOperator
to the target qubit.
Snowflurry.sigma_p
— Function.
sigma_p()
Return the spin-$\frac{1}{2}$ raising Operator
, which is defined as:
$$ \sigma_+ = \begin{bmatrix} 0 & 1 \newline 0 & 0 \end{bmatrix}. $$
Snowflurry.sigma_m
— Function.
sigma_m()
Return the spin-$\frac{1}{2}$ lowering Operator
, which is defined as:
$$ \sigma_- = \begin{bmatrix} 0 & 0 \newline 1 & 0 \end{bmatrix}. $$
Snowflurry.sigma_x
— Function.
sigma_x()
Return the Pauli-X AntiDiagonalOperator
, which is defined as:
$$ \sigma_x = \begin{bmatrix} 0 & 1 \newline 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
— Function.
sigma_y()
Return the Pauli-Y Operator
, which is defined as:
$$ \sigma_y = \begin{bmatrix} 0 & -i \newline 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
— Function.
sigma_z()
Return the Pauli-Z Operator
, which is defined as:
$$ \sigma_z = \begin{bmatrix} 1 & 0 \newline 0 & -1 \end{bmatrix}. $$
sigma_z(target)
Return the Pauli-Z Gate
, which applies the sigma_z()
Operator
to the target qubit.
Snowflurry.hadamard
— Function.
hadamard()
Return the Hadamard Operator
, which is defined as:
$$ H = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \newline 1 & -1 \end{bmatrix}. $$
hadamard(target)
Return the Hadamard Gate
, which applies the hadamard()
Operator
to the target
qubit.
Snowflurry.pi_8
— Function.
pi_8()
Return the Operator
for the $π/8$ gate, which is defined as:
$$ T = \begin{bmatrix} 1 & 0 \newline 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
— Function.
pi_8_dagger()
Return the adjoint DiagonalOperator
of the $π/8$ gate, which is defined as:
$$ T^\dagger = \begin{bmatrix} 1 & 0 \newline 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
— Function.
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 \newline -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
— Function.
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 \newline 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
— Function.
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 \newline 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
— Function.
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 \newline -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
— Function.
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 & e^{i\frac{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
— Function.
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 \newline 0 & e^{-i\frac{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
— Function.
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) \newline -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 an axis $\vec{n}$ defined by: $\vec{n}=\cos(\phi)~X+\sin(\phi)~Y$.
The corresponding Operator
is rotation(theta, phi)
.
Snowflurry.rotation_x
— Function.
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) \newline -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
— Function.
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) \newline \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
— Function.
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 \newline 0 & e^{i\frac{\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.phase_shift
— Function.
phase_shift(phi)
Return the DiagonalOperator
that applies a phase shift phi
.
The DiagonalOperator
is defined as:
$$ P(\phi) = \begin{bmatrix} 1 & 0 \newline 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
— Function.
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) \newline 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
— Function.
control_z()
Return the controlled-Z Operator
, which is defined as:
$$ CZ = \begin{bmatrix} 1 & 0 & 0 & 0 \newline 0 & 1 & 0 & 0 \newline 0 & 0 & 1 & 0 \newline 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
— Function.
control_x()
Return the controlled-X (or controlled NOT) Operator
, which is defined as:
$$ CX = CNOT = \begin{bmatrix} 1 & 0 & 0 & 0 \newline 0 & 1 & 0 & 0 \newline 0 & 0 & 0 & 1 \newline 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
— Function.
iswap()
Return the imaginary swap Operator
, which is defined as:
$$ iSWAP = \begin{bmatrix} 1 & 0 & 0 & 0 \newline 0 & 0 & i & 0 \newline 0 & i & 0 & 0 \newline 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
— Function.
swap()
Return the swap Operator
, which is defined as:
$$ iSWAP = \begin{bmatrix} 1 & 0 & 0 & 0 \newline 0 & 0 & 1 & 0 \newline 0 & 1 & 0 & 0 \newline 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
— Function.
toffoli()
Return the Toffoli Operator
, which is defined as:
$$ CCX = CCNOT = \begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \newline 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \newline 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \newline 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \newline 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \newline 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \newline 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \newline 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
— Function.
iswap_dagger()
Return the adjoint of the imaginary swap Operator
, which is defined as:
$$ iSWAP^\dagger = \begin{bmatrix} 1 & 0 & 0 & 0 \newline 0 & 0 & -i & 0 \newline 0 & -i & 0 & 0 \newline 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.:*
— 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
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
Snowflurry.get_operator
— Function.
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 .
Base.inv
— Method.
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
Snowflurry.move_instruction
— Function.
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 .
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