评估所有数组条目的积分

时间:2017-11-10 17:41:31

标签: python scipy numerical-integration

我需要在数字上解决卷积问题。我想一次将卷积解析为scipy.stats.quad的数组:

# Python 2.7.12
import numpy as np
from scipy import integrate


def gauss(x, sig, mu):
    return(1 / np.sqrt(2*np.pi*sig**2) * np.exp(-(x-mu)**2/(2.*sig**2)))


def PDF_log(x, sig, mu):
    mu = np.log(mu)
    x = np.asarray(x)  # get nans instead of errors for 1/x
    a = 1/(x * sig * np.sqrt(2*np.pi)) * np.exp(-(np.log(x)-mu)**2/(2*sig**2))
    # make sure negative 'x' are returned to 0., as the function only is
    # defined for positive values.
    a = np.nan_to_num(a)
    return a


def gauss_conv(t, x, sig, mu, sig0, mu0):
    a = PDF_log(t, sig, mu) * gauss(x-t, sig0, mu0)
    return a


def gauss_log_num(x, sig, mu, sig0, mu0):
    return integrate.quad(
        gauss_conv,
        a=-np.inf, b=np.inf, args=(x, sig, mu, sig0, mu0)
        )


mu = 0.3
sig = 0.12
mu0 = 0.
sig0 = 0.05

x = np.array([
    0.06581838,
    0.11165416,
    0.15748993,
    0.20332571,
    0.24916149,
    0.29499726,
    0.34083304,
    0.38666882,
    0.43250459,
    0.47834037,
    0.52417615,
    ])

print(gauss_log_num(x, sig, mu, sig0, mu0))

这引起了:

Traceback (most recent call last):
  File "num_gauss_lognormal.py", line 327, in <module>
    test()
  File "num_gauss_lognormal.py", line 325, in test
    print(gauss_log_num(x, sig, mu, sig0, mu0))
  File "num_gauss_lognormal.py", line 163, in gauss_log_num
    return ( integrate.quad(gauss_conv, a = -np.inf, b = np.inf, args=(x,sig,mu,sig0,mu0)) )
  File "/usr/local/lib/python2.7/dist-packages/scipy/integrate/quadpack.py", line 323, in quad
    points)
  File "/usr/local/lib/python2.7/dist-packages/scipy/integrate/quadpack.py", line 390, in _quad
    return _quadpack._qagie(func,bound,infbounds,args,full_output,epsabs,epsrel,limit)
TypeError: only length-1 arrays can be converted to Python scalars`

如果我只评估单个位置的x,例如x[0],卷积起作用,我得到一个值。显然,我现在可以在x上运行for循环,但这感觉就像这样做的最慢的方式。 我需要做什么来一次评估x的每个值的卷积?

1 个答案:

答案 0 :(得分:1)

x中对所有元素执行计算的一种方法是对计算进行向量化。

from scipy import  integrate
import numpy as np

def gauss(x,sig,mu):
    return( 1/(np.sqrt(2*np.pi*sig**2)) * np.exp(-(x-mu)**2/(2.*sig**2)) )

def PDF_log(x,sig,mu):
    mu = np.log(mu)
    x = np.asarray(x) # get nans instead of errors for 1/x
    a =  (1/x)*(1/(sig*np.sqrt(2*np.pi)))*np.exp(-(np.log(x)-mu)**2/(2*sig**2)) 
    a = np.nan_to_num(a) #make sure negative 'x' are returned to 0., as the function only is defined for positive values.
    return(a)

def gauss_conv(t,x,sig,mu,sig0,mu0):
    a = PDF_log(t,sig,mu) * gauss(x-t,sig0,mu0) 
    return(a)

def gauss_log_num(x, sig, mu, sig0, mu0):
    return ( integrate.quad(gauss_conv, a = -np.inf, b = np.inf, args=(x,sig,mu,sig0,mu0)) )


x = np.array([[ 0.06581838 , 0.11165416 , 0.15748993 , 0.20332571 , 0.24916149,  0.29499726 , 0.34083304,  0.38666882 , 0.43250459 , 0.47834037 , 0.52417615]])


mu = 0.3
sig = 0.12
mu0 = 0.
sig0 = 0.05

convolver = lambda t: gauss_log_num(t, sig, mu, sig0, mu0)
vfunc = np.vectorize(convolver)
ans = vfunc(x)

返回:

print ans
(array([[  2.64327555e-03,   4.42748593e-02,   3.87454290e-01,
          1.80492291e+00,   4.57171773e+00,   6.44923191e+00,
          5.20617751e+00,   2.47941776e+00,   7.20733704e-01,
          1.32773639e-01,   1.61483270e-02]]), array([[  8.75523521e-09,   3.90932482e-09,   9.90265796e-09,
          6.87900177e-09,   9.93674832e-10,   5.72760020e-08,
          3.17433287e-09,   2.29346039e-10,   6.21327924e-09,
          5.81321976e-09,   1.33339787e-08]]))

请参阅How can I custom-format the Autocomplete plug-in results?