2016-07-24 19 views
-1

我想了解從http://gruntthepeon.free.fr/ssemath/sse_mathfun.hexp256_ps()http://software-lisc.fbk.eu/avx_mathfun/avx_mathfun.hexp_ps()的實現。
我明白幾乎所有的計算,除了如何確定恆定cephes_exp_C2。它似乎增加了計算的準確性。如果將其從計算中移除,則結果函數顯着更快且精確度稍低(對於+/- 10左右的值,相對誤差仍低於1%)。我在其他數字庫中發現了這樣的係數,但沒有更詳細的解釋。exp()函數的數值計算中的係數

+3

碼?嘗試?例子? –

+0

我想這個常數是'exp(C2)',其中'C2'是其他常數。你真的瞭解其他一切嗎?例如。什麼是'cephes_exp_p0'? – user463035818

+2

不僅你不顯示任何[mcve],而且還會將兩個鏈接轉儲到一堆文本中,甚至沒有**特定的**問題。這不是它的工作原理。在這裏3年後,你真的應該知道[問]! – Olaf

回答

2

經過Cephes來源搜索後,我認爲這是Pommier的翻譯錯誤。這不是我第一次在Pommier的代碼中看到錯誤。我建議在Gromacs中使用數學庫。


exp.c在Cephe的,

static double C1 = 6.93145751953125E-1; 
static double C2 = 1.42860682030941723212E-6; 
.... 
px = floor(LOG2E * x + 0.5); 
n = px; 
x -= px * C1; 
x -= px * C2; 

從POMMIER,

_PS_CONST(cephes_exp_C1, 0.693359375); 
_PS_CONST(cephes_exp_C2, -2.12194440e-4); <-- Wrong value 
.... 

// 
// fx = LOG2E * x + 0.5 
// 
fx = _mm_mul_ps(x, *(v4sf*)_ps_cephes_LOG2EF); 
fx = _mm_add_ps(fx, *(v4sf*)_ps_0p5); 

// 
// fx = floor(fx) 
// 
emm0 = _mm_cvttps_epi32(fx); 
tmp = _mm_cvtepi32_ps(emm0); 
v4sf mask = _mm_cmpgt_ps(tmp, fx);  
mask = _mm_and_ps(mask, one); 
fx = _mm_sub_ps(tmp, mask); 

// 
// x -= fx * C1; 
// x -= fx * C2; (Using z allows for better ILP in this step) 
// 
tmp = _mm_mul_ps(fx, *(v4sf*)_ps_cephes_exp_C1); 
v4sf z = _mm_mul_ps(fx, *(v4sf*)_ps_cephes_exp_C2); 
x = _mm_sub_ps(x, tmp); 
x = _mm_sub_ps(x, z); 
+0

感謝鏈接到cephes庫,這對於研究基本數學函數的實現來說好得多。但我仍然不明白C2有什麼好處。 (2)= e ^(g + n loge(2))=> x = g + n loge(2) )。 n用floor/round函數計算,x - = px * C1等價於g = x - n loge(2)(C1 == loge(2))。用x - = px * C2計算什麼?它是否與浮點數有關,以提高精度? – faramir