У вас есть пара вопросов здесь, и пошаговая функция - это только малая часть.Вы можете определить пошаговую функцию с помощью простого lambda
, а затем просто захватить ее из внешней области, даже не передавая ее в вашу функцию.Потому что иногда это не так, мы будем явными и передадим это.Ваша следующая проблема - порядок аргументов в интегрируемой функции.Согласно документам (у, т, ...).Т.е. сначала функция, затем вектор времени, затем остальные args
аргументы.Итак, для первой части мы получаем:
u = lambda t : 2 if t>5 else 0
def model(x,t,u):
dxdt = (-x+u(t))/2
return dxdt
x0 = 0
y0 = 0
t = np.linspace(0,40)
x = odeint(model,x0,t,args=(u,))
Переходя к следующей части, проблема в том, что вы не можете подать x
в качестве аргумента к y, потому что это вектор значений для x(t)
для определенного времени и поэтому y+x
не имеет смысла в функции, как вы ее написали.Вы можете следовать своей интуиции из математического класса, если передадите функцию x вместо значений x.Для этого необходимо, чтобы вы интерполировали значения x, используя конкретные значения времени, которые вас интересуют (с которыми может справиться Сципи, без проблем):
from scipy.interpolate import interp1d
xfunc = interp1d(t.flatten(),x.flatten(),fill_value="extrapolate")
#flatten cuz the shape is off , extrapolate because odeint will go out of bounds
def model2(y,t,x):
dydt = -(y+x(t))/5
return dydt
y = odeint(model2,y0,t,args=(xfunc,))
Тогда вы получите:
@ Ответ Свена более идиоматичен для векторного программирования, например, scipy / numpy.Но я надеюсь, что мой ответ обеспечит более четкий путь от того, что вы уже знаете, к рабочему решению.