我写了一个程序,用odeint求解微分方程。但有个问题。当我将Cosmopara设置为np.array([70.0,0.3,0,-1.0,0])
时,它给出了一个警告,即invalid value encountered in sqrt
和{np.array([70.0,0.3,0.0,-1.0,0.0])
,Y不应该改变,但是它改变了。另外,如果我选择Cosmopara=np.array([70.0,0.3,0.1,-1.0,0.1])
,这个程序可以给出正确的结果。在
我做错什么了?在
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
global CosmoPara
Cosmopara = np.array([70.0,0.3,0.0,-1.0,0.0])
def derivfun(Y,t):
Omega_M = Cosmopara[1]
Sigma_0 = Cosmopara[2]
omega = Cosmopara[3]
delta = Cosmopara[4]
Omega_DE = 1-Omega_M-Sigma_0**2
y1 = Y[0]
y2 = Y[1]
h = np.sqrt(y1**2 + Omega_M*t**(-3) + Omega_DE*y2)
dy1dt = -3.0*y1/t + (delta*Omega_DE*y2)/(t*h)
dy2dt = -(3.0*(1+omega) + 2.0*delta*y1/h)*y2/t
return np.array([dy1dt,dy2dt])
z = np.linspace(1,2.5,15001)
time = 1.0/z
Omega_M = Cosmopara[1]
Sigma_0 = Cosmopara[2]
omega = Cosmopara[3]
delta = Cosmopara[4]
Omega_DE = 1-Omega_M-Sigma_0**2
y1init = Sigma_0
y2init = 1.0
Yinit = np.array([y1init,y2init])
Y = odeint(derivfun,Yinit,time)
y1 = Y[:,0]
y2 = Y[:,1]
h = np.sqrt(y1**2 + Omega_M*time**(-3) + Omega_DE*y2)
plt.figure()
plt.plot(z,h)
plt.show()
当}。在
sqrt()
中的值小于0时导致的错误。并且sqrt()
中的值将小于0是由于时间值t
突然减小到{为了找出原因,我测试了几个例子,我发现函数}的时间间隔是不同的,即使函数}变化不快时,结果可以看作是具有较大时间间隔的线性函数。在导数变化不快的情况下,该函数将增大下一步的时间间隔,并且可以用较少的步骤求解。在你提供的情况下。导数}始终等于零且不改变。这种情况会导致错误的时间值。在
derivfun
的时间值t
的时间间隔和全局数组{odeint
工作正常。我想这是一种加速odeint
的机制。因为当导数dydt1
和{dydt1
和{根据这个结果,我们可以知道当导数不变时,
odeint
函数会给出错误的时间值,而这不在用户给出的时间数组范围内。如果要避免这种情况,可以使用全局时间变量而不是原始时间值。但是用odeint
来求解常微分方程会花费更多的时间。在下面的代码是您提供的代码,我添加了一些行进行测试。您可以更改参数并检查结果。在
下图显示,当函数正常工作时(使用您提供的参数),函数中的时间值和全局时间值具有不同的时间间隔:
下图显示,当导数
dydt1
和dydt2
不变(也使用您提供的参数),并且函数中的时间值突然减小到小于0
的值:相关问题 更多 >
编程相关推荐