Skip to content

Commit

Permalink
added simd_asin function
Browse files Browse the repository at this point in the history
  • Loading branch information
Geolm committed Jan 11, 2024
1 parent 8e46e02 commit 34467c8
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
33 changes: 33 additions & 0 deletions simd_math.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,5 +252,38 @@ void simd_sincos(simd_vector x, simd_vector* s, simd_vector* c)
*c = simd_xor(xmm2, sign_bit_cos);
}

//-----------------------------------------------------------------------------
// based on https://github.com/jeremybarnes/cephes/blob/master/single/asinf.c
simd_vector simd_asin(simd_vector xx)
{
simd_vector x = xx;
simd_vector sign = simd_sign(xx);
simd_vector a = simd_abs(x);
simd_vector greater_one = simd_cmp_gt(a, simd_splat(1.f));
simd_vector small_value = simd_cmp_lt(a, simd_splat(1.0e-4f));

simd_vector z1 = simd_mul(simd_splat(.5f), simd_sub(simd_splat(1.f), a));
simd_vector z2 = simd_mul(a, a);
simd_vector flag = simd_cmp_gt(a, simd_splat(.5f));
simd_vector z = simd_select(z2, z1, flag);

x = simd_select(a, simd_sqrt(z), flag);

simd_vector tmp = simd_fmad(simd_splat(4.2163199048E-2f), z, simd_splat(2.4181311049E-2f));
tmp = simd_fmad(tmp, z, simd_splat(4.5470025998E-2f));
tmp = simd_fmad(tmp, z, simd_splat(7.4953002686E-2f));
tmp = simd_fmad(tmp, z, simd_splat(1.6666752422E-1f));
tmp = simd_mul(tmp, z);
z = simd_fmad(tmp, x, x);

tmp = simd_add(z, z);
tmp = simd_sub(simd_splat(SIMD_MATH_PI2), tmp);
z = simd_select(z, tmp, flag);

z = simd_select(z, a, small_value);
z = simd_select(z, simd_splat_zero(), greater_one);
z = simd_mul(z, sign);
return z;
}


1 change: 1 addition & 0 deletions simd_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ static simd_vector simd_sin(simd_vector x); // output equal to sinf()
static simd_vector simd_cos(simd_vector a); // output equal to cosf()
void simd_sincos(simd_vector x, simd_vector* s, simd_vector* c); // output equal to sinf()/cosf()
static simd_vector simd_acos(simd_vector x); // // max error : 0.000068
simd_vector simd_asin(simd_vector x);
simd_vector simd_atan2(simd_vector x, simd_vector y); // max error : 0.000002
simd_vector simd_log(simd_vector x); // output equal to logf()
simd_vector simd_exp(simd_vector x); // output equal to expf()
Expand Down
31 changes: 31 additions & 0 deletions tests/test_simd_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,36 @@ TEST approx_sin(void)
PASS();
}

TEST arcsin(void)
{
float array[NUM_ELEMENTS];
float result[NUM_ELEMENTS];
float step = 2.f / (float) NUM_ELEMENTS;

for(int i=0; i<NUM_ELEMENTS; ++i)
{
array[i] = (step * (float)i) - 1.f;
result[i] = asinf(array[i]);
}

simd_vector epsilon = simd_splat(FLT_MAX);
simd_vector max_error = simd_splat_zero();

for(int i=0; i<NUM_VECTORS; ++i)
{
simd_vector v_approx = simd_asin(simd_load_offset(array, i));
simd_vector v_result = simd_load_offset(result, i);

ASSERT(simd_all(simd_equal(v_approx, v_result, epsilon)));

max_error = simd_max(max_error, simd_abs_diff(v_approx, v_result));
}

printf("simd_asin max error : %f\n", simd_hmax(max_error));

PASS();
}

TEST arcos(void)
{
float array[NUM_ELEMENTS];
Expand Down Expand Up @@ -371,6 +401,7 @@ SUITE(trigonometry)
RUN_TEST(sinus);
RUN_TEST(approx_sin);
RUN_TEST(arcos);
RUN_TEST(arcsin);
RUN_TEST(approx_arcos);
RUN_TEST(arctan2);
RUN_TEST(sinuscosinus);
Expand Down

0 comments on commit 34467c8

Please sign in to comment.