В настоящее время я хочу реализовать модель Гаммерштейна в Sympy. Теперь я создал небольшой пример для простой системы:
import numpy as np
from sympy import *
####HAMMERSTEIN MODEL####
#time
t = symbols("t")
#inputs
u = symbols('u')
#states
y = symbols('y',cls = Function, Function = True)
#init states
y_init =symbols('y_init')
#parameters
gain = 2 #symbols('gain')
time_constant = 20000#symbols('time_constant')
#EQUATIONS
#NONLINEAR STATIC PART
u_nonlinear = u**2 # nonlinear input
#DYNAMIC PART
# first order system with inputs
rhe = (gain * u_nonlinear - y(t)) * 1/time_constant
ode = Eq(diff(y(t),t),rhe)
#solve equation
sol_step = dsolve(ode, ics = {y(0): y_init})
sol_step = sol_step.rhs
#lambdify (sympy)
system_step =lambdify((t,u, y_init),sol_step, 'sympy')
#####SIMULATE STEPWISE######
nr_steps = 10
dt=1
u_data =IndexedBase('u_data')
y_init_data =symbols('y_init_data')
#solution vector
sol =[]
for i in range(nr_steps):
#first sim. step
if i == 0:
sol.append(system_step(dt,u_data[i],y_init_data))
#uses the states of prev. solution as inits
else:
sol.append(system_step(dt,u_data[i],sol[i-1]))
#convert
system=lambdify((u_data,y_init_data),sol, 'numpy')
#EXAMPLE
t_obs = np.linspace(0,10,10)
u_obs = np.ones(10)* 40
x_obs_init =20
#RESULT
print(system(u_obs,x_obs_init))
Как видно из примера, я решаю проблему шаг за шагом. Я всегда вызываю объект функции Sympy "system_step". Производительность не особенно хороша для больших систем.
Однако я также хотел бы использовать симуляцию в оптимизаторе scipy, что приводит к тому, что он вызывается несколько раз, что чрезвычайно увеличивает время решения
Моя проблема:
1.) Может ли этот пошаговый расчет также быть реализован с использованием sympy (например, индексированных объектов)? Можно ли избежать повторного вычисления в l oop?
2.) Если это так, как это можно сделать, если длина входных переменных (u) должна оставаться гибкой и не указываться фиксированной index (m) с использованием жесткого кода (см. nr_steps).
Большое спасибо!