使用 scipy.integrate.odeint 覆盖 ODE 集成中的值
Override values in ODE integration with scipy.integrate.odeint
我正在使用 scipy.integrate.odeint 对 ODE 系统进行数值积分。 在摘要中,我希望能够为求解器提供任意条件以应用于其输出值。例如:如果项的值(例如 X[0]
)小于 1,将值覆盖为 0,而不是使用通过数值积分计算的值。然后进行整合。
这是我如何处理集成的示例。
# Toy ODE system to be integrated
def dXdt(X, t, args):
return [args[0]*X[0], t*args[1]*X[1]]
# Setup initial conditions and integrate the system.
from scipy.integrate import odeint
import numpy as np
t = np.linspace(0, 100, 100) # timepoints to integrate
x0 = [100, 100] # initial conditions
args = [-.01, -.02]
X = odeint(dXdt, x0, t, args=(args,))
实现大致我想要的行为的解决方法是修改 dXdt
如下:
def dXdt(X, t, args):
if X[0] > 1: # make dX[0]/dt extremely negative to force X[0] toward 0
return [-1e200, t*args[1]*X[1]]
return [args[0]*X[0], t*args[1]*X[1]]
这显然不能推广到其他可能需要的条件,也不能精确地解决问题(精确的解决方案需要了解 dXdt
中求解器的步长。
这是不可能的。您必须将 odeint
视为黑盒,您无法访问内部状态和集成过程中采取的步骤。
在其他上下文(语言、库)中,您有一个 event-action 机制,您可以在其中定义向下跨越某个值的事件并采取操作来修改状态。
在 scipy.integrate.solve_ivp
中,您实现了 one-half 事件机制。您必须将事件定义为终端,提取事件的最后状态,修改它并重新启动与修改后状态的集成。最后,您可以连接解决方案段。
我正在使用 scipy.integrate.odeint 对 ODE 系统进行数值积分。 在摘要中,我希望能够为求解器提供任意条件以应用于其输出值。例如:如果项的值(例如 X[0]
)小于 1,将值覆盖为 0,而不是使用通过数值积分计算的值。然后进行整合。
这是我如何处理集成的示例。
# Toy ODE system to be integrated
def dXdt(X, t, args):
return [args[0]*X[0], t*args[1]*X[1]]
# Setup initial conditions and integrate the system.
from scipy.integrate import odeint
import numpy as np
t = np.linspace(0, 100, 100) # timepoints to integrate
x0 = [100, 100] # initial conditions
args = [-.01, -.02]
X = odeint(dXdt, x0, t, args=(args,))
实现大致我想要的行为的解决方法是修改 dXdt
如下:
def dXdt(X, t, args):
if X[0] > 1: # make dX[0]/dt extremely negative to force X[0] toward 0
return [-1e200, t*args[1]*X[1]]
return [args[0]*X[0], t*args[1]*X[1]]
这显然不能推广到其他可能需要的条件,也不能精确地解决问题(精确的解决方案需要了解 dXdt
中求解器的步长。
这是不可能的。您必须将 odeint
视为黑盒,您无法访问内部状态和集成过程中采取的步骤。
在其他上下文(语言、库)中,您有一个 event-action 机制,您可以在其中定义向下跨越某个值的事件并采取操作来修改状态。
在 scipy.integrate.solve_ivp
中,您实现了 one-half 事件机制。您必须将事件定义为终端,提取事件的最后状态,修改它并重新启动与修改后状态的集成。最后,您可以连接解决方案段。