Skip to content

Commit f8a73b7

Browse files
Fix mcsolve
1 parent b1e45cc commit f8a73b7

File tree

3 files changed

+60
-28
lines changed

3 files changed

+60
-28
lines changed

src/time_evolution/mcsolve.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ function mcsolve(
395395
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
396396
ntraj::Int = 500,
397397
ensemblealg::EnsembleAlgorithm = EnsembleThreads(),
398-
keep_runs_results::Val = Val(false),
398+
keep_runs_results = Val(false),
399399
normalize_states = Val(true),
400400
)
401401
sol = _ensemble_dispatch_solve(ens_prob_mc, alg, ensemblealg, ntraj)

src/time_evolution/time_evolution.jl

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,13 @@ A structure storing the results and some information from solving quantum trajec
118118
119119
When the keyword argument `keep_runs_results` is passed as `Val(false)` to a multi-trajectory solver, the `states` and `expect` fields store only the average results (averaged over all trajectories). The results can be accessed by the following index-order:
120120
121-
- `sol.states[time]`
122-
- `sol.expect[e_op,time]`
121+
- `sol.states[time_idx]`
122+
- `sol.expect[e_op,time_idx]`
123123
124124
If the keyword argument `keep_runs_results = Val(true)`, the results for each trajectory and each time are stored, and the index-order of the elements in fields `states` and `expect` are:
125125
126-
- `sol.states[trajectory,time]`
127-
- `sol.expect[e_op,trajectory,time]`
126+
- `sol.states[trajectory,time_idx]`
127+
- `sol.expect[e_op,trajectory,time_idx]`
128128
129129
We also provide the following functions for statistical analysis of multi-trajectory solutions:
130130
@@ -194,13 +194,13 @@ A structure storing the results and some information from solving trajectories o
194194
195195
When the keyword argument `keep_runs_results` is passed as `Val(false)` to a multi-trajectory solver, the `states` and `expect` fields store only the average results (averaged over all trajectories). The results can be accessed by the following index-order:
196196
197-
- `sol.states[time]`
198-
- `sol.expect[e_op,time]`
197+
- `sol.states[time_idx]`
198+
- `sol.expect[e_op,time_idx]`
199199
200200
If the keyword argument `keep_runs_results = Val(true)`, the results for each trajectory and each time are stored, and the index-order of the elements in fields `states` and `expect` are:
201201
202-
- `sol.states[trajectory,time]`
203-
- `sol.expect[e_op,trajectory,time]`
202+
- `sol.states[trajectory,time_idx]`
203+
- `sol.expect[e_op,trajectory,time_idx]`
204204
205205
We also provide the following functions for statistical analysis of multi-trajectory solutions:
206206
@@ -257,7 +257,7 @@ average_states(sol::TimeEvolutionMultiTrajSol{<:Vector{<:QuantumObject}}) = sol.
257257

258258
_average_traj_states(states::Matrix{<:QuantumObject{Ket}}) = dropdims(mean(ket2dm, states, dims = 1), dims = 1)
259259
_average_traj_states(states::Matrix{<:QuantumObject{ObjType}}) where {ObjType<:Union{Operator,OperatorKet}} =
260-
mean(states)
260+
dropdims(mean(states, dims = 1), dims = 1)
261261

262262
@doc raw"""
263263
average_expect(sol::TimeEvolutionMultiTrajSol)
@@ -276,24 +276,17 @@ _store_multitraj_states(states::Matrix{<:QuantumObject}, keep_runs_results::Val{
276276
_store_multitraj_expect(expvals::Array{T,3}, keep_runs_results::Val{false}) where {T<:Number} =
277277
_average_traj_expect(expvals)
278278
_store_multitraj_expect(expvals::Array{T,3}, keep_runs_results::Val{true}) where {T<:Number} = expvals
279-
_store_multitraj_expect(expvals::Nothing, keep_runs_results::Val{false}) = nothing
280-
_store_multitraj_expect(expvals::Nothing, keep_runs_results::Val{true}) = nothing
279+
_store_multitraj_expect(expvals::Nothing, keep_runs_results) = nothing
281280

282281
@doc raw"""
283282
std_expect(sol::TimeEvolutionMultiTrajSol)
284283
285284
Return the trajectory-wise standard deviation of the expectation values at each time point.
286285
"""
287286
function std_expect(sol::TimeEvolutionMultiTrajSol{TS,Array{T,3}}) where {TS,T<:Number}
288-
# the following standard deviation (std) is defined as the square-root of variance instead of pseudo-variance
289-
# i.e., it is equivalent to (even for complex expectation values):
290-
# dropdims(
291-
# sqrt.(mean(abs2.(sol.expect), dims = 2) .- abs2.(mean(sol.expect, dims = 2))),
292-
# dims = 2
293-
# )
294287
return dropdims(std(sol.expect, corrected = false, dims = 2), dims = 2)
295288
end
296-
std_expect(::TimeEvolutionMultiTrajSol{Nothing}) = nothing
289+
std_expect(::TimeEvolutionMultiTrajSol{TS,Nothing}) where {TS} = nothing
297290

298291
#######################################
299292
#=

test/core-test/time_evolution.jl

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -333,15 +333,54 @@ end
333333

334334
@testset "Memory Allocations (mcsolve)" begin
335335
ntraj = 100
336-
allocs_tot = @allocations mcsolve(H, ψ0, tlist, c_ops, e_ops = e_ops, ntraj = ntraj, progress_bar = Val(false)) # Warm-up
337-
allocs_tot = @allocations mcsolve(H, ψ0, tlist, c_ops, e_ops = e_ops, ntraj = ntraj, progress_bar = Val(false))
338-
@test allocs_tot < 120 * ntraj + 400 # 150 allocations per trajectory + 500 for initialization
339-
340-
allocs_tot =
341-
@allocations mcsolve(H, ψ0, tlist, c_ops, ntraj = ntraj, saveat = [tlist[end]], progress_bar = Val(false)) # Warm-up
342-
allocs_tot =
343-
@allocations mcsolve(H, ψ0, tlist, c_ops, ntraj = ntraj, saveat = [tlist[end]], progress_bar = Val(false))
344-
@test allocs_tot < 110 * ntraj + 300 # 100 allocations per trajectory + 300 for initialization
336+
for keep_runs_results in (Val(false), Val(true))
337+
n1 = QuantumToolbox.getVal(keep_runs_results) ? 120 : 140
338+
n2 = QuantumToolbox.getVal(keep_runs_results) ? 110 : 130
339+
340+
allocs_tot = @allocations mcsolve(
341+
H,
342+
ψ0,
343+
tlist,
344+
c_ops,
345+
e_ops = e_ops,
346+
ntraj = ntraj,
347+
progress_bar = Val(false),
348+
keep_runs_results = Val(true),
349+
) # Warm-up
350+
allocs_tot = @allocations mcsolve(
351+
H,
352+
ψ0,
353+
tlist,
354+
c_ops,
355+
e_ops = e_ops,
356+
ntraj = ntraj,
357+
progress_bar = Val(false),
358+
keep_runs_results = Val(true),
359+
)
360+
@test allocs_tot < n1 * ntraj + 400 # 150 allocations per trajectory + 500 for initialization
361+
362+
allocs_tot = @allocations mcsolve(
363+
H,
364+
ψ0,
365+
tlist,
366+
c_ops,
367+
ntraj = ntraj,
368+
saveat = [tlist[end]],
369+
progress_bar = Val(false),
370+
keep_runs_results = Val(true),
371+
) # Warm-up
372+
allocs_tot = @allocations mcsolve(
373+
H,
374+
ψ0,
375+
tlist,
376+
c_ops,
377+
ntraj = ntraj,
378+
saveat = [tlist[end]],
379+
progress_bar = Val(false),
380+
keep_runs_results = Val(true),
381+
)
382+
@test allocs_tot < n2 * ntraj + 300 # 100 allocations per trajectory + 300 for initialization
383+
end
345384
end
346385

347386
@testset "Type Inference (mcsolve)" begin

0 commit comments

Comments
 (0)