使用SciPy求解ODE会在double_scalars错误中遇到无效值

时间:2017-02-22 23:33:43

标签: python scipy ode

我试图解决任意n值(多变指数)的Lane-Emden方程。为了使用SciPy,我将二阶ODE表示为一组两个耦合的一阶ODE。我有以下代码:

import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint

def poly(y,xi,n):  
    theta, phi = y  
    dydt = [phi/(xi**2), -(xi**2)*theta**n]  
    return dydt

在这里,我定义了phi = theta'

y0 = [1.,0.]  
xi = np.linspace(0., 16., 201)    
for n in range(0,11):  
    sol = odeint(poly, y0, xi, args=(n/2.,))  
    plt.plot(xi, sol[:, 0], label=str(n/2.))  
plt.legend(loc='best')  
plt.xlabel('xi')  
plt.grid()  
plt.show()

但是,运行此代码会导致以下错误:

  

RuntimeWarning:double_scalars中遇到无效值
  app.launch_new_instance()

起初,我认为这是xi = 0时方程奇点的结果,所以我改变了积分区间:

xi = np.linspace(1e-10, 16., 201)

这解决了n = 0时的问题,但没有修正n的其他值。我得到的情节没有任何意义,只是完全错误。

为什么我会收到此错误消息,以及如何修复代码?

1 个答案:

答案 0 :(得分:1)

以下适用于我(看起来类似于Wikipedia entry)。导数写得不正确(错误的元素为负),导数的输入只改为n

import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint

def poly(y,xi,n):  
    theta, phi = y  
    dydxi = [-phi/(xi**2), (xi**2)*theta**n]  
    return dydxi

fig, ax = plt.subplots()

y0 = [1.,0.]  
xi = np.linspace(10e-4, 16., 201)

for n in range(6):
    sol = odeint(poly, y0, xi, args=(n,))
    ax.plot(xi, sol[:, 0])

ax.axhline(y = 0.0, linestyle = '--', color = 'k')
ax.set_xlim([0, 10])
ax.set_ylim([-0.5, 1.0])
ax.set_xlabel(r"$\xi$")
ax.set_ylabel(r"$\theta$")
plt.show()

enter image description here

原始问题使用多变指数的小数值,因此可以使用以下内容来调查这些值......

for n in range(12):
    sol = odeint(poly, y0, xi, args=(n/2.,))

    if np.isnan(sol[:,1]).any():
        stopper = np.where(np.isnan(sol[:,1]))[0][0]
        ax.plot(xi[:stopper], sol[:stopper, 0])
    else:
        ax.plot(xi, sol[:, 0])

fractional polytropic index values