将属性分配给方法

时间:2019-04-09 13:55:35

标签: python scipy

我有一个用于动态系统的类,其中包含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)

4 个答案:

答案 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()

enter image description here

答案 1 :(得分:0)

目前尚不清楚您想要实现什么。但给您一些想法:

1。您可以尝试为函数事件包装,或者使函数接收可以根据需要输入的对象。

  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