【问题标题】:How to pass parameters to event functions in`scipy.integrate.solve_ivp`?如何将参数传递给`scipy.integrate.solve_ivp`中的事件函数?
【发布时间】:2019-09-01 00:43:18
【问题描述】:

Scipy 正在从 odeint 转向 solve_ivp,它不再支持为动态函数传递额外的参数。相反,lambdas are recommended。但是,当我对事件尝试相同的操作时,它们无法正常工作。有什么想法吗?

MWE(修改自doc page):

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

# dynamics of a simple mass with ballistic flight and a bit of drag
def cannon(t, y, p): 
    return [y[2],y[3], -p['friction']*y[2], p['gravity']-p['friction']*y[3]]

# termination condition: cannonball hits the ground
# this event does not require parameters, but more complex events might
def hit_ground1(t, y, p): 
    return y[1]
hit_ground1.terminal = True
hit_ground1.direction = -1

def hit_ground2(t,y):
    return y[1]
hit_ground2.terminal = True
hit_ground2.direction = -1

p = {'gravity':-1,'friction':0} # paramters as a dict
y0 = [0, 0, 0, 10] # initial conditions
t_span = [0, 22] # integration time a bit over what is necessary

# we can handle dynamics with parameters by using lambdas
# but somehow the same doesn't seem to work with events
sol1 = solve_ivp(fun=lambda t,x:cannon(t,x,p), t_span=t_span, 
    y0=y0, events=hit_ground2, max_step=0.01)    
sol2 = solve_ivp(fun=lambda t,x:cannon(t,x,p), t_span=t_span, 
    y0=y0, events=lambda t,x:hit_ground1(t,x,p), max_step=0.01)

print(sol1.t[-1]) # terminates correctly
print(sol2.t[-1]) # continues integrating
plt.plot(sol1.t,sol1.y[1], linewidth=3)
plt.plot(sol2.t,sol2.y[1],'--',linewidth=3)
plt.show()

【问题讨论】:

  • 在您提出问题后不久,args have been added again,至少对于 RHS 功能。虽然找不到 event 功能的任何东西......我的用例需要的东西。也许我会尝试lambda 方法。

标签: python scipy


【解决方案1】:

事件的属性 terminaldirection 不会转移到您的 lambda 表达式中。您需要将 lambda 保存到一个变量中,并在其中添加属性,而不是在 hit_ground1 函数上。

def hit_ground1(t, y, p):
    return y[1]

ground_event = lambda t,x:hit_ground1(t,x,p)
ground_event.terminal = True
ground_event.direction = -1

使用此事件,它应该会按预期工作。

 sol2 = solve_ivp(fun=lambda t,x:cannon(t,x,p), t_span=t_span,
    y0=y0, events=ground_event, max_step=0.01)

【讨论】:

  • 史蒂夫,正在运行 print(sol1.t_events); print(sol2.t_events) 求解器捕获事件,t=20。出现在这两种方法中。不知道为什么 sol2, hitground1 也捕获了 t=0.. 这在 Alex 的解决方案中不会发生
猜你喜欢
  • 2020-08-27
  • 1970-01-01
  • 2010-10-04
  • 2011-10-06
  • 2013-05-16
  • 2011-09-18
  • 1970-01-01
  • 2019-11-15
  • 1970-01-01
相关资源
最近更新 更多