Using a modifier function on the output of DifferentialEquation for plotting

Hello,

I am using the (fantastic) DifferentialEquation.jl package to run some simulation and would like to plot the solution, but after applying a modifying function on the solution.

What I mean is that I would like to apply a function, for instance sin on all the solution’s points.

In the past, I would make this work by simply not using the dedicated Plots recipes for DifferentialEquations and do something like this (I know the following is rather trivial):

# Define system of equation 
function f(du, u, p, t)
    du[1] = u[1]
end

# Parameter for system (in this case there are none)
p = []

# Initial conditions
u0 = [0.5]

# Time points to integrate
times = 0:0.01:4

# Define ODE problem
prob = ODEProblem(
    f,                      # system to integrate
    u0,                     # initial conditions
    (times[1], times[end]), # time bounds to integrate in
    p                       # parameters for the system
)

# Solve problem
sol = solve(
    prob,           # problem to solve for
    saveat = times  # times to get an answer for, but shifted by the transient time
    )

# Plot trajectories
modifier_function(x) = sin(x)
newdata = modifier_function.(sol[1, :])
plot(sol.t, newdata)

Although this works, I feel like there must be a more systematic way of achieving the same thing. Perhaps, modifying the recipe for DifferentialEquations?
A more “mathy” alternative would be to change the differential equations themselves to obtain the desired output, but systems of nonlinearly coupled equations it becomes a little messy.

Thanks in advance for any help!

The plotting docs have a few examples Plot Functions · DifferentialEquations.jl

It shows mostly phase plots, but variable 0 is time.

2 Likes

Thanks so much, this is perfect! I skimmed over that section to quick, my bad!

This does exactly what I need:

# Define system of equation 
function f(du, u, p, t)
    du[1] = u[1]
end

# Parameter for system (in this case there are none)
p = []

# Initial conditions
u0 = [0.5]

# Time points to integrate
times = 0:0.01:4

# Define ODE problem
prob = ODEProblem(
    f,                      # system to integrate
    u0,                     # initial conditions
    (times[1], times[end]), # time bounds to integrate in
    p                       # parameters for the system
)

# Solve problem
sol = solve(
    prob,           # problem to solve for
    saveat = times  # times to get an answer for, but shifted by the transient time
    )

# Plot trajectories
modifier_function(x, t) = (sin(x), t) # returns a tuple

plot(sol, idxs = [(modifier_function, 1, 0)])   # applying the modifier function on the data at index 1, and leaving time at index 0 unchanged
1 Like

Good to hear.

1 Like