我有一个用于动态系统的类,其中包含ODE函数的方法以及终止集成的事件函数。我想用scipy.integrate.solve_ivp
解决这个问题。根据{{3}},这是通过将事件属性分配为myEvent.terminal = True
来完成的。但是,由于我将所有函数都放在一个对象中,所以这些是方法而不是对象本身,因此无法分配属性。有什么建议吗?
M(非)WE:
import numpy as np
from scipy.integrate import solve_ivp
class MySystem:
def __init__(self):
self.param_ = 1
def dynamics(self,t,x):
return (x-self.param)**3-x
def event(self, t, x):
return x
model = MySystem()
event1 = model.event
event1.terminal = True # this does not work
sol = solve_ivp(model.dynamics, [0, 100], [0, 10], events=event1)
答案 0 :(得分:3)
假设您创建了两个MySystem
的实例:
model1 = MySystem()
model2 = MySystem()
如果允许model1.event.terminal = True
,那么也会影响
model2.event.terminal
。 Python不允许在方法上设置属性以
远距离防止这种意外动作。
explained here进一步说明了不允许这样做的原因。
每PEP-0232(我的重点):
无法设置 绑定或未绑定方法上的属性,除非在 基础功能对象
可以使用event1.__dict__['terminal'] = True
在方法上设置属性
但请注意,这样做会影响MySystem
的所有实例,而不仅仅是一个实例model
。
由于这会在类级别影响MySystem.event
,因此最好在类定义中设置event.terminal
,
或在定义类后立即使用MySystem.event.terminal = True
。 (请注意,MySystem.event
是基础函数对象
在上面的PEP报价中引用。)
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
class MySystem:
def __init__(self):
self.param = 1
def dynamics(self,t,x):
return (x-self.param)**3-x
def event(self, t, x):
return x
event.terminal = True
# MySystem.event.terminal = True # also works
model = MySystem()
event1 = model.event
# event1.__dict__['terminal'] = True # works, but perhaps confusing because it affects all instances
sol = solve_ivp(model.dynamics, t_span=(0, 1.5), y0=[1], events=event1)
print(sol)
plt.plot(sol['t'], sol['y'][0])
plt.scatter(sol['t_events'][0], [0], c='red')
plt.show()
答案 1 :(得分:0)
目前尚不清楚您想要实现什么。但给您一些想法:
1。您可以尝试为函数事件包装,或者使函数接收可以根据需要输入的对象。
答案 2 :(得分:0)
从var q = GetQuarters(new DateTime(2019, 08, 03), new DateTime(2020, 01, 01));
中删除self
并在顶部添加event
,这使您可以将@staticmethod
分配给event1。
terminal
答案 3 :(得分:0)
非常感谢,scipy文件非常不清楚,这个线程救了我。这是有些不同的方法。我在扭曲ivp例程的成员函数中定义事件,您可以在其中访问实例“ self”。希望这会帮助某人。
sudo composer update