Вы совершенно не правы, передавая массив значений F
в производную функцию, не имея возможности связать ее записи со временем t
, в котором оценивается функция. Помните, что аргументы y
и t
являются вектором состояния и (единичным, скалярным) временем, которое решатель должен вычислить на следующем этапе в численном методе. Самый простой способ - передать F
как функцию, чтобы можно было напрямую вычислить ее значение.
def spring(y,t,par):
m,k,c,F = par
return [ y[1], F(t)/m-c*y[1]/m-k*y[0]/m ]
#cases:[ti,tf,x0,xdot0,c]
A=[0.0,0.3,0.1,0.0,37.7]
B=[0.0,3.0,0.0,1.0,37.7]
C=[0.0,3.0,0.1,1.0,377]
D=[0.0,5.0,0.0,0.0,37.7]
E=[0.0,3.0,0.0,0.0,37.7]
cases = [A, B, C, D, E] #0,1,2,3,4
m=10.0
k=3553.0
h = 0.01
Для pythoni c удобнее использовать назначения кортежей для распаковки кортежей параметров, выполняя в одной строке то, что ранее было распределено по нескольким, также улучшило видимость порядка параметров.
Удалите некоторые ненужные сложности, такие как наличие дополнительного механизма подсчета, используйте механизм enumerate(list)
. Кроме того, не используйте явно составленный список параметров par
, когда его гораздо проще создать ad-ho c в необязательном аргументе args
(это было бы иначе, если бы были сотни систематически сконструированных записей).
В общем случае F
может быть функцией интерполяции, сгенерированной методами из scipy.interpolate
. Здесь достаточно преобразовать данные уравнения в лямбда-выражения, чтобы определить соответствующие скалярные функции.
for cont,case in enumerate(cases):
ti,tf,x0,xdot0,c = case
y = [x0,xdot0]
t = np.arange(ti, tf, h)
F = lambda t: 0
if cont == 3:
F = lambda t: 1000*np.sin(np.pi*t+np.pi/2)
elif (cont == 4):
F = lambda t: 1000 if t >= 0.5 else 0
Y = ode(spring,y,t,args=([m,k,c,F],))
Xn,Vn = Y.T
graph.figure(figsize=(9,3))
graph.subplot(1,3,1); graph.plot(t,Xn)
graph.subplot(1,3,2); graph.plot(t,Vn)
graph.subplot(1,3,3); graph.plot(Xn,Vn)
graph.tight_layout(); graph.show()
Все остальное происходит так же, как и раньше, с использованием вспомогательных участков для сборки различных графиков в одном изображении. Например, 4-й пример дает хаотически колеблющийся результат