Skip to content

Commit 1471726

Browse files
author
cailixun
committed
add support of QobjEvo for SteadyStateODESolver
1 parent a61bfa2 commit 1471726

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
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+
- Add support of `QobjEvo` for `steadystate` (ODE solver only). ([#536])
11+
1012
## [v0.34.1]
1113
Release date: 2025-08-23
1214

@@ -301,3 +303,4 @@ Release date: 2024-11-13
301303
[#517]: https://github.com/qutip/QuantumToolbox.jl/issues/517
302304
[#520]: https://github.com/qutip/QuantumToolbox.jl/issues/520
303305
[#531]: https://github.com/qutip/QuantumToolbox.jl/issues/531
306+
[#536]: https://github.com/qutip/QuantumToolbox.jl/issues/536

src/steadystate.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ end
9696

9797
@doc raw"""
9898
steadystate(
99-
H::QuantumObject{OpType},
99+
H::AbstractQuantumObject{OpType},
100100
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
101101
solver::SteadyStateSolver = SteadyStateDirectSolver(),
102102
kwargs...,
@@ -111,7 +111,7 @@ Solve the stationary state based on different solvers.
111111
- `kwargs`: The keyword arguments for the solver.
112112
"""
113113
function steadystate(
114-
H::QuantumObject{OpType},
114+
H::AbstractQuantumObject{OpType},
115115
c_ops::Union{Nothing,AbstractVector,Tuple} = nothing;
116116
solver::SteadyStateSolver = SteadyStateDirectSolver(),
117117
kwargs...,
@@ -199,7 +199,7 @@ function _steadystate(L::QuantumObject{SuperOperator}, solver::SteadyStateDirect
199199
return QuantumObject(ρss, Operator(), L.dimensions)
200200
end
201201

202-
function _steadystate(L::QuantumObject{SuperOperator}, solver::SteadyStateODESolver; kwargs...)
202+
function _steadystate(L::AbstractQuantumObject{SuperOperator}, solver::SteadyStateODESolver; kwargs...)
203203
tmax = solver.tmax
204204

205205
ψ0 = isnothing(solver.ψ0) ? rand_ket(L.dimensions) : solver.ψ0
@@ -224,6 +224,9 @@ function _steadystate(L::QuantumObject{SuperOperator}, solver::SteadyStateODESol
224224
return ρss
225225
end
226226

227+
_steadystate(L::QuantumObjectEvolution{SuperOperator}, solver::SteadyStateSolver; kwargs...) =
228+
throw(ArgumentError("$(get_typename_wrapper(solver)) does not support QobjEvo."))
229+
227230
struct SteadyStateODECondition{CT<:AbstractArray}
228231
cache::CT
229232
end

test/core-test/steady_state.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
a = destroy(N)
44
a_d = a'
55
H = a_d * a + 0.1 * (a + a_d)
6+
Ht = QobjEvo(H, (p, t) -> 1) # for test throw
67
c_ops = [sqrt(0.1) * a]
78
e_ops = [a_d * a]
89
psi0 = fock(N, 3)
@@ -17,18 +18,17 @@
1718
solver = SteadyStateDirectSolver()
1819
ρ_ss = steadystate(H, c_ops, solver = solver)
1920
@test tracedist(rho_me, ρ_ss) < 1e-4
21+
@test_throws ArgumentError steadystate(Ht, c_ops, solver = solver)
2022

2123
solver = SteadyStateLinearSolver()
2224
ρ_ss = steadystate(H, c_ops, solver = solver)
2325
@test tracedist(rho_me, ρ_ss) < 1e-4
24-
25-
solver = SteadyStateLinearSolver()
26-
ρ_ss = steadystate(H, c_ops, solver = solver)
27-
@test tracedist(rho_me, ρ_ss) < 1e-4
26+
@test_throws ArgumentError steadystate(Ht, c_ops, solver = solver)
2827

2928
solver = SteadyStateEigenSolver()
3029
ρ_ss = steadystate(H, c_ops, solver = solver)
3130
@test tracedist(rho_me, ρ_ss) < 1e-4
31+
@test_throws ArgumentError steadystate(Ht, c_ops, solver = solver)
3232

3333
@testset "Type Inference (steadystate)" begin
3434
L = liouvillian(H, c_ops)

test/ext-test/cpu/autodiff/autodiff.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ function my_f_mesolve(p)
6767
return real(expect(a' * a, sol.states[end]))
6868
end
6969

70+
function my_f_steadystate(p)
71+
ρss = steadystate(
72+
L,
73+
SteadyStateODESolver(ψ0 = ψ0_mesolve, tmax = tlist_mesolve[end]);
74+
params = p,
75+
sensealg = BacksolveAdjoint(autojacvec = EnzymeVJP()),
76+
)
77+
78+
return real(expect(a' * a, ρss))
79+
end
80+
7081
# Analytical solution
7182
n_ss(Δ, F, γ) = abs2(F /+ 1im * γ / 2))
7283

@@ -113,8 +124,12 @@ n_ss(Δ, F, γ) = abs2(F / (Δ + 1im * γ / 2))
113124

114125
my_f_mesolve_direct(params)
115126
my_f_mesolve(params)
127+
my_f_steadystate(params)
116128

129+
# calculate exact solution and check if steadystate works
117130
grad_exact = Zygote.gradient((p) -> n_ss(p[1], p[2], p[3]), params)[1]
131+
grad_ss = Zygote.gradient(my_f_steadystate, params)[1]
132+
@test grad_ss grad_exact atol=1e-6
118133

119134
@testset "ForwardDiff.jl" begin
120135
grad_qt = ForwardDiff.gradient(my_f_mesolve_direct, params)

0 commit comments

Comments
 (0)