Python Sympy:使用索引对象逐步计算ODE系统
我目前想在sympy中实现一个Hammerstein模型。我现在为一个简单的系统创建了一个小示例:Python Sympy:使用索引对象逐步计算ODE系统,python,controls,simulation,sympy,Python,Controls,Simulation,Sympy,我目前想在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 =symb
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系统,我不需要一步一步地计算它。然后,解决过程非常快。因此,我的想法是使用向量或索引对象来建立系统,这可以防止分步计算 我的目标是:
- 使用可变输入变量设置系统
- 象征性地解决系统问题,即使需要很长时间
- Lambdify和二进制文件中的存储
- 对不同的操作使用已解决的系统
system\u step
,则其他所有内容都只是数字,运行速度会快得多