What's wrong with this Python program on Euler's forward algorithm?

Click For Summary
SUMMARY

The discussion focuses on a Python implementation of Euler's forward algorithm for solving non-stiff ordinary differential equations (ODEs). The user identified an issue with the stability of their implementation, which produced incorrect results compared to MATLAB's ode45 function. Key findings indicate that increasing the number of steps significantly improved the accuracy of the results, highlighting the importance of numerical stability in the explicit Euler method. The user also mentioned having implemented other numerical methods, such as RK2, Heun's, and Ralston's algorithms, which yielded correct results.

PREREQUISITES
  • Understanding of numerical methods for ODEs, specifically Euler's method
  • Familiarity with Python programming and libraries such as NumPy and Matplotlib
  • Knowledge of numerical stability concepts in computational mathematics
  • Experience with MATLAB, particularly the ode45 function
NEXT STEPS
  • Research "Numerical stability in Euler's method" to understand limitations and improvements
  • Learn about "Runge-Kutta methods" for more accurate ODE solutions
  • Explore "Adaptive step size control" techniques in numerical integration
  • Investigate "Comparative analysis of numerical solvers" between Python and MATLAB
USEFUL FOR

Mathematicians, data scientists, and software developers working on numerical simulations, particularly those interested in solving ordinary differential equations using Python.

Wrichik Basu
Science Advisor
Insights Author
Gold Member
Messages
2,186
Reaction score
2,694
Here is the function that I have written:
Python:
import numpy as np

def ode_euler_forward(odefun, y_initial, x_range, num_steps):
    """
    Solves a system of non-stiff ODEs using Euler's forward algorithm.

    Parameters
    ----------
    odefun : callable(x, y1, y2, ...)
        The function that represents the system of ODEs.
    y_initial : tuple
        The initial values of all the dependent variables in the form (y_1_initial, y_2_initial, ...)
        If there is only one variable, turn it into a tuple with a trailing comma: (y_initial,)
    x_range : tuple
        The start and the end values of the independent variable in the form (x_start, x_end)
    num_steps : int
        The number of steps to be used.

    Returns
    -------
    x, y : tuple
        The values of the independent variable, and corresponding values of each dependent variable in the form
        (np.ndarray, np.ndarray).
    """
    x_initial = x_range[0]
    x_end = x_range[1]

    h = (x_end - x_initial) / num_steps  # The size of each step

    y_initial = np.asarray(y_initial)[np.newaxis, :]

    # y = [[y_initial], [0, 0, ...], [0, 0, ...], ...]. Each row will hold the value from one iteration.
    y = np.vstack((y_initial, np.zeros((num_steps - 1, np.size(y_initial, 1)), dtype=float)))

    x = np.linspace(x_initial, x_end, num_steps)[np.newaxis, :].T

    for i in range(0, num_steps - 1):
        y[i + 1, :] = y[i, :] + h * odefun(x[i], y[i, :][np.newaxis, :])

    return x, y
and here is how I call the function:
Python:
import numpy as np
import matplotlib.pyplot as plt

m = 10
k = 15

def myODE(t, x): return np.array([x[0, 1], -k * x[0, 0] / m])[np.newaxis, :]

tSol, xSol_euler = ode_euler_forward(myODE, (0.0, 1.0), (0.0, 30.0), 501)

plt.plot(tSol, xSol_euler[:, 1], '-b', label=r'$x(t)$')
plt.plot(tSol, xSol_euler[:, 0], '-r', label=r'$v(t)$')
plt.legend(loc='best')
plt.grid(True, which='both')
plt.show()
Here is the graph that I get:

Figure_1.png

If I run the (almost) same program in MATLAB using ode45, here is the graph I get:

untitled.png

In Python, I have also written functions for RK2 midpoint, Heun's and Ralston's algorithms. If I solve the problem using the first one of those functions, I get the following graph:

Figure_2.png

This matches the plot from MATLAB, which means there is something wrong with the Euler's algorithm function that I have written. Can anyone please point out the error?
 
Last edited:
Technology news on Phys.org
You may want to investigate the concept of numerical stability. The explicit Euler method is a very simple integrator to implement but unfortunately also one with the smallest region of stability.
 
  • Like
Likes   Reactions: Wrichik Basu
Filip Larsen said:
You may want to investigate the concept of numerical stability. The explicit Euler method is a very simple integrator to implement but unfortunately also one with the smallest region of stability.
In the Wikipedia page for Euler's method, there is one small section on Numerical stability. The example written there shows that the algorithm becomes quite unstable for larger step sizes. I increased the number of steps to 50000, and I could reproduce the correct graph. Thanks a lot for the help!
 

Similar threads

  • · Replies 4 ·
Replies
4
Views
6K
  • · Replies 15 ·
Replies
15
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 1 ·
Replies
1
Views
2K
Replies
3
Views
4K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 16 ·
Replies
16
Views
2K
  • · Replies 1 ·
Replies
1
Views
5K