Skip to content

Commit 9d7f6b3

Browse files
Fix noise derivative definition
1 parent 9832ecc commit 9d7f6b3

File tree

3 files changed

+24
-11
lines changed

3 files changed

+24
-11
lines changed

src/time_evolution/callback_helpers/callback_helpers.jl

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,17 @@ function _generate_stochastic_kwargs(
2424
) where {SF<:AbstractSaveFunc}
2525
cb_save = _generate_stochastic_save_callback(e_ops, sc_ops, tlist, store_measurement, progress_bar, method)
2626

27+
# Ensure that the noise is stored in tlist. # TODO: Fix this directly in DiffEqNoiseProcess.jl
28+
# See https://github.com/SciML/DiffEqNoiseProcess.jl/issues/214 for example
29+
tstops = haskey(kwargs, :tstops) ? sort!(vcat(tlist, kwargs.tstops)) : tlist
30+
kwargs2 = merge(kwargs, (tstops = tstops,))
31+
2732
if SF === SaveFuncSSESolve
2833
cb_normalize = _ssesolve_generate_normalize_cb()
29-
return _merge_kwargs_with_callback(kwargs, CallbackSet(cb_normalize, cb_save))
34+
return _merge_kwargs_with_callback(kwargs2, CallbackSet(cb_normalize, cb_save))
3035
end
3136

32-
return _merge_kwargs_with_callback(kwargs, cb_save)
37+
return _merge_kwargs_with_callback(kwargs2, cb_save)
3338
end
3439
_generate_stochastic_kwargs(
3540
e_ops::Nothing,
@@ -69,7 +74,7 @@ function _generate_stochastic_save_callback(e_ops, sc_ops, tlist, store_measurem
6974
expvals = e_ops isa Nothing ? nothing : Array{ComplexF64}(undef, length(e_ops), length(tlist))
7075
m_expvals = getVal(store_measurement) ? Array{Float64}(undef, length(sc_ops), length(tlist) - 1) : nothing
7176

72-
_save_func = method(store_measurement, e_ops_data, m_ops_data, progr, Ref(1), expvals, m_expvals)
77+
_save_func = method(store_measurement, e_ops_data, m_ops_data, progr, Ref(1), expvals, m_expvals, tlist)
7378
return FunctionCallingCallback(_save_func, funcat = tlist)
7479
end
7580

@@ -163,8 +168,12 @@ _get_save_callback_idx(cb, method) = 1
163168
# %% ------------ Noise Measurement Helpers ------------ %%
164169

165170
# TODO: Add some cache mechanism to avoid memory allocations
166-
function _homodyne_dWdt(integrator)
167-
@inbounds _dWdt = (integrator.W.u[end] .- integrator.W.u[end-1]) ./ (integrator.W.t[end] - integrator.W.t[end-1])
171+
# TODO: To improve. See https://github.com/SciML/DiffEqNoiseProcess.jl/issues/214
172+
function _homodyne_dWdt(integrator, tlist, iter)
173+
idx = findfirst(>=(tlist[iter[]-1]), integrator.W.t)
174+
175+
# We are assuming that the last element is tlist[iter[]]
176+
@inbounds _dWdt = (integrator.W.u[end] .- integrator.W.u[idx]) ./ (integrator.W.t[end] - integrator.W.t[idx])
168177

169178
return _dWdt
170179
end

src/time_evolution/callback_helpers/smesolve_callback_helpers.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ struct SaveFuncSMESolve{
1010
IT,
1111
TEXPV<:Union{Nothing,AbstractMatrix},
1212
TMEXPV<:Union{Nothing,AbstractMatrix},
13+
TLT<:AbstractVector,
1314
} <: AbstractSaveFunc
1415
store_measurement::Val{SM}
1516
e_ops::TE
@@ -18,10 +19,11 @@ struct SaveFuncSMESolve{
1819
iter::IT
1920
expvals::TEXPV
2021
m_expvals::TMEXPV
22+
tlist::TLT
2123
end
2224

2325
(f::SaveFuncSMESolve)(u, t, integrator) =
24-
_save_func_smesolve(u, integrator, f.e_ops, f.m_ops, f.progr, f.iter, f.expvals, f.m_expvals)
26+
_save_func_smesolve(u, integrator, f.e_ops, f.m_ops, f.progr, f.iter, f.expvals, f.m_expvals, f.tlist)
2527
(f::SaveFuncSMESolve{false,Nothing})(u, t, integrator) = _save_func(integrator, f.progr) # Common for both all solvers
2628

2729
_get_e_ops_data(e_ops, ::Type{SaveFuncSMESolve}) = _get_e_ops_data(e_ops, SaveFuncMESolve)
@@ -31,7 +33,7 @@ _get_m_ops_data(sc_ops, ::Type{SaveFuncSMESolve}) =
3133
##
3234

3335
# When e_ops is a list of operators
34-
function _save_func_smesolve(u, integrator, e_ops, m_ops, progr, iter, expvals, m_expvals)
36+
function _save_func_smesolve(u, integrator, e_ops, m_ops, progr, iter, expvals, m_expvals, tlist)
3537
# This is equivalent to tr(op * ρ), when both are matrices.
3638
# The advantage of using this convention is that We don't need
3739
# to reshape u to make it a matrix, but we reshape the e_ops once.
@@ -45,7 +47,7 @@ function _save_func_smesolve(u, integrator, e_ops, m_ops, progr, iter, expvals,
4547
end
4648

4749
if !isnothing(m_expvals) && iter[] > 1
48-
_dWdt = _homodyne_dWdt(integrator)
50+
_dWdt = _homodyne_dWdt(integrator, tlist, iter)
4951
@. m_expvals[:, iter[]-1] = real(_expect(m_ops)) + _dWdt
5052
end
5153

src/time_evolution/callback_helpers/ssesolve_callback_helpers.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ struct SaveFuncSSESolve{
1010
IT,
1111
TEXPV<:Union{Nothing,AbstractMatrix},
1212
TMEXPV<:Union{Nothing,AbstractMatrix},
13+
TLT<:AbstractVector,
1314
} <: AbstractSaveFunc
1415
store_measurement::Val{SM}
1516
e_ops::TE
@@ -18,10 +19,11 @@ struct SaveFuncSSESolve{
1819
iter::IT
1920
expvals::TEXPV
2021
m_expvals::TMEXPV
22+
tlist::TLT
2123
end
2224

2325
(f::SaveFuncSSESolve)(u, t, integrator) =
24-
_save_func_ssesolve(u, integrator, f.e_ops, f.m_ops, f.progr, f.iter, f.expvals, f.m_expvals)
26+
_save_func_ssesolve(u, integrator, f.e_ops, f.m_ops, f.progr, f.iter, f.expvals, f.m_expvals, f.tlist)
2527
(f::SaveFuncSSESolve{false,Nothing})(u, t, integrator) = _save_func(integrator, f.progr) # Common for both all solvers
2628

2729
_get_e_ops_data(e_ops, ::Type{SaveFuncSSESolve}) = get_data.(e_ops)
@@ -32,7 +34,7 @@ _get_save_callback_idx(cb, ::Type{SaveFuncSSESolve}) = 2 # The first one is the
3234
##
3335

3436
# When e_ops is a list of operators
35-
function _save_func_ssesolve(u, integrator, e_ops, m_ops, progr, iter, expvals, m_expvals)
37+
function _save_func_ssesolve(u, integrator, e_ops, m_ops, progr, iter, expvals, m_expvals, tlist)
3638
ψ = u
3739

3840
_expect = op -> dot(ψ, op, ψ)
@@ -42,7 +44,7 @@ function _save_func_ssesolve(u, integrator, e_ops, m_ops, progr, iter, expvals,
4244
end
4345

4446
if !isnothing(m_expvals) && iter[] > 1
45-
_dWdt = _homodyne_dWdt(integrator)
47+
_dWdt = _homodyne_dWdt(integrator, tlist, iter)
4648
@. m_expvals[:, iter[]-1] = real(_expect(m_ops)) + _dWdt
4749
end
4850

0 commit comments

Comments
 (0)