From 81638090e7107e21b89e45d096d2a95f3ecf6482 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 29 Aug 2025 15:08:29 +0800 Subject: [PATCH 1/7] Fix keyword argument handling for `SteadyStateODESolver` --- CHANGELOG.md | 2 ++ src/steadystate.jl | 49 +++++++++++++++++++++++++--------------------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f71b63114..3e3b13b40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) - Add support of `QobjEvo` for `steadystate` (ODE solver only). ([#536]) +- Fix keyword argument handling for `SteadyStateODESolver`. ([#537]) ## [v0.34.1] Release date: 2025-08-23 @@ -304,3 +305,4 @@ Release date: 2024-11-13 [#520]: https://github.com/qutip/QuantumToolbox.jl/issues/520 [#531]: https://github.com/qutip/QuantumToolbox.jl/issues/531 [#536]: https://github.com/qutip/QuantumToolbox.jl/issues/536 +[#537]: https://github.com/qutip/QuantumToolbox.jl/issues/537 diff --git a/src/steadystate.jl b/src/steadystate.jl index 7e55911ac..78d8fc902 100644 --- a/src/steadystate.jl +++ b/src/steadystate.jl @@ -47,11 +47,11 @@ end alg = Tsit5(), ψ0 = nothing, tmax = Inf, - ) - -An ordinary differential equation (ODE) solver for solving [`steadystate`](@ref). + terminate_reltol = 1e-5, + terminate_abstol = 1e-7 + ) -Solve the stationary state based on time evolution (ordinary differential equations; `OrdinaryDiffEq.jl`) with a given initial state. +An ordinary differential equation (ODE) solver for solving [`steadystate`](@ref). It solves the stationary state based on [`mesolve`](@ref) with a termination condition. The termination condition of the stationary state ``|\rho\rangle\rangle`` is that either the following condition is `true`: @@ -69,14 +69,21 @@ or - `alg::OrdinaryDiffEqAlgorithm=Tsit5()`: The algorithm to solve the ODE. - `ψ0::Union{Nothing,QuantumObject}=nothing`: The initial state of the system. If not specified, a random pure state will be generated. - `tmax::Real=Inf`: The final time step for the steady state problem. +- `terminate_reltol` = The relative tolerance for stationary state terminate condition. Default to `1e-5`. +- `terminate_abstol` = The absolute tolerance for stationary state terminate condition. Default to `1e-7`. + +!!! warning "Tolerances for terminate condition" + The terminate condition tolerances `terminate_reltol` and `terminate_abstol` should be larger than `reltol` and `abstol` of [`mesolve`](@ref), respectively. -For more details about the solvers, please refer to [`OrdinaryDiffEq.jl`](https://docs.sciml.ai/OrdinaryDiffEq/stable/). +For more details about the solving `alg`orithms, please refer to [`OrdinaryDiffEq.jl`](https://docs.sciml.ai/OrdinaryDiffEq/stable/). """ Base.@kwdef struct SteadyStateODESolver{MT<:OrdinaryDiffEqAlgorithm,ST<:Union{Nothing,QuantumObject},T<:Real} <: SteadyStateSolver alg::MT = Tsit5() ψ0::ST = nothing tmax::T = Inf + terminate_reltol::Real = 10 * DEFAULT_ODE_SOLVER_OPTIONS.reltol + terminate_abstol::Real = 10 * DEFAULT_ODE_SOLVER_OPTIONS.abstol end @doc raw""" @@ -200,27 +207,25 @@ function _steadystate(L::QuantumObject{SuperOperator}, solver::SteadyStateDirect end function _steadystate(L::AbstractQuantumObject{SuperOperator}, solver::SteadyStateODESolver; kwargs...) - tmax = solver.tmax - ψ0 = isnothing(solver.ψ0) ? rand_ket(L.dimensions) : solver.ψ0 - abstol = haskey(kwargs, :abstol) ? kwargs[:abstol] : DEFAULT_ODE_SOLVER_OPTIONS.abstol - reltol = haskey(kwargs, :reltol) ? kwargs[:reltol] : DEFAULT_ODE_SOLVER_OPTIONS.reltol - ftype = _float_type(ψ0) - _terminate_func = SteadyStateODECondition(similar(mat2vec(ket2dm(ψ0)).data)) - cb = TerminateSteadyState(abstol, reltol, _terminate_func) - sol = mesolve( - L, - ψ0, - [ftype(0), ftype(tmax)]; - alg = solver.alg, - progress_bar = Val(false), - save_everystep = false, - saveat = ftype[], - callback = cb, - kwargs..., + tlist = [ftype(0), ftype(solver.tmax)] + + # overwrite some kwargs and throw warning message to tell the users that we are ignoring these settings + haskey(kwargs, :progress_bar) && @warn "Ignore keyword argument 'progress_bar' for SteadyStateODESolver" + haskey(kwargs, :save_everystep) && @warn "Ignore keyword argument 'save_everystep' for SteadyStateODESolver" + haskey(kwargs, :saveat) && @warn "Ignore keyword argument 'saveat' for SteadyStateODESolver" + kwargs2 = merge(kwargs, (progress_bar = Val(false), save_everystep = false, saveat = ftype[])) + + # add terminate condition (callback) + cb = TerminateSteadyState( + solver.terminate_abstol, + solver.terminate_reltol, + SteadyStateODECondition(similar(mat2vec(ket2dm(ψ0)).data)), ) + kwargs3 = _merge_kwargs_with_callback(kwargs2, cb) + sol = mesolve(L, ψ0, tlist; kwargs3...) ρss = sol.states[end] return ρss end From ebc27a360492e2937772930b45ef688a751f5912 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 29 Aug 2025 15:30:23 +0800 Subject: [PATCH 2/7] fix typo --- src/steadystate.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/steadystate.jl b/src/steadystate.jl index 78d8fc902..9b64a8e1b 100644 --- a/src/steadystate.jl +++ b/src/steadystate.jl @@ -215,7 +215,10 @@ function _steadystate(L::AbstractQuantumObject{SuperOperator}, solver::SteadySta haskey(kwargs, :progress_bar) && @warn "Ignore keyword argument 'progress_bar' for SteadyStateODESolver" haskey(kwargs, :save_everystep) && @warn "Ignore keyword argument 'save_everystep' for SteadyStateODESolver" haskey(kwargs, :saveat) && @warn "Ignore keyword argument 'saveat' for SteadyStateODESolver" - kwargs2 = merge(kwargs, (progress_bar = Val(false), save_everystep = false, saveat = ftype[])) + kwargs2 = merge( + NamedTuple(kwargs), # we convert to NamedTuple just in case if kwargs is empty + (progress_bar = Val(false), save_everystep = false, saveat = ftype[]), + ) # add terminate condition (callback) cb = TerminateSteadyState( From b44b2b7bc81173dd151da593d38c6d65fb7ad552 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 29 Aug 2025 20:04:55 +0800 Subject: [PATCH 3/7] fix type instability --- src/steadystate.jl | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/steadystate.jl b/src/steadystate.jl index 9b64a8e1b..a7114bf13 100644 --- a/src/steadystate.jl +++ b/src/steadystate.jl @@ -77,13 +77,18 @@ or For more details about the solving `alg`orithms, please refer to [`OrdinaryDiffEq.jl`](https://docs.sciml.ai/OrdinaryDiffEq/stable/). """ -Base.@kwdef struct SteadyStateODESolver{MT<:OrdinaryDiffEqAlgorithm,ST<:Union{Nothing,QuantumObject},T<:Real} <: - SteadyStateSolver +Base.@kwdef struct SteadyStateODESolver{ + MT<:OrdinaryDiffEqAlgorithm, + ST<:Union{Nothing,QuantumObject}, + T1<:Real, + T2<:Real, + T3<:Real, +} <: SteadyStateSolver alg::MT = Tsit5() ψ0::ST = nothing - tmax::T = Inf - terminate_reltol::Real = 10 * DEFAULT_ODE_SOLVER_OPTIONS.reltol - terminate_abstol::Real = 10 * DEFAULT_ODE_SOLVER_OPTIONS.abstol + tmax::T1 = Inf + terminate_reltol::T2 = 10 * DEFAULT_ODE_SOLVER_OPTIONS.reltol + terminate_abstol::T3 = 10 * DEFAULT_ODE_SOLVER_OPTIONS.abstol end @doc raw""" From 2c95bad4b60b6a8bd6b3a99af759ad62a3837795 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 29 Aug 2025 20:07:40 +0800 Subject: [PATCH 4/7] minor changes --- src/steadystate.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/steadystate.jl b/src/steadystate.jl index a7114bf13..49ce2f44c 100644 --- a/src/steadystate.jl +++ b/src/steadystate.jl @@ -80,15 +80,15 @@ For more details about the solving `alg`orithms, please refer to [`OrdinaryDiffE Base.@kwdef struct SteadyStateODESolver{ MT<:OrdinaryDiffEqAlgorithm, ST<:Union{Nothing,QuantumObject}, - T1<:Real, - T2<:Real, - T3<:Real, + TT<:Real, + RT<:Real, + AT<:Real, } <: SteadyStateSolver alg::MT = Tsit5() ψ0::ST = nothing - tmax::T1 = Inf - terminate_reltol::T2 = 10 * DEFAULT_ODE_SOLVER_OPTIONS.reltol - terminate_abstol::T3 = 10 * DEFAULT_ODE_SOLVER_OPTIONS.abstol + tmax::TT = Inf + terminate_reltol::RT = 10 * DEFAULT_ODE_SOLVER_OPTIONS.reltol + terminate_abstol::AT = 10 * DEFAULT_ODE_SOLVER_OPTIONS.abstol end @doc raw""" From 0631a95ca1d63fcfaf703842455a68e50bafd90d Mon Sep 17 00:00:00 2001 From: Yi-Te Huang <44385685+ytdHuang@users.noreply.github.com> Date: Sat, 30 Aug 2025 15:37:30 +0800 Subject: [PATCH 5/7] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e3b13b40..7d6244361 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main) - Add support of `QobjEvo` for `steadystate` (ODE solver only). ([#536]) -- Fix keyword argument handling for `SteadyStateODESolver`. ([#537]) +- Changes to `SteadyStateODESolver`. ([#537]) + - Introduce the terminate tolerances for calculating `steadystate` (two new fields: `terminate_abstol = 1e-5` and `terminate_abstol = 1e-7`) + - Fix keyword argument handling for `SteadyStateODESolver`. ## [v0.34.1] Release date: 2025-08-23 From b19452a3e06f5cb769674ea2287d54ca5701251a Mon Sep 17 00:00:00 2001 From: Yi-Te Huang <44385685+ytdHuang@users.noreply.github.com> Date: Sat, 30 Aug 2025 15:39:58 +0800 Subject: [PATCH 6/7] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d6244361..decab2c75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add support of `QobjEvo` for `steadystate` (ODE solver only). ([#536]) - Changes to `SteadyStateODESolver`. ([#537]) - - Introduce the terminate tolerances for calculating `steadystate` (two new fields: `terminate_abstol = 1e-5` and `terminate_abstol = 1e-7`) + - Introduce the terminate tolerances for `steadystate` terminate condition (two new fields: `terminate_reltol = 1e-5` and `terminate_abstol = 1e-7`) - Fix keyword argument handling for `SteadyStateODESolver`. ## [v0.34.1] From 7ee2583fea34eddda2c5b1d6bca53c5b6bb99b40 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang <44385685+ytdHuang@users.noreply.github.com> Date: Sat, 30 Aug 2025 15:40:42 +0800 Subject: [PATCH 7/7] Update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index decab2c75..0985357d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add support of `QobjEvo` for `steadystate` (ODE solver only). ([#536]) - Changes to `SteadyStateODESolver`. ([#537]) - - Introduce the terminate tolerances for `steadystate` terminate condition (two new fields: `terminate_reltol = 1e-5` and `terminate_abstol = 1e-7`) - - Fix keyword argument handling for `SteadyStateODESolver`. + - Introduce the tolerances for `steadystate` terminate condition (two new fields: `terminate_reltol = 1e-5` and `terminate_abstol = 1e-7`) + - Fix keyword argument handling for `SteadyStateODESolver` before passing to `mesolve`. ## [v0.34.1] Release date: 2025-08-23