2016-07-24 3 views
-1

exp_ps()의 구현을 http://gruntthepeon.free.fr/ssemath/sse_mathfun.h 또는 exp256_ps()에서 http://software-lisc.fbk.eu/avx_mathfun/avx_mathfun.h으로 이해하려고합니다.
상수 cephes_exp_C2이 어떻게 결정되는지를 제외하고 계산의 거의 모든 것을 이해합니다. 그것은 계산의 정확성을 증가시키는 것으로 보인다. 계산에서 제거 된 경우 결과 함수가 상당히 빠르고 약간 정확하지 않습니다 (상대 오차는 +/- 10 주변의 값이 1 % 미만 임). 나는 다른 수치 라이브러리에서 이러한 계수를 발견했으나 자세한 설명은하지 않았습니다.exp() 함수의 수치 계산에 사용되는 약어

+3

코드? 시도? 예? –

+0

이 상수는'exp (C2)'입니다. 여기서'C2'는 다른 상수입니다. 너는 그 밖의 모든 것을 정말로 이해하고 있니? 예 : 'cephes_exp_p0'는 무엇입니까? – user463035818

+2

[mcve]를 표시하지 않을뿐만 아니라 여러 개의 텍스트 링크를 덤프 할 수있을뿐만 아니라 ** 특정 ** 질문이 없습니다. 그것이 작동하는 방식이 아닙니다. 3 년이 지난 후에 당신은 정말로 [묻는다]를 알아야한다! – Olaf

답변

2

Cephes 소스를 통해 약간 검색 한 후에는 Pommier의 번역에서 오류라고 생각합니다. Pommier의 코드에서 오류를 본 것은 이번이 처음이 아닙니다. Gromacs에서 수학 라이브러리를 사용하는 것이 좋습니다.

Cephe의에서 exp.c에서

, Pommier에서

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; 

,

_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가 무엇인지 이해하지 못한다. e^x는 다음과 같이 변환된다. e^x = e^g^n = e^ge^(nloge (2)) = e^(g + nloge (2)) => x = g + nloge). n은 floor/round 함수로 계산되고 x - = px * C1은 g = x - n loge (2) (C1 == loge (2))와 동일합니다. x - = px * C2로 계산되는 것은 무엇입니까? 정확도를 높이기 위해 float 숫자와 관련이 있습니다. – faramir