【问题标题】:Shape mismatch when using fsolve in python在 python 中使用 fsolve 时形状不匹配
【发布时间】:2016-11-26 17:21:52
【问题描述】:
#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])                                   

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

提前致谢。

【问题讨论】:

  • 编辑f(x),使其返回一个形状为 (2,) 的数组或一个 2 元素列表(不是嵌套列表)。查看形状 (2,) 和 (2,1) 之间的区别。
  • 感谢您的回答。但是你能说出这两个代码之间的区别吗?为什么第二个有效?

标签: python numpy scipy


【解决方案1】:

与你的第二个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]] 是等效的列表表达式。

【讨论】:

    猜你喜欢
    • 2015-08-18
    • 2019-06-10
    • 2018-04-11
    • 2021-12-29
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 2020-03-09
    • 2021-05-11
    相关资源
    最近更新 更多