Skip to content
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main)

- Return `sesolve` when `mesolve` allows it. ([#455])
- Simplify structure of `QuantumObjectType`s. ([#456])

## [v0.30.1]
Release date: 2025-04-24
Expand Down Expand Up @@ -215,3 +216,4 @@ Release date: 2024-11-13
[#450]: https://github.com/qutip/QuantumToolbox.jl/issues/450
[#453]: https://github.com/qutip/QuantumToolbox.jl/issues/453
[#455]: https://github.com/qutip/QuantumToolbox.jl/issues/455
[#456]: https://github.com/qutip/QuantumToolbox.jl/issues/456
9 changes: 4 additions & 5 deletions docs/src/getting_started/type_stability.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ and its type is
obj_type = typeof(σx_2)
```

This is exactly what the Julia compiler sees: it is a [`QuantumObject`](@ref), composed by a field of type `SparseMatrixCSC{ComplexF64, Int64}` (i.e., the 8x8 matrix containing the Pauli matrix, tensored with the identity matrices of the other two qubits). Then, we can also see that it is a [`OperatorQuantumObject`](@ref), with `3` subsystems in total. Hence, just looking at the type of the object, the compiler has all the information it needs to generate a specialized version of the functions.
This is exactly what the Julia compiler sees: it is a [`QuantumObject`](@ref), composed by a field of type `SparseMatrixCSC{ComplexF64, Int64}` (i.e., the 8x8 matrix containing the Pauli matrix, tensored with the identity matrices of the other two qubits). Then, we can also see that it is a [`Operator`](@ref), with `3` subsystems in total. Hence, just looking at the type of the object, the compiler has all the information it needs to generate a specialized version of the functions.

Let's see more in the details all the internal fields of the [`QuantumObject`](@ref) type:

Expand All @@ -174,7 +174,6 @@ fieldnames(obj_type)
σx_2.type
```

[`Operator`](@ref) is a synonym for [`OperatorQuantumObject`](@ref).

```@example type-stability
σx_2.dims
Expand All @@ -184,7 +183,7 @@ The `dims` field contains the dimensions of the subsystems (in this case, three

```@example type-stability
function reshape_operator_data(dims)
op = Qobj(randn(prod(dims), prod(dims)), type=Operator, dims=dims)
op = Qobj(randn(prod(dims), prod(dims)), type=Operator(), dims=dims)
op_dims = op.dims
op_data = op.data
return reshape(op_data, vcat(op_dims, op_dims)...)
Expand Down Expand Up @@ -235,7 +234,7 @@ function my_fock(N::Int, j::Int = 0; sparse::Bool = false)
array = zeros(ComplexF64, N)
array[j+1] = 1
end
return QuantumObject(array; type = Ket)
return QuantumObject(array; type = Ket())
end
@show my_fock(2, 1)
@show my_fock(2, 1; sparse = true)
Expand Down Expand Up @@ -263,7 +262,7 @@ function my_fock_good(N::Int, j::Int = 0; sparse::Val = Val(false))
else
array = sparsevec([j + 1], [1.0 + 0im], N)
end
return QuantumObject(array; type = Ket)
return QuantumObject(array; type = Ket())
end
@show my_fock_good(2, 1)
@show my_fock_good(2, 1; sparse = Val(true))
Expand Down
6 changes: 0 additions & 6 deletions docs/src/resources/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,11 @@ Space
Dimensions
GeneralDimensions
AbstractQuantumObject
BraQuantumObject
Bra
KetQuantumObject
Ket
OperatorQuantumObject
Operator
OperatorBraQuantumObject
OperatorBra
OperatorKetQuantumObject
OperatorKet
SuperOperatorQuantumObject
SuperOperator
QuantumObject
QuantumObjectEvolution
Expand Down
2 changes: 1 addition & 1 deletion docs/src/users_guide/QuantumObject/QuantumObject.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Qobj(M, dims = SVector(2, 2)) # dims as StaticArrays.SVector (recommended)
Please note that here we put the `dims` as a tuple `(2, 2)`. Although it supports also `Vector` type (`dims = [2, 2]`), it is recommended to use `Tuple` or `SVector` from [`StaticArrays.jl`](https://github.com/JuliaArrays/StaticArrays.jl) to improve performance. For a brief explanation on the impact of the type of `dims`, see the Section [The Importance of Type-Stability](@ref doc:Type-Stability).

```@example Qobj
Qobj(rand(4, 4), type = SuperOperator)
Qobj(rand(4, 4), type = SuperOperator())
```

!!! note "Difference between `dims` and `size`"
Expand Down
2 changes: 1 addition & 1 deletion docs/src/users_guide/states_and_operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ B = Qobj(rand(ComplexF64, N, N))
mat2vec(A * ρ * B) ≈ spre(A) * spost(B) * mat2vec(ρ) ≈ sprepost(A, B) * mat2vec(ρ)
```

In addition, dynamical generators on this extended space, often called Liouvillian superoperators, can be created using the [`liouvillian`](@ref) function. Each of these takes a Hamiltonian along with a list of collapse operators, and returns a [`type=SuperOperator`](@ref SuperOperator) object that can be exponentiated to find the superoperator for that evolution.
In addition, dynamical generators on this extended space, often called Liouvillian superoperators, can be created using the [`liouvillian`](@ref) function. Each of these takes a Hamiltonian along with a list of collapse operators, and returns a [`QuantumObject`](@ref) of type [`SuperOperator`](@ref) that can be exponentiated to find the superoperator for that evolution.

```@example states_and_operators
H = 10 * sigmaz()
Expand Down
12 changes: 6 additions & 6 deletions ext/QuantumToolboxMakieExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function QuantumToolbox.plot_wigner(
location::Union{GridPosition,Nothing} = nothing,
colorbar::Bool = false,
kwargs...,
) where {OpType<:Union{BraQuantumObject,KetQuantumObject,OperatorQuantumObject}}
) where {OpType<:Union{Bra,Ket,Operator}}
QuantumToolbox.getVal(projection) == :two_dim ||
QuantumToolbox.getVal(projection) == :three_dim ||
throw(ArgumentError("Unsupported projection: $projection"))
Expand Down Expand Up @@ -84,7 +84,7 @@ function _plot_wigner(
location::Union{GridPosition,Nothing},
colorbar::Bool;
kwargs...,
) where {OpType<:Union{BraQuantumObject,KetQuantumObject,OperatorQuantumObject}}
) where {OpType<:Union{Bra,Ket,Operator}}
fig, location = _getFigAndLocation(location)

lyt = GridLayout(location)
Expand Down Expand Up @@ -117,7 +117,7 @@ function _plot_wigner(
location::Union{GridPosition,Nothing},
colorbar::Bool;
kwargs...,
) where {OpType<:Union{BraQuantumObject,KetQuantumObject,OperatorQuantumObject}}
) where {OpType<:Union{Bra,Ket,Operator}}
fig, location = _getFigAndLocation(location)

lyt = GridLayout(location)
Expand Down Expand Up @@ -148,7 +148,7 @@ end
unit_y_range::Bool = true,
location::Union{GridPosition,Nothing} = nothing,
kwargs...
) where {SType<:Union{KetQuantumObject,OperatorQuantumObject}}
) where {SType<:Union{Ket,Operator}}

Plot the [Fock state](https://en.wikipedia.org/wiki/Fock_state) distribution of `ρ`.

Expand Down Expand Up @@ -178,7 +178,7 @@ function QuantumToolbox.plot_fock_distribution(
unit_y_range::Bool = true,
location::Union{GridPosition,Nothing} = nothing,
kwargs...,
) where {SType<:Union{BraQuantumObject,KetQuantumObject,OperatorQuantumObject}}
) where {SType<:Union{Bra,Ket,Operator}}
return _plot_fock_distribution(
library,
ρ;
Expand All @@ -196,7 +196,7 @@ function _plot_fock_distribution(
unit_y_range::Bool = true,
location::Union{GridPosition,Nothing} = nothing,
kwargs...,
) where {SType<:Union{BraQuantumObject,KetQuantumObject,OperatorQuantumObject}}
) where {SType<:Union{Bra,Ket,Operator}}
ρ = ket2dm(ρ)
D = prod(ρ.dims)
isapprox(tr(ρ), 1, atol = 1e-4) || (@warn "The input ρ should be normalized.")
Expand Down
40 changes: 14 additions & 26 deletions src/correlations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,11 @@ function correlation_3op_2t(
tlist::AbstractVector,
τlist::AbstractVector,
c_ops::Union{Nothing,AbstractVector,Tuple},
A::QuantumObject{OperatorQuantumObject},
B::QuantumObject{OperatorQuantumObject},
C::QuantumObject{OperatorQuantumObject};
A::QuantumObject{Operator},
B::QuantumObject{Operator},
C::QuantumObject{Operator};
kwargs...,
) where {
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject},
}
) where {HOpType<:Union{Operator,SuperOperator},StateOpType<:Union{Ket,Operator}}
# check tlist and τlist
_check_correlation_time_list(tlist)
_check_correlation_time_list(τlist)
Expand Down Expand Up @@ -78,14 +75,11 @@ function correlation_3op_1t(
ψ0::Union{Nothing,QuantumObject{StateOpType}},
τlist::AbstractVector,
c_ops::Union{Nothing,AbstractVector,Tuple},
A::QuantumObject{OperatorQuantumObject},
B::QuantumObject{OperatorQuantumObject},
C::QuantumObject{OperatorQuantumObject};
A::QuantumObject{Operator},
B::QuantumObject{Operator},
C::QuantumObject{Operator};
kwargs...,
) where {
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject},
}
) where {HOpType<:Union{Operator,SuperOperator},StateOpType<:Union{Ket,Operator}}
corr = correlation_3op_2t(H, ψ0, [0], τlist, c_ops, A, B, C; kwargs...)

return corr[1, :] # 1 means tlist[1] = 0
Expand Down Expand Up @@ -114,14 +108,11 @@ function correlation_2op_2t(
tlist::AbstractVector,
τlist::AbstractVector,
c_ops::Union{Nothing,AbstractVector,Tuple},
A::QuantumObject{OperatorQuantumObject},
B::QuantumObject{OperatorQuantumObject};
A::QuantumObject{Operator},
B::QuantumObject{Operator};
reverse::Bool = false,
kwargs...,
) where {
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject},
}
) where {HOpType<:Union{Operator,SuperOperator},StateOpType<:Union{Ket,Operator}}
C = eye(prod(H.dimensions), dims = H.dimensions)
if reverse
corr = correlation_3op_2t(H, ψ0, tlist, τlist, c_ops, A, B, C; kwargs...)
Expand Down Expand Up @@ -153,14 +144,11 @@ function correlation_2op_1t(
ψ0::Union{Nothing,QuantumObject{StateOpType}},
τlist::AbstractVector,
c_ops::Union{Nothing,AbstractVector,Tuple},
A::QuantumObject{OperatorQuantumObject},
B::QuantumObject{OperatorQuantumObject};
A::QuantumObject{Operator},
B::QuantumObject{Operator};
reverse::Bool = false,
kwargs...,
) where {
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject},
}
) where {HOpType<:Union{Operator,SuperOperator},StateOpType<:Union{Ket,Operator}}
corr = correlation_2op_2t(H, ψ0, [0], τlist, c_ops, A, B; reverse = reverse, kwargs...)

return corr[1, :] # 1 means tlist[1] = 0
Expand Down
40 changes: 14 additions & 26 deletions src/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,31 +33,25 @@ correlation_3op_2t(
ψ0::QuantumObject{StateOpType},
t_l::AbstractVector,
τ_l::AbstractVector,
A::QuantumObject{OperatorQuantumObject},
B::QuantumObject{OperatorQuantumObject},
C::QuantumObject{OperatorQuantumObject},
A::QuantumObject{Operator},
B::QuantumObject{Operator},
C::QuantumObject{Operator},
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
kwargs...,
) where {
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject},
} = error(
) where {HOpType<:Union{Operator,SuperOperator},StateOpType<:Union{Ket,Operator}} = error(
"The parameter order of `correlation_3op_2t` has been changed, please use `?correlation_3op_2t` to check the updated docstring.",
)

correlation_3op_1t(
H::QuantumObject{HOpType},
ψ0::QuantumObject{StateOpType},
τ_l::AbstractVector,
A::QuantumObject{OperatorQuantumObject},
B::QuantumObject{OperatorQuantumObject},
C::QuantumObject{OperatorQuantumObject},
A::QuantumObject{Operator},
B::QuantumObject{Operator},
C::QuantumObject{Operator},
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
kwargs...,
) where {
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject},
} = error(
) where {HOpType<:Union{Operator,SuperOperator},StateOpType<:Union{Ket,Operator}} = error(
"The parameter order of `correlation_3op_1t` has been changed, please use `?correlation_3op_1t` to check the updated docstring.",
)

Expand All @@ -66,31 +60,25 @@ correlation_2op_2t(
ψ0::QuantumObject{StateOpType},
t_l::AbstractVector,
τ_l::AbstractVector,
A::QuantumObject{OperatorQuantumObject},
B::QuantumObject{OperatorQuantumObject},
A::QuantumObject{Operator},
B::QuantumObject{Operator},
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
reverse::Bool = false,
kwargs...,
) where {
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject},
} = error(
) where {HOpType<:Union{Operator,SuperOperator},StateOpType<:Union{Ket,Operator}} = error(
"The parameter order of `correlation_2op_2t` has been changed, please use `?correlation_2op_2t` to check the updated docstring.",
)

correlation_2op_1t(
H::QuantumObject{HOpType},
ψ0::QuantumObject{StateOpType},
τ_l::AbstractVector,
A::QuantumObject{OperatorQuantumObject},
B::QuantumObject{OperatorQuantumObject},
A::QuantumObject{Operator},
B::QuantumObject{Operator},
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
reverse::Bool = false,
kwargs...,
) where {
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject},
} = error(
) where {HOpType<:Union{Operator,SuperOperator},StateOpType<:Union{Ket,Operator}} = error(
"The parameter order of `correlation_2op_1t` has been changed, please use `?correlation_2op_1t` to check the updated docstring.",
)

Expand Down
23 changes: 7 additions & 16 deletions src/entropy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@ julia> entropy_vn(ρ, base=2)
1.0
```
"""
function entropy_vn(
ρ::QuantumObject{ObjType};
base::Int = 0,
tol::Real = 1e-15,
) where {ObjType<:Union{KetQuantumObject,OperatorQuantumObject}}
function entropy_vn(ρ::QuantumObject{ObjType}; base::Int = 0, tol::Real = 1e-15) where {ObjType<:Union{Ket,Operator}}
T = eltype(ρ)
vals = eigenenergies(ket2dm(ρ))
indexes = findall(x -> abs(x) > tol, vals)
Expand Down Expand Up @@ -78,10 +74,7 @@ function entropy_relative(
σ::QuantumObject{ObjType2};
base::Int = 0,
tol::Real = 1e-15,
) where {
ObjType1<:Union{KetQuantumObject,OperatorQuantumObject},
ObjType2<:Union{KetQuantumObject,OperatorQuantumObject},
}
) where {ObjType1<:Union{Ket,Operator},ObjType2<:Union{Ket,Operator}}
check_dimensions(ρ, σ)

# the logic of this code follows the detail given in the reference of the docstring
Expand Down Expand Up @@ -131,8 +124,7 @@ Calculates the quantum linear entropy ``S_L = 1 - \textrm{Tr} \left[ \hat{\rho}^

Note that `ρ` can be either a [`Ket`](@ref) or an [`Operator`](@ref).
"""
entropy_linear(ρ::QuantumObject{ObjType}) where {ObjType<:Union{KetQuantumObject,OperatorQuantumObject}} =
1.0 - purity(ρ) # use 1.0 to make sure it always return value in Float-type
entropy_linear(ρ::QuantumObject{ObjType}) where {ObjType<:Union{Ket,Operator}} = 1.0 - purity(ρ) # use 1.0 to make sure it always return value in Float-type

@doc raw"""
entropy_mutual(ρAB::QuantumObject, selA, selB; kwargs...)
Expand All @@ -153,7 +145,7 @@ function entropy_mutual(
selA::Union{Int,AbstractVector{Int},Tuple},
selB::Union{Int,AbstractVector{Int},Tuple};
kwargs...,
) where {ObjType<:Union{KetQuantumObject,OperatorQuantumObject},N}
) where {ObjType<:Union{Ket,Operator},N}
# check if selA and selB matches the dimensions of ρAB
sel_A_B = (selA..., selB...)
(length(sel_A_B) != N) && throw(
Expand Down Expand Up @@ -185,8 +177,7 @@ entropy_conditional(
ρAB::QuantumObject{ObjType,<:AbstractDimensions{N,N}},
selB::Union{Int,AbstractVector{Int},Tuple};
kwargs...,
) where {ObjType<:Union{KetQuantumObject,OperatorQuantumObject},N} =
entropy_vn(ρAB; kwargs...) - entropy_vn(ptrace(ρAB, selB); kwargs...)
) where {ObjType<:Union{Ket,Operator},N} = entropy_vn(ρAB; kwargs...) - entropy_vn(ptrace(ρAB, selB); kwargs...)

@doc raw"""
entanglement(ρ::QuantumObject, sel; kwargs...)
Expand All @@ -203,7 +194,7 @@ function entanglement(
ρ::QuantumObject{OpType},
sel::Union{Int,AbstractVector{Int},Tuple},
kwargs...,
) where {OpType<:Union{KetQuantumObject,OperatorQuantumObject}}
) where {OpType<:Union{Ket,Operator}}
p = purity(ρ)
isapprox(p, 1; atol = 1e-2) || throw(
ArgumentError(
Expand All @@ -229,7 +220,7 @@ Calculate the [concurrence](https://en.wikipedia.org/wiki/Concurrence_(quantum_c

- [Hill-Wootters1997](@citet)
"""
function concurrence(ρ::QuantumObject{OpType}) where {OpType<:Union{KetQuantumObject,OperatorQuantumObject}}
function concurrence(ρ::QuantumObject{OpType}) where {OpType<:Union{Ket,Operator}}
(ρ.dimensions == Dimensions((Space(2), Space(2)))) || throw(
ArgumentError(
"The `concurrence` only works for a two-qubit state, invalid dims = $(_get_dims_string(ρ.dimensions)).",
Expand Down
Loading
Loading