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
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
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
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 .
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
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
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
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
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
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
.
Base.adjoint
— Function.
Base.adjoint(x)
Compute the adjoint (a.k.a. conjugate transpose) of a Ket, a Bra, or an Operator.
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
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
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
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
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
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 i
th 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
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
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
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.
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
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
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
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
Snowflurry.ket2dm
— Function.
ket2dm(ψ::Ket)
Returns the density matrix corresponding to the pure state ψ.
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
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
Snowflurry.moyal
— Function.
moyal(m, n)
Returns the Moyal function w_mn(eta)
for Fock states m
and n
.
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.
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
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
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
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
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
Snowflurry.fock
— Function.
fock(i, hspace_size,T::Type{<:Complex}=ComplexF64)
Returns the i
th 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
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
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
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.
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.
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.
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
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
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