How to plot the variables generated in a for loop and with " OverflowError: (34, 'Result too large') "

How to plot the variables generated in a for loop and with " OverflowError: (34, 'Result too large') "

我正在尝试用 Python3 中的四阶龙格 - 库塔法求解微分方程。该函数是故意使解趋于无穷大。

我的问题是有人要求我绘制迭代解,但在 for 循环中将迭代器和相应的解值存储在列表中时,我似乎无法理解如何处理无穷大,以及当我在循环外调用该列表时。下面是带有错误消息的完整代码和结果窗格。

    import math
    import numpy as np
    import matplotlib.pyplot as plt
    
# Problem function  #
    def diffEq(x, y):
        return (5*math.exp(y)) + (x)**2
    
    # 4th order Runge - Kutta method #
    def RK_fourth(x0,y0,x,h):
        average_slope = 0 
        i = 0
        x_axis = [] # For plotting #
        y_axis = [] # For plotting #
        print("Iterations of 4th Order Runge - Kutta Method")
        for i in np.arange(x0,x,h, dtype=float):
            k1 = diffEq(y0,i)
            k2 = diffEq(y0 + (k1 * (h/2)), i + (h/2))
            k3 = diffEq(y0 + (k2 * (h/2)), i + (h/2))
            k4 = diffEq(y0 + (k3 * h), i + h)
            average_slope = (1/6) * (k1 + (2* k2) + (2*k3) + k4)
            print('average_slope:',average_slope)
            y = y0 + (average_slope * h)
            y0 = y
            x_axis.append(i + h)
            y_axis.append(y)
            print("x:", i+h)
            print("y:", y)
            print(x_axis)
            print(y_axis)
        print(x_axis)
        print(y_axis)
        print("The solution using 4th order Runge - Kutta method is : ","%.4f"%y)
    
    # main #
    RK_fourth(0, 0 ,1, 0.1)
    
    # Console #
    Iterations of 4th Order Runge - Kutta Method
    average_slope: 5.350250926709215
    x: 0.1
    y: 0.5350250926709216
    [0.1]
    [0.5350250926709216]
    average_slope: 6.568756155777355
    x: 0.2
    y: 1.191900708248657
    [0.1, 0.2]
    [0.5350250926709216, 1.191900708248657]
    average_slope: 9.107515760505036
    x: 0.30000000000000004
    y: 2.1026522842991606
    [0.1, 0.2, 0.30000000000000004]
    [0.5350250926709216, 1.191900708248657, 2.1026522842991606]
    average_slope: 14.993810753267782
    x: 0.4
    y: 3.602033359625939
    [0.1, 0.2, 0.30000000000000004, 0.4]
    [0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939]
    average_slope: 33.7279469045296
    x: 0.5
    y: 6.9748280500789
    [0.1, 0.2, 0.30000000000000004, 0.4, 0.5]
    [0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939, 6.9748280500789]
    average_slope: 185.38472029098983
    x: 0.6
    y: 25.51330007917788
    [0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6]
    [0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939, 6.9748280500789, 25.51330007917788]
    average_slope: 2568779.276837211
    x: 0.7000000000000001
    y: 256903.4409838003
    [0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7000000000000001]
    [0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939, 6.9748280500789, 25.51330007917788, 256903.4409838003]
    average_slope: 1.4658111185680487e+68
    x: 0.8
    y: 1.4658111185680488e+67
    [0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7000000000000001, 0.8]
    [0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939, 6.9748280500789, 25.51330007917788, 256903.4409838003, 1.4658111185680488e+67]
    ---------------------------------------------------------------------------
    OverflowError                             Traceback (most recent call last)
    /var/folders/bt/kqf88mw53h55m9mj35rkwt6h0000gn/T/ipykernel_18686/1130051705.py in <module>
          6 #ImprovedEuler(0.2, 0.1 ,0.3, 0.1)
          7 #print("\n")
    ----> 8 RK_fourth(0, 0 ,1, 0.1)
          9 #print("\n")
         10 #GaussJordan(12,3,-5,1,1,5,3,28,3,7,13,76) # Enter the coefficients #
    
    /var/folders/bt/kqf88mw53h55m9mj35rkwt6h0000gn/T/ipykernel_18686/303333894.py in RK_fourth(x0, y0, x, h)
         74         k1 = diffEq(y0,i)
         75         k2 = diffEq(y0 + (k1 * (h/2)), i + (h/2))
    ---> 76         k3 = diffEq(y0 + (k2 * (h/2)), i + (h/2))
         77         k4 = diffEq(y0 + (k3 * h), i + h)
         78         average_slope = (1/6) * (k1 + (2* k2) + (2*k3) + k4)
    
    /var/folders/bt/kqf88mw53h55m9mj35rkwt6h0000gn/T/ipykernel_18686/303333894.py in diffEq(x, y)
         12 def diffEq(x, y):
         13     #Function for GVF
    ---> 14     return (5*math.exp(y)) + (x)**2
         15 
         16 
    
    OverflowError: (34, 'Result too large')

请注意,我还没有调用 plt.plot(x_axis, y_axis)。为了验证 x_axisy_axis 能够获取我在循环内和循环外分别调用它们的所有值。错误消息之前的最后打印来自循环内的 print() 语句。

如何解决这个问题,我对Python很陌生。如果您不清楚这个问题,我深表歉意,很乐意进一步澄清。

提前感谢您的帮助。

您可以使用 numpy 的 np.exp 而不是 math.exp 来处理无穷大:

def diffEq(x, y):
    return (5*np.exp(y)) + (x)**2

结果:

Iterations of 4th Order Runge - Kutta Method
average_slope: 5.350250926709215
x: 0.1
y: 0.5350250926709216
[0.1]
[0.5350250926709216]
average_slope: 6.568756155777355
x: 0.2
y: 1.191900708248657
[0.1, 0.2]
[0.5350250926709216, 1.191900708248657]
average_slope: 9.107515760505036
x: 0.30000000000000004
y: 2.1026522842991606
[0.1, 0.2, 0.30000000000000004]
[0.5350250926709216, 1.191900708248657, 2.1026522842991606]
average_slope: 14.993810753267782
x: 0.4
y: 3.602033359625939
[0.1, 0.2, 0.30000000000000004, 0.4]
[0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939]
average_slope: 33.7279469045296
x: 0.5
y: 6.9748280500789
[0.1, 0.2, 0.30000000000000004, 0.4, 0.5]
[0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939, 6.9748280500789]
average_slope: 185.38472029098983
x: 0.6
y: 25.51330007917788
[0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6]
[0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939, 6.9748280500789, 25.51330007917788]
average_slope: 2568779.276837211
x: 0.7000000000000001
y: 256903.4409838003
[0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7000000000000001]
[0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939, 6.9748280500789, 25.51330007917788, 256903.4409838003]
average_slope: 1.4658111185680487e+68
x: 0.8
y: 1.4658111185680488e+67
[0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7000000000000001, 0.8]
[0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939, 6.9748280500789, 25.51330007917788, 256903.4409838003, 1.4658111185680488e+67]
average_slope: inf
x: 0.9
y: inf
[0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7000000000000001, 0.8, 0.9]
[0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939, 6.9748280500789, 25.51330007917788, 256903.4409838003, 1.4658111185680488e+67, inf]
average_slope: inf
x: 1.0
y: inf
[0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7000000000000001, 0.8, 0.9, 1.0]
[0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939, 6.9748280500789, 25.51330007917788, 256903.4409838003, 1.4658111185680488e+67, inf, inf]
[0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7000000000000001, 0.8, 0.9, 1.0]
[0.5350250926709216, 1.191900708248657, 2.1026522842991606, 3.602033359625939, 6.9748280500789, 25.51330007917788, 256903.4409838003, 1.4658111185680488e+67, inf, inf]
The solution using 4th order Runge - Kutta method is :  inf

程序将输出运行时警告RuntimeWarning: overflow encountered in double_scalars...。您可以使用上下文管理器来抑制此警告:

import warnings

with warnings.catch_warnings():
    warnings.filterwarnings("ignore", "overflow")
    RK_fourth(0, 0 ,1, 0.1)