Skip to content

Commit de31edb

Browse files
Check tlist properties (#378)
1 parent 2f0ce8e commit de31edb

File tree

8 files changed

+40
-5
lines changed

8 files changed

+40
-5
lines changed

CHANGELOG.md

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

1010
- Fix Dynamical Fock Dimension states saving due to wrong saving of dimensions. ([#375])
1111
- Support a list of observables for `expect`. ([#374], [#376])
12+
- Add checks for `tlist` in time evolution solvers. The checks are to ensure that `tlist` is not empty, the elements are in increasing order, and the elements are unique. ([#378])
1213

1314
## [v0.25.0]
1415
Release date: 2025-01-20
@@ -89,3 +90,4 @@ Release date: 2024-11-13
8990
[#374]: https://github.com/qutip/QuantumToolbox.jl/issues/374
9091
[#375]: https://github.com/qutip/QuantumToolbox.jl/issues/375
9192
[#376]: https://github.com/qutip/QuantumToolbox.jl/issues/376
93+
[#378]: https://github.com/qutip/QuantumToolbox.jl/issues/378

src/time_evolution/lr_mesolve.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ function lr_mesolveProblem(
409409
c_ops = get_data.(c_ops)
410410
e_ops = get_data.(e_ops)
411411

412-
t_l = convert(Vector{_FType(H)}, tlist)
412+
t_l = _check_tlist(tlist, _FType(H))
413413

414414
# Initialization of Arrays
415415
expvals = Array{ComplexF64}(undef, length(e_ops), length(t_l))

src/time_evolution/mcsolve.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ function mcsolveProblem(
167167
c_ops isa Nothing &&
168168
throw(ArgumentError("The list of collapse operators must be provided. Use sesolveProblem instead."))
169169

170-
tlist = convert(Vector{_FType(ψ0)}, tlist) # Convert it to support GPUs and avoid type instabilities for OrdinaryDiffEq.jl
170+
tlist = _check_tlist(tlist, _FType(ψ0))
171171

172172
H_eff_evo = _mcsolve_make_Heff_QobjEvo(H, c_ops)
173173

src/time_evolution/mesolve.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function mesolveProblem(
6868
haskey(kwargs, :save_idxs) &&
6969
throw(ArgumentError("The keyword argument \"save_idxs\" is not supported in QuantumToolbox."))
7070

71-
tlist = convert(Vector{_FType(ψ0)}, tlist) # Convert it to support GPUs and avoid type instabilities for OrdinaryDiffEq.jl
71+
tlist = _check_tlist(tlist, _FType(ψ0))
7272

7373
L_evo = _mesolve_make_L_QobjEvo(H, c_ops)
7474
check_dimensions(L_evo, ψ0)

src/time_evolution/sesolve.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function sesolveProblem(
5959
haskey(kwargs, :save_idxs) &&
6060
throw(ArgumentError("The keyword argument \"save_idxs\" is not supported in QuantumToolbox."))
6161

62-
tlist = convert(Vector{_FType(ψ0)}, tlist) # Convert it to support GPUs and avoid type instabilities for OrdinaryDiffEq.jl
62+
tlist = _check_tlist(tlist, _FType(ψ0))
6363

6464
H_evo = _sesolve_make_U_QobjEvo(H) # Multiply by -i
6565
isoper(H_evo) || throw(ArgumentError("The Hamiltonian must be an Operator."))

src/time_evolution/ssesolve.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ function ssesolveProblem(
162162
sc_ops isa Nothing &&
163163
throw(ArgumentError("The list of collapse operators must be provided. Use sesolveProblem instead."))
164164

165-
tlist = convert(Vector{Float64}, tlist) # Convert it into Float64 to avoid type instabilities for StochasticDiffEq.jl
165+
tlist = _check_tlist(tlist, _FType(ψ0))
166166

167167
H_eff_evo = _mcsolve_make_Heff_QobjEvo(H, sc_ops)
168168
isoper(H_eff_evo) || throw(ArgumentError("The Hamiltonian must be an Operator."))

src/time_evolution/time_evolution.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,19 @@ struct DiscreteLindbladJumpCallback <: LindbladJumpCallbackType end
212212

213213
ContinuousLindbladJumpCallback(; interp_points::Int = 10) = ContinuousLindbladJumpCallback(interp_points)
214214

215+
function _check_tlist(tlist, T::Type)
216+
tlist2 = convert(Vector{T}, tlist) # Convert it to support GPUs and avoid type instabilities for OrdinaryDiffEq.jl
217+
218+
# Check if the list of times is not empty
219+
isempty(tlist2) && throw(ArgumentError("The time list must not be empty."))
220+
# Check if the list of times is sorted
221+
issorted(tlist2) || throw(ArgumentError("The time list must be sorted."))
222+
# Check if the list of times is unique
223+
allunique(tlist2) || throw(ArgumentError("The time list must be unique."))
224+
225+
return tlist2
226+
end
227+
215228
#######################################
216229

217230
function liouvillian_floquet(

test/core-test/time_evolution.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@
6363
"abstol = $(sol2.abstol)\n" *
6464
"reltol = $(sol2.reltol)\n"
6565

66+
tlist1 = Float64[]
67+
tlist2 = [0, 0.2, 0.1]
68+
tlist3 = [0, 0.1, 0.1, 0.2]
69+
@test_throws ArgumentError sesolve(H, ψ0, tlist1, progress_bar = Val(false))
70+
@test_throws ArgumentError sesolve(H, ψ0, tlist2, progress_bar = Val(false))
71+
@test_throws ArgumentError sesolve(H, ψ0, tlist3, progress_bar = Val(false))
72+
6673
@testset "Memory Allocations" begin
6774
allocs_tot = @allocations sesolve(H, ψ0, tlist, e_ops = e_ops, progress_bar = Val(false)) # Warm-up
6875
allocs_tot = @allocations sesolve(H, ψ0, tlist, e_ops = e_ops, progress_bar = Val(false))
@@ -190,6 +197,19 @@
190197
"abstol = $(sol_sse.abstol)\n" *
191198
"reltol = $(sol_sse.reltol)\n"
192199

200+
tlist1 = Float64[]
201+
tlist2 = [0, 0.2, 0.1]
202+
tlist3 = [0, 0.1, 0.1, 0.2]
203+
@test_throws ArgumentError mesolve(H, ψ0, tlist1, c_ops, progress_bar = Val(false))
204+
@test_throws ArgumentError mesolve(H, ψ0, tlist2, c_ops, progress_bar = Val(false))
205+
@test_throws ArgumentError mesolve(H, ψ0, tlist3, c_ops, progress_bar = Val(false))
206+
@test_throws ArgumentError mcsolve(H, ψ0, tlist1, c_ops, progress_bar = Val(false))
207+
@test_throws ArgumentError mcsolve(H, ψ0, tlist2, c_ops, progress_bar = Val(false))
208+
@test_throws ArgumentError mcsolve(H, ψ0, tlist3, c_ops, progress_bar = Val(false))
209+
@test_throws ArgumentError ssesolve(H, ψ0, tlist1, c_ops, progress_bar = Val(false))
210+
@test_throws ArgumentError ssesolve(H, ψ0, tlist2, c_ops, progress_bar = Val(false))
211+
@test_throws ArgumentError ssesolve(H, ψ0, tlist3, c_ops, progress_bar = Val(false))
212+
193213
# Time-Dependent Hamiltonian
194214
# ssesolve is slow to be run on CI. It is not removed from the test because it may be useful for testing in more powerful machines.
195215

0 commit comments

Comments
 (0)