Snowflurry Logo

Library reference

Quantum Toolkit

Basic Quantum Objects

There are three basic quantum objects in Snowflurry to simulate a quantum system. These objects are Ket, Bra, and AbstractOperator.

Snowflurry.Ket — Type.

A Ket represents a quantum wavefunction and is mathematically equivalent to a column vector of complex values. The norm of a Ket should always be unity. A Ket representing a system with a qubit count of $n=2$ has $2^n$ states. By convention, qubit 1 is the leftmost digit, followed by every subsequent qubit. Hence, a 2-qubit Ket has 4 complex-valued coefficients $a_{ij}$, each corresponding to state $\left|ij\right\rangle$, in the following order:

$$ \psi = \begin{bmatrix} a_{00} \newline a_{10} \newline a_{01} \newline a_{11} \newline \end{bmatrix}. $$

Examples

A Ket can be initialized by using a pre-built basis such as the fock basis. See fock for further information on this function.

julia> ψ = fock(2, 4)
4-element Ket{ComplexF64}:
0.0 + 0.0im
0.0 + 0.0im
1.0 + 0.0im
0.0 + 0.0im

Although NOT the preferred way, one can also directly build a Ket object by passing a column vector as the initializer.

julia> using Snowflurry

julia> ψ = Ket([1.0; 0.0; 0.0; 0.0])
4-element Ket{ComplexF64}:
1.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im

source

Snowflurry.Bra — Type.

A structure representing a Bra (i.e., a row vector of complex values). A Bra is created as the complex conjugate of a Ket.

Examples

julia> ψ = fock(1, 3)
3-element Ket{ComplexF64}:
0.0 + 0.0im
1.0 + 0.0im
0.0 + 0.0im


julia>= Bra(ψ)
3-element Bra{ComplexF64}:
0.0 - 0.0im
1.0 - 0.0im
0.0 - 0.0im


julia>* ψ    # A Bra times a Ket is a scalar
1.0 + 0.0im

julia> ψ*_ψ     # A Ket times a Bra is an operator
(3, 3)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
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

source

Snowflurry.DiagonalOperator — Type.

DiagonalOperator{N,T<:Complex}<:AbstractOperator

A structure representing a diagonal quantum Operator (i.e., a complex matrix of element type T, with non-zero elements all lying on the diagonal). The equivalent dense matrix would have size NxN.

Examples

julia> z = DiagonalOperator([1.0,-1.0])
(2,2)-element Snowflurry.DiagonalOperator:
Underlying data type: ComplexF64:
1.0 + 0.0im    .
.    -1.0 + 0.0im

julia> z = DiagonalOperator([1.0+im,1.0,1.0,0.0-im])
(4,4)-element Snowflurry.DiagonalOperator:
Underlying data type: ComplexF64:
1.0 + 1.0im    .    .    .
.    1.0 + 0.0im    .    .
.    .    1.0 + 0.0im    .
.    .    .    0.0 - 1.0im

source

Snowflurry.AntiDiagonalOperator — Type.

AntiDiagonalOperator{N,T<:Complex}<:AbstractOperator

A structure representing a anti-diagonal quantum Operator (i.e., a complex matrix of element type T, with non-zero elements all lying on the cross-diagonal). The equivalent dense matrix would have size NxN.

Examples

julia> AntiDiagonalOperator([1, 2])
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
    .    1.0 + 0.0im
    2.0 + 0.0im    .

source

Snowflurry.DenseOperator — Type.

DenseOperator{N,T<:Complex}<:AbstractOperator

A structure representing a quantum operator with a full (dense) matrix representation of size NxN and containing elements of type T.

Examples

julia> z = DenseOperator([1.0 0.0;0.0 -1.0])
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
1.0 + 0.0im    0.0 + 0.0im
0.0 + 0.0im    -1.0 + 0.0im

Alternatively:

julia> z = rotation(π/2, -π/4)  
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
0.7071067811865476 + 0.0im    0.4999999999999999 - 0.5im
-0.4999999999999999 - 0.5im    0.7071067811865476 + 0.0im

source

Snowflurry.SwapLikeOperator — Type.

SwapLikeOperator{N,T<:Complex}<:AbstractOperator

A structure representing a quantum operator performing a "swap" operation, with element type T. A phase value is applied to the swapped qubit coefficients. This operator is always of size 4x4.

For example, the iswap Operator can be built using a phase=0.0 + 1.0im by calling:

julia> SwapLikeOperator(0.0 + 1.0im)
(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

source

Snowflurry.IdentityOperator — Type.

IdentityOperator{N,T<:Complex}<:AbstractOperator

A structure representing the identity quantum operator, with element type T. This operator is always of size 2x2.

Example

julia> IdentityOperator()
(2, 2)-element Snowflurry.IdentityOperator:
Underlying data ComplexF64:
Equivalent DenseOperator:
1.0 + 0.0im    0.0 + 0.0im
0.0 + 0.0im    1.0 + 0.0im

source

Snowflurry.SparseOperator — Type.

SparseOperator{N,T<:Complex}<:AbstractOperator

A structure representing a quantum operator with a sparse (CSR) matrix representation, with element type T. The equivalent dense matrix would have size NxN.

Warning

The apply_operator() method is not implemented for this operator type. Try using DenseOperator instead.

Examples

julia> z = SparseOperator([-1.0 1.0;0.0 -1.0])
(2, 2)-element Snowflurry.SparseOperator:
Underlying data ComplexF64:
 -1.0 + 0.0im   1.0 + 0.0im
-1.0 + 0.0im

source

Snowflurry.Readout — Type.

Readout <: AbstractInstruction

Readout is an implementation of an AbstractInstruction that specifies an explicit measurement on a particular qubit, and the destination bit in the classical result registry (classical bit). It is built using the readout(qubit::Int, bit::Int) helper function, where the first argument is the target qubit, and the second is the destination classical bit. Measurements are always performed in the $Z$ basis (also known as the computational basis).

Examples

julia> r = readout(1, 2)
Explicit Readout object:
   connected_qubit: 1 
   destination_bit: 2

source

Snowflurry.readout — Function.

readout(qubit::Int, bit::Int)

Return a Readout AbstractInstruction, which performs a readout on the target qubit, and places the result in the destination bit.

source

Base.adjoint — Function.

Base.adjoint(x)

Compute the adjoint (a.k.a. conjugate transpose) of a Ket, a Bra, or an Operator.

source

Snowflurry.is_hermitian — Function.

is_hermitian(A::AbstractOperator)

Determine if Operator A is Hermitian (i.e., self-adjoint).

Examples

julia> Y = sigma_y()
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
    .    0.0 - 1.0im
    0.0 + 1.0im    .


julia> is_hermitian(Y)
true

julia> P = sigma_p()
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
    .    1.0 + 0.0im
    0.0 + 0.0im    .


julia> is_hermitian(P)
false

source

Base.exp — Method.

exp(A::AbstractOperator)

Compute the matrix exponential of Operator A.

Examples

julia> X = sigma_x()
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
    .    1.0 + 0.0im
    1.0 + 0.0im    .


julia> x_rotation_90_deg = exp(-im*π/4*X)
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
0.7071067811865475 + 0.0im    0.0 - 0.7071067811865475im
0.0 - 0.7071067811865475im    0.7071067811865475 + 0.0im

source

Base.getindex — Method.

getindex(A::AbstractOperator, i::Integer, j::Integer)

Access the element at row i and column j in the matrix corresponding to Operator A.

Examples

julia> Y = sigma_y()
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
    .    0.0 - 1.0im
    0.0 + 1.0im    .


julia> Y[1,1]
0.0 + 0.0im

julia> Y[1,2]
0.0 - 1.0im

julia> Y[2,1]
0.0 + 1.0im

julia> Y[2,2]
0.0 + 0.0im

source

Snowflurry.expected_value — Method.

expected_value(A::AbstractOperator, psi::Ket)

Compute the expectation value ⟨ψ|A|ψ⟩ given Operator A and Ket |ψ⟩.

Examples

julia> ψ = Ket([0.0; 1.0])
2-element Ket{ComplexF64}:
0.0 + 0.0im
1.0 + 0.0im


julia> A = sigma_z()
(2,2)-element Snowflurry.DiagonalOperator:
Underlying data type: ComplexF64:
1.0 + 0.0im    .
.    -1.0 + 0.0im


julia> expected_value(A, ψ)
-1.0 + 0.0im

source

SparseArrays.sparse — Function.

sparse(x::AbstractOperator)

Returns a SparseOperator representation of x.

Examples

julia> z = sparse(sigma_z())
(2, 2)-element Snowflurry.SparseOperator:
Underlying data ComplexF64:
 1.0 + 0.0im        ⋅     
-1.0 + 0.0im

source

LinearAlgebra.eigen — Function.

eigen(A::AbstractOperator)

Compute the eigenvalue decomposition of Operator A and return an Eigen factorization object F. Eigenvalues are found in F.values while eigenvectors are found in the matrix F.vectors. Each column of this matrix corresponds to an eigenvector. The ith eigenvector is extracted by calling F.vectors[:, i].

Examples

julia> X = sigma_x()
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
    .    1.0 + 0.0im
    1.0 + 0.0im    .

julia> F = eigen(X);

julia> eigenvalues = F.values
2-element Vector{Float64}:
 -1.0
  1.0

julia> eigenvector_1 = F.vectors[:, 1]
2-element Vector{ComplexF64}:
 -0.7071067811865475 + 0.0im
  0.7071067811865475 + 0.0im

source

LinearAlgebra.tr — Function.

tr(A::AbstractOperator)

Compute the trace of Operator A.

Examples

julia> I = 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> trace = tr(I)
2.0 + 0.0im

source

Base.kron — Function.

kron(x, y)

Compute the Kronecker product of two Kets or two DenseOperator , DiagonalOperator, AntiDiagonalOperator. More details about the Kronecker product can be found here.

Examples

julia> ψ_0 = Ket([0.0; 1.0])
2-element Ket{ComplexF64}:
0.0 + 0.0im
1.0 + 0.0im


julia> ψ_1 = Ket([1.0; 0.0])
2-element Ket{ComplexF64}:
1.0 + 0.0im
0.0 + 0.0im


julia> ψ_0_1 = kron(ψ_0, ψ_1)
4-element Ket{ComplexF64}:
0.0 + 0.0im
0.0 + 0.0im
1.0 + 0.0im
0.0 + 0.0im


julia> kron(sigma_x(), sigma_y())
(4, 4)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
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 - 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

source

Snowflurry.MultiBodySystem — Type.

A structure representing a quantum multi-body system.

Fields

  • hilbert_space_structure – a vector of integers specifying the local Hilbert space size for each "body" within the multi-body system.

source

Snowflurry.commute — Function.

commute(A::AbstractOperator, B::AbstractOperator)

Returns the commutation of A and B.

julia> σ_x = sigma_x()
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
    .    1.0 + 0.0im
    1.0 + 0.0im    .


julia> σ_y = sigma_y()
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
    .    0.0 - 1.0im
    0.0 + 1.0im    .


julia> commute(σ_x, σ_y)
(2,2)-element Snowflurry.DiagonalOperator:
Underlying data type: ComplexF64:
0.0 + 2.0im    .
.    0.0 - 2.0im

source

Snowflurry.anticommute — Function.

anticommute(A::AbstractOperator, B::AbstractOperator)

Returns the anticommutation of A and B.

julia> σ_x = sigma_x()
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
    .    1.0 + 0.0im
    1.0 + 0.0im    .


julia> anticommute(σ_x, σ_x)
(2,2)-element Snowflurry.DiagonalOperator:
Underlying data type: ComplexF64:
2.0 + 0.0im    .
.    2.0 + 0.0im

source

LinearAlgebra.normalize! — Function.

normalize!(x::Ket)

Normalizes Ket x such that its magnitude becomes unity.

julia> ψ = Ket([1., 2., 4.])
3-element Ket{ComplexF64}:
1.0 + 0.0im
2.0 + 0.0im
4.0 + 0.0im

julia> normalize!(ψ)
3-element Ket{ComplexF64}:
0.2182178902359924 + 0.0im
0.4364357804719848 + 0.0im
0.8728715609439696 + 0.0im

source

Snowflurry.get_measurement_probabilities — Method.

get_measurement_probabilities(x::Ket{Complex{T}},
    [target_bodies::Vector{U},
    hspace_size_per_body::Union{U,Vector{U}}=2])::AbstractVector{T}
    where {T<:Real, U<:Integer}

Returns a vector listing the measurement probabilities of the target_bodies of Ket x.

The Hilbert space size per body can be specified by providing a Vector of Integer for the hspace_size_per_body argument. The Vector must specify the Hilbert space size for each body. If the space size is uniform, a single Integer can be given instead. If only x is provided, the probabilities are provided for all the bodies.

The measurement probabilities are listed from the smallest to the largest computational basis state. For instance, for a 2-qubit Ket, the probabilities are listed for $\left|00\right\rangle$, $\left|10\right\rangle$, $\left|01\right\rangle$, and $\left|11\right\rangle$.

Note

By convention, qubit 1 is the leftmost digit, followed by every subsequent qubit. $\left|10\right\rangle$ has qubit 1 in state $\left|1\right\rangle$ and qubit 2 in state $\left|0\right\rangle$

Examples

The following example constructs a Ket, where the probability of measuring $\left|00\right\rangle$ is 50% and the probability of measuring $\left|01\right\rangle$ is also 50%.

julia> ψ = 1/sqrt(2) * Ket([1, 0, 1, 0])
4-element Ket{ComplexF64}:
0.7071067811865475 + 0.0im
0.0 + 0.0im
0.7071067811865475 + 0.0im
0.0 + 0.0im


julia> get_measurement_probabilities(ψ)
4-element Vector{Float64}:
 0.4999999999999999
 0.0
 0.4999999999999999
 0.0

For the same Ket, the probability of measuring qubit 2 and finding 0 is 100%.

julia> target_qubit = [2];

julia> get_measurement_probabilities(ψ, target_qubit)
2-element Vector{Float64}:
 0.9999999999999998
 0.0

source

Snowflurry.ket2dm — Function.

ket2dm(ψ::Ket)

Returns the density matrix corresponding to the pure state ψ.

source

Snowflurry.fock_dm — Function.

fock_dm(i::Int64, hspace_size::Int64)

Returns the density matrix corresponding to the Fock base i defined in a Hilbert space of size hspace_size.

julia> dm = fock_dm(0, 2)
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
1.0 + 0.0im    0.0 + 0.0im
0.0 + 0.0im    0.0 + 0.0im

source

Snowflurry.wigner — Function.

wigner(ρ::AbstractOperator, p::Real, q::Real)

Computes the Wigner function of the density matrix ρ at the point (p,q).

julia> alpha = 0.25;

julia> hspace_size = 8;

julia> Ψ = coherent(alpha, hspace_size);

julia> prob = wigner(ket2dm(Ψ), 0, 0);

julia> @printf "prob: %.6f" prob
prob: -0.561815

source

Snowflurry.moyal — Function.

moyal(m, n)

Returns the Moyal function w_mn(eta) for Fock states m and n.

source

Snowflurry.genlaguerre — Function.

genlaguerre(x, alpha, n)

Returns the generalized Laguerre polynomial of degree n for x using a recursive method. See https://en.wikipedia.org/wiki/Laguerre_polynomials.

source

Snowflurry.get_embed_operator — Function.

get_embed_operator(op::DenseOperator, target_body_index::Int, system::MultiBodySystem)

Uses a local operator (op), which is defined for a particular body (e.g. qubit) with index target_body_index, to build the corresponding operator for the Hilbert space of the multi-body system given by system.

Examples

julia> system = MultiBodySystem(3, 2)
Snowflurry.Multibody system with 3 bodies
   Hilbert space structure:
   [2, 2, 2]

julia> x = sigma_x()
(2,2)-element Snowflurry.AntiDiagonalOperator:
Underlying data type: ComplexF64:
    .    1.0 + 0.0im
    1.0 + 0.0im    .

julia> X_1 = get_embed_operator(x, 1, system)
(8, 8)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
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
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

source

Snowflurry.get_num_qubits — Method.

get_num_qubits(x::AbstractOperator)

Returns the number of qubits associated with an Operator.

Examples

julia> ρ = DenseOperator([1. 0. 
                          0. 0.])
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
1.0 + 0.0im    0.0 + 0.0im
0.0 + 0.0im    0.0 + 0.0im

julia> get_num_qubits(ρ)
1

source

Snowflurry.get_num_qubits — Method.

get_num_qubits(x::Union{Ket, Bra})

Returns the number of qubits associated with a Ket or a Bra.

Examples

julia> ψ = Ket([1., 0., 0., 0.])
4-element Ket{ComplexF64}:
1.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im


julia> get_num_qubits(ψ)
2

source

Snowflurry.get_num_bodies — Function.

get_num_bodies(x::AbstractOperator, hilbert_space_size_per_body=2)

Returns the number of bodies associated with an Operator given the hilbert_space_size_per_body.

Examples

julia> ρ = DenseOperator([1. 0. 0.
                          0. 0. 0.
                          0. 0. 0.])
(3, 3)-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

julia> get_num_bodies(ρ, 3)
1

source

Snowflurry.get_num_bodies — Function.

get_num_bodies(x::Union{Ket, Bra}, hilbert_space_size_per_body=2)

Returns the number of bodies associated with a Ket or a Bra given the hilbert_space_size_per_body.

Examples

julia> ψ = Ket([1., 0., 0., 0., 0., 0., 0., 0., 0.])
9-element Ket{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


julia> get_num_bodies(ψ, 3)
2

source

Snowflurry.fock — Function.

fock(i, hspace_size,T::Type{<:Complex}=ComplexF64)

Returns the ith Fock basis of a Hilbert space with size hspace_size as a Ket.

The Ket contains values of type T, which by default is ComplexF64.

Examples

julia> ψ = fock(0, 3)
3-element Ket{ComplexF64}:
1.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im


julia> ψ = fock(1, 3)
3-element Ket{ComplexF64}:
0.0 + 0.0im
1.0 + 0.0im
0.0 + 0.0im


julia> ψ = fock(1, 3, ComplexF32) # specifying a type other than ComplexF64
3-element Ket{ComplexF32}:
0.0f0 + 0.0f0im
1.0f0 + 0.0f0im
0.0f0 + 0.0f0im

source

Snowflurry.spin_up — Function.

spin_up(T::Type{<:Complex}=ComplexF64)

Returns the Ket representation of the spin-up state.

The Ket stores values of type T, which is ComplexF64 by default.

Examples

julia> ψ = spin_up()
2-element Ket{ComplexF64}:
1.0 + 0.0im
0.0 + 0.0im

source

Snowflurry.spin_down — Function.

spin_down(T::Type{<:Complex}=ComplexF64)

Returns the Ket representation of the spin-down state.

The Ket stores values of type T, which is ComplexF64 by default.

Examples

julia> ψ = spin_down()
2-element Ket{ComplexF64}:
0.0 + 0.0im
1.0 + 0.0im

source

Snowflurry.create — Function.

create(hspace_size,T::Type{<:Complex}=ComplexF64)

Returns the bosonic creation operator for a Fock space of size hspace_size, of default type ComplexF64.

source

Snowflurry.destroy — Function.

destroy(hspace_size,T::Type{<:Complex}=ComplexF64)

Returns the bosonic annhilation operator for a Fock space of size hspace_size, of default type ComplexF64.

source

Snowflurry.number_op — Function.

number_op(hspace_size,T::Type{<:Complex}=ComplexF64)

Returns the number operator for a Fock space of size hspace_size, of default type ComplexF64.

source

Snowflurry.coherent — Function.

coherent(alpha, hspace_size)

Returns a coherent state for the parameter alpha in a Fock space of size hspace_size. Note that |alpha|^2 is equal to the photon number of the coherent state.

# Examples
julia> ψ = coherent(2.0, 20)
20-element Ket{ComplexF64}:
0.1353352832366127 + 0.0im
0.2706705664732254 + 0.0im
0.3827859860416437 + 0.0im
0.44200318416631873 + 0.0im
0.44200318416631873 + 0.0im
0.3953396664268989 + 0.0im
0.3227934859426707 + 0.0im
0.24400893961026582 + 0.0im
0.17254037586855772 + 0.0im
0.11502691724570517 + 0.0im
0.07274941014482605 + 0.0im
0.043869544940011405 + 0.0im
0.025328093580341972 + 0.0im
0.014049498479026656 + 0.0im
0.007509772823502764 + 0.0im
0.003878030010563634 + 0.0im
0.001939015005281817 + 0.0im
0.000940560432521708 + 0.0im
0.0004433844399679012 + 0.0im
0.00020343873336404819 + 0.0im


julia> expected_value(number_op(20), ψ)
3.99999979364864 + 0.0im

source

Snowflurry.compare_kets — Function.

compare_kets(ψ_0::Ket,ψ_1::Ket)

Checks for equivalence allowing for a global phase difference between two input kets.

Examples

julia> ψ_0 = Ket([1., 2., 3., 4.])
4-element Ket{ComplexF64}:
1.0 + 0.0im
2.0 + 0.0im
3.0 + 0.0im
4.0 + 0.0im


julia> δ = π/3 # phase offset
1.0471975511965976

julia> ψ_1 = exp(im * δ) * ψ_0
4-element Ket{ComplexF64}:
0.5000000000000001 + 0.8660254037844386im
1.0000000000000002 + 1.7320508075688772im
1.5000000000000004 + 2.598076211353316im
2.0000000000000004 + 3.4641016151377544im


julia> compare_kets(ψ_0, ψ_1)
true

julia> apply_instruction!(ψ_1, sigma_x(1))
4-element Ket{ComplexF64}:
1.5000000000000004 + 2.598076211353316im
2.0000000000000004 + 3.4641016151377544im
0.5000000000000001 + 0.8660254037844386im
1.0000000000000002 + 1.7320508075688772im


julia> compare_kets(ψ_0, ψ_1) # no longer equivalent after SigmaX gate
false

source

Snowflurry.compare_operators — Function.

compare_operators(H_0::AbstractOperator, H_1::AbstractOperator)::Bool

Checks for equivalence allowing for a global phase difference between two input operators.

Examples

julia> H_0 = z_90()
(2,2)-element Snowflurry.DiagonalOperator:
Underlying data type: ComplexF64:
0.7071067811865476 - 0.7071067811865475im    .
.    0.7071067811865476 + 0.7071067811865475im


julia> H_1 = phase_shift(pi / 2)
(2,2)-element Snowflurry.DiagonalOperator:
Underlying data type: ComplexF64:
1.0 + 0.0im    .
.    6.123233995736766e-17 + 1.0im


julia> compare_operators(H_0, H_1)
true

julia> H_1 *= sigma_x()
(2, 2)-element Snowflurry.DenseOperator:
Underlying data ComplexF64:
0.0 + 0.0im    1.0 + 0.0im
6.123233995736766e-17 + 1.0im    0.0 + 0.0im


julia> compare_operators(H_0, H_1) # no longer equivalent after applying sigma x
false

source

Previous
Real hardware