Skip to content

Commit 42db850

Browse files
committed
improve accuracy for ODE solvers
1 parent 16f3836 commit 42db850

File tree

12 files changed

+75
-71
lines changed

12 files changed

+75
-71
lines changed

Project.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ authors = ["Alberto Mercurio", "Yi-Te Huang"]
55

66
[deps]
77
ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
8-
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
98
DiffEqCallbacks = "459566f4-90b8-5000-8ac3-15dfb0a30def"
109
DiffEqNoiseProcess = "77a26b50-5914-5dd7-bc55-306e6241c503"
1110
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
@@ -16,7 +15,8 @@ LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
1615
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1716
LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae"
1817
OrdinaryDiffEqCore = "bbf590c4-e513-4bbe-9b18-05decba2e5d8"
19-
OrdinaryDiffEqTsit5 = "b1df2697-797e-41e3-8120-5422d3b24e4a"
18+
OrdinaryDiffEqLowOrderRK = "1344f307-1e59-4825-a18e-ace9aa3fa4c6"
19+
OrdinaryDiffEqVerner = "79d7bb75-1356-48c1-b8c0-6832512096c2"
2020
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
2121
ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca"
2222
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
@@ -45,7 +45,6 @@ QuantumToolboxMakieExt = "Makie"
4545
ArrayInterface = "6, 7"
4646
CUDA = "5.0 - 5.8"
4747
ChainRulesCore = "1"
48-
DiffEqBase = "6"
4948
DiffEqCallbacks = "4.2.1 - 4"
5049
DiffEqNoiseProcess = "5"
5150
Distributed = "1"
@@ -59,7 +58,8 @@ LinearAlgebra = "1"
5958
LinearSolve = "2, 3"
6059
Makie = "0.24"
6160
OrdinaryDiffEqCore = "1"
62-
OrdinaryDiffEqTsit5 = "1"
61+
OrdinaryDiffEqLowOrderRK = "1"
62+
OrdinaryDiffEqVerner = "1"
6363
Pkg = "1"
6464
ProgressMeter = "1.11.0"
6565
Random = "1"

src/QuantumToolbox.jl

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
module QuantumToolbox
22

3-
# Standard Julia libraries
3+
## Standard Julia libraries
44
using LinearAlgebra
5-
import LinearAlgebra: checksquare
65
using SparseArrays
6+
7+
import Distributed: RemoteChannel
8+
import LinearAlgebra: checksquare
9+
import Pkg
10+
import Random: AbstractRNG, default_rng, seed!
711
import Statistics: mean, std
812

9-
# SciML packages (for QobjEvo, OrdinaryDiffEq, and LinearSolve)
13+
## SciML packages (for QobjEvo, OrdinaryDiffEq, and LinearSolve)
1014
import SciMLBase:
1115
solve,
1216
solve!,
@@ -32,8 +36,10 @@ import SciMLBase:
3236
DiscreteCallback,
3337
AbstractSciMLProblem,
3438
AbstractODEIntegrator,
35-
AbstractODESolution
36-
import StochasticDiffEq: StochasticDiffEqAlgorithm, SRA2, SRIW1
39+
AbstractODEAlgorithm,
40+
AbstractODESolution,
41+
AbstractSDEAlgorithm
42+
import StochasticDiffEq: SRA2, SRIW1
3743
import SciMLOperators:
3844
cache_operator,
3945
iscached,
@@ -49,43 +55,41 @@ import SciMLOperators:
4955
concretize
5056
import LinearSolve:
5157
SciMLLinearSolveAlgorithm, KrylovJL_MINRES, KrylovJL_GMRES, UMFPACKFactorization, OperatorAssumptions
52-
import DiffEqBase: get_tstops
5358
import DiffEqCallbacks: PeriodicCallback, FunctionCallingCallback, FunctionCallingAffect, TerminateSteadyState
54-
import OrdinaryDiffEqCore: OrdinaryDiffEqAlgorithm
55-
import OrdinaryDiffEqTsit5: Tsit5
59+
import OrdinaryDiffEqVerner: Vern7
60+
import OrdinaryDiffEqLowOrderRK: DP5
5661
import DiffEqNoiseProcess: RealWienerProcess!, RealWienerProcess
5762

58-
# other dependencies (in alphabetical order)
63+
## other dependencies (in alphabetical order)
5964
import ArrayInterface: allowed_getindex, allowed_setindex!
60-
import Distributed: RemoteChannel
6165
import FFTW: fft, ifft, fftfreq, fftshift
6266
import Graphs: connected_components, DiGraph
6367
import IncompleteLU: ilu
6468
import LaTeXStrings: @L_str
65-
import Pkg
6669
import ProgressMeter: Progress, next!
67-
import Random: AbstractRNG, default_rng, seed!
6870
import SpecialFunctions: loggamma
6971
import StaticArraysCore: SVector, MVector
7072

7173
# Export functions from the other modules
7274

73-
# LinearAlgebra
75+
## LinearAlgebra
7476
export ishermitian, issymmetric, isposdef, dot, tr, svdvals, norm, normalize, normalize!, diag, Hermitian, Symmetric
7577

76-
# SparseArrays
78+
## SparseArrays
7779
export permute
7880

79-
# SciMLOperators
81+
## SciMLOperators
8082
export cache_operator, iscached, isconstant
8183

82-
# Utility
84+
# Source files
85+
86+
## Utility
8387
include("settings.jl")
8488
include("utilities.jl")
8589
include("versioninfo.jl")
8690
include("linear_maps.jl")
8791

88-
# Quantum Object
92+
## Quantum Object
8993
include("qobj/space.jl")
9094
include("qobj/energy_restricted.jl")
9195
include("qobj/dimensions.jl")
@@ -102,7 +106,7 @@ include("qobj/superoperators.jl")
102106
include("qobj/synonyms.jl")
103107
include("qobj/block_diagonal_form.jl")
104108

105-
# time evolution
109+
## time evolution
106110
include("time_evolution/time_evolution.jl")
107111
include("time_evolution/callback_helpers/callback_helpers.jl")
108112
include("time_evolution/callback_helpers/sesolve_callback_helpers.jl")
@@ -119,7 +123,7 @@ include("time_evolution/ssesolve.jl")
119123
include("time_evolution/smesolve.jl")
120124
include("time_evolution/time_evolution_dynamical.jl")
121125

122-
# Others
126+
## Others
123127
include("correlations.jl")
124128
include("wigner.jl")
125129
include("spin_lattice.jl")
@@ -131,7 +135,7 @@ include("steadystate.jl")
131135
include("spectrum.jl")
132136
include("visualization.jl")
133137

134-
# deprecated functions
138+
## deprecated functions
135139
include("deprecated.jl")
136140

137141
end

src/qobj/eigsolve.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ end
422422
H::Union{AbstractQuantumObject{HOpType},Tuple},
423423
T::Real,
424424
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
425-
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
425+
alg::AbstractODEAlgorithm = DP5(),
426426
params::NamedTuple = NamedTuple(),
427427
ρ0::AbstractMatrix = rand_dm(prod(H.dimensions)).data,
428428
eigvals::Int = 1,
@@ -440,7 +440,7 @@ Solve the eigenvalue problem for a Liouvillian superoperator `L` using the Arnol
440440
- `H`: The Hamiltonian (or directly the Liouvillian) of the system. It can be a [`QuantumObject`](@ref), a [`QuantumObjectEvolution`](@ref), or a tuple of the form supported by [`mesolve`](@ref).
441441
- `T`: The time at which to evaluate the time evolution.
442442
- `c_ops`: A vector of collapse operators. Default is `nothing` meaning the system is closed.
443-
- `alg`: The differential equation solver algorithm. Default is `Tsit5()`.
443+
- `alg`: The differential equation solver algorithm. Default is `DP5()`.
444444
- `params`: A `NamedTuple` containing the parameters of the system.
445445
- `ρ0`: The initial density matrix. If not specified, a random density matrix is used.
446446
- `eigvals`: The number of eigenvalues to compute.
@@ -465,7 +465,7 @@ function eigsolve_al(
465465
H::Union{AbstractQuantumObject{HOpType},Tuple},
466466
T::Real,
467467
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
468-
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
468+
alg::AbstractODEAlgorithm = DP5(),
469469
params::NamedTuple = NamedTuple(),
470470
ρ0::AbstractMatrix = rand_dm(prod(H.dimensions)).data,
471471
eigvals::Int = 1,

src/steadystate.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ end
4444

4545
@doc raw"""
4646
SteadyStateODESolver(
47-
alg = Tsit5(),
47+
alg = DP5(),
4848
ψ0 = nothing,
4949
tmax = Inf,
5050
terminate_reltol = 1e-4,
@@ -66,7 +66,7 @@ or
6666
```
6767
6868
# Arguments
69-
- `alg::OrdinaryDiffEqAlgorithm=Tsit5()`: The algorithm to solve the ODE.
69+
- `alg::AbstractODEAlgorithm=DP5()`: The algorithm to solve the ODE.
7070
- `ψ0::Union{Nothing,QuantumObject}=nothing`: The initial state of the system. If not specified, a random pure state will be generated.
7171
- `tmax::Real=Inf`: The final time step for the steady state problem.
7272
- `terminate_reltol` = The relative tolerance for stationary state terminate condition. Default to `1e-4`.
@@ -78,13 +78,13 @@ or
7878
For more details about the solving `alg`orithms, please refer to [`OrdinaryDiffEq.jl`](https://docs.sciml.ai/OrdinaryDiffEq/stable/).
7979
"""
8080
Base.@kwdef struct SteadyStateODESolver{
81-
MT<:OrdinaryDiffEqAlgorithm,
81+
MT<:AbstractODEAlgorithm,
8282
ST<:Union{Nothing,QuantumObject},
8383
TT<:Real,
8484
RT<:Real,
8585
AT<:Real,
8686
} <: SteadyStateSolver
87-
alg::MT = Tsit5()
87+
alg::MT = DP5()
8888
ψ0::ST = nothing
8989
tmax::TT = Inf
9090
terminate_reltol::RT = 1e-4

src/time_evolution/lr_mesolve.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct TimeEvolutionLRSol{
2525
TS<:AbstractVector,
2626
TE<:Matrix{ComplexF64},
2727
RetT<:Enum,
28-
AlgT<:OrdinaryDiffEqAlgorithm,
28+
AlgT<:AbstractODEAlgorithm,
2929
TolT<:Real,
3030
TSZB<:AbstractVector,
3131
TM<:Vector{<:Integer},
@@ -45,7 +45,7 @@ struct TimeEvolutionLRSol{
4545
end
4646

4747
lr_mesolve_options_default = (
48-
alg = Tsit5(),
48+
alg = DP5(),
4949
progress = true,
5050
err_max = 0.0,
5151
p0 = 0.0,

src/time_evolution/mcsolve.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ end
274274
ψ0::QuantumObject{Ket},
275275
tlist::AbstractVector,
276276
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
277-
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
277+
alg::AbstractODEAlgorithm = DP5(),
278278
e_ops::Union{Nothing,AbstractVector,Tuple} = nothing,
279279
params = NullParameters(),
280280
rng::AbstractRNG = default_rng(),
@@ -329,7 +329,7 @@ If the environmental measurements register a quantum jump, the wave function und
329329
- `ψ0`: Initial state of the system ``|\psi(0)\rangle``.
330330
- `tlist`: List of time points at which to save either the state or the expectation values of the system.
331331
- `c_ops`: List of collapse operators ``\{\hat{C}_n\}_n``. It can be either a `Vector` or a `Tuple`.
332-
- `alg`: The algorithm to use for the ODE solver. Default to `Tsit5()`.
332+
- `alg`: The algorithm to use for the ODE solver. Default to `DP5()`.
333333
- `e_ops`: List of operators for which to calculate expectation values. It can be either a `Vector` or a `Tuple`.
334334
- `params`: Parameters to pass to the solver. This argument is usually expressed as a `NamedTuple` or `AbstractVector` of parameters. For more advanced usage, any custom struct can be used.
335335
- `rng`: Random number generator for reproducibility.
@@ -361,7 +361,7 @@ function mcsolve(
361361
ψ0::QuantumObject{Ket},
362362
tlist::AbstractVector,
363363
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
364-
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
364+
alg::AbstractODEAlgorithm = DP5(),
365365
e_ops::Union{Nothing,AbstractVector,Tuple} = nothing,
366366
params = NullParameters(),
367367
rng::AbstractRNG = default_rng(),
@@ -398,7 +398,7 @@ end
398398

399399
function mcsolve(
400400
ens_prob_mc::TimeEvolutionProblem,
401-
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
401+
alg::AbstractODEAlgorithm = DP5(),
402402
ntraj::Int = 500,
403403
ensemblealg::EnsembleAlgorithm = EnsembleThreads(),
404404
keep_runs_results = Val(false),

src/time_evolution/mesolve.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ end
129129
ψ0::QuantumObject,
130130
tlist::AbstractVector,
131131
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
132-
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
132+
alg::AbstractODEAlgorithm = DP5(),
133133
e_ops::Union{Nothing,AbstractVector,Tuple} = nothing,
134134
params = NullParameters(),
135135
progress_bar::Union{Val,Bool} = Val(true),
@@ -155,7 +155,7 @@ where
155155
- `ψ0`: Initial state of the system ``|\psi(0)\rangle``. It can be either a [`Ket`](@ref), [`Operator`](@ref) or [`OperatorKet`](@ref).
156156
- `tlist`: List of time points at which to save either the state or the expectation values of the system.
157157
- `c_ops`: List of collapse operators ``\{\hat{C}_n\}_n``. It can be either a `Vector` or a `Tuple`.
158-
- `alg`: The algorithm for the ODE solver. The default value is `Tsit5()`.
158+
- `alg`: The algorithm for the ODE solver. The default value is `DP5()`.
159159
- `e_ops`: List of operators for which to calculate expectation values. It can be either a `Vector` or a `Tuple`.
160160
- `params`: Parameters to pass to the solver. This argument is usually expressed as a `NamedTuple` or `AbstractVector` of parameters. For more advanced usage, any custom struct can be used.
161161
- `progress_bar`: Whether to show the progress bar. Using non-`Val` types might lead to type instabilities.
@@ -180,7 +180,7 @@ function mesolve(
180180
ψ0::QuantumObject{StateOpType},
181181
tlist::AbstractVector,
182182
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
183-
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
183+
alg::AbstractODEAlgorithm = DP5(),
184184
e_ops::Union{Nothing,AbstractVector,Tuple} = nothing,
185185
params = NullParameters(),
186186
progress_bar::Union{Val,Bool} = Val(true),
@@ -225,7 +225,7 @@ function mesolve(
225225
end
226226
end
227227

228-
function mesolve(prob::TimeEvolutionProblem, alg::OrdinaryDiffEqAlgorithm = Tsit5(); kwargs...)
228+
function mesolve(prob::TimeEvolutionProblem, alg::AbstractODEAlgorithm = DP5(); kwargs...)
229229
sol = solve(prob.prob, alg; kwargs...)
230230

231231
return _gen_mesolve_solution(sol, prob.times, prob.dimensions, prob.kwargs.isoperket)
@@ -237,7 +237,7 @@ end
237237
ψ0::Union{QuantumObject,AbstractVector{<:QuantumObject}},
238238
tlist::AbstractVector,
239239
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
240-
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
240+
alg::AbstractODEAlgorithm = DP5(),
241241
ensemblealg::EnsembleAlgorithm = EnsembleThreads(),
242242
e_ops::Union{Nothing,AbstractVector,Tuple} = nothing,
243243
params::Union{NullParameters,Tuple} = NullParameters(),
@@ -267,7 +267,7 @@ for each combination in the ensemble.
267267
- `ψ0`: Initial state(s) of the system. Can be a single [`QuantumObject`](@ref) or a `Vector` of initial states. It can be either a [`Ket`](@ref), [`Operator`](@ref) or [`OperatorKet`](@ref).
268268
- `tlist`: List of time points at which to save either the state or the expectation values of the system.
269269
- `c_ops`: List of collapse operators ``\{\hat{C}_n\}_n``. It can be either a `Vector` or a `Tuple`.
270-
- `alg`: The algorithm for the ODE solver. The default is `Tsit5()`.
270+
- `alg`: The algorithm for the ODE solver. The default is `DP5()`.
271271
- `ensemblealg`: Ensemble algorithm to use for parallel computation. Default is `EnsembleThreads()`.
272272
- `e_ops`: List of operators for which to calculate expectation values. It can be either a `Vector` or a `Tuple`.
273273
- `params`: A `Tuple` of parameter sets. Each element should be an `AbstractVector` representing the sweep range for that parameter. The function will solve for all combinations of initial states and parameter sets.
@@ -290,7 +290,7 @@ function mesolve_map(
290290
ψ0::AbstractVector{<:QuantumObject{StateOpType}},
291291
tlist::AbstractVector,
292292
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
293-
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
293+
alg::AbstractODEAlgorithm = DP5(),
294294
ensemblealg::EnsembleAlgorithm = EnsembleThreads(),
295295
e_ops::Union{Nothing,AbstractVector,Tuple} = nothing,
296296
params::Union{NullParameters,Tuple} = NullParameters(),
@@ -357,7 +357,7 @@ mesolve_map(
357357
function mesolve_map(
358358
prob::TimeEvolutionProblem{<:ODEProblem},
359359
iter::AbstractArray,
360-
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
360+
alg::AbstractODEAlgorithm = DP5(),
361361
ensemblealg::EnsembleAlgorithm = EnsembleThreads();
362362
prob_func::Union{Function,Nothing} = nothing,
363363
output_func::Union{Tuple,Nothing} = nothing,

0 commit comments

Comments
 (0)