API
Quantum object functions
QuantumToolbox.BraQuantumObject
— TypeBraQuantumObject <: QuantumObjectType
Constructor representing a bra state $\bra{\psi}$.
QuantumToolbox.Bra
— Constantconst Bra = BraQuantumObject()
A constant representing the type of BraQuantumObject
QuantumToolbox.KetQuantumObject
— TypeKetQuantumObject <: QuantumObjectType
Constructor representing a ket state $\ket{\psi}$.
QuantumToolbox.Ket
— Constantconst Ket = KetQuantumObject()
A constant representing the type of KetQuantumObject
QuantumToolbox.OperatorQuantumObject
— TypeOperatorQuantumObject <: QuantumObjectType
Constructor representing an operator $\hat{O}$.
QuantumToolbox.Operator
— Constantconst Operator = OperatorQuantumObject()
A constant representing the type of OperatorQuantumObject
QuantumToolbox.OperatorBraQuantumObject
— TypeOperatorBraQuantumObject <: QuantumObjectType
Constructor representing a bra state in the super-operator formalism $\langle\langle\rho|$.
QuantumToolbox.OperatorBra
— Constantconst OperatorBra = OperatorBraQuantumObject()
A constant representing the type of OperatorBraQuantumObject
QuantumToolbox.OperatorKetQuantumObject
— TypeOperatorKetQuantumObject <: QuantumObjectType
Constructor representing a ket state in the super-operator formalism $|\rho\rangle\rangle$.
QuantumToolbox.OperatorKet
— Constantconst OperatorKet = OperatorKetQuantumObject()
A constant representing the type of OperatorKetQuantumObject
QuantumToolbox.SuperOperatorQuantumObject
— TypeSuperOperatorQuantumObject <: QuantumObjectType
Constructor representing a super-operator $\hat{\mathcal{O}}$.
QuantumToolbox.SuperOperator
— Constantconst SuperOperator = SuperOperatorQuantumObject()
A constant representing the type of SuperOperatorQuantumObject
QuantumToolbox.QuantumObject
— Typemutable struct QuantumObject{MT<:AbstractArray,ObjType<:QuantumObjectType}
data::MT
type::ObjType
dims::Vector{Int}
end
Julia struct representing any quantum operator.
Examples
julia> a = destroy(20)
Quantum Object: type=Operator dims=[20] size=(20, 20) ishermitian=false
20×20 SparseMatrixCSC{ComplexF64, Int64} with 19 stored entries:
⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠈⠢⡀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠈⠢⡀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠈⠢⡀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢
julia> a isa QuantumObject
true
QuantumToolbox.Qobj
— FunctionQobj(A::AbstractArray; type::QuantumObjectType, dims::Vector{Int})
Generate QuantumObject
QuantumToolbox.ket2dm
— Functionket2dm(ψ::QuantumObject)
Transform the ket state $\ket{\psi}$ into a pure density matrix $\hat{\rho} = \dyad{\psi}$.
QuantumToolbox.isbra
— Functionisbra(A::QuantumObject)
Checks if the QuantumObject
A
is a BraQuantumObject
state.
QuantumToolbox.isket
— Functionisket(A::QuantumObject)
Checks if the QuantumObject
A
is a KetQuantumObject
state.
QuantumToolbox.isoper
— Functionisoper(A::QuantumObject)
Checks if the QuantumObject
A
is a OperatorQuantumObject
state.
QuantumToolbox.isoperbra
— Functionisoperbra(A::QuantumObject)
Checks if the QuantumObject
A
is a OperatorBraQuantumObject
state.
QuantumToolbox.isoperket
— Functionisoperket(A::QuantumObject)
Checks if the QuantumObject
A
is a OperatorKetQuantumObject
state.
QuantumToolbox.issuper
— Functionissuper(A::QuantumObject)
Checks if the QuantumObject
A
is a SuperOperatorQuantumObject
state.
Base.size
— Functionsize(A::QuantumObject)
Returns the size of the matrix or vector corresponding to the QuantumObject
A
.
Base.eltype
— Functioneltype(A::QuantumObject)
Returns the elements type of the matrix or vector corresponding to the QuantumObject
A
.
Base.length
— Functionlength(A::QuantumObject)
Returns the length of the matrix or vector corresponding to the QuantumObject
A
.
LinearAlgebra.tr
— Functiontr(A::QuantumObject})
Returns the trace of A
.
Examples
julia> a = destroy(20)
Quantum Object: type=Operator dims=[20] size=(20, 20) ishermitian=false
20×20 SparseMatrixCSC{ComplexF64, Int64} with 19 stored entries:
⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠈⠢⡀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠈⠢⡀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠈⠢⡀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢
julia> tr(a' * a)
190.0 + 0.0im
LinearAlgebra.norm
— Functionnorm(A::QuantumObject)
Returns the norm of A
.
Examples
julia> ψ = fock(10, 2)
Quantum Object: type=Ket dims=[10] size=(10,)
10-element Vector{ComplexF64}:
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
julia> norm(ψ)
1.0
Base.kron
— Functionkron(A::QuantumObject, B::QuantumObject)
Returns the Kronecker product $\hat{A} \otimes \hat{B}$.
Examples
julia> a = destroy(20)
Quantum Object: type=Operator dims=[20] size=(20, 20) ishermitian=false
20×20 SparseMatrixCSC{ComplexF64, Int64} with 19 stored entries:
⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠈⠢⡀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠈⠢⡀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠈⠢⡀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢
julia> kron(a, a)
Quantum Object: type=Operator dims=[20, 20] size=(400, 400) ishermitian=false
400×400 SparseMatrixCSC{ComplexF64, Int64} with 361 stored entries:
⠀⠀⠘⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠦
QuantumToolbox.tensor
— Functiontensor(A1::QuantumObject, A2::QuantumObject, ...)
Returns the Kronecker product $\hat{A}_1 \otimes \hat{A}_2 \otimes \cdots$.
Examples
julia> x = sigmax()
Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=true
2×2 SparseMatrixCSC{ComplexF64, Int64} with 2 stored entries:
⋅ 1.0+0.0im
1.0+0.0im ⋅
julia> x_list = fill(x, 3);
julia> tensor(x_list...)
Quantum Object: type=Operator dims=[2, 2, 2] size=(8, 8) ishermitian=true
8×8 SparseMatrixCSC{ComplexF64, Int64} with 8 stored entries:
⋅ ⋅ ⋅ … ⋅ ⋅ 1.0+0.0im
⋅ ⋅ ⋅ ⋅ 1.0+0.0im ⋅
⋅ ⋅ ⋅ 1.0+0.0im ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ 1.0+0.0im … ⋅ ⋅ ⋅
⋅ 1.0+0.0im ⋅ ⋅ ⋅ ⋅
1.0+0.0im ⋅ ⋅ ⋅ ⋅ ⋅
QuantumToolbox.:⊗
— Function⊗(A::QuantumObject, B::QuantumObject)
Returns the Kronecker product $\hat{A} \otimes \hat{B}$.
Examples
julia> a = destroy(20)
Quantum Object: type=Operator dims=[20] size=(20, 20) ishermitian=false
20×20 SparseMatrixCSC{ComplexF64, Int64} with 19 stored entries:
⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠈⠢⡀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠈⠢⡀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠈⠢⡀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢
julia> a ⊗ a
Quantum Object: type=Operator dims=[20, 20] size=(400, 400) ishermitian=false
400×400 SparseMatrixCSC{ComplexF64, Int64} with 361 stored entries:
⠀⠀⠘⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠦
General functions
QuantumToolbox.row_major_reshape
— Functionrow_major_reshape(Q::AbstractArray, shapes...)
Reshapes Q
in the row-major order, as numpy.
QuantumToolbox.meshgrid
— Functionmeshgrid(x::AbstractVector, y::AbstractVector)
Equivalent to numpy meshgrid.
QuantumToolbox.sparse_to_dense
— Functionsparse_to_dense(A::QuantumObject)
Converts a sparse QuantumObject to a dense QuantumObject.
QuantumToolbox.dense_to_sparse
— Functiondense_to_sparse(A::QuantumObject)
Converts a dense QuantumObject to a sparse QuantumObject.
QuantumToolbox.tidyup
— Functiontidyup(A::QuantumObject, tol::Real=1e-14)
Removes those elements of a QuantumObject A
whose absolute value is less than tol
.
QuantumToolbox.tidyup!
— Functiontidyup!(A::QuantumObject, tol::Real=1e-14)
Removes those elements of a QuantumObject A
whose absolute value is less than tol
. In-place version of tidyup
.
QuantumToolbox.gaussian
— Functiongaussian(x::Number, μ::Number, σ::Number)
Returns the gaussian function $\exp \left[- \frac{(x - \mu)^2}{2 \sigma^2} \right]$, where $\mu$ and $\sigma^2$ are the mean and the variance respectively.
QuantumToolbox.ptrace
— Functionptrace(QO::QuantumObject, sel::Vector{Int})
Partial trace of a quantum state QO
leaving only the dimensions with the indices present in the sel
vector.
Examples
Two qubits in the state $\ket{\psi} = \ket{e,g}$:
julia> ψ = kron(fock(2,0), fock(2,1))
Quantum Object: type=Ket dims=[2, 2] size=(4,)
4-element Vector{ComplexF64}:
0.0 + 0.0im
1.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
julia> ptrace(ψ, [2])
Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=true
2×2 Matrix{ComplexF64}:
0.0+0.0im 0.0+0.0im
0.0+0.0im 1.0+0.0im
or in an entangled state $\ket{\psi} = \frac{1}{\sqrt{2}} \left( \ket{e,e} + \ket{g,g} \right)$:
julia> ψ = 1 / √2 * (kron(fock(2,0), fock(2,0)) + kron(fock(2,1), fock(2,1)))
Quantum Object: type=Ket dims=[2, 2] size=(4,)
4-element Vector{ComplexF64}:
0.7071067811865475 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.7071067811865475 + 0.0im
julia> ptrace(ψ, [1])
Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=true
2×2 Matrix{ComplexF64}:
0.5+0.0im 0.0+0.0im
0.0+0.0im 0.5+0.0im
QuantumToolbox.partial_transpose
— Functionpartial_transpose(ρ::QuantumObject, mask::Vector{Bool})
Return the partial transpose of a density matrix $\rho$, where mask
is an array/vector with length that equals the length of ρ.dims
. The elements in mask
are boolean (true
or false
) which indicates whether or not the corresponding subsystem should be transposed.
Arguments
ρ::QuantumObject
: The density matrix (ρ.type
must beOperatorQuantumObject
).mask::Vector{Bool}
: A boolean vector selects which subsystems should be transposed.
Returns
ρ_pt::QuantumObject
: The density matrix with the selected subsystems transposed.
QuantumToolbox.negativity
— Functionnegativity(ρ::QuantumObject, subsys::Int; logarithmic::Bool=false)
Compute the negativity $N(\rho) = \frac{\Vert \rho^{\Gamma}\Vert_1 - 1}{2}$ where $\rho^{\Gamma}$ is the partial transpose of $\rho$ with respect to the subsystem, and $\Vert X \Vert_1=\Tr\sqrt{X^\dagger X}$ is the trace norm.
Arguments
ρ::QuantumObject
: The density matrix (ρ.type
must beOperatorQuantumObject
).subsys::Int
: an index that indicates which subsystem to compute the negativity for.logarithmic::Bool
: choose whether to calculate logarithmic negativity or not. Default asfalse
Returns
N::Real
: The value of negativity.
Examples
julia> Ψ = 1 / √2 * ( basis(2,0) ⊗ basis(2,0) + basis(2,1) ⊗ basis(2,1) )
Quantum Object: type=Ket dims=[2, 2] size=(4,)
4-element Vector{ComplexF64}:
0.7071067811865475 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.7071067811865475 + 0.0im
julia> ρ = ket2dm(Ψ)
Quantum Object: type=Operator dims=[2, 2] size=(4, 4) ishermitian=true
4×4 Matrix{ComplexF64}:
0.5+0.0im 0.0+0.0im 0.0+0.0im 0.5+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.5+0.0im 0.0+0.0im 0.0+0.0im 0.5+0.0im
julia> negativity(ρ, 2)
0.4999999999999998
QuantumToolbox.entropy_vn
— Functionentropy_vn(ρ::QuantumObject; base::Int=0, tol::Real=1e-15)
Calculates the Von Neumann entropy $S = - \Tr \left[ \hat{\rho} \log \left( \hat{\rho} \right) \right]$ where $\hat{\rho}$ is the density matrix of the system.
The base
parameter specifies the base of the logarithm to use, and when using the default value 0, the natural logarithm is used. The tol
parameter describes the absolute tolerance for detecting the zero-valued eigenvalues of the density matrix $\hat{\rho}$.
Examples
Pure state:
julia> ψ = fock(2,0)
Quantum Object: type=Ket dims=[2] size=(2,)
2-element Vector{ComplexF64}:
1.0 + 0.0im
0.0 + 0.0im
julia> ρ = ket2dm(ψ)
Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=true
2×2 Matrix{ComplexF64}:
1.0+0.0im 0.0+0.0im
0.0+0.0im 0.0+0.0im
julia> entropy_vn(ρ, base=2)
-0.0
Mixed state:
julia> ρ = 1 / 2 * ( ket2dm(fock(2,0)) + ket2dm(fock(2,1)) )
Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=true
2×2 Matrix{ComplexF64}:
0.5+0.0im 0.0+0.0im
0.0+0.0im 0.5+0.0im
julia> entropy_vn(ρ, base=2)
1.0
QuantumToolbox.entanglement
— Functionentanglement(QO::QuantumObject, sel::Vector)
Calculates the entanglement by doing the partial trace of QO
, selecting only the dimensions with the indices contained in the sel
vector, and then using the Von Neumann entropy entropy_vn
.
QuantumToolbox.expect
— Functionexpect(O::QuantumObject, ψ::QuantumObject)
Expectation value of the operator O
with the state ψ
. The latter can be a KetQuantumObject
, BraQuantumObject
or a OperatorQuantumObject
. If ψ
is a density matrix, the function calculates $\Tr \left[ \hat{O} \hat{\psi} \right]$, while if ψ
is a state, the function calculates $\mel{\psi}{\hat{O}}{\psi}$.
The function returns a real number if the operator is hermitian, and returns a complex number otherwise.
Examples
julia> ψ = 1 / √2 * (fock(10,2) + fock(10,4));
julia> a = destroy(10);
julia> expect(a' * a, ψ) ≈ 3
true
QuantumToolbox.wigner
— Functionwigner(state::QuantumObject, xvec::AbstractVector, yvec::AbstractVector; g::Real=√2,
solver::WignerSolver=WignerLaguerre())
Generates the Wigner quasipropability distribution of state
at points xvec + 1im * yvec
. The g
parameter is a scaling factor related to the value of $\hbar$ in the commutation relation $[x, y] = i \hbar$ via $\hbar=2/g^2$ giving the default value $\hbar=1$.
The solver
parameter can be either WignerLaguerre()
or WignerClenshaw()
. The former uses the Laguerre polynomial expansion of the Wigner function, while the latter uses the Clenshaw algorithm. The Laguerre expansion is faster for sparse matrices, while the Clenshaw algorithm is faster for dense matrices. The WignerLaguerre
solver has an optional parallel
parameter which defaults to true
and uses multithreading to speed up the calculation.
QuantumToolbox.get_coherence
— Functionget_coherence(ψ::QuantumObject)
Get the coherence value $\alpha$ by measuring the expectation value of the destruction operator $\hat{a}$ on the state $\ket{\psi}$.
It returns both $\alpha$ and the state $\ket{\delta_\psi} = \exp ( \bar{\alpha} \hat{a} - \alpha \hat{a}^\dagger )$. The latter corresponds to the quantum fulctuations around the coherent state $\ket{\alpha}$.
QuantumToolbox.n_th
— Functionn_th(ω::Number, T::Real)
Gives the mean number of excitations in a mode with frequency ω at temperature T: $n_{\rm th} (\omega, T) = \frac{1}{e^{\omega/T} - 1}$
QuantumToolbox.get_data
— Functionget_data(A::QuantumObject)
Returns the data of a QuantumObject.
QuantumToolbox.mat2vec
— Functionmat2vec(A::AbstractMatrix)
Converts a matrix to a vector.
mat2vec(A::QuantumObject)
Convert a quantum object from matrix (OperatorQuantumObject
-type) to vector (OperatorKetQuantumObject
-type)
QuantumToolbox.vec2mat
— Functionvec2mat(A::AbstractVector)
Converts a vector to a matrix.
vec2mat(A::QuantumObject)
Convert a quantum object from vector (OperatorKetQuantumObject
-type) to matrix (OperatorQuantumObject
-type)
Quantum states, operators and super-operators
QuantumToolbox.spre
— Functionspre(O::QuantumObject, Id_cache=I(size(O,1)))
Returns the super-operator form of O
acting on the left of the density matrix operator, $\mathcal{O} \left(\hat{O}\right) \left[ \hat{\rho} \right] = \hat{O} \hat{\rho}$.
Since the density matrix is vectorized, this super-operator is always a matrix, obtained from $\mathcal{O} \left(\hat{O}\right) \boldsymbol{\cdot} = \hat{\mathbb{1}} \otimes \hat{O}$.
The optional argument Id_cache
can be used to pass a precomputed identity matrix. This can be useful when the same function is applied multiple times with a known Hilbert space dimension.
QuantumToolbox.spost
— Functionspost(O::QuantumObject)
Returns the super-operator form of O
acting on the right of the density matrix operator, $\mathcal{O} \left(\hat{O}\right) \left[ \hat{\rho} \right] = \hat{\rho} \hat{O}$.
Since the density matrix is vectorized, this super-operator is always a matrix, obtained from $\mathcal{O} \left(\hat{O}\right) \boldsymbol{\cdot} = \hat{O}^T \otimes \hat{\mathbb{1}}$.
The optional argument Id_cache
can be used to pass a precomputed identity matrix. This can be useful when the same function is applied multiple times with a known Hilbert space dimension.
QuantumToolbox.sprepost
— Functionsprepost(A::QuantumObject, B::QuantumObject)
Returns the super-operator form of A
and B
acting on the left and the right of the density matrix operator respectively, $\mathcal{O} \left( \hat{A}, \hat{B} \right) \left[ \hat{\rho} \right] = \hat{A} \hat{\rho} \hat{B}$.
Since the density matrix is vectorized, this super-operator is always a matrix, obtained from $\mathcal{O} \left(\hat{A}, \hat{B}\right) \boldsymbol{\cdot} = \text{spre}(A) * \text{spost}(B)$.
QuantumToolbox.lindblad_dissipator
— Functionlindblad_dissipator(O::QuantumObject, Id_cache=I(size(O,1))
Returns the Lindblad super-operator defined as $\mathcal{D} \left( \hat{O} \right) \left[ \hat{\rho} \right] = \frac{1}{2} \left( 2 \hat{O} \hat{\rho} \hat{O}^\dagger - \hat{O}^\dagger \hat{O} \hat{\rho} - \hat{\rho} \hat{O}^\dagger \hat{O} \right)$ considering the density matrix $\hat{\rho}$ in the vectorized form.
The optional argument Id_cache
can be used to pass a precomputed identity matrix. This can be useful when the same function is applied multiple times with a known Hilbert space dimension.
QuantumToolbox.destroy
— Functiondestroy(N::Int)
Bosonic annihilation operator with Hilbert space cutoff N
. This operator acts on a fock state as $\hat{a} \ket{n} = \sqrt{n} \ket{n-1}$.
Examples
julia> a = destroy(20)
Quantum Object: type=Operator dims=[20] size=(20, 20) ishermitian=false
20×20 SparseMatrixCSC{ComplexF64, Int64} with 19 stored entries:
⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠈⠢⡀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠈⠢⡀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠈⠢⡀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢
julia> fock(20, 3)' * a * fock(20, 4)
2.0 + 0.0im
QuantumToolbox.create
— Functioncreate(N::Int)
Bosonic creation operator with Hilbert space cutoff N
. This operator acts on a fock state as $\hat{a}^\dagger \ket{n} = \sqrt{n+1} \ket{n+1}$.
Examples
julia> a_d = create(20)
Quantum Object: type=Operator dims=[20] size=(20, 20) ishermitian=false
20×20 SparseMatrixCSC{ComplexF64, Int64} with 19 stored entries:
⠢⡀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠈⠢⡀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠈⠢⡀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠈⠢⡀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠈⠢⡀
julia> fock(20, 4)' * a_d * fock(20, 3)
2.0 + 0.0im
QuantumToolbox.sigmap
— Functionsigmap()
Pauli ladder operator $\hat{\sigma}_+ = \hat{\sigma}_x + i \hat{\sigma}_y$.
QuantumToolbox.sigmam
— Functionsigmam()
Pauli ladder operator $\hat{\sigma}_- = \hat{\sigma}_x - i \hat{\sigma}_y$.
QuantumToolbox.sigmax
— Functionsigmax()
Pauli operator $\hat{\sigma}_x = \hat{\sigma}_- + \hat{\sigma}_+$.
QuantumToolbox.sigmay
— Functionsigmay()
Pauli operator $\hat{\sigma}_y = i \left( \hat{\sigma}_- - \hat{\sigma}_+ \right)$.
QuantumToolbox.sigmaz
— Functionsigmaz()
Pauli operator $\hat{\sigma}_z = \comm{\hat{\sigma}_+}{\hat{\sigma}_-}$.
QuantumToolbox.eye
— Functioneye(N::Int; type=OperatorQuantumObject, dims=[N])
Identity operator $\hat{\mathbb{1}}$ with Hilbert dimension N
.
QuantumToolbox.qeye
— Functionqeye(N::Int; type=OperatorQuantumObject, dims=[N])
Identity operator $\hat{\mathbb{1}}$ with Hilbert dimension N
.
QuantumToolbox.fock
— Functionfock(N::Int, pos::Int; dims::Vector{Int}=[N], sparse::Bool=false)
Generates a fock state $\ket{\psi}$ of dimension N
. It is also possible to specify the list of dimensions dims
if different subsystems are present.
QuantumToolbox.basis
— Functionbasis(N::Int, pos::Int; dims::Vector{Int}=[N])
Generates a fock state like fock
.
QuantumToolbox.coherent
— Functioncoherent(N::Real, α::T)
Generates a coherent state $\ket{\alpha}$, which is defined as an eigenvector of the bosonic annihilation operator $\hat{a} \ket{\alpha} = \alpha \ket{\alpha}$.
QuantumToolbox.rand_dm
— Functionrand_dm(N::Integer; kwargs...)
Generates a random density matrix $\hat{\rho}$, with the property to be positive definite, and that $\Tr \left[ \hat{\rho} \right] = 1$.
QuantumToolbox.projection
— Functionprojection(N::Int, i::Int, j::Int)
Generates the projection operator $\hat{O} = \dyad{i}{j}$ with Hilbert space dimension N
.
QuantumToolbox.sinm
— Functionsinm(O::QuantumObject)
Generates the sine of the operator O
, defined as
$\sin \left( \hat{O} \right) = \frac{e^{i \hat{O}} - e^{-i \hat{O}}}{2 i}$
QuantumToolbox.cosm
— Functioncosm(O::QuantumObject)
Generates the cosine of the operator O
, defined as
$\cos \left( \hat{O} \right) = \frac{e^{i \hat{O}} + e^{-i \hat{O}}}{2}$
Time evolution
QuantumToolbox.sesolveProblem
— FunctionsesolveProblem(H::QuantumObject,
ψ0::QuantumObject,
t_l::AbstractVector;
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5()
e_ops::AbstractVector=[],
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
progress_bar::Bool=true,
kwargs...)
Generates the ODEProblem for the Schrödinger time evolution of a quantum system.
Arguments
H::QuantumObject
: The Hamiltonian of the system.ψ0::QuantumObject
: The initial state of the system.t_l::AbstractVector
: The time list of the evolution.alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm
: The algorithm used for the time evolution.e_ops::AbstractVector
: The list of operators to be evaluated during the evolution.H_t::Union{Nothing,Function,TimeDependentOperatorSum}
: The time-dependent Hamiltonian of the system. Ifnothing
, the Hamiltonian is time-independent.params::NamedTuple
: The parameters of the system.progress_bar::Bool
: Whether to show the progress bar.kwargs...
: The keyword arguments passed to theODEProblem
constructor.
Returns
prob
: TheODEProblem
for the Schrödinger time evolution of the system.
QuantumToolbox.mesolveProblem
— FunctionmesolveProblem(H::QuantumObject,
ψ0::QuantumObject,
t_l::AbstractVector, c_ops::AbstractVector=[];
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::AbstractVector=[],
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
progress_bar::Bool=true,
kwargs...)
Generates the ODEProblem for the master equation time evolution of an open quantum system.
Arguments
H::QuantumObject
: The Hamiltonian or the Liouvillian of the system.ψ0::QuantumObject
: The initial state of the system.t_l::AbstractVector
: The time list of the evolution.c_ops::AbstractVector=[]
: The list of the collapse operators.alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5()
: The algorithm used for the time evolution.e_ops::AbstractVector=[]
: The list of the operators for which the expectation values are calculated.H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing
: The time-dependent Hamiltonian or Liouvillian.params::NamedTuple=NamedTuple()
: The parameters of the time evolution.progress_bar::Bool=true
: Whether to show the progress bar.kwargs...
: The keyword arguments for the ODEProblem.
Returns
prob::ODEProblem
: The ODEProblem for the master equation time evolution.
QuantumToolbox.lr_mesolveProblem
— Functionlr_mesolveProblem(H, z, B, t_l, c_ops; e_ops=(), f_ops=(), opt=LRMesolveOptions(), kwargs...) where T
Formulates the ODEproblem for the low-rank time evolution of the system. The function is called by lr_mesolve.
Parameters
----------
H : QuantumObject
The Hamiltonian of the system.
z : AbstractMatrix{T}
The initial z matrix.
B : AbstractMatrix{T}
The initial B matrix.
t_l : AbstractVector{T}
The time steps at which the expectation values and function values are calculated.
c_ops : AbstractVector{QuantumObject}
The jump operators of the system.
e_ops : Tuple{QuantumObject}
The operators whose expectation values are calculated.
f_ops : Tuple{Function}
The functions whose values are calculated.
opt : LRMesolveOptions
The options of the problem.
kwargs : NamedTuple
Additional keyword arguments for the ODEProblem.
QuantumToolbox.mcsolveProblem
— FunctionmcsolveProblem(H::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject},
ψ0::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
t_l::AbstractVector,
c_ops::Vector{QuantumObject{Tc, OperatorQuantumObject}}=QuantumObject{Matrix, OperatorQuantumObject}[];
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::Vector{QuantumObject{Te, OperatorQuantumObject}}=QuantumObject{Matrix, OperatorQuantumObject}[],
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
jump_callback::TJC=ContinuousLindbladJumpCallback(),
kwargs...)
Generates the ODEProblem for a single trajectory of the Monte Carlo wave function time evolution of an open quantum system.
Arguments
H::QuantumObject
: Hamiltonian of the system.ψ0::QuantumObject
: Initial state of the system.t_l::AbstractVector
: List of times at which to save the state of the system.c_ops::Vector
: List of collapse operators.alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm
: Algorithm to use for the time evolution.e_ops::Vector
: List of operators for which to calculate expectation values.H_t::Union{Nothing,Function,TimeDependentOperatorSum}
: Time-dependent part of the Hamiltonian.params::NamedTuple
: Dictionary of parameters to pass to the solver.seeds::Union{Nothing, Vector{Int}}
: List of seeds for the random number generator. Length must be equal to the number of trajectories provided.jump_callback::LindbladJumpCallbackType
: The Jump Callback type: Discrete or Continuous.kwargs...
: Additional keyword arguments to pass to the solver.
Returns
prob::ODEProblem
: The ODEProblem for the Monte Carlo wave function time evolution.
QuantumToolbox.mcsolveEnsembleProblem
— FunctionmcsolveEnsembleProblem(H::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject},
ψ0::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
t_l::AbstractVector,
c_ops::Vector{QuantumObject{Tc, OperatorQuantumObject}}=QuantumObject{Matrix, OperatorQuantumObject}[];
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::Vector{QuantumObject{Te, OperatorQuantumObject}}=QuantumObject{Matrix, OperatorQuantumObject}[],
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
jump_callback::TJC=ContinuousLindbladJumpCallback(),
prob_func::Function=_mcsolve_prob_func,
output_func::Function=_mcsolve_output_func,
kwargs...)
Generates the ODEProblem for an ensemble of trajectories of the Monte Carlo wave function time evolution of an open quantum system.
Arguments
H::QuantumObject
: Hamiltonian of the system.ψ0::QuantumObject
: Initial state of the system.t_l::AbstractVector
: List of times at which to save the state of the system.c_ops::Vector
: List of collapse operators.alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm
: Algorithm to use for the time evolution.e_ops::Vector
: List of operators for which to calculate expectation values.H_t::Union{Nothing,Function,TimeDependentOperatorSum}
: Time-dependent part of the Hamiltonian.params::NamedTuple
: Dictionary of parameters to pass to the solver.seeds::Union{Nothing, Vector{Int}}
: List of seeds for the random number generator. Length must be equal to the number of trajectories provided.jump_callback::LindbladJumpCallbackType
: The Jump Callback type: Discrete or Continuous.prob_func::Function
: Function to use for generating the ODEProblem.output_func::Function
: Function to use for generating the output of a single trajectory.kwargs...
: Additional keyword arguments to pass to the solver.
Returns
prob::EnsembleProblem with ODEProblem
: The Ensemble ODEProblem for the Monte Carlo
wave function time evolution.
QuantumToolbox.sesolve
— Functionsesolve(H::QuantumObject,
ψ0::QuantumObject,
t_l::AbstractVector;
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::AbstractVector=[],
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
progress_bar::Bool=true,
kwargs...)
Time evolution of a closed quantum system using the Schrödinger equation.
Arguments
H::QuantumObject
: Hamiltonian of the system.ψ0::QuantumObject
: Initial state of the system.t_l::AbstractVector
: List of times at which to save the state of the system.alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm
: Algorithm to use for the time evolution.e_ops::AbstractVector
: List of operators for which to calculate expectation values.H_t::Union{Nothing,Function,TimeDependentOperatorSum}
: Time-dependent part of the Hamiltonian.params::NamedTuple
: Dictionary of parameters to pass to the solver.progress_bar::Bool
: Whether to show the progress bar.kwargs...
: Additional keyword arguments to pass to the solver.Returns
sol::TimeEvolutionSol
: The solution of the time evolution.
QuantumToolbox.mesolve
— Functionmesolve(H::QuantumObject,
ψ0::QuantumObject,
t_l::AbstractVector, c_ops::AbstractVector=[];
alg::OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::AbstractVector=[],
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
progress_bar::Bool=true,
kwargs...)
Time evolution of an open quantum system using master equation.
Arguments
H::QuantumObject
: Hamiltonian of Liouvillian of the system.ψ0::QuantumObject
: Initial state of the system.t_l::AbstractVector
: List of times at which to save the state of the system.c_ops::AbstractVector
: List of collapse operators.alg::OrdinaryDiffEqAlgorithm
: Algorithm to use for the time evolution.e_ops::AbstractVector
: List of operators for which to calculate expectation values.H_t::Union{Nothing,Function,TimeDependentOperatorSum}
: Time-dependent part of the Hamiltonian.params::NamedTuple
: Named Tuple of parameters to pass to the solver.progress_bar::Bool
: Whether to show the progress bar.kwargs...
: Additional keyword arguments to pass to the solver.
Returns
sol::TimeEvolutionSol
: The solution of the time evolution.
QuantumToolbox.lr_mesolve
— Functionlr_mesolve(prob::ODEProblem; kwargs...)
Solves the ODEProblem formulated by lr_mesolveProblem. The function is called by lr_mesolve.
Parameters
----------
prob : ODEProblem
The ODEProblem formulated by lr_mesolveProblem.
kwargs : NamedTuple
Additional keyword arguments for the ODEProblem.
QuantumToolbox.mcsolve
— Functionmcsolve(H::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject},
ψ0::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
t_l::AbstractVector,
c_ops::Vector{QuantumObject{Tc, OperatorQuantumObject}}=QuantumObject{Matrix, OperatorQuantumObject}[];
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::Vector{QuantumObject{Te, OperatorQuantumObject}}=QuantumObject{Matrix, OperatorQuantumObject}[],
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
n_traj::Int=1,
ensemble_method=EnsembleThreads(),
jump_callback::TJC=ContinuousLindbladJumpCallback(),
kwargs...)
Time evolution of an open quantum system using quantum trajectories.
Arguments
H::QuantumObject
: Hamiltonian of the system.ψ0::QuantumObject
: Initial state of the system.t_l::AbstractVector
: List of times at which to save the state of the system.c_ops::Vector
: List of collapse operators.alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm
: Algorithm to use for the time evolution.e_ops::Vector
: List of operators for which to calculate expectation values.H_t::Union{Nothing,Function,TimeDependentOperatorSum}
: Time-dependent part of the Hamiltonian.params::NamedTuple
: Dictionary of parameters to pass to the solver.seeds::Union{Nothing, Vector{Int}}
: List of seeds for the random number generator. Length must be equal to the number of trajectories provided.n_traj::Int
: Number of trajectories to use.ensemble_method
: Ensemble method to use.jump_callback::LindbladJumpCallbackType
: The Jump Callback type: Discrete or Continuous.prob_func::Function
: Function to use for generating the ODEProblem.output_func::Function
: Function to use for generating the output of a single trajectory.kwargs...
: Additional keyword arguments to pass to the solver.
Returns
sol::TimeEvolutionMCSol
: The solution of the time evolution.
Notes
ensemble_method
can be one of EnsembleThreads()
, EnsembleSerial()
, EnsembleDistributed()
.
QuantumToolbox.dfd_mesolve
— Functionfunction dfd_mesolve(H::Function, ψ0::QuantumObject,
t_l::AbstractVector, c_ops::Function, maxdims::AbstractVector,
dfd_params::NamedTuple=NamedTuple();
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::Function=(dim_list) -> Vector{Vector{T1}}([]),
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
tol_list::Vector{<:Number}=fill(1e-8, length(maxdims)),
kwargs...)
Time evolution of an open quantum system using master equation, dynamically changing the dimension of the Hilbert subspaces.
QuantumToolbox.dsf_mesolve
— Functionfunction dsf_mesolve(H::Function,
ψ0::QuantumObject,
t_l::AbstractVector, c_ops::Function,
op_list::Vector{TOl},
α0_l::Vector{<:Number}=zeros(length(op_list)),
dsf_params::NamedTuple=NamedTuple();
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::Function=(op_list,p) -> Vector{TOl}([]),
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
δα_list::Vector{<:Number}=fill(0.2, length(op_list)),
krylov_dim::Int=min(5,cld(length(ket2dm(ψ0).data), 3)),
kwargs...)
Time evolution of an open quantum system using master equation and the Dynamical Shifted Fock algorithm.
QuantumToolbox.dsf_mcsolve
— Functionfunction dsf_mcsolve(H::Function,
ψ0::QuantumObject,
t_l::AbstractVector, c_ops::Function,
op_list::Vector{TOl},
α0_l::Vector{<:Number}=zeros(length(op_list)),
dsf_params::NamedTuple=NamedTuple();
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::Function=(op_list,p) -> Vector{TOl}([]),
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
δα_list::Vector{<:Real}=fill(0.2, length(op_list)),
n_traj::Int=1,
ensemble_method=EnsembleThreads(),
jump_callback::LindbladJumpCallbackType=ContinuousLindbladJumpCallback(),
krylov_dim::Int=min(5,cld(length(ψ0.data), 3)),
kwargs...)
Time evolution of a quantum system using the Monte Carlo wave function method and the Dynamical Shifted Fock algorithm.
QuantumToolbox.liouvillian
— Functionliouvillian(H::QuantumObject, c_ops::AbstractVector, Id_cache=I(prod(H.dims))
Construct the Liouvillian superoperator for a system Hamiltonian and a set of collapse operators: $\mathcal{L} \cdot = -i[\hat{H}, \cdot] + \sum_i \mathcal{D}[\hat{O}_i] \cdot$, where $\mathcal{D}[\hat{O}_i] \cdot = \hat{O}_i \cdot \hat{O}_i^\dagger - \frac{1}{2} \hat{O}_i^\dagger \hat{O}_i \cdot - \frac{1}{2} \cdot \hat{O}_i^\dagger \hat{O}_i$.
The optional argument Id_cache
can be used to pass a precomputed identity matrix. This can be useful when the same function is applied multiple times with a known Hilbert space dimension.
QuantumToolbox.liouvillian_generalized
— Functionliouvillian_generalized(H::QuantumObject, fields::Vector,
T_list::Vector; N_trunc::Int=size(H,1), tol::Float64=0.0, σ_filter::Union{Nothing, Real}=nothing)
Constructs the generalized Liouvillian for a system coupled to a bath of harmonic oscillators.
See, e.g., Settineri, Alessio, et al. "Dissipation and thermal noise in hybrid quantum systems in the ultrastrong-coupling regime." Physical Review A 98.5 (2018): 053834.
QuantumToolbox.steadystate_floquet
— Functionsteadystate_floquet(H_0::QuantumObject,
c_ops::Vector, H_p::QuantumObject,
H_m::QuantumObject,
ω::Real; n_max::Int=4, lf_solver::LSolver=LiouvillianDirectSolver(),
ss_solver::Type{SSSolver}=SteadyStateDirectSolver)
Calculates the steady state of a periodically driven system. Here H_0
is the Hamiltonian or the Liouvillian of the undriven system. Considering a monochromatic drive at frequency $\\omega$, we divide it into two parts, H_p
and H_m
, where H_p
oscillates as $e^{i \\omega t}$ and H_m
oscillates as $e^{-i \\omega t}$. n_max
is the number of iterations used to obtain the effective Liouvillian, lf_solver
is the solver used to solve the effective Liouvillian, and ss_solver
is the solver used to solve the steady state.
Correlations and Spectrum
QuantumToolbox.correlation_3op_2t
— Functioncorrelation_3op_2t(H::QuantumObject,
ψ0::QuantumObject,
t_l::AbstractVector,
τ_l::AbstractVector,
A::QuantumObject,
B::QuantumObject,
C::QuantumObject,
c_ops::AbstractVector=[];
kwargs...)
Returns the two-times correlation function of three operators $\hat{A}$, $\hat{B}$ and $\hat{C}$: $\expval{\hat{A}(t) \hat{B}(t + \tau) \hat{C}(t)}$ for a given initial state $\ket{\psi_0}$.
QuantumToolbox.correlation_2op_2t
— Functioncorrelation_2op_2t(H::QuantumObject,
ψ0::QuantumObject,
t_l::AbstractVector,
τ_l::AbstractVector,
A::QuantumObject,
B::QuantumObject,
c_ops::AbstractVector=[];
reverse::Bool=false,
kwargs...)
Returns the two-times correlation function of two operators $\hat{A}$ and $\hat{B}$at different times
\expval{\hat{A}(t + \tau) \hat{B}(t)}
. When
reverse=true
, the correlation function is calculated as
\expval{\hat{A}(t) \hat{B}(t + \tau)}
`.
QuantumToolbox.correlation_2op_1t
— Functioncorrelation_2op_1t(H::QuantumObject,
ψ0::QuantumObject,
τ_l::AbstractVector,
A::QuantumObject,
B::QuantumObject,
c_ops::AbstractVector=[];
reverse::Bool=false,
kwargs...)
Returns the one-time correlation function of two operators $\hat{A}$ and $\hat{B}$ at different times $\expval{\hat{A}(\tau) \hat{B}(0)}$. When $reverse=true$, the correlation function is calculated as $\expval{\hat{A}(0) \hat{B}(\tau)}$.
QuantumToolbox.spectrum
— Functionspectrum(H::QuantumObject,
ω_list::AbstractVector,
A::QuantumObject{<:AbstractArray{T2},OperatorQuantumObject},
B::QuantumObject{<:AbstractArray{T3},OperatorQuantumObject},
c_ops::AbstractVector=[];
solver::MySolver=ExponentialSeries(),
kwargs...)
Returns the emission spectrum $S(\omega) = \int_{-\infty}^\infty \expval{\hat{A}(\tau) \hat{B}(0)} e^{-i \omega \tau} d \tau$.
Eigenvalues and eigenvectors
LinearAlgebra.eigen
— FunctionLinearAlgebra.eigen(A::QuantumObject; kwargs...)
Calculates the eigenvalues and eigenvectors of the QuantumObject
A
using the Julia LinearAlgebra package.
julia> a = destroy(5);
julia> H = a + a'
Quantum Object: type=Operator dims=[5] size=(5, 5) ishermitian=true
5×5 SparseMatrixCSC{ComplexF64, Int64} with 8 stored entries:
⋅ 1.0+0.0im ⋅ ⋅ ⋅
1.0+0.0im ⋅ 1.41421+0.0im ⋅ ⋅
⋅ 1.41421+0.0im ⋅ 1.73205+0.0im ⋅
⋅ ⋅ 1.73205+0.0im ⋅ 2.0+0.0im
⋅ ⋅ ⋅ 2.0+0.0im ⋅
julia> E, U = eigen(H)
Eigen{ComplexF64, Float64, Matrix{ComplexF64}, Vector{Float64}}
values:
5-element Vector{Float64}:
-2.8569700138728
-1.3556261799742608
1.3322676295501878e-15
1.3556261799742677
2.8569700138728056
vectors:
5×5 Matrix{ComplexF64}:
0.106101+0.0im -0.471249-0.0im … 0.471249-0.0im 0.106101-0.0im
-0.303127-0.0im 0.638838+0.0im 0.638838+0.0im 0.303127-0.0im
0.537348+0.0im -0.279149-0.0im 0.279149-0.0im 0.537348-0.0im
-0.638838-0.0im -0.303127-0.0im -0.303127-0.0im 0.638838+0.0im
0.447214+0.0im 0.447214+0.0im -0.447214-0.0im 0.447214-0.0im
julia> ψ_1 = QuantumObject(U[:,1], dims=H.dims);
julia> expect(H, ψ_1) ≈ E[1]
true
LinearAlgebra.eigvals
— FunctionLinearAlgebra.eigvals(A::QuantumObject; kwargs...)
Same as eigen(A::QuantumObject; kwargs...)
but for only the eigenvalues.
QuantumToolbox.eigsolve
— Functionfunction eigsolve(A::QuantumObject; v0::Union{Nothing,AbstractVector}=nothing,
sigma::Union{Nothing, Real}=nothing, k::Int = min(4, size(A, 1)),
krylovdim::Int = min(10, size(A, 1)), tol::Real = 1e-8, maxiter::Int = 200,
solver::Union{Nothing, LinearSolve.SciMLLinearSolveAlgorithm} = nothing, kwargs...)
Solve for the eigenvalues and eigenvectors of a matrix A
using the Arnoldi method. The keyword arguments are passed to the linear solver.
QuantumToolbox.eigsolve_al
— Functioneigsolve_al(H::QuantumObject,
T::Real, c_ops::AbstractVector=[];
alg::OrdinaryDiffEqAlgorithm=Tsit5(),
H_t::Union{Nothing,Function}=nothing,
params::NamedTuple=NamedTuple(),
ρ0::Union{Nothing, AbstractMatrix} = nothing,
k::Int=1,
krylovdim::Int=min(10, size(H, 1)),
maxiter::Int=200,
eigstol::Real=1e-6,
kwargs...)
Solve the eigenvalue problem for a Liouvillian superoperator L
using the Arnoldi-Lindblad method.
Arguments
H
: The Hamiltonian (or directly the Liouvillian) of the system.T
: The time at which to evaluate the time evolutionc_ops
: A vector of collapse operatorsalg
: The differential equation solver algorithmH_t
: A functionH_t(t)
that returns the additional term at timet
params
: A dictionary of additional parametersρ0
: The initial density matrix. If not specified, a random density matrix is usedk
: The number of eigenvalues to computekrylovdim
: The dimension of the Krylov subspacemaxiter
: The maximum number of iterations for the eigsolvereigstol
: The tolerance for the eigsolverkwargs
: Additional keyword arguments passed to the differential equation solver
Returns
EigsolveResult
: A struct containing the eigenvalues, the eigenvectors, and some information about the eigsolver
References
- [1] Minganti, F., & Huybrechts, D. (2022). Arnoldi-Lindblad time evolution:
Faster-than-the-clock algorithm for the spectrum of time-independent and Floquet open quantum systems. Quantum, 6, 649.
Low Rank internal APIs
QuantumToolbox._calculate_expectation!
— Function_calculate_expectation!(p,z,B,idx) where T
Calculates the expectation values and function values of the operators and functions in p.e_ops and p.f_ops, respectively, and stores them in p.expvals and p.funvals.
The function is called by the callback _save_affect_lr_mesolve!.
Parameters
----------
p : NamedTuple
The parameters of the problem.
z : AbstractMatrix{T}
The z matrix.
B : AbstractMatrix{T}
The B matrix.
idx : Integer
The index of the current time step.
QuantumToolbox._adjM_condition_variational
— Function_adjM_condition_variational(u, t, integrator) where T
Condition for the dynamical rank adjustment based on the leakage out of the low-rank manifold.
Parameters
----------
u : AbstractVector{T}
The current state of the system.
t : Real
The current time.
integrator : ODEIntegrator
The integrator of the problem.
QuantumToolbox._adjM_affect!
— Function_adjM_affect!(integrator)
Affect function for the dynamical rank adjustment. It increases the rank of the low-rank manifold by one, and updates the matrices accordingly.
If Δt>0, it rewinds the integrator to the previous time step.
Parameters
----------
integrator : ODEIntegrator
The integrator of the problem.
QuantumToolbox._adjM_condition_ratio
— Function_adjM_condition_ratio(u, t, integrator) where T
Condition for the dynamical rank adjustment based on the ratio between the smallest and largest eigenvalues of the density matrix.
The spectrum of the density matrix is calculated efficiently using the properties of the SVD decomposition of the matrix.
Parameters
----------
u : AbstractVector{T}
The current state of the system.
t : Real
The current time.
integrator : ODEIntegrator
The integrator of the problem.
QuantumToolbox._pinv!
— Function_pinv!(A, T1, T2; atol::Real=0.0, rtol::Real=(eps(real(float(oneunit(T))))*min(size(A)...))*iszero(atol)) where T
Computes the pseudo-inverse of a matrix A, and stores it in T1. If T2 is provided, it is used as a temporary matrix.
The algorithm is based on the SVD decomposition of A, and is taken from the Julia package LinearAlgebra.
The difference with respect to the original function is that the cutoff is done with a smooth function instead of a step function.
Parameters
----------
A : AbstractMatrix{T}
The matrix to be inverted.
T1 : AbstractMatrix{T}
T2 : AbstractMatrix{T}
Temporary matrices used in the calculation.
atol : Real
Absolute tolerance for the calculation of the pseudo-inverse.
rtol : Real
Relative tolerance for the calculation of the pseudo-inverse.
QuantumToolbox.dBdz!
— FunctiondBdz!(du, u, p, t) where T
Dynamical evolution equations for the low-rank manifold. The function is called by the ODEProblem.
Parameters
----------
du : AbstractVector{T}
The derivative of the state of the system.
u : AbstractVector{T}
The current state of the system.
p : NamedTuple
The parameters of the problem.
t : Real
The current time.