Skip to content
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ body:
attributes:
label: Code Output
description: Please paste the relevant output here (automatically formatted)
placeholder: "Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=true\n2×2 Diagonal{ComplexF64, Vector{ComplexF64}}:\n 1.0+0.0im ⋅ \n ⋅ 1.0+0.0im"
placeholder: "Quantum Object: type=Operator() dims=[2] size=(2, 2) ishermitian=true\n2×2 Diagonal{ComplexF64, Vector{ComplexF64}}:\n 1.0+0.0im ⋅ \n ⋅ 1.0+0.0im"
render: shell
- type: textarea
id: expected-behaviour
Expand Down
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
24 changes: 12 additions & 12 deletions docs/src/users_guide/extensions/cuda.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ V = fock(2, 0) # CPU dense vector
```

```
Quantum Object: type=Ket dims=[2] size=(2,)
Quantum Object: type=Ket() dims=[2] size=(2,)
2-element Vector{ComplexF64}:
1.0 + 0.0im
0.0 + 0.0im
Expand All @@ -47,7 +47,7 @@ cu(V)
```

```
Quantum Object: type=Ket dims=[2] size=(2,)
Quantum Object: type=Ket() dims=[2] size=(2,)
2-element CuArray{ComplexF64, 1, CUDA.DeviceMemory}:
1.0 + 0.0im
0.0 + 0.0im
Expand All @@ -58,7 +58,7 @@ cu(V; word_size = 32)
```

```
Quantum Object: type=Ket dims=[2] size=(2,)
Quantum Object: type=Ket() dims=[2] size=(2,)
2-element CuArray{ComplexF32, 1, CUDA.DeviceMemory}:
1.0 + 0.0im
0.0 + 0.0im
Expand All @@ -69,7 +69,7 @@ M = Qobj([1 2; 3 4]) # CPU dense matrix
```

```
Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=false
Quantum Object: type=Operator() dims=[2] size=(2, 2) ishermitian=false
2×2 Matrix{Int64}:
1 2
3 4
Expand All @@ -80,7 +80,7 @@ cu(M)
```

```
Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=false
Quantum Object: type=Operator() dims=[2] size=(2, 2) ishermitian=false
2×2 CuArray{Int64, 2, CUDA.DeviceMemory}:
1 2
3 4
Expand All @@ -91,7 +91,7 @@ cu(M; word_size = 32)
```

```
Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=false
Quantum Object: type=Operator() dims=[2] size=(2, 2) ishermitian=false
2×2 CuArray{Int32, 2, CUDA.DeviceMemory}:
1 2
3 4
Expand All @@ -104,7 +104,7 @@ V = fock(2, 0; sparse=true) # CPU sparse vector
```

```
Quantum Object: type=Ket dims=[2] size=(2,)
Quantum Object: type=Ket() dims=[2] size=(2,)
2-element SparseVector{ComplexF64, Int64} with 1 stored entry:
[1] = 1.0+0.0im
```
Expand All @@ -114,7 +114,7 @@ cu(V)
```

```
Quantum Object: type=Ket dims=[2] size=(2,)
Quantum Object: type=Ket() dims=[2] size=(2,)
2-element CuSparseVector{ComplexF64, Int32} with 1 stored entry:
[1] = 1.0+0.0im
```
Expand All @@ -124,7 +124,7 @@ cu(V; word_size = 32)
```

```
Quantum Object: type=Ket dims=[2] size=(2,)
Quantum Object: type=Ket() dims=[2] size=(2,)
2-element CuSparseVector{ComplexF32, Int32} with 1 stored entry:
[1] = 1.0+0.0im
```
Expand All @@ -134,7 +134,7 @@ M = sigmax() # CPU sparse matrix
```

```
Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=true
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 ⋅
Expand All @@ -145,7 +145,7 @@ cu(M)
```

```
Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=true
Quantum Object: type=Operator() dims=[2] size=(2, 2) ishermitian=true
2×2 CuSparseMatrixCSC{ComplexF64, Int32} with 2 stored entries:
⋅ 1.0+0.0im
1.0+0.0im ⋅
Expand All @@ -156,7 +156,7 @@ cu(M; word_size = 32)
```

```
Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=true
Quantum Object: type=Operator() dims=[2] size=(2, 2) ishermitian=true
2×2 CuSparseMatrixCSC{ComplexF32, Int32} with 2 stored entries:
⋅ 1.0+0.0im
1.0+0.0im ⋅
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
Loading
Loading