2016-07-24 9 views
-1

Ich versuche, die Implementierung von exp_ps() von http://gruntthepeon.free.fr/ssemath/sse_mathfun.h oder exp256_ps() von http://software-lisc.fbk.eu/avx_mathfun/avx_mathfun.h zu verstehen.
Ich verstehe fast alles in der Berechnung, außer wie konstant cephes_exp_C2 bestimmt wird. Es scheint, dass es die Genauigkeit der Berechnung erhöht. Wenn es aus der Berechnung entfernt wird, ist die resultierende Funktion wesentlich schneller und etwas weniger genau (der relative Fehler liegt immer noch unter 1% für Werte um +/- 10). Ich fand solche Koeffizienten in anderen numerischen Bibliotheken, aber ohne nähere Erklärung.Koeffizienten in numerischen Berechnungen von exp() Funktion

+3

Code? Versuche? Beispiele? –

+0

Ich denke, diese Konstante ist 'exp (C2)', wobei 'C2' eine andere Konstante ist. Verstehst du wirklich alles andere? Z.B. Was ist 'cephes_exp_p0'? – user463035818

+2

Nicht nur, dass Sie keine [mcve] anzeigen, sondern auch zwei Links auf einen Textstapel ausgeben, Sie haben nicht einmal eine ** spezifische ** Frage. So geht es nicht. Nach 3 Jahren solltest du wirklich [ask] wissen! – Olaf

Antwort

2

Nach ein wenig Suche durch die Cephes Quelle, ich denke, es ist ein Fehler in Pommier-Übersetzung. Dies ist nicht das erste Mal, dass ich Fehler in Pommiers Code gesehen habe. Ich empfehle die Verwendung der Math-Bibliothek in Gromacs.


Von exp.c in Cephe des,

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; 

Von 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

Danke für den Link zu Cephes-Bibliothek, es ist viel besser für das Studium der Umsetzung der grundlegenden mathematischen Funktionen. Aber ich verstehe immer noch nicht, wofür C2 gut ist. e^x wird in e^x = e^g 2^n = e^ge^(n loge (2)) = e^(g + n loge (2)) => x = g + n loge (2). n wird mit floor/round-Funktion berechnet und x - = px * C1 entspricht g = x - n loge (2) (C1 == loge (2)). Was wird mit x - = px * C2 berechnet? Ist es irgendwie mit Gleitkommazahlen verwandt, um die Präzision zu erhöhen? – faramir

Verwandte Themen