Как я могу исправить эту ошибку TypeError при установке ODE со Scipy? - PullRequest
0 голосов
/ 21 марта 2020

Я бы хотел настроить параметры простого ODE с помощью пакета scipy. У меня такое ощущение, что это терпимо. Мне известно об этом сообщении , но я думаю, что мой вопрос другой.

Сначала мы импортируем необходимые пакеты:

import numpy as np
from scipy import integrate, optimize

Мы определяем ODE с подписью, соответствующей новый scipy.interpolate.solve_ivp метод:

def GGM_ODE(t, C, r, p):
    return r*np.power(C, p)

Мы определяем интегрированное решение ODE с сигнатурой, соответствующей classi c scipy.optimize.curve_fit :

def GGM_sol(t, C, r, p):
    return integrate.solve_ivp(GGM_ODE, (t[0], t[-1]), [C], t_eval=t, args=(r, p))

Мы создаем синтетический набор данных c, решая проблему IV для данного набора параметров:

t = np.arange(0, 21)
sol = GGM_sol(t, 1, 0.5, 0.7)

Это прекрасно работает.

Наконец, мы пытаемся настроить параметры, подбирая интегрированное решение:

popt, pcov = optimize.curve_fit(GGM_sol, t, sol.y)

К сожалению, этот последний шаг завершается неудачно с ошибкой crypti c (по крайней мере, crypti c для меня, потому что мне не хватает понимание того, как строится scipy):

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-45-22b0c3097986> in <module>
----> 1 popt, pcov = optimize.curve_fit(GGM_sol, t, sol.y)

~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
    761         # Remove full_output from kwargs, otherwise we're passing it in twice.
    762         return_full = kwargs.pop('full_output', False)
--> 763         res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
    764         popt, pcov, infodict, errmsg, ier = res
    765         ysize = len(infodict['fvec'])

~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
    386     if not isinstance(args, tuple):
    387         args = (args,)
--> 388     shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
    389     m = shape[0]
    390 

~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in _check_func(checker, argname, thefunc, x0, args, numinputs, output_shape)
     24 def _check_func(checker, argname, thefunc, x0, args, numinputs,
     25                 output_shape=None):
---> 26     res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
     27     if (output_shape is not None) and (shape(res) != output_shape):
     28         if (output_shape[0] != 1):

~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in func_wrapped(params)
    461     if transform is None:
    462         def func_wrapped(params):
--> 463             return func(xdata, *params) - ydata
    464     elif transform.ndim == 1:
    465         def func_wrapped(params):

TypeError: unsupported operand type(s) for -: 'OdeResult' and 'float'

Я вижу, что эта ошибка - classi c TypeError о несовместимых операндах для оператора разности. Он утверждает, что не может вычесть float объекту OdeResult. Это касается только пакета optimize, а не integrate.

Что я не понимаю, так это почему я получаю эту ошибку.

Что я должен изменить в сигнатуре или вызове функции, чтобы curve_fit работал? Или я что-то пропустил?

1 Ответ

1 голос
/ 21 марта 2020

Как указано в сообщении об ошибке, solve_ivp возвращает объект решения, который содержит данные решения. Попробуйте

def GGM_sol(t, C, r, p):
    res = integrate.solve_ivp(GGM_ODE, (t[0], t[-1]), [C], t_eval=t, args=(r, p))
    return res.y[0]

, чтобы получить только значения решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...