为什么prepare_events无法在Solve_ivp中找到终端属性?

时间:2019-12-19 18:37:51

标签: python scipy attributeerror

我正在尝试使用scipy的solve_ivp中的事件函数来终止发现的事件。我为函数分配了属性,可以看到它们已被适当分配。在调试时,我注意到,当resolve_ivp调用prepare_events时,它会引发AttributeError,指出对象必须具有'terminal'属性,因此它将默认值设置为False。我应该以其他方式分配终端属性吗?

Solve_Ivp呼叫:

solution = scipy.integrate.solve_ivp(
lambda t,y: self.rhs(t, y, hasHS),(0, 1e15),simvector,method='BDF', events = lambda t, y: self.eventfun(t, y, hasHS))
    print("Reached end of solver at t = " + str(max(solution.t)))
    print("Direction: " + str(self.eventfun.direction))
    print("Terminal: " + str(self.eventfun.terminal))
    print(solution)

这是我的事件功能:

def eventAttr():
    def decorator(func):
        func.terminal = True
        func.direction = 0
        return func
    return decorator

## Event function
@eventAttr()
def eventfun(self, t, stateVector,hasHS):
    dy = self.rhs(t, stateVector,hasHS)
    x = norm(dy) - 1e-8
    return x

最后,这是我运行代码时的输出:

Reached end of solver at t = 1000000000000000.0
Direction: 0
Terminal: True
  message: 'The solver successfully reached the end of the integration interval.'
     nfev: 188
     njev: 13
      nlu: 43
      sol: None
   status: 0
  success: True
        t: array([0.00000000e+00, 4.13385988e-05, 8.26771976e-05, 4.96063186e-04,
       9.09449174e-04, 1.54691091e-03, 2.18437264e-03, 2.82183437e-03,
       3.96472459e-03, 5.10761480e-03, 6.25050501e-03, 7.39339522e-03,
       9.55710076e-03, 1.17208063e-02, 1.38845118e-02, 1.60482174e-02,
       2.28891941e-02, 2.97301708e-02, 3.65711476e-02, 5.70008840e-02,
       7.74306204e-02, 1.25358621e-01, 1.73286622e-01, 2.21214623e-01,
       3.79170155e-01, 5.37125688e-01, 7.97053765e-01, 1.05698184e+00,
       1.31690992e+00, 1.79126726e+00, 2.26562460e+00, 2.73998194e+00,
       3.49608272e+00, 4.25218349e+00, 5.00828427e+00, 5.76438504e+00,
       6.89976824e+00, 8.03515144e+00, 9.17053463e+00, 1.50812551e+01,
       2.09919755e+01, 8.00991800e+01, 1.39206384e+02, 7.30278429e+02,
       1.32135047e+03, 7.23207092e+03, 1.31427914e+04, 7.22499958e+04,
       1.31357200e+05, 7.22429245e+05, 1.31350129e+06, 7.22422174e+06,
       1.31349422e+07, 7.22421467e+07, 1.31349351e+08, 7.22421396e+08,
       1.31349344e+09, 7.22421389e+09, 1.31349343e+10, 7.22421388e+10,
       1.31349343e+11, 7.22421388e+11, 1.31349343e+12, 7.22421388e+12,
       1.31349343e+13, 7.22421388e+13, 1.31349343e+14, 7.22421388e+14,
       1.00000000e+15])
 t_events: [array([ 1305948.92714663,  3775274.62982964, 11770897.57749387,
       60058078.65234353, 89829759.09852111])]
        y: array([[  0.  ,   0.  ,   0.  , ...,   0.  ,   0.  ,   0.  ],
       [  0.  ,   0.  ,   0.  , ...,   0.  ,   0.  ,   0.  ],
       [273.15, 273.15, 273.15, ..., 273.15, 273.15, 273.15],
       ...,
       [  0.  ,   0.  ,   0.  , ...,   0.  ,   0.  ,   0.  ],
       [  0.  ,   0.  ,   0.  , ...,   0.  ,   0.  ,   0.  ],
       [  0.  ,   0.  ,   0.  , ...,   0.  ,   0.  ,   0.  ]])
pH:  4.4534303151127315
Elapsed time:  0.9140002727508545

1 个答案:

答案 0 :(得分:1)

修饰的功能(eventfun)必须是可调用的,且已分配给events。相反,您要给出一个lambda表达式。因此,分配给events的可调用对象没有任何属性,因此为何选择AttributeError。确实,您只需要更改eventfun的签名,因为只允许使用两个参数。您可以通过self.hasHS合并hasHS。