Skip to content

Mismatch between times and states in sesolve with callbacks #504

@LorenzoFioroni

Description

@LorenzoFioroni

Bug Description

When using a callback function during time evolution with mesolve, the ODE integrator may evaluate the system at additional intermediate time points beyond those explicitly specified in the input tlist. Consequently, the solution object can contain more state vectors than entries in tlist. However, the times attribute of the solution object is not updated to reflect these additional evaluations. As a result, there may be a mismatch between the number of recorded states and the number of corresponding time points, making it unclear which time each state is associated with.

Code to Reproduce the Bug

using QuantumToolbox
using DifferentialEquations

H_tuple = (
    sum(multisite_operator(Val(3), i => sigmaz()) for i  1:3),
    ((multisite_operator(Val(3), i => sigmax()), (p, t) -> p.g[i]) for i  1:3)...
)
H_t = QobjEvo(H_tuple)
    
ψ0 = basis(8, 0, dims=(2,2,2))
t_list = collect(LinRange(0.0, 10.0, 100))

quench_disorder!(integrator) = begin
    integrator.p.g .= randn(3)
    return nothing
end
quench_callback = PeriodicCallback(quench_disorder!, 0.25)
initial_disorder = randn(3) 

problem = sesolveProblem(H_t, ψ0, t_list, params=(g=initial_disorder,), callback=quench_callback)
solution = sesolve(problem)

println("Number of states: ", length(solution.states))
println("Number of times: ", length(solution.times))

Code Output

Number of states: 178
Number of times: 100

Expected Behaviour

One would expect the solution object to be constructed using the states and corresponding time points as returned by the integrator. However, the current behavior is inconsistent: while the states are taken from the times at which the integrator evaluates the system, the times attribute of the solution object is retained as the original tlist provided to mesolve.

I think the problem is in line 208 from the snipped below. The times are initialised to prob.time instead of to those actually visited by the integrator.

return TimeEvolutionSol(
prob.times,
ρt,
_get_expvals(sol, SaveFuncMESolve),
sol.retcode,
sol.alg,
NamedTuple(sol.prob.kwargs).abstol,
NamedTuple(sol.prob.kwargs).reltol,
)

Your Environment

Package information:
====================================
Julia              Ver. 1.11.5
QuantumToolbox     Ver. 0.32.1
SciMLOperators     Ver. 0.4.0
LinearSolve        Ver. 3.18.2
OrdinaryDiffEqCore Ver. 1.26.2

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions