Skip to content

Commit

Permalink
Merge pull request #65 from ytdHuang/dev/Qobj-type
Browse files Browse the repository at this point in the history
Abbreviated constants for all `QuantumObjectType`
  • Loading branch information
ytdHuang committed Apr 8, 2024
2 parents 131f81c + 3f69a27 commit a986c50
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 48 deletions.
6 changes: 6 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@ CurrentModule = QuantumToolbox

```@docs
BraQuantumObject
Bra
KetQuantumObject
Ket
OperatorQuantumObject
Operator
OperatorBraQuantumObject
OperatorBra
OperatorKetQuantumObject
OperatorKet
SuperOperatorQuantumObject
SuperOperator
QuantumObject
Qobj
ket2dm
Expand Down
1 change: 1 addition & 0 deletions src/QuantumToolbox.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ include("negativity.jl")
include("progress_bar.jl")

export QuantumObject, Qobj, BraQuantumObject, KetQuantumObject, OperatorQuantumObject, OperatorBraQuantumObject, OperatorKetQuantumObject, SuperOperatorQuantumObject, TimeEvolutionSol
export Bra, Ket, Operator, OperatorBra, OperatorKet, SuperOperator
export isket, isbra, isoper, isoperbra, isoperket, issuper, ket2dm
export spre, spost, sprepost, lindblad_dissipator
export fock, basis, coherent
Expand Down
8 changes: 4 additions & 4 deletions src/general_functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ end
@doc raw"""
vec2mat(A::QuantumObject)
Convert a quantum object from vector (`OperatorKetQuantumObject`-type) to matrix (`OperatorQuantumObject`-type)
Convert a quantum object from vector ([`OperatorKetQuantumObject`](@ref)-type) to matrix ([`OperatorQuantumObject`](@ref)-type)
"""
vec2mat(A::QuantumObject{<:AbstractArray{T},OperatorKetQuantumObject}) where {T} = QuantumObject(vec2mat(A.data), OperatorQuantumObject(), A.dims)
vec2mat(A::QuantumObject{<:AbstractArray{T},OperatorKetQuantumObject}) where {T} = QuantumObject(vec2mat(A.data), Operator, A.dims)

@doc raw"""
gaussian(x::Number, μ::Number, σ::Number)
Expand Down Expand Up @@ -404,6 +404,6 @@ end
@doc raw"""
mat2vec(A::QuantumObject)
Convert a quantum object from matrix (`OperatorQuantumObject`-type) to vector (`OperatorKetQuantumObject`-type)
Convert a quantum object from matrix ([`OperatorQuantumObject`](@ref)-type) to vector ([`OperatorKetQuantumObject`](@ref)-type)
"""
mat2vec(A::QuantumObject{<:AbstractArray{T},OperatorQuantumObject}) where {T} = QuantumObject(mat2vec(A.data), OperatorKetQuantumObject(), A.dims)
mat2vec(A::QuantumObject{<:AbstractArray{T},OperatorQuantumObject}) where {T} = QuantumObject(mat2vec(A.data), OperatorKet, A.dims)
8 changes: 4 additions & 4 deletions src/negativity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ where ``\rho^{\Gamma}`` is the partial transpose of ``\rho`` with respect to the
and ``\Vert X \Vert_1=\Tr\sqrt{X^\dagger X}`` is the trace norm.
# Arguments
- `ρ::QuantumObject`: The density matrix (`ρ.type` must be `OperatorQuantumObject`).
- `ρ::QuantumObject`: The density matrix (`ρ.type` must be [`OperatorQuantumObject`](@ref)).
- `subsys::Int`: an index that indicates which subsystem to compute the negativity for.
- `logarithmic::Bool`: choose whether to calculate logarithmic negativity or not. Default as `false`
Expand Down Expand Up @@ -60,7 +60,7 @@ end
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 be `OperatorQuantumObject`).
- `ρ::QuantumObject`: The density matrix (`ρ.type` must be [`OperatorQuantumObject`](@ref)).
- `mask::Vector{Bool}`: A boolean vector selects which subsystems should be transposed.
# Returns
Expand Down Expand Up @@ -88,7 +88,7 @@ function _partial_transpose(ρ::QuantumObject{<:AbstractArray, OperatorQuantumOb
]
return QuantumObject(
reshape(PermutedDimsArray(reshape.data, (ρ.dims..., ρ.dims...)), pt_idx), size(ρ)),
OperatorQuantumObject(),
Operator,
ρ.dims
)
end
Expand Down Expand Up @@ -130,7 +130,7 @@ function _partial_transpose(ρ::QuantumObject{<:AbstractSparseArray, OperatorQua

return QuantumObject(
sparse(I_pt, J_pt, V_pt, M, N),
OperatorQuantumObject(),
Operator,
ρ.dims
)
end
68 changes: 55 additions & 13 deletions src/quantum_object.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,83 @@ Constructor representing a bra state ``\bra{\psi}``.
"""
struct BraQuantumObject <: QuantumObjectType end

@doc raw"""
const Bra = BraQuantumObject()
A constant representing the type of [`BraQuantumObject`](@ref)
"""
const Bra = BraQuantumObject()

@doc raw"""
KetQuantumObject <: QuantumObjectType
Constructor representing a ket state ``\ket{\psi}``.
"""
struct KetQuantumObject <: QuantumObjectType end

@doc raw"""
const Ket = KetQuantumObject()
A constant representing the type of [`KetQuantumObject`](@ref)
"""
const Ket = KetQuantumObject()

@doc raw"""
OperatorQuantumObject <: QuantumObjectType
Constructor representing an operator ``\hat{O}``.
"""
struct OperatorQuantumObject <: QuantumObjectType end

@doc raw"""
const Operator = OperatorQuantumObject()
A constant representing the type of [`OperatorQuantumObject`](@ref)
"""
const Operator = OperatorQuantumObject()

@doc raw"""
SuperOperatorQuantumObject <: QuantumObjectType
Constructor representing a super-operator ``\hat{\mathcal{O}}``.
"""
struct SuperOperatorQuantumObject <: QuantumObjectType end

@doc raw"""
const SuperOperator = SuperOperatorQuantumObject()
A constant representing the type of [`SuperOperatorQuantumObject`](@ref)
"""
const SuperOperator = SuperOperatorQuantumObject()

@doc raw"""
OperatorBraQuantumObject <: QuantumObjectType
Constructor representing a bra state in the super-operator formalism ``\langle\langle\rho|``.
"""
struct OperatorBraQuantumObject <: QuantumObjectType end

@doc raw"""
const OperatorBra = OperatorBraQuantumObject()
A constant representing the type of [`OperatorBraQuantumObject`](@ref)
"""
const OperatorBra = OperatorBraQuantumObject()

@doc raw"""
OperatorKetQuantumObject <: QuantumObjectType
Constructor representing a ket state in the super-operator formalism ``|\rho\rangle\rangle``.
"""
struct OperatorKetQuantumObject <: QuantumObjectType end

@doc raw"""
const OperatorKet = OperatorKetQuantumObject()
A constant representing the type of [`OperatorKetQuantumObject`](@ref)
"""
const OperatorKet = OperatorKetQuantumObject()

@doc raw"""
mutable struct QuantumObject{MT<:AbstractArray,ObjType<:QuantumObjectType}
data::MT
Expand Down Expand Up @@ -91,11 +133,11 @@ function QuantumObject(A::AbstractArray{T, N}; type::ObjType=nothing, dims=nothi
# decide QuantumObjectType from the size of A
if type === nothing
if Size[1] == Size[2]
type = OperatorQuantumObject()
type = Operator
elseif Size[2] == 1
type = KetQuantumObject()
type = Ket
elseif Size[1] == 1
type = BraQuantumObject()
type = Bra
else
throw(DomainError(Size, "The dimension of the array is not compatible with Quantum Object"))
end
Expand Down Expand Up @@ -332,17 +374,17 @@ end
function LinearAlgebra.:(*)(A::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject},
B::QuantumObject{<:AbstractArray{T2},KetQuantumObject}) where {T1,T2}
A.dims != B.dims && throw(ErrorException("The two operators are not of the same Hilbert dimension."))
QuantumObject(A.data * B.data, KetQuantumObject(), A.dims)
QuantumObject(A.data * B.data, Ket, A.dims)
end
function LinearAlgebra.:(*)(A::QuantumObject{<:AbstractArray{T1},BraQuantumObject},
B::QuantumObject{<:AbstractArray{T2},OperatorQuantumObject}) where {T1,T2}
A.dims != B.dims && throw(ErrorException("The two operators are not of the same Hilbert dimension."))
QuantumObject(A.data * B.data, BraQuantumObject(), A.dims)
QuantumObject(A.data * B.data, Bra, A.dims)
end
function LinearAlgebra.:(*)(A::QuantumObject{<:AbstractArray{T1},KetQuantumObject},
B::QuantumObject{<:AbstractArray{T2},BraQuantumObject}) where {T1,T2}
A.dims != B.dims && throw(ErrorException("The two operators are not of the same Hilbert dimension."))
QuantumObject(A.data * B.data, OperatorQuantumObject(), A.dims)
QuantumObject(A.data * B.data, Operator, A.dims)
end
function LinearAlgebra.:(*)(A::QuantumObject{<:AbstractArray{T1},BraQuantumObject},
B::QuantumObject{<:AbstractArray{T2},KetQuantumObject}) where {T1,T2}
Expand All @@ -352,7 +394,7 @@ end
function LinearAlgebra.:(*)(A::QuantumObject{<:AbstractArray{T1},SuperOperatorQuantumObject},
B::QuantumObject{<:AbstractArray{T2},OperatorQuantumObject}) where {T1,T2}
A.dims != B.dims && throw(ErrorException("The two operators are not of the same Hilbert dimension."))
QuantumObject(vec2mat(A.data * mat2vec(B.data)), OperatorQuantumObject(), A.dims)
QuantumObject(vec2mat(A.data * mat2vec(B.data)), Operator, A.dims)
end
function LinearAlgebra.:(*)(A::QuantumObject{<:AbstractArray{T1},OperatorBraQuantumObject},
B::QuantumObject{<:AbstractArray{T2},OperatorKetQuantumObject}) where {T1,T2}
Expand All @@ -362,12 +404,12 @@ end
function LinearAlgebra.:(*)(A::QuantumObject{<:AbstractArray{T1},SuperOperatorQuantumObject},
B::QuantumObject{<:AbstractArray{T2},OperatorKetQuantumObject}) where {T1,T2}
A.dims != B.dims && throw(ErrorException("The two operators are not of the same Hilbert dimension."))
QuantumObject(A.data * B.data, OperatorKetQuantumObject(), A.dims)
QuantumObject(A.data * B.data, OperatorKet, A.dims)
end
function LinearAlgebra.:(*)(A::QuantumObject{<:AbstractArray{T1},OperatorBraQuantumObject},
B::QuantumObject{<:AbstractArray{T2},SuperOperatorQuantumObject}) where {T1,T2}
A.dims != B.dims && throw(ErrorException("The two operators are not of the same Hilbert dimension."))
QuantumObject(A.data * B.data, OperatorBraQuantumObject(), A.dims)
QuantumObject(A.data * B.data, OperatorBra, A.dims)
end

LinearAlgebra.:(^)(A::QuantumObject{<:AbstractArray{T},OpType}, n::T1) where {T,T1<:Number,OpType<:QuantumObjectType} =
Expand All @@ -388,13 +430,13 @@ LinearAlgebra.adjoint(A::QuantumObject{<:AbstractArray{T},OpType}) where {T,OpTy
LinearAlgebra.transpose(A::QuantumObject{<:AbstractArray{T},OpType}) where {T,OpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
QuantumObject(transpose(A.data), OpType(), A.dims)
LinearAlgebra.adjoint(A::QuantumObject{<:AbstractArray{T},KetQuantumObject}) where {T} =
QuantumObject(adjoint(A.data), BraQuantumObject(), A.dims)
QuantumObject(adjoint(A.data), Bra, A.dims)
LinearAlgebra.adjoint(A::QuantumObject{<:AbstractArray{T},BraQuantumObject}) where {T} =
QuantumObject(adjoint(A.data), KetQuantumObject(), A.dims)
QuantumObject(adjoint(A.data), Ket, A.dims)
LinearAlgebra.adjoint(A::QuantumObject{<:AbstractArray{T},OperatorKetQuantumObject}) where {T} =
QuantumObject(adjoint(A.data), OperatorBraQuantumObject(), A.dims)
QuantumObject(adjoint(A.data), OperatorBra, A.dims)
LinearAlgebra.adjoint(A::QuantumObject{<:AbstractArray{T},OperatorBraQuantumObject}) where {T} =
QuantumObject(adjoint(A.data), OperatorKetQuantumObject(), A.dims)
QuantumObject(adjoint(A.data), OperatorKet, A.dims)

LinearAlgebra.inv(A::QuantumObject{<:AbstractArray{T},OpType}) where {T,OpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
QuantumObject(sparse(inv(Matrix(A.data))), OpType(), A.dims)
Expand Down
18 changes: 9 additions & 9 deletions src/quantum_operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The optional argument `Id_cache` can be used to pass a precomputed identity matr
the same function is applied multiple times with a known Hilbert space dimension.
"""
spre(O::QuantumObject{<:AbstractArray{T},OperatorQuantumObject}, Id_cache=I(size(O,1))) where {T} =
QuantumObject(kron(Id_cache, O.data), SuperOperatorQuantumObject(), O.dims)
QuantumObject(kron(Id_cache, O.data), SuperOperator, O.dims)

@doc raw"""
spost(O::QuantumObject)
Expand All @@ -26,7 +26,7 @@ The optional argument `Id_cache` can be used to pass a precomputed identity matr
the same function is applied multiple times with a known Hilbert space dimension.
"""
spost(O::QuantumObject{<:AbstractArray{T},OperatorQuantumObject}, Id_cache=I(size(O,1))) where {T} =
QuantumObject(kron(sparse(transpose(sparse(O.data))), Id_cache), SuperOperatorQuantumObject(), O.dims) # TODO: fix the sparse conversion
QuantumObject(kron(sparse(transpose(sparse(O.data))), Id_cache), SuperOperator, O.dims) # TODO: fix the sparse conversion

@doc raw"""
sprepost(A::QuantumObject, B::QuantumObject)
Expand All @@ -38,7 +38,7 @@ 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)``.
"""
sprepost(A::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject},
B::QuantumObject{<:AbstractArray{T2},OperatorQuantumObject}) where {T1,T2} = QuantumObject(kron(sparse(transpose(sparse(B.data))), A.data), SuperOperatorQuantumObject(), A.dims) # TODO: fix the sparse conversion
B::QuantumObject{<:AbstractArray{T2},OperatorQuantumObject}) where {T1,T2} = QuantumObject(kron(sparse(transpose(sparse(B.data))), A.data), SuperOperator, A.dims) # TODO: fix the sparse conversion

@doc raw"""
lindblad_dissipator(O::QuantumObject, Id_cache=I(size(O,1))
Expand Down Expand Up @@ -83,7 +83,7 @@ julia> fock(20, 3)' * a * fock(20, 4)
2.0 + 0.0im
```
"""
destroy(N::Int) = QuantumObject(spdiagm(1 => Array{ComplexF64}(sqrt.(1:N-1))), OperatorQuantumObject(), [N])
destroy(N::Int) = QuantumObject(spdiagm(1 => Array{ComplexF64}(sqrt.(1:N-1))), Operator, [N])

@doc raw"""
create(N::Int)
Expand All @@ -107,7 +107,7 @@ julia> fock(20, 4)' * a_d * fock(20, 3)
2.0 + 0.0im
```
"""
create(N::Int) = QuantumObject(spdiagm(-1 => Array{ComplexF64}(sqrt.(1:N-1))), OperatorQuantumObject(), [N])
create(N::Int) = QuantumObject(spdiagm(-1 => Array{ComplexF64}(sqrt.(1:N-1))), Operator, [N])

@doc raw"""
sigmap()
Expand Down Expand Up @@ -149,15 +149,15 @@ sigmaz() = sigmap() * sigmam() - sigmam() * sigmap()
Identity operator ``\hat{\mathbb{1}}`` with Hilbert dimension `N`.
"""
eye(N::Int; type::ObjType=OperatorQuantumObject(), dims::Vector{Int}=[N]) where
eye(N::Int; type::ObjType=Operator, dims::Vector{Int}=[N]) where
{ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} = QuantumObject(Diagonal(ones(ComplexF64, N)), type, dims)

@doc raw"""
qeye(N::Int; type=OperatorQuantumObject, dims=[N])
Identity operator ``\hat{\mathbb{1}}`` with Hilbert dimension `N`.
"""
qeye(N::Int; type::ObjType=OperatorQuantumObject(), dims::Vector{Int}=[N]) where
qeye(N::Int; type::ObjType=Operator, dims::Vector{Int}=[N]) where
{ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} = eye(N, type=type, dims=dims)

@doc raw"""
Expand All @@ -168,11 +168,11 @@ to specify the list of dimensions `dims` if different subsystems are present.
"""
function fock(N::Int, pos::Int; dims::Vector{Int}=[N], sparse::Bool=false)
if sparse
return QuantumObject(sparsevec([pos+1], [1.0+0im], N), KetQuantumObject(), dims)
return QuantumObject(sparsevec([pos+1], [1.0+0im], N), Ket, dims)
else
array = zeros(ComplexF64, N)
array[pos+1] = 1
return QuantumObject(array, KetQuantumObject(), dims)
return QuantumObject(array, Ket, dims)
end
end

Expand Down
8 changes: 4 additions & 4 deletions src/time_evolution/time_evolution.jl
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ function liouvillian_generalized(H::QuantumObject{MT, OperatorQuantumObject}, fi
Ω1 = kron(Ω, M1)
Ω2 = kron(M1, Ω)
Ωdiff = Ω1 .- Ω2
F2 = QuantumObject(gaussian.(Ωdiff, 0, σ), SuperOperatorQuantumObject(), dims)
F2 = QuantumObject(gaussian.(Ωdiff, 0, σ), SuperOperator, dims)
F2 = dense_to_sparse(F2, tol)

L = liouvillian(H_d)
Expand Down Expand Up @@ -239,8 +239,8 @@ function _liouvillian_floquet(L₀::QuantumObject{<:AbstractArray{T1},SuperOpera
T = -(L_0 + 1im * n_i * ω * I + L_p * T) \ L_m_dense
end

solver.tol == 0 && return QuantumObject(L_0 + L_m * S + L_p * T, SuperOperatorQuantumObject(), L₀.dims)
return QuantumObject(dense_to_sparse(L_0 + L_m * S + L_p * T, solver.tol), SuperOperatorQuantumObject(), L₀.dims)
solver.tol == 0 && return QuantumObject(L_0 + L_m * S + L_p * T, SuperOperator, L₀.dims)
return QuantumObject(dense_to_sparse(L_0 + L_m * S + L_p * T, solver.tol), SuperOperator, L₀.dims)
end

function steadystate(L::QuantumObject{<:AbstractArray{T},SuperOperatorQuantumObject};
Expand Down Expand Up @@ -270,7 +270,7 @@ function _steadystate(L::QuantumObject{<:AbstractArray{T},SuperOperatorQuantumOb
ρss_vec = L_tmp \ v0
ρss = reshape(ρss_vec, N, N)
ρss = (ρss + ρss') / 2 # Hermitianize
QuantumObject(ρss, OperatorQuantumObject(), L.dims)
QuantumObject(ρss, Operator, L.dims)
end

@doc raw"""
Expand Down
Loading

0 comments on commit a986c50

Please sign in to comment.