# Accessing solutions from earlier times in Callback functions

**URL:** <https://discourse.julialang.org/t/accessing-solutions-from-earlier-times-in-callback-functions/89613>\
**Category:** Numerics\
**Tags:** question, diffeq\
**Created:** [November 1, 2022, 12:29pm UTC](https://discourse.julialang.org/t/accessing-solutions-from-earlier-times-in-callback-functions/89613 "2022-11-01T12:29:19Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![LM\_Julia](https://avatars.discourse-cdn.com/v4/letter/l/b19c9b/32.png) [@LM\_Julia](https://discourse.julialang.org/u/LM_Julia)\
**Post date:** [November 1, 2022, 12:29pm UTC](https://discourse.julialang.org/t/accessing-solutions-from-earlier-times-in-callback-functions/89613/1 "2022-11-01T12:29:19Z")

</div>

Hi everyone, I’ve only recently started using Julia and I was wondering if it’s possible to access the values obtained at earlier times by a solver in a callback function.

For example, I’m trying to identify maxima (as a function of time) in the solution of a simple oscillator and store them in a vector, but I don’t know how/if it’s possible to access the values of `u` at previous times to compare them to the value at the current time. I’ve written out the logic I’m trying to achieve in the code below, but I don’t know how to define `u_prev` or `u_prev2` in the condition function. I want for the affect! function to store the current time when `u_prev` is a local maximum.

```julia
using DifferentialEquations, Plots

function condition(u, t, integrator)
	# u_prev = ? # Value of u[1] at the previous time
	# u_prev2 = ? # Value of u[1] at the time before the previous time
	u_curr = u[1]
	if (u_curr < u_prev) && (u_prev2 < u_prev)
		return 0
	else
		return 1
	end
end
function affect!(integrator)
	push!(peaks, integrator.t) # Store current time in peaks vector
end
cb = ContinuousCallback(condition, affect!)

# Initialise problem
u0 = ones(2)
p = (2.0, 1.0)
peaks = zeros(0)
function f!(du,u,p,t)
	a, b = p
	du[1] = a * u[2]
	du[2] = -b * u[1]
end
prob = ODEProblem(f!, u0, (0.0, 50.0), p)
sol = solve(prob, Tsit5(), maxiters = 1e3, callback = cb, abstol=1e-6, reltol=1e-5)

```

I was thinking that I might be able to access previous values of `u` through the `integrator`, but I haven’t been able to figure this out. Similarly, when I try to display the value of `integrator.du`, only the word “nothing” is outputted.

Any help would be greatly appreciated, and thank you in advance for your help!

---

<div class="post-metadata">

**Author:** ![cmarcotte](https://avatars.discourse-cdn.com/v4/letter/c/a3d4f5/32.png) [@cmarcotte](https://discourse.julialang.org/u/cmarcotte)\
**Post date:** [November 1, 2022, 1:51pm UTC](https://discourse.julialang.org/t/accessing-solutions-from-earlier-times-in-callback-functions/89613/2 "2022-11-01T13:51:18Z")

</div>

Since u'(t) = 0 and u''(t) \< 0 at the maxima, you can write a continuous callback which evaluates those terms, and [saves](https://diffeqcallbacks.sciml.ai/stable/output_saving/) the current state at time t, I think? Your condition instead seems to be trying to find maxima discretely from u\_{n-1}, u\_n, and u\_{n+1}, which is (afaik!) not something the callback interface can do. If you really want to do that, then I would not run it online (with the ODE solve) but analyze the solution array after it is complete.

---

<div class="post-metadata">

**Author:** ![LM\_Julia](https://avatars.discourse-cdn.com/v4/letter/l/b19c9b/32.png) [@LM\_Julia](https://discourse.julialang.org/u/LM_Julia)\
**Post date:** [November 1, 2022, 2:19pm UTC](https://discourse.julialang.org/t/accessing-solutions-from-earlier-times-in-callback-functions/89613/3 "2022-11-01T14:19:18Z")

</div>

I think that a continuous callback function that calculates when u\_1'(t)=0 and u\_1''(t)\<0 would be ideal, but I haven’t been able to find out how to evaluate the derivatives of u(t) within a callback function. I don’t know how/if it’s possible to explicitly pass the derivatives to the callback function, and I don’t think they’re accessible through the `integrator`.

Do you know how I can access u\_1'(t) and u\_1''(t) within the callback function?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [November 1, 2022, 7:01pm UTC](https://discourse.julialang.org/t/accessing-solutions-from-earlier-times-in-callback-functions/89613/4 "2022-11-01T19:01:24Z")

</div>

> [@LM\_Julia](#):
>
> Do you know how I can access u\_1’(t) u′1(t)u\_1’(t) and u\_1’‘(t) u′′1(t)u\_1’'(t) within the callback function?

`integrator(t,Val{i})` for the `i`th derivative.

---

<div class="post-metadata">

**Author:** ![LM\_Julia](https://avatars.discourse-cdn.com/v4/letter/l/b19c9b/32.png) [@LM\_Julia](https://discourse.julialang.org/u/LM_Julia)\
**Post date:** [November 2, 2022, 10:28am UTC](https://discourse.julialang.org/t/accessing-solutions-from-earlier-times-in-callback-functions/89613/5 "2022-11-02T10:28:40Z")

</div>

Thanks for the help!

After testing, I’ve found that I can store the times of maxima in `u[1]` using the functions:

```julia
condition(u, t, integrator) = integrator(t, Val{1})[1]
function affect!(integrator)
	if (integrator(integrator.t, Val{2})[1] < 0.0)
		push!(peaks, integrator.t) # Store current time in peaks vector
	end
end
cb = ContinuousCallback(condition, affect!)

```

I’ve used the time stored in the `integrator` (`integrator.t`) in the `affect!` function since `t` is not passed to it explicitly, but do you know exactly what time this will correspond to? Ideally I would want the time at which the condition is satisfied, but I wanted to check whether `integrator.t` would reference the time at the end of the current interval in this case (as I would expect it to if I displayed it from the `condition` function).

Also, when using these functions in my original code two values of time are outputted to the `peaks` vector for each maxima in `u[1]`. These times are very similar (for example `0.6755106670700617` and `0.6755108454503309` for the first maxima). Is this due to floating point errors in the observed derivatives over short time intervals?
