Skip to content

Commit 85d23ef

Browse files
Return sesolve when mesolve allows it (#455)
1 parent 2b5e86e commit 85d23ef

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main)
99

10+
- Return `sesolve` when `mesolve` allows it. ([#455])
11+
1012
## [v0.30.1]
1113
Release date: 2025-04-24
1214

@@ -212,3 +214,4 @@ Release date: 2024-11-13
212214
[#448]: https://github.com/qutip/QuantumToolbox.jl/issues/448
213215
[#450]: https://github.com/qutip/QuantumToolbox.jl/issues/450
214216
[#453]: https://github.com/qutip/QuantumToolbox.jl/issues/453
217+
[#455]: https://github.com/qutip/QuantumToolbox.jl/issues/455

src/time_evolution/mesolve.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ where
4646
4747
- The states will be saved depend on the keyword argument `saveat` in `kwargs`.
4848
- If `e_ops` is empty, the default value of `saveat=tlist` (saving the states corresponding to `tlist`), otherwise, `saveat=[tlist[end]]` (only save the final state). You can also specify `e_ops` and `saveat` separately.
49+
- If `H` is an [`Operator`](@ref), `ψ0` is a [`Ket`](@ref) and `c_ops` is `Nothing`, the function will call [`sesolveProblem`](@ref) instead.
4950
- The default tolerances in `kwargs` are given as `reltol=1e-6` and `abstol=1e-8`.
5051
- For more details about `kwargs` please refer to [`DifferentialEquations.jl` (Keyword Arguments)](https://docs.sciml.ai/DiffEqDocs/stable/basics/common_solver_opts/)
5152
@@ -67,6 +68,17 @@ function mesolveProblem(
6768
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
6869
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject,OperatorKetQuantumObject},
6970
}
71+
(isoper(H) && isket(ψ0) && isnothing(c_ops)) && return sesolveProblem(
72+
H,
73+
ψ0,
74+
tlist;
75+
e_ops = e_ops,
76+
params = params,
77+
progress_bar = progress_bar,
78+
inplace = inplace,
79+
kwargs...,
80+
)
81+
7082
haskey(kwargs, :save_idxs) &&
7183
throw(ArgumentError("The keyword argument \"save_idxs\" is not supported in QuantumToolbox."))
7284

@@ -141,6 +153,7 @@ where
141153
142154
- The states will be saved depend on the keyword argument `saveat` in `kwargs`.
143155
- If `e_ops` is empty, the default value of `saveat=tlist` (saving the states corresponding to `tlist`), otherwise, `saveat=[tlist[end]]` (only save the final state). You can also specify `e_ops` and `saveat` separately.
156+
- If `H` is an [`Operator`](@ref), `ψ0` is a [`Ket`](@ref) and `c_ops` is `Nothing`, the function will call [`sesolve`](@ref) instead.
144157
- The default tolerances in `kwargs` are given as `reltol=1e-6` and `abstol=1e-8`.
145158
- For more details about `alg` please refer to [`DifferentialEquations.jl` (ODE Solvers)](https://docs.sciml.ai/DiffEqDocs/stable/solvers/ode_solve/)
146159
- For more details about `kwargs` please refer to [`DifferentialEquations.jl` (Keyword Arguments)](https://docs.sciml.ai/DiffEqDocs/stable/basics/common_solver_opts/)
@@ -164,6 +177,18 @@ function mesolve(
164177
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
165178
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject,OperatorKetQuantumObject},
166179
}
180+
(isoper(H) && isket(ψ0) && isnothing(c_ops)) && return sesolve(
181+
H,
182+
ψ0,
183+
tlist;
184+
alg = alg,
185+
e_ops = e_ops,
186+
params = params,
187+
progress_bar = progress_bar,
188+
inplace = inplace,
189+
kwargs...,
190+
)
191+
167192
prob = mesolveProblem(
168193
H,
169194
ψ0,

test/core-test/time_evolution.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@
183183
rng = MersenneTwister(12),
184184
)
185185

186+
# Redirect to `sesolve`
187+
sol_me5 = mesolve(H, ψ0, tlist, progress_bar = Val(false))
188+
186189
ρt_mc = [ket2dm.(normalize.(states)) for states in sol_mc_states.states]
187190
expect_mc_states = mapreduce(states -> expect.(Ref(e_ops[1]), states), hcat, ρt_mc)
188191
expect_mc_states_mean = sum(expect_mc_states, dims = 2) / size(expect_mc_states, 2)
@@ -198,6 +201,7 @@
198201
sol_sme_string = sprint((t, s) -> show(t, "text/plain", s), sol_sme)
199202
@test prob_me.prob.f.f isa MatrixOperator
200203
@test prob_mc.prob.f.f isa MatrixOperator
204+
@test isket(sol_me5.states[1])
201205
@test sum(abs, sol_mc.expect .- sol_me.expect) / length(tlist) < 0.1
202206
@test sum(abs, sol_mc2.expect .- sol_me.expect) / length(tlist) < 0.1
203207
@test sum(abs, vec(expect_mc_states_mean) .- vec(sol_me.expect[1, saveat_idxs])) / length(tlist) < 0.1

0 commit comments

Comments
 (0)