Sympy: пошаговый расчет системы ODE с использованием индексированных объектов - PullRequest
0 голосов
/ 17 февраля 2020

В настоящее время я хочу реализовать модель Гаммерштейна в 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).

Большое спасибо!

1 Ответ

0 голосов
/ 18 февраля 2020

Спасибо за информацию. Если я вычисляю систему ODE с постоянными входными значениями, мне не нужно рассчитывать ее шаг за шагом. Тогда процесс решения очень быстрый. Поэтому моя идея состояла в том, чтобы настроить систему с использованием векторов или индексированных объектов, что может помешать пошаговому вычислению.

Моя цель:

  • настроить систему с помощью переменные входные переменные
  • символически решают систему, даже если это занимает очень много времени
  • Lambdify и хранение в двоичном файле
  • используют решенную систему для различных операций
...