Итак, как мне подойти к написанию кода для оптимизации констант a и b в дифференциальном уравнении, например dy/dt = a*y^2 + b, с помощью curve_fit? Я бы использовал odeint для решения ODE, а затем curve_fit для оптимизации a и b. Если бы вы могли, пожалуйста, внести свой вклад в эту ситуацию, я был бы очень признателен!
Оптимизация констант в дифференциальных уравнениях в Python
Ответы (3)
Возможно, вам будет лучше взглянуть на ODE с Sympy. Scipy/Numpy - это в основном числовые пакеты, которые на самом деле не предназначены для выполнения алгебраических/символических операций.
person
BrenBarn
schedule
25.04.2013
Спасибо, это интересно и может помочь, например, то, что я хочу сделать с дифференциальным уравнением, однажды решенным с помощью odeint, - это оптимизировать одну или две константы с помощью curve_fit. Как вы думаете, мне придется использовать sympy, чтобы сделать это, или есть другой способ?
- person user2199360; 25.04.2013
Более подходящей ссылкой SymPy является docs.sympy.org/dev/modules/solvers/ ode.html
- person Warren Weckesser; 25.04.2013
@ user2199360: Хотя Scipy не настроен для символьных операций, Sympy не настроен для числовых операций, таких как оптимизация. Если вы используете подгонку кривой, тип кривой, которую вы подгоняете, может дать вам интерпретацию числовых результатов, которые вы можете использовать для создания символьной функции (например, если параметры являются полиномиальными коэффициентами, вы можете использовать их для записи многочлен в символьной форме). Возможно, если вы отредактируете свой вопрос, чтобы описать общую задачу, которую вы пытаетесь выполнить, люди смогут внести более полезный вклад.
- person BrenBarn; 25.04.2013
На самом деле эта задача не требует аналитического решения ОДУ (которого Sympy не нашел бы, если бы RHS была более сложной).
- person pv.; 26.04.2013
Вы определенно можете сделать это:
import numpy as np
from scipy.integrate import odeint
from scipy.optimize import curve_fit
def f(y, t, a, b):
return a*y**2 + b
def y(t, a, b, y0):
"""
Solution to the ODE y'(t) = f(t,y,a,b) with initial condition y(0) = y0
"""
y = odeint(f, y0, t, args=(a, b))
return y.ravel()
# Some random data to fit
data_t = np.sort(np.random.rand(200) * 10)
data_y = data_t**2 + np.random.rand(200)*10
popt, cov = curve_fit(y, data_t, data_y, [-1.2, 0.1, 0])
a_opt, b_opt, y0_opt = popt
print("a = %g" % a_opt)
print("b = %g" % b_opt)
print("y0 = %g" % y0_opt)
import matplotlib.pyplot as plt
t = np.linspace(0, 10, 2000)
plt.plot(data_t, data_y, '.',
t, y(t, a_opt, b_opt, y0_opt), '-')
plt.gcf().set_size_inches(6, 4)
plt.savefig('out.png', dpi=96)
plt.show()
person
pv.
schedule
26.04.2013
Чтобы решить именно этот тип проблемы, я решил написать пакет-оболочку, который объединяет sympy
и scipy
. Он называется symfit
. Подгонка к вашему ODE будет выглядеть так:
tdata = np.array([10, 26, 44, 70, 120])
ydata = 10e-4 * np.array([44, 34, 27, 20, 14])
y, t = variables('y, t')
a, b = parameters('a, b')
model_dict = {
D(y, t): a*y^2 + b
}
ode_model = ODEModel(model_dict, initial={t: 0.0, y: 0.0})
fit = Fit(ode_model, t=tdata, y=ydata)
fit_result = fit.execute()
Как вы можете видеть из того, как он определяется как dict, подгонка к системам ОДУ (первого порядка) не проблема. Ознакомьтесь с документами, чтобы узнать больше!
person
tBuLi
schedule
23.10.2016