我需要在数字上解决卷积问题。我想一次将卷积解析为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
的每个值的卷积?
答案 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?