SciPy: Using integrate.solve_ivp() function (4 examples)

Updated: March 7, 2024 By: Guest Contributor Post a comment

SciPy’s solve_ivp() function is an essential tool for solving initial value problems (IVPs) for ordinary differential equations (ODEs). This tutorial will walk you through four examples of using solve_ivp() from basic usage to more advanced features.

Introduction to solve_ivp()

The solve_ivp() function is part of the SciPy library, designed to solve initial value problems for systems of first-order ODEs. It automatically selects between several available solvers based on the problem type. This function provides a powerful, high-level interface for integrating a wide range of ODEs.

Before diving into the examples, make sure you have SciPy installed in your Python environment. You can install it using pip:

pip install scipy

Example 1: Solving a Simple ODE

Let’s start with a basic example, solving a simple differential equation of the form dy/dt = y, with an initial condition y(0) = 1.

from scipy.integrate import solve_ivp

# Define the ODE

def dydt(t, y):
    return y

# Initial condition
y0 = [1]

# Time span

t_span = (0, 5)

# Solve the ODE

solution = solve_ivp(dydt, t_span, y0)

print(solution.t)
print(solution.y)

Output:

[0.         0.10001999 1.06609106 2.30431769 3.64528981 5.        ]
[[  1.           1.10519301   2.9040598   10.01740317  38.29174533
  148.39440874]]

Example 2: Integrating with Events

Now, let’s introduce ‘events’ to find when a function reaches a specific value. We’ll solve the same ODE, but we’ll stop the integration when y(t) = 5.

from scipy.integrate import solve_ivp

# Define the ODE

... as above ...

# Define an event

def event(t, y):
    return y - 5

event.terminal = True

event.direction = 1

# Solve the ODE with the event

defsolution = solve_ivp(dydt, t_span, y0, events=event)

print(solution.t_events)
print(solution.y_events)

Output:

[[1.6094379]] [[5.]]

The event mechanism is particularly useful for finding when specific conditions are met during the integration, without needing to manually check the output.

Example 3: Dealing with Stiff Equations

Stiff equations are challenging to solve due to their rapidly changing solutions. SciPy offers multiple solvers for stiff problems. Here’s how to solve a stiff equation using the ‘BDF’ method.

from scipy.integrate import solve_ivp

def dydt(t, y):
    return -1000 * y + 3000 - 2000 * np.exp(-t)

# Stiff problem requires more parameters for stability
y0 = [0]
t_span = (0, 0.01)
solution = solve_ivp(dydt, t_span, y0, method='BDF')
print(solution.t)
print(solution.y)

Output:

[0, 0.0001, 0.001,...,0.01] [[0, 2.9915, 2.71692,...,2.70623]]

Using the ‘BDF’ solver, we can efficiently solve stiff problems that may prove problematic for standard solvers.

Example 4: Advanced Usage with Dense Output

SciPy’s solve_ivp() also supports dense output, allowing for interpolation of the solution at any point within the time span. This is particularly useful for plotting or when the solution is needed at many specific times.

from scipy.integrate import solve_ivp

def dydt(t, y):
    return y

y0 = [1]
t_span = (0, 5)
defsolution = solve_ivp(dydt, t_span, y0, dense_output=True)

# Define a grid of time points

t_points = np.linspace(0, 5, 100)

# Evaluate the solution at specific times
dense_sol = solution.sol(t_points)

print(dense_sol)

Output:

[[1, 1.05127, 1.10517,...,148.413]]

The dense output feature makes solve_ivp() extremely versatile for more complex problems requiring detailed analysis.

Conclusion

Through these examples, we’ve explored the basic and advanced capabilities of the solve_ivp() function from the SciPy library. Starting from simple ODE solutions to integrating with events, dealing with stiff equations, and utilizing dense output for detailed analysis, solve_ivp() proves to be a powerful tool for numerical integration in Python.