我目前想在sympy中实现一个Hammerstein模型。我现在为一个简单的系统创建了一个小示例:
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\u step”。 对于较大的系统,性能不是特别好
但是,我也希望在一个scipy优化器中使用模拟,这会导致多次调用它,这极大地增加了解决方案的时间
我的问题是:
1.) 是否也可以使用sympy(例如索引对象)实现此逐步计算?是否可以避免循环中的重复计算
2.)如果是这样,如果输入变量(u)的长度应保持灵活,且不由使用硬代码的固定索引(m)指定,如何实现这一点(参见nr_步骤)
多谢各位
谢谢你提供的信息。如果我用恒定的输入值计算ODE系统,我不需要一步一步地计算它。然后,解决过程非常快。因此,我的想法是使用向量或索引对象来建立系统,这可以防止分步计算
我的目标是:
相关问题 更多 >
编程相关推荐