科学优化错误 [英] Scipy optimize error

查看:191
本文介绍了科学优化错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要在Python中解决的ODE有一个相当简单的参数估计问题.我一直在使用odeint函数来求解ODE,并使用scipy.optimize库来查找参数.当我单独使用odeint函数时,没有任何问题,但是通过scipy.optimize它给了我一个错误RuntimeError:func返回的数组必须是一维的,但是得到了ndim = 2.

I have a fairly simply parameter estimation problem with ODEs I want to solve in Python. I have been using the odeint function for solving the ODEs and the scipy.optimize library for finding the parameter. When I use the odeint function by itself I get no problems but via the scipy.optimize it gives me an error RuntimeError: The array return by func must be one-dimensional, but got ndim=2.

我不认为它与

I do not think it is a duplicate with How to fix the error: The array return by func must be one-dimensional, but got ndim=2 as I can run the odeint solver independently....

以下代码:

import numpy as np
from scipy.integrate import odeint
from scipy.optimize import minimize

init = [0,0]
t_end = 5
dt = 0.01
tspan = np.arange(0,t_end+dt,dt)

def my_fun(y,t,K):
    if t<=0.07:
        s = 2000
    else:
        s = 0
    return np.array([s+3.6*(y[1]-y[0]) +K*y[0], 0.38*y[0]-0.48*y[1] +K*y[1]])

def solver(t,p2):    
    y_ode = odeint(my_fun,init,t,args = (p2,))
    return y_ode

test = solver(tspan,0.01)
print(test)

y_real = solver(tspan, 0.1)

def err_fun(p):
    return np.sum((y_real-solver(tspan,p))**2)


print(err_fun(0.01))      
c0 = [0.2]

optim = minimize(err_fun,c0,method='Nelder-Mead')

推荐答案

问题是minimize用一个长度为1的一维数组的参数调用err_funerr_fun将其传递给solversolver将其传递给odeint,后者将其作为K参数传递给my_fun.看看K是标量还是长度为1的数组时,my_fun的输出形状的差异.

The problem is that minimize calls err_fun with an argument that is a one-dimensional array of length 1; err_fun passes this to solver, and solver passes it to odeint, which passes it to my_fun as the K argument. Take a look at the difference in the shape of the output of my_fun when K is either a scalar or an array with length 1:

In [43]: my_fun([1, 2], 0, 0.05)  # K is a scalar.
Out[43]: array([ 2.00365e+03, -4.80000e-01])

In [44]: my_fun([1, 2], 0, np.array([0.05]))  # K is an array.
Out[44]: 
array([[ 2.00365e+03],
       [-4.80000e-01]])

K是长度为1的一维数组时,my_fun返回形状为(2,1)的数组.这不是odeint所期望的.

When K is a one-dimensional array with length 1, my_fun returns an array with shape (2, 1). That's not what odeint expects.

要解决此问题,您必须将该数组转换为调用链中某个位置的标量.例如,您可以在err_fun中立即执行以下操作:

To fix this, you'll have to convert that array to a scalar somewhere in the chain of calls. For example, you could do it immediately in err_fun, with something like:

def err_fun(p):
    if not np.isscalar(p):
        p = p[0]
    return np.sum((y_real-solver(tspan,p))**2)

当我这样做并运行您的脚本时,代码就起作用了.这是我从optim获得的东西:

When I do that and run your script, the code works. Here's what I get for optim:

In [46]: optim
Out[46]: 
 final_simplex: (array([[0.1       ],
       [0.09999512]]), array([2.95795174e-22, 4.03900365e-05]))
           fun: 2.9579517415523713e-22
       message: 'Optimization terminated successfully.'
          nfev: 34
           nit: 17
        status: 0
       success: True
             x: array([0.1])

这篇关于科学优化错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆