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

Click For Summary
The discussion revolves around a Python implementation of Euler's forward algorithm for solving non-stiff ordinary differential equations (ODEs). The user presents a function, `ode_euler_forward`, which takes an ODE function, initial values, a range for the independent variable, and the number of steps as parameters. The function uses a loop to iteratively compute the values of the dependent variables. However, when comparing results with MATLAB's `ode45`, discrepancies arise, indicating potential issues with the Euler method's implementation.Key points include the recognition of numerical stability as a critical factor affecting the accuracy of the Euler method, particularly with larger step sizes. The user notes that increasing the number of steps to 50,000 resolved the discrepancies, leading to results that matched those obtained from MATLAB. This highlights the importance of step size in numerical methods and suggests that while Euler's method is straightforward to implement, it may require careful consideration of parameters to ensure stability and accuracy in solutions.
Wrichik Basu
Science Advisor
Insights Author
Gold Member
Messages
2,180
Reaction score
2,721
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 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!
 
Learn If you want to write code for Python Machine learning, AI Statistics/data analysis Scientific research Web application servers Some microcontrollers JavaScript/Node JS/TypeScript Web sites Web application servers C# Games (Unity) Consumer applications (Windows) Business applications C++ Games (Unreal Engine) Operating systems, device drivers Microcontrollers/embedded systems Consumer applications (Linux) Some more tips: Do not learn C++ (or any other dialect of C) as a...

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
1K
  • · Replies 15 ·
Replies
15
Views
5K
  • · Replies 16 ·
Replies
16
Views
2K