Python matplotlib错误:提供的函数不返回有效的float

时间:2014-02-02 22:19:30

标签: python matplotlib

from __future__ import division
import functools
import warnings
import numpy as np
import scipy as sp
from scipy import integrate
from numpy import exp, pi
import matplotlib.pyplot as plt

warnings.simplefilter("ignore", np.ComplexWarning)


def legendrePoly(a,n):

    def integrand(t):
        return ( ((a + exp(2j*pi*t))**2 - 1)/(2*exp(2j*pi*t)) )**n

    return sp.integrate.quad(integrand,0,1)[0]


basisDim = 6
legendreBasis = [functools.partial(legendrePoly, n=i) for i in range(basisDim)]

integrand = [lambda x,i=i: exp(x) * legendreBasis[i](x) for i in range(basisDim)]
normalizingConst = [lambda x,i=i: legendreBasis[i](x)**2 for i in range(basisDim)]
basisCoeff = [sp.integrate.quad(integrand[i],-1,1)[0]
             /sp.integrate.quad(normalizingConst[i],-1,1)[0] for i in range(basisDim)]

approxPoly = lambda x: sum(basisCoeff[i]*legendreBasis[i](x) for i in range(basisDim))


t = np.arange(-1, 1, 1e-3)
plt.plot(t,exp(t),'b')
plt.plot(t,approxPoly(t),'r')
plt.show()

我使用勒让德多项式作为指数函数的多项式逼近的基础。我也使用Cauchy的积分公式来评估它们,而不是直接从numpy中导入它们。

一切都运行良好,包括定义approxPoly,而aboutPoly返回我输入的任何输入的预期值。但由于某些原因,当我尝试绘制approxPoly(t)时,它会返回错误:提供的函数不会返回有效的浮点数。

这个错误似乎表明,当我在legendreBasis中的函数调用scipy.integrate.quad时,那里出现了问题,但是如果是这样的话那么approxPoly将不起作用,但如果你在2000之间评估它-1和1手动,并绘制这些点,一切正常,但这是不是plt.plot在尝试绘制我的函数时所做的事情?

回溯:

Traceback (most recent call last):
  File "/private/var/folders/mb/yyp8v3_95l538z3g7jsttq540000gn/T/Cleanup At Startup/Exercise-413072597.643.py", line 34, in <module>
    plt.plot(t,approxPoly(t),'r')
  File "/private/var/folders/mb/yyp8v3_95l538z3g7jsttq540000gn/T/Cleanup At Startup/Exercise-413072597.643.py", line 29, in <lambda>
    approxPoly = lambda x: sum(basisCoeff[i]*legendreBasis[i](x) for i in range(basisDim))
  File "/private/var/folders/mb/yyp8v3_95l538z3g7jsttq540000gn/T/Cleanup At Startup/Exercise-413072597.643.py", line 29, in <genexpr>
    approxPoly = lambda x: sum(basisCoeff[i]*legendreBasis[i](x) for i in range(basisDim))
  File "/private/var/folders/mb/yyp8v3_95l538z3g7jsttq540000gn/T/Cleanup At Startup/Exercise-413072597.643.py", line 18, in legendrePoly
    return sp.integrate.quad(integrand,0,1)[0]
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/integrate/quadpack.py", line 247, in quad
    retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/integrate/quadpack.py", line 312, in _quad
    return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
quadpack.error: Supplied function does not return a valid float.
logout

1 个答案:

答案 0 :(得分:2)

scipy.integrate.quad不集成返回数组的函数。这意味着当您尝试调用approxPoly(t)时,t会被传递,直到它在此函数中结束:

def legendrePoly(a,n):

    def integrand(t):
        return ( ((a + exp(2j*pi*t))**2 - 1)/(2*exp(2j*pi*t)) )**n

    return sp.integrate.quad(integrand,0,1)[0]

integrand返回一个数组,sp.integrate.quad扼流圈。您的代码中会出现同样的问题。似乎所有东西都是用标量论证来写的。

您可以通过致电approxPoly上的vectorize来解决此问题:

plt.plot(t,np.vectorize(approxPoly)(t),'r')

NumPy会分别在approxPoly的每个元素上调用t