I'm having difficulty solving an initial value problem (IVP) in Python backwards in time. The code is at the end of this post.
First, please let me state my simplified problem.
The forward IVP is defined as the following $$\left\{ \begin{array}{cl} u'(t)=-21 u + e^{-t}, & \ t\in[0,2] \\ u(0)=1 & \end{array} \right. $$
The picture below is the solution obtained by using solve_ivp
package of scipy.integrate
.
Up until this point, everything has gone as expected.
Now, I'd like to see if solve_ivp
can solve general ODEs backward in time. For the above ODE, it should be solved from $t=2$ to $t=0$ by starting with $u(2)\approx0.00676677$.
However, the backward in time solution I got was exploding
Theoretically, the forward and backward ODE should lead to the same solution (regardless numerical errors). So I'm quite confused with the result I got here.
I've testified with different drift terms, tolerance, and solvers. In some cases, numerical forward and backward solutions coincided but in most cases, they didn't.
I guess it may due to the ODEs are "stiff" but I have no clues how to fix the problem...
Below, I provide my code to this particular question.
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
#define the drift function of ode
def f(t, u):
drift = -21 * u + np.exp(-t)
return drift
#define hyperparameters
ti = 0.
tf = 2.
N = 100
tol = 1e-8
time = np.linspace(ti, tf, N)
#solve forward in time
sol = solve_ivp(f, [ti, tf], [0.0], method='RK45', t_eval=time, atol=tol, rtol=tol,
dense_output=True)
#plot forward solution
plt.plot(time, sol.y[0])
print("sol.y[0]:", sol.y[0])
#solve backward in time
sol_f = solve_ivp(f, [tf, ti], [sol.y[0][-1]], method='RK45', t_eval=time[::-1],
atol=tol, rtol=tol, dense_output=True)
#plot backward solution
plt.plot(time, sol_f.y[0][::-1])
print("reverse:", sol_f.y[0][::-1])