从Python/SciPy集成“quad”和“quadrature”

8
阅读完这篇文章那篇文章后,我认为“quad”和“quadrature”两个词至少在语法上应该是可以互换的。但奇怪的是似乎它们并不是可互换的:
from scipy.integrate import quad as q
#from scipy.integrate import quadrature as q

def myfunc(x):
    return x

def integr():
    return q(myfunc, 0, 1)[0]

print integr()


def myfunc2(x, y):
    return x + y

def integr2(y):
    return q(myfunc2, 0, 1, args=(y))[0]
    #return q(myfunc2, 0, 1, args=[y])[0] 

print integr2(10)

这个例子在“quad”上运行良好,但在“quadrature”上不行 - 最后我得到了:

Traceback (most recent call last):
  File "./test.py", line 38, in <module>
    print integr2(10)
  File "./test.py", line 36, in integr2
    return q(myfunc2, 0, 1, args=(y))[0]
  File "/usr/lib/python2.6/dist-packages/scipy/integrate/quadrature.py", line 136, in quadrature
    newval = fixed_quad(vfunc, a, b, (), n)[0]
  File "/usr/lib/python2.6/dist-packages/scipy/integrate/quadrature.py", line 48, in fixed_quad
    return (b-a)/2.0*sum(w*func(y,*args),0), None
  File "/usr/lib/python2.6/dist-packages/scipy/integrate/quadrature.py", line 77, in vfunc
    return func(x, *args)
TypeError: myfunc2() argument after * must be a sequence, not int

我必须将args元组切换为列表(参见integr2中的注释行),即使文档说它应该是一个元组。看起来这就是解释器抱怨的原因... (对吧?)
这是有意为之吗?还是我做错了什么?最终,我希望能够在不太改变其余代码的情况下选择积分方法。
*实际上,我不太明白如何在两者之间进行选择。我确实了解高斯积分和自适应积分之间的区别,但我不知道“自适应高斯积分”应该是什么意思 - 如果是节点数量适应,那么如何适应呢?

1
quad接受一个标量参数的函数,而quadrature则接受一个接受矢量参数(函数同时进行多个不同的求值)的函数。自适应意味着它会采取更多的样本(高效地),直到边际误差降低到某个容限以下。 - Andrew Mao
1个回答

5
问题出在这一行代码:return q(myfunc2, 0, 1, args=(y))[0],具体是在 args=(y) 部分。正确的写法应该是 args=(y,)(注意 y 后面的逗号)或者 args=[y]
问题在于,在 Python 中,元组需要用逗号来创建,而不是用括号。看下面的例子:
>>> a = (1,)
>>> b = (1)
>>> print a, type(a)
(1,) <type 'tuple'>
>>> print b, type(b)
1 <type 'int'>

谢谢!这解释了我做错了什么...你有没有想过为什么它对“quad”有效? - NichtJens
不,它适用于args=(y)args=(y,),但最终可能是quad中的一个“错误”,它接受单个参数作为非元组类型... args=[y]只是为了让quadrature工作。但这可能是幸运的,因为这不是正确的方法。 - NichtJens
1
请向scipy开发人员报告此问题,并提出希望有更好的错误提示信息。 - plaes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接