Inconsistency with SavingCallback

dnldlg
Fri, 12 Sep 2025 13:04:01 +0000
General Usage

I try to track the behavior of the parameters throughout an integration with DifferentialEquations.jl while using Callbacks. To do this I used SavingCallback, but noticed the following inconsistency with the argument saveat. Let us consider a little example: The parameter p is increased at fixed times T = \{1, ..., 9\} by some \Delta p.

using DifferentialEquations
using DiffEqCallbacks
using Plots


function f(u, p, t)
    return -1im * p * u
end

function affect!(integrator)
    integrator.p += 0.1
end

function test()
    u0 = 1.0 + 0im
    tspan = (0.0, 10.0)
    t_eval = range(tspan[1], tspan[2], length=100)

    prob = ODEProblem(f, u0, tspan, 0.5)
    cb = PresetTimeCallback(range(1, 9), affect!)

    # Defining the SavingCallback
    saved_values = SavedValues(Float64, Float64)
    savecb = SavingCallback((u, t, integrator) -> integrator.p, saved_values)
    sol = solve(prob, callback=CallbackSet(cb, savecb))
    return saved_values
end

sv = test()
plot(sv.t, sv.saveval, xticks=1:9)

For that I get the following result:

This is perfect - the parameter seems to change exactly at every t \in T. But I disliked, that the instantaneous changes looked so “slow”, that’s why I changed the setup of the SavingCallback to

savecb = SavingCallback((u, t, integrator) -> integrator.p, saved_values, saveat=t_eval)

where t_eval should provide a much finer sampling to get sharp flanks. However, instead I got the following result

The flanks seem to have shifted and are no longer at the defined PresetTimeCallbacks, which looks wrong now. Am I missing something?

2 posts - 2 participants