【问题标题】:TypeError when I try to implement a function on a grid当我尝试在网格上实现函数时出现 TypeError
【发布时间】:2018-12-21 23:10:01
【问题描述】:

简介

我有一对称为 numeric(x,y,z) 和 analytic(x,y,z) 的函数,其中 numeric(x,y,z) 是 analytic(x,y,z) 的近似值。我想制作一些等高线图,看看这些函数在 x-y 平面上的样子,所以对于下面的函数,我设置了 z=0。然后我尝试在网格上定义函数;

def numerical_plane(x,y):
    return numerical(x, y, 0)

def analytic_plane(x,y):
    R = np.sqrt(x**2+y**2)
    return -G*M/(np.sqrt(R**2 + (a+np.sqrt(b**2))**2))

x = np.linspace(-20, 20, 50)
y = np.linspace(-20, 20, 50)

X, Y = np.meshgrid(x, y)
Z1 = numerical(X, Y)
Z2 = analytic(X, Y)

这个问题的底部定义了函数 numeric(x,y,z)。

问题

Z2 工作正常,但 Z1 提高

TypeError: only size-1 arrays can be converted to Python scalars

由于这是一个 TypeError,我尝试检查 numeric(1,2); 返回的类型;那是一个花车。另一方面,analytic(1,2) 返回一个 numpy.float64。我尝试强制 numeric(x,y) 返回一个 numpy.float64 但这实际上并没有帮助,所以也许我走错了路。有谁明白这里出了什么问题?

如果您需要关于函数 numeric(x,y,z) 的更多信息,那么我已经在此处编写了它的定义

def rho(x,y,z,M = 5e10,a = 4,b =0.8):

    R = np.sqrt(x**2+y**2)
    rho = ((b**2*M)/(4*np.pi))*(a*R**2+(a+3*np.sqrt(z**2+b**2))*(a+np.sqrt(z**2+b**2))**2)\
          /((R**2+(a+np.sqrt(z**2+b**2))**2)**(2.5)*(z**2+b**2)**(1.5))
    return rho

def numerical(x, y, z, s=0.01):

    integrand = lambda xx, yy, zz: -G*rho(xx,yy,zz,M,a,b)/(np.sqrt((xx-      x)**2+(yy-y)**2+(zz-z)**2+s**2))      
    phi =   nquad(integrand, ranges = [(-np.inf, np.inf), (-np.inf, np.inf), (-np.inf, np.inf)], opts = {'epsrel' : 1e-1})[0]
    return phi

它涉及调用另一个函数 rho(x,y,z, ...),然后在所有空间上执行积分。

这里也是完整的回溯...


TypeError                                 Traceback (most recent call last)
<ipython-input-62-cb38a0d34db9> in <module>()
     11 X, Y = np.meshgrid(x, y)
     12 Z1 = analytic(X, Y)
---> 13 Z2 = numeric(X, Y)

<ipython-input-62-cb38a0d34db9> in numeric(x, y)
      1 def numeric(x,y):
----> 2     return numerical_phi_MN(x, y, 0)
      3 
      4 def analytic(x,y):
      5     R = np.sqrt(x**2+y**2)

<ipython-input-43-c7e02143837e> in numerical_phi_MN(x, y, z, s)
     14 
     15     integrand = lambda xx, yy, zz: -G*rho_MN(xx,yy,zz,M,a,b)/(np.sqrt((xx-x)**2+(yy-y)**2+(zz-z)**2+s**2))
---> 16     phi =   nquad(integrand, ranges = [(-np.inf, np.inf), (-np.inf, np.inf), (-np.inf, np.inf)], opts = {'epsrel' : 1e-1})[0]
     17 
     18     return phi

/opt/python-2.7.14/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in nquad(func, ranges, args, opts, full_output)
    712     else:
    713         opts = [opt if callable(opt) else _OptFunc(opt) for opt in opts]
--> 714     return _NQuad(func, ranges, opts, full_output).integrate(*args)
    715 
    716 

/opt/python-2.7.14/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in integrate(self, *args, **kwargs)
    767             f = partial(self.integrate, depth=depth+1)
    768         quad_r = quad(f, low, high, args=args, full_output=self.full_output,
--> 769                       **opt)
    770         value = quad_r[0]
    771         abserr = quad_r[1]

/opt/python-2.7.14/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in quad(func, a, b, args, full_output, epsabs, epsrel, limit, points, weight, wvar, wopts, maxp1, limlst)
    321     if (weight is None):
    322         retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,
--> 323                        points)
    324     else:
    325         retval = _quad_weight(func, a, b, args, full_output, epsabs, epsrel,

/opt/python-2.7.14/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in _quad(func, a, b, args, full_output, epsabs, epsrel, limit, points)
    388             return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
    389         else:
--> 390             return _quadpack._qagie(func,bound,infbounds,args,full_output,epsabs,epsrel,limit)
    391     else:
    392         if infbounds != 0:

/opt/python-2.7.14/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in integrate(self, *args, **kwargs)
    767             f = partial(self.integrate, depth=depth+1)
    768         quad_r = quad(f, low, high, args=args, full_output=self.full_output,
--> 769                       **opt)
    770         value = quad_r[0]
    771         abserr = quad_r[1]

/opt/python-2.7.14/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in quad(func, a, b, args, full_output, epsabs, epsrel, limit, points, weight, wvar, wopts, maxp1, limlst)
    321     if (weight is None):
    322         retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,
--> 323                        points)
    324     else:
    325         retval = _quad_weight(func, a, b, args, full_output, epsabs, epsrel,

/opt/python-2.7.14/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in _quad(func, a, b, args, full_output, epsabs, epsrel, limit, points)
    388             return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
    389         else:
--> 390             return _quadpack._qagie(func,bound,infbounds,args,full_output,epsabs,epsrel,limit)
    391     else:
    392         if infbounds != 0:

/opt/python-2.7.14/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in integrate(self, *args, **kwargs)
    767             f = partial(self.integrate, depth=depth+1)
    768         quad_r = quad(f, low, high, args=args, full_output=self.full_output,
--> 769                       **opt)
    770         value = quad_r[0]
    771         abserr = quad_r[1]

/opt/python-2.7.14/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in quad(func, a, b, args, full_output, epsabs, epsrel, limit, points, weight, wvar, wopts, maxp1, limlst)
    321     if (weight is None):
    322         retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,
--> 323                        points)
    324     else:
    325         retval = _quad_weight(func, a, b, args, full_output, epsabs, epsrel,

/opt/python-2.7.14/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in _quad(func, a, b, args, full_output, epsabs, epsrel, limit, points)
    388             return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
    389         else:
--> 390             return _quadpack._qagie(func,bound,infbounds,args,full_output,epsabs,epsrel,limit)
    391     else:
    392         if infbounds != 0:

TypeError: only size-1 arrays can be converted to Python scalars

非常感谢

【问题讨论】:

  • 请提供完整的回溯,以便我们知道此问题发生在哪一行。
  • 目前GMrrho_MN未定义。前两个明明是数值常数,但后一个是函数……
  • 道歉@Graphier ...我的工作代码中的函数名称非常混乱,所以为了使我的代码更具可读性,当我将代码转移到stackoverflow时,我给出了我的函数更简单的名字。例如,我的问题中的“numerical(x,y,z)”实际上是我的代码中的“numerical_phi_MN(x,y,z)”。我删除了下标“_phi_MN”以缩短名称。我为 'rho' 做了类似的事情,但正如你所注意到的,我在所有情况下都忘记删除下标。干杯

标签: python function numpy typeerror


【解决方案1】:

问题在于scipy.integrate.nquad 只能集成单个(n 维)函数。因此,它将始终返回单个值,而不是按元素应用于多维向量。

您可以通过使用numpy.vectorize 将函数向量化来解决此问题。但是,请注意文档中所说的内容:

提供矢量化功能主要是为了方便,而不是为了 表现。该实现本质上是一个 for 循环。

有了这个(和G = 1M = 1rho_MN = rho),它就会运行(虽然需要很长时间,但它会在完成时通知你):

def numerical_plane(x, y):
    return np.vectorize(numerical)(x, y, 0)

【讨论】:

    猜你喜欢
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    • 2020-07-09
    • 2017-10-17
    • 2021-02-06
    • 2018-07-02
    相关资源
    最近更新 更多