AttributeError: при решении системы уравнений с использованием классов в python

У меня есть модель двух связанных ODE [dXdt, dVdt] с некоторыми параметрами (rho, F1,...), которые я хочу решить, используя odeint из Scipy внутри класса. Когда я попытался, я получил AttributeError, как вы можете видеть здесь:

  File "C:/Users/Asus/Desktop/Mixer_model.py", line 20, in Mixer_model
    dXdt = (1/(self.rho*Z[1]))*(self.F1*(self.x1-Z[0]) + self.F2*(self.x2-Z[0]))

AttributeError: 'numpy.ndarray' object has no attribute 'rho'
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
class Mixer_class:
    def __init__(self, rho, F1, F2, F, x1,x2):
        self.rho = rho
        self.F1 = F1
        self.F2 = F2
        self.F = F
        self.x1 = x1
        self.x2 = x2
    def Mixer_model(self, Z):
        dXdt = (1/(self.rho*Z[1]))*(self.F1*(self.x1-Z[0]) + self.F2*(self.x2-Z[0]))
        dVdt = (1/self.rho)*(self.F1 + self.F2 - self.F)
        return [dXdt, dVdt]
    t = np.arange(0,650, 22.5)
    # initial condition
    V0 = 0.75  # m^3
    x0 = 0.95
    Z0 = [x0, V0]
    # ODE solve
    Vx = odeint(Mixer_model,Z0,t)
    plt.plot(t,Vx[:,0],'ko--',linewidth = 1.5)
    plt.plot(t,Vx[:,1],'cs-',linewidth = 1.5)
    plt.ylabel('V(t) and X(t)')
    plt.xlabel('Time(sec)')
    plt.show()
Mix = Mixer_class(1000, 12.5, 6.7, 3.87, 0.42, 0.58)

Когда я запускаю код, я получаю следующую ошибку атрибута:

  File "C:/Users/Asus/Desktop/Mixer_model.py", line 20, in Mixer_model
    dXdt = (1/(self.rho*Z[1]))*(self.F1*(self.x1-Z[0]) + self.F2*(self.x2-Z[0]))

AttributeError: 'numpy.ndarray' object has no attribute 'rho'

Может ли кто-нибудь помочь мне понять, что происходит с моим кодом? Всем большое спасибо


person Jeddouibi    schedule 19.05.2019    source источник


Ответы (1)


Предполагая, что отступ в вашем коде правильный, что решатель ОДУ не вызывается на уровне класса, вы проигнорировали формат параметра, который odeint ожидает от своей функции ОДУ. Формат

ode_func(y,t)

вектор состояния, за которым следует время. В вашем случае переданные параметры пространства и времени входят в self и time. Таким образом, сообщение об ошибке.

Сначала вам нужно создать экземпляр класса, а затем передать интегратору обернутый вариант функции экземпляра.

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
class Mixer_class:
    def __init__(self, rho, F1, F2, F, x1,x2):
        self.rho = rho
        self.F1 = F1
        self.F2 = F2
        self.F = F
        self.x1 = x1
        self.x2 = x2
    def Mixer_model(self, Z):
        dXdt = (1/(self.rho*Z[1]))*(self.F1*(self.x1-Z[0]) + self.F2*(self.x2-Z[0]))
        dVdt = (1/self.rho)*(self.F1 + self.F2 - self.F)
        return [dXdt, dVdt]

Mix = Mixer_class(1000, 12.5, 6.7, 3.87, 0.42, 0.58)
t = np.arange(0,650, 22.5)
# initial condition
V0 = 0.75  # m^3
x0 = 0.95
Z0 = [x0, V0]
# ODE solve
Vx = odeint(lambda Z,t: Mix.Mixer_model(Z), Z0,t)
plt.plot(t,Vx[:,0],'ko--',linewidth = 1.5)
plt.plot(t,Vx[:,1],'cs-',linewidth = 1.5)
plt.ylabel('V(t) and X(t)')
plt.xlabel('Time(sec)')
plt.show()

введите здесь описание изображения

В качестве альтернативы вы можете поместить решатель в правильно объявленный метод класса. Тогда обертка выглядит как lambda Z,t: self.Mixer_model(Z).

person Lutz Lehmann    schedule 19.05.2019