2017-07-22 85 views
0

我有一個統計情況,我想找到一些極其尖銳的函數的總和。也就是說,給定一組輸入點in和輸出點out,我想找到數字sum_in f(in,out),其中f是非常尖銳的尖峯。高效地找到一個稀疏函數的總和

爲具體的情況可能是這樣的:

import numpy as np 

sample_pts = 10 ** 7 
data_pts = 10 ** 5 

mu = np.random.rand(data_pts) 
x = np.linspace(0, 1, sample_pts) 

def f(mu, x): 
    return np.exp(-1e10 * ((mu - x) ** 2)) 

我目前的解決方案僅僅是在數據點遍歷樣本點,矢量:

results = np.zeros(sample_pts) 
for i in range(sample_pts): 
    results[i] = np.sum(f(mu, x[i])) 

然而,這是非常低效的,因爲這裏計算的絕大多數數字都非常小 - 事實上,許多數字都是零以達到浮點精度!至少應該有足夠的空間來加快一千倍的速度。

假設一些小的數值誤差(比如說十億分之一)是可以接受的,那麼在numpy中計算這個總和的最快方法是什麼?

+0

你打算如何找到這個總和不看陣列中的每個元素?您無法預先知道某個函數的值是否很小。 –

+0

@ErikGodard實際函數的行爲非常簡單(很容易知道峯值在哪裏),儘管它比這裏的示例稍微複雜一些。 – knzhou

+0

*「但是,這是非常低效的,因爲這裏計算的絕大多數數字都非常小 - 事實上,許多數字在浮點精度內爲零!應該有足夠的空間來加快一千個,至少。「*爲什麼這表明你可以加快性能? (你當然可以,但不是這個原因。) –

回答

0

有了這個功能,你並不需要遍歷

In [833]: mu = np.random.rand(10) 
In [834]: x = np.linspace(0,1,6) 
In [836]: def f(mu, x): 
    ...:  return np.exp(.1* ((mu - x) ** 2)) 
    ...: 
In [837]: f(mu, np.arange(10)) # same shape 
Out[837]: 
array([ 1.00005667e+00, 1.00151080e+00, 1.33174582e+00, 
     2.27563858e+00, 3.14399507e+00, 9.37132782e+00, 
     1.53439871e+01, 6.54667741e+01, 4.85267134e+02, 
     3.11160087e+03]) 
In [838]: f(mu, x[:,None]) # 'outer' broadcasting 
Out[838]: 
array([[ 1.00005667, 1.079973 , 1.00949403, 1.00175693, 1.03860883, 
     1.00729568, 1.06179883, 1.0288728 , 1.00184352, 1.00010102], 
     [ 1.00310927, 1.04691816, 1.00115406, 1.00045585, 1.01741263, 
     1.00048473, 1.03353998, 1.01118532, 1.00041336, 1.00283372], 
     [ 1.01425284, 1.0230266 , 1.00085791, 1.00718177, 1.00465417, 
     1.00170149, 1.01411376, 1.00178422, 1.00700916, 1.01365075], 
     [ 1.03375727, 1.00770978, 1.00859845, 1.02209706, 1.00002398, 
     1.01097526, 1.00304502, 1.00044212, 1.02179017, 1.032814 ], 
     [ 1.06209967, 1.00059511, 1.02456265, 1.04556437, 1.00341039, 
     1.0285303 , 1.00006571, 1.0071267 , 1.0451157 , 1.06079202], 
     [ 1.0999839 , 1.0015108 , 1.04913917, 1.07816138, 1.01489503, 
     1.05479487, 1.00510399, 1.02199931, 1.0775598 , 1.09827913]]) 

,並與和

In [839]: _.sum(axis=1) 
Out[839]: 
array([ 10.22980131, 10.11750708, 10.08823266, 10.1412531 , 
     10.27786262, 10.50142738]) 

我改變了常數;與-1e10所有術語0(在公差範圍內)。

我不知道一種壓縮計算方式,而不是消除已知會產生非常小的結果的mux的值。

隨着-1e10參數,我必須給它一個x非常接近mu得到一個非零和:

In [857]: f(mu, mu-.0001).sum() 
Out[857]: 3.7200759760847501e-43 
相關問題