在python中使用fsolve时形状不匹配

时间:2016-11-26 17:21:53

标签: python numpy scipy

#solve for U[i],sig[i]

def f(x):
    u=x[0]
    v=x[1]
    s1=0 #sum
    s2=0
    for j in range (N-i,N+i+1):
        s1=s1+Qu[j,i]/(1+u*exp(v*(N-j)*sdt)*dt)
        s2=s2+Qd[j,i]/(1+u*exp(v*(N-j)*sdt)*dt)

    return [Pu[i+1]-s1,Pd[i+1]-s2]

result=fsolve(f,[0,0])
  

TypeError:fsolve:' func'的输入和输出形状之间存在不匹配。论证' f'。形状应为(2,),但它是(2,1)。

所有其他参数都是已知数字(除了u,v)。

以下是一个成功案例,我认为我的代码格式相同。

# success example

def f(x):                                  
    u=x[0]
    v=x[1]
    return [u+v-4, u**2+v**2-8]   

result=fsolve(f,[0,0])                                   

它们具有相同的格式,但第一个不起作用。

提前致谢。

1 个答案:

答案 0 :(得分:0)

使用您的第二个f

In [596]: def f(x):                                  
     ...:     u=x[0]
     ...:     v=x[1]
     ...:     return [u+v-4, u**2+v**2-8]   
     ...: 

我给它一个2元素列表,并返回一个2元素列表

In [597]: f([0,0])
Out[597]: [-4, -8]

实际上fsolve会将您的x0转换为2元素数组,并将返回视为数组

In [598]: f(np.array([0,0]))
Out[598]: [-4, -8]

In [599]: np.array(f(np.array([0,0])))
Out[599]: array([-4, -8])
In [600]: _.shape
Out[600]: (2,)

由于所有未定义的变量(Qu,Pu等),我无法演示您的第一个f。我想我可以猜出合理的形状,但我不喜欢这样做。

但是错误消息表明它生成了类似的内容:

In [601]: np.array([[1],[2]])
Out[601]: 
array([[1],
       [2]])
In [602]: _.shape
Out[602]: (2, 1)

我可以通过对你的第二个f稍作修改来模仿:

In [606]: def f1(x):                                  
     ...:     u=x[0]
     ...:     v=x[1]
     ...:     return [[u+v-4], [u**2+v**2-8]]   
     ...: 
In [607]: optimize.fsolve(f1,[0,0])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-607-a21691ae31f8> in <module>()
----> 1 optimize.fsolve(f1,[0,0])

/usr/lib/python3/dist-packages/scipy/optimize/minpack.py in fsolve(func, x0, args, fprime, full_output, col_deriv, xtol, maxfev, band, epsfcn, factor, diag)
    144                'diag': diag}
    145 
--> 146     res = _root_hybr(func, x0, args, jac=fprime, **options)
    147     if full_output:
    148         x = res['x']

/usr/lib/python3/dist-packages/scipy/optimize/minpack.py in _root_hybr(func, x0, args, jac, col_deriv, xtol, maxfev, band, eps, factor, diag, **unknown_options)
    210     if not isinstance(args, tuple):
    211         args = (args,)
--> 212     shape, dtype = _check_func('fsolve', 'func', func, x0, args, n, (n,))
    213     if epsfcn is None:
    214         epsfcn = finfo(dtype).eps

/usr/lib/python3/dist-packages/scipy/optimize/minpack.py in _check_func(checker, argname, thefunc, x0, args, numinputs, output_shape)
     38                 msg += "."
     39             msg += 'Shape should be %s but it is %s.' % (output_shape, shape(res))
---> 40             raise TypeError(msg)
     41     if issubdtype(res.dtype, inexact):
     42         dt = res.dtype

TypeError: fsolve: there is a mismatch between the input and output shape of the 'func' argument 'f1'.Shape should be (2,) but it is (2, 1).

因此,它会执行测试计算,例如f(x0),并检查返回的维度。当他们的期望不符合时抱怨。

请记住numpy数组中的数组可以包含0,1,2或更多维。相比之下,MATLAB至少有2d。所以在numpy中,像(2,)这样的形状与(2,1)或(1,2)不同。它们都有2个元素,并且可以相互重新形成,但对于许多操作,维度的数量很重要。

[1,2][[1],[2]][[1,2]]是等效的列表表达式。