Нахождение оптимального значения. Функция MINIMIZE. Python
Всем привет, это химическая-кинетика с поиском оптимального значения концентрации для регулирования молекулярной массы (в первой части кода представлена система ДУ и решена она через odeint). И задача в следующем - надо найти минимум s[1] при значении Mw = 600000. (одномерная оптимизация) Смысл в том, что Mw интерполируется сплайнами и вычисляем то t, при котором Mw==600000. Проблема заключается в расположении индекса x0. Функция minimize считает до 4 итерации и выдает ошибку "index 0 is out of bounds for axis 0 with size 0". Скорее всего, надо изменить метод minimize (я пробовал - симплекс Нелдера-Мида, BFGS, сопряженных градиентов Ньютона, COBYLA и SLSQP) - все сводилось к ошибке.Помогите пожалуйста в исправлении ошибки, буду весьма благодарен )
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
from scipy.integrate import odeint
from scipy.interpolate import splev, splrep, sproot
def F(s,t):
kp = 48; km = 0.0048; ka1 = 8.16; ka2 = 0.96
dMdt = -s[0]*s[3]*(kp*km)-s[0]*(kp+km)*s[4]
dA1dt = -ka1*s[1]*s[3]-ka1*s[1]*s[4]
dA2dt = -ka2*s[2]*s[3]-ka2*s[2]*s[4]
dPdt = -kp*s[0]*s[3]+(km*s[0]+ka1*s[1]+ka2*s[2])*s[4]
dQdt = km*s[0]*s[3]+ka1*s[1]*s[3]+ka2*s[2]*s[3]*s[4]
dm0dt = kp*s[0]*s[3]-(km*s[0]+ka1*s[1]+ka2*s[2])*s[4]
dn0dt = (km*s[0]*ka1*s[2]+ka2*s[2]*s[3])*s[4]
dm1dt = 2*kp*s[0]*s[3]+kp*s[0]*s[4]-(km*s[0]+ka1*s[1]+ka2*s[2])*s[5]
dn1dt = (km*s[0]+ka1*s[1]+ka2*s[2])*s[5]
dm2dt = 4*kp*s[0]*s[3]+kp*s[0]*s[4]+2*kp*s[0]*s[5]-(km*s[0]+ka1*s[1]+ka2*s[2])*s[6]
dn2dt = (km*s[0]+ka1*s[1]+ka2*s[2])*s[6]
return [dMdt, dA1dt, dA2dt, dPdt, dQdt, dm0dt, dn0dt, dm1dt, dn1dt, dm2dt, dn2dt]
def F2(s0):
t = np.linspace(0, 8500)
print(s0)
s = odeint(F, s0, t)
Mw = ((s[:,9]+s[:,10])/(s[:,7]+s[:,8]+2**-100))*68
plt.plot(t,Mw,'b-',linewidth=2.0,label='Mw')
plt.xlabel("W0")
plt.ylabel("Mw")
plt.legend()
plt.grid()
plt.show()
curve = splrep(t, Mw - 600000)
x0=sproot(curve)
y1=splrep(t, s[:, 1])
s1=splev(x0[0], y1)
print (s1)
return s1
s0 = [1.39,0.000177,0.00168,0.0000007,0,0,0,0,0,0,0]
res = minimize(F2, s0, method='BFGS', tol=1e-3)