简体   繁体   English

如何在 scipy 集成模块“solve_ivp”中正确设置“rtol”和“atol”以求解具有未知解析解的 ODE 系统?

[英]How to correctly set the 'rtol' and 'atol' in scipy integration module 'solve_ivp' for solving a system of ODE with unknown analytic solution?

I was trying to reproduce some results of ode45 solver in Python using solve_ivp.我试图使用 solve_ivp 在 Python 中重现 ode45 求解器的一些结果。 Though all parameters, initial conditions, step size, and 'atol' and 'rtol' (which are 1e-6 and 1e-3) are same, I am getting different solutions.尽管所有参数、初始条件、步长以及“atol”和“rtol”(即 1e-6 和 1e-3)都相同,但我得到了不同的解决方案。 Both of the solutions are converging to a periodic solution but of different kind.这两种解决方案都收敛于周期性解决方案,但类型不同。 As solve_ivp uses same rk4(5) method as ode45, this discrepancy in the final result is not quite understable.由于 solve_ivp 使用与 ode45 相同的 rk4(5) 方法,因此最终结果中的这种差异不太稳定。 How can we know which one is the correct solution?我们怎么知道哪一个是正确的解决方案? The code is included below代码包含在下面

import sys
import numpy as np
from scipy.integrate import solve_ivp
#from scipy import integrate
import matplotlib.pyplot as plt
from matplotlib.patches import Circle


# Pendulum rod lengths (m), bob masses (kg).

L1, L2, mu, a1 = 1, 1, 1/5, 1
m1, m2, B = 1, 1, 0.1
# The gravitational acceleration (m.s-2).

g = 9.81

# The forcing frequency,forcing amplitude

w, a_m =10, 4.5
A=(a_m*w**2)/g
A1=a_m/g

def deriv(t, y, mu, a1, B, w, A): # beware of the order of the aruments
"""Return the first derivatives of y = theta1, z1, theta2, z2, z3."""
a, c, b, d, e = y

#c, s = np.cos(theta1-theta2), np.sin(theta1-theta2)
adot = c
cdot = (-(1-A*np.sin(e))*(((1+mu)*np.sin(a))-(mu*np.cos(a-b)*np.sin(b)))-((mu/a1)*((d**2)+(a1*np.cos(a-b)*c**2))*np.sin(a-b))-(2*B*(1+(np.sin(a-b))**2)*c)-((2*B*A/w)*(2*np.sin(a)-(np.cos(a-b)*np.sin(b)))*np.cos(e)))/(1+mu*(np.sin(a-b))**2)

bdot = d
ddot = ((-a1*(1+mu)*(1-A*np.sin(e))*(np.sin(b)-(np.cos(a-b)*np.sin(a))))+(((a1*(1+mu)*c**2)+(mu*np.cos(a-b)*d**2))*np.sin(a-b))-((2*B/mu)*(((1+mu*(np.sin(a-b))**2)*d)+(a1*(1-mu)*np.cos(a-b)*c)))-((2*B*a1*A/(w*mu))*(((1+mu)*np.sin(b))-(2*mu*np.cos(a-b)*np.sin(a)))*np.cos(e)))/(1+mu*(np.sin(a-b))**2)
edot = w
return adot, cdot, bdot, ddot, edot





# Initial conditions: theta1, dtheta1/dt, theta2, dtheta2/dt.

y0 = np.array([3.15, -0.1, 3.13, 0.1, 0])


# Do the numerical integration of the equations of motion



sol = integrate.solve_ivp(deriv,[0,40000], y0, args=(mu, a1, B, w, A), method='RK45',t_eval=np.arange(0, 40000, 0.005), dense_output=True, rtol=1e-3, atol=1e-6)


T = sol.t
Y = sol.y

I am expecting similar result from ode45 in MATLAB and solve_ivp in Python.我期待 MATLAB 中的 ode45 和 Python 中的 solve_ivp 得到类似的结果。 How can I exactly reproduce the result from ode45 in python?我怎样才能在 python 中准确地重现 ode45 的结果? What is the reason of discrepancy?差异的原因是什么?

Even if ode45 and RK45 use the same underlying scheme, they do not necessarily use the same exact strategy regarding the evolution of the time step and its adaptation to match the error tolerance.即使ode45RK45使用相同的底层方案,它们也不一定使用完全相同的关于时间步长的演化及其适应性以匹配容错的策略。 Thus, it is difficult to know which one is better.因此,很难知道哪个更好。 The only thing you could is simply trying lower tolerances, eg 1e-10.您唯一能做的就是尝试降低公差,例如 1e-10。 Then, both solutions should end up being virtually identical... Here, your current error tolerance might be insufficiently low, so that small discrepancies in the fine details of both algorithms create a visible difference in the solution.然后,两种解决方案最终应该几乎相同......在这里,您当前的错误容忍度可能不够低,因此两种算法的细节上的微小差异会在解决方案中产生明显的差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM