Skip to content

Commit f365582

Browse files
Make everything type stable
1 parent cb8cfad commit f365582

File tree

7 files changed

+41
-52
lines changed

7 files changed

+41
-52
lines changed

src/qobj/superoperators.jl

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -180,18 +180,5 @@ liouvillian(H::AbstractQuantumObject{Operator}, Id_cache::Diagonal = I(prod(H.di
180180
liouvillian(H::AbstractQuantumObject{SuperOperator}, Id_cache::Diagonal) = H
181181

182182
function _sum_lindblad_dissipators(c_ops, Id_cache::Diagonal)
183-
D = 0
184-
# sum all the (time-independent) c_ops first
185-
c_ops_ti = filter(op -> isa(op, QuantumObject), c_ops)
186-
if !isempty(c_ops_ti)
187-
D += mapreduce(op -> lindblad_dissipator(op, Id_cache), +, c_ops_ti)
188-
end
189-
190-
# sum rest of the QobjEvo together
191-
c_ops_td = filter(op -> isa(op, QuantumObjectEvolution), c_ops)
192-
if !isempty(c_ops_td)
193-
D += mapreduce(op -> lindblad_dissipator(op, Id_cache), +, c_ops_td)
194-
end
195-
196-
return D
183+
return sum(op -> lindblad_dissipator(op, Id_cache), c_ops; init = zero(spre(first(c_ops), Id_cache)))
197184
end

src/time_evolution/brmesolve.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export bloch_redfield_tensor, brterm, brmesolve
33
@doc raw"""
44
bloch_redfield_tensor(
55
H::QuantumObject{Operator},
6-
a_ops::Union{AbstractVector, Tuple},
6+
a_ops::Union{AbstractVector, Tuple, Nothing},
77
c_ops::Union{AbstractVector, Tuple, Nothing}=nothing;
88
sec_cutoff::Real=0.1,
99
fock_basis::Union{Val,Bool}=Val(false)
@@ -28,7 +28,7 @@ The return depends on `fock_basis`.
2828
"""
2929
function bloch_redfield_tensor(
3030
H::QuantumObject{Operator},
31-
a_ops::Union{AbstractVector,Tuple},
31+
a_ops::Union{AbstractVector,Tuple,Nothing},
3232
c_ops::Union{AbstractVector,Tuple,Nothing} = nothing;
3333
sec_cutoff::Real = 0.1,
3434
fock_basis::Union{Val,Bool} = Val(false),
@@ -44,7 +44,9 @@ function bloch_redfield_tensor(
4444
# Check whether we can rotate the terms to the eigenbasis directly in the Hamiltonian space
4545
fock_basis_hamiltonian = getVal(fock_basis) && sec_cutoff == -1
4646

47-
R = isempty(a_ops) ? 0 : sum(x -> _brterm(rst, x[1], x[2], sec_cutoff, fock_basis_hamiltonian), a_ops)
47+
R =
48+
(isnothing(a_ops) || isempty(a_ops)) ? 0 :
49+
sum(x -> _brterm(rst, x[1], x[2], sec_cutoff, fock_basis_hamiltonian), a_ops)
4850

4951
# If in fock basis, we need to transform the terms back to the fock basis
5052
# Note: we can transform the terms in the Hamiltonian space only if sec_cutoff is -1

src/time_evolution/mesolve.jl

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -339,13 +339,7 @@ function mesolve_map(
339339
ens_prob = TimeEvolutionProblem(
340340
EnsembleProblem(
341341
prob.prob,
342-
prob_func = (prob, i, repeat) -> remake(
343-
prob,
344-
f = deepcopy(prob.f.f),
345-
u0 = iter[i][1],
346-
p = iter[i][2:end],
347-
callback = haskey(prob.kwargs, :callback) ? deepcopy(prob.kwargs[:callback]) : nothing,
348-
),
342+
prob_func = (prob, i, repeat) -> _se_me_map_prob_func(prob, i, repeat, iter),
349343
output_func = _output_func[1],
350344
safetycopy = false,
351345
),
@@ -357,7 +351,7 @@ function mesolve_map(
357351

358352
# handle solution and make it become an Array of TimeEvolutionSol
359353
sol_vec =
360-
[_gen_mesolve_solution(sol[:, i], prob.times, prob.dimensions, prob.kwargs.isoperket) for i in eachindex(sol)]
354+
[_gen_mesolve_solution(sol[:, i], prob.times, prob.dimensions, prob.kwargs.isoperket) for i in eachindex(sol)] # map is type unstable
361355
return reshape(sol_vec, size(iter))
362356
end
363357
mesolve_map(

src/time_evolution/sesolve.jl

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,23 @@ export sesolveProblem, sesolve, sesolve_map
22

33
_sesolve_make_U_QobjEvo(H) = -1im * QuantumObjectEvolution(H, type = Operator())
44

5+
function _gen_sesolve_solution(sol, times, dimensions)
6+
ψt = map-> QuantumObject(ϕ, type = Ket(), dims = dimensions), sol.u)
7+
8+
kwargs = NamedTuple(sol.prob.kwargs) # Convert to NamedTuple for Zygote.jl compatibility
9+
10+
return TimeEvolutionSol(
11+
times,
12+
sol.t,
13+
ψt,
14+
_get_expvals(sol, SaveFuncSESolve),
15+
sol.retcode,
16+
sol.alg,
17+
kwargs.abstol,
18+
kwargs.reltol,
19+
)
20+
end
21+
522
@doc raw"""
623
sesolveProblem(
724
H::Union{AbstractQuantumObject{Operator},Tuple},
@@ -160,23 +177,6 @@ function sesolve(prob::TimeEvolutionProblem, alg::OrdinaryDiffEqAlgorithm = Tsit
160177
return _gen_sesolve_solution(sol, prob.times, prob.dimensions)
161178
end
162179

163-
function _gen_sesolve_solution(sol, times, dimensions)
164-
ψt = map-> QuantumObject(ϕ, type = Ket(), dims = dimensions), sol.u)
165-
166-
kwargs = NamedTuple(sol.prob.kwargs) # Convert to NamedTuple for Zygote.jl compatibility
167-
168-
return TimeEvolutionSol(
169-
times,
170-
sol.t,
171-
ψt,
172-
_get_expvals(sol, SaveFuncSESolve),
173-
sol.retcode,
174-
sol.alg,
175-
kwargs.abstol,
176-
kwargs.reltol,
177-
)
178-
end
179-
180180
@doc raw"""
181181
sesolve_map(
182182
H::Union{AbstractQuantumObject{Operator},Tuple},
@@ -254,13 +254,7 @@ function sesolve_map(
254254
ens_prob = TimeEvolutionProblem(
255255
EnsembleProblem(
256256
prob.prob,
257-
prob_func = (prob, i, repeat) -> remake(
258-
prob,
259-
f = deepcopy(prob.f.f),
260-
u0 = iter[i][1],
261-
p = iter[i][2:end],
262-
callback = haskey(prob.kwargs, :callback) ? deepcopy(prob.kwargs[:callback]) : nothing,
263-
),
257+
prob_func = (prob, i, repeat) -> _se_me_map_prob_func(prob, i, repeat, iter),
264258
output_func = _output_func[1],
265259
safetycopy = false,
266260
),
@@ -271,7 +265,7 @@ function sesolve_map(
271265
sol = _ensemble_dispatch_solve(ens_prob, alg, ensemblealg, ntraj)
272266

273267
# handle solution and make it become an Array of TimeEvolutionSol
274-
sol_vec = [_gen_sesolve_solution(sol[:, i], prob.times, prob.dimensions) for i in eachindex(sol)]
268+
sol_vec = [_gen_sesolve_solution(sol[:, i], prob.times, prob.dimensions) for i in eachindex(sol)] # map is type unstable
275269
return reshape(sol_vec, size(iter))
276270
end
277271
sesolve_map(H::Union{AbstractQuantumObject{Operator},Tuple}, ψ0::QuantumObject{Ket}, tlist::AbstractVector; kwargs...) =

src/time_evolution/time_evolution.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,18 @@ function _ensemble_dispatch_solve(
436436
return sol
437437
end
438438

439+
# For mapped solvers
440+
function _se_me_map_prob_func(prob, i, repeat, iter)
441+
f = deepcopy(prob.f.f)
442+
u0 = iter[i][1]
443+
p = iter[i][2:end]
444+
if haskey(prob.kwargs, :callback)
445+
return remake(prob, f = f, u0 = u0, p = p, callback = deepcopy(prob.kwargs[:callback]))
446+
else
447+
return remake(prob, f = f, u0 = u0, p = p)
448+
end
449+
end
450+
439451
#######################################
440452
#=
441453
Stochastic funcs

test/core-test/brmesolve.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ end
9898
_z_c_op = γ * sigmaz()
9999
_x_a_op = (sigmax(), spectra)
100100

101-
arg_sets = [[[_m_c_op], [], [_x_a_op]], [[_m_c_op], [_m_c_op], []], [[_m_c_op, _z_c_op], [_z_c_op], [_x_a_op]]]
101+
arg_sets =
102+
(([_m_c_op], nothing, [_x_a_op]), ([_m_c_op], [_m_c_op], nothing), ([_m_c_op, _z_c_op], [_z_c_op], [_x_a_op]))
102103

103104
δ = 0
104105
ϵ = 0.5 * 2π

test/core-test/time_evolution.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,6 @@ end
154154
a = TESetup.a
155155
σz = TESetup.σz
156156
σm = TESetup.σm
157-
ψ0 = TESetup.ψ0
158157
e_ops = TESetup.e_ops
159158

160159
g = 0.01

0 commit comments

Comments
 (0)