test_math4.c (4275B)
1 /* Copyright (C) 2013-2021 Vincent Forest (vaplv@free.fr) 2 * 3 * The RSIMD library is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published 5 * by the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * The RSIMD library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with the RSIMD library. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #define _POSIX_C_SOURCE 200112L 17 18 #include "rsimd.h" 19 #include "math.h" 20 21 #include <math.h> 22 23 #define LOG2E 1.4426950408889634074 /* log_2 e */ 24 #define LN10 2.30258509299404568402 /* log_e 10 */ 25 26 #define CHKV4_EPS(V, Ref, Eps) { \ 27 CHK(eq_eps(v4f_x(V), Ref[0], fabsf(Ref[0]) * Eps)); \ 28 CHK(eq_eps(v4f_y(V), Ref[1], fabsf(Ref[1]) * Eps)); \ 29 CHK(eq_eps(v4f_z(V), Ref[2], fabsf(Ref[2]) * Eps)); \ 30 CHK(eq_eps(v4f_w(V), Ref[3], fabsf(Ref[3]) * Eps)); \ 31 } (void)0 32 33 #define CHKV4_FUNC_EPS(V, Func, Eps) { \ 34 const v4f_T r__ = v4f_##Func(V); \ 35 float ref__[4]; \ 36 ref__[0] = (float)Func(v4f_x(V)); \ 37 ref__[1] = (float)Func(v4f_y(V)); \ 38 ref__[2] = (float)Func(v4f_z(V)); \ 39 ref__[3] = (float)Func(v4f_w(V)); \ 40 CHKV4_EPS(r__, ref__, Eps); \ 41 } (void)0 42 43 static void 44 test_trigo(void) 45 { 46 v4f_T i, j, k; 47 float ref[4]; 48 49 i = v4f_set((float)PI/2.f, (float)PI/3.f, (float)PI/4.f, (float)PI/6.f); 50 51 CHKV4_FUNC_EPS(i, cos, 1.e-6f); 52 CHKV4_FUNC_EPS(i, sin, 1.e-6f); 53 54 v4f_sincos(i, &k, &j); 55 ref[0] = (float)sin(v4f_x(i)); 56 ref[1] = (float)sin(v4f_y(i)); 57 ref[2] = (float)sin(v4f_z(i)); 58 ref[3] = (float)sin(v4f_w(i)); 59 CHKV4_EPS(k, ref, 1.e-6f); 60 ref[0] = (float)cos(v4f_x(i)); 61 ref[1] = (float)cos(v4f_y(i)); 62 ref[2] = (float)cos(v4f_z(i)); 63 ref[3] = (float)cos(v4f_w(i)); 64 CHKV4_EPS(j, ref, 1.e-6f); 65 66 i = v4f_set((float)PI/8.f, (float)PI/3.f, (float)PI/4.f, (float)PI/6.f); 67 CHKV4_FUNC_EPS(i, tan, 1.e-6f); 68 CHKV4_FUNC_EPS(v4f_cos(i), acos, 1.e-6f); 69 CHKV4_FUNC_EPS(v4f_sin(i), asin, 1.e-6f); 70 CHKV4_FUNC_EPS(v4f_tan(i), atan, 1.e-6f); 71 } 72 73 static void 74 test_exp(void) 75 { 76 const v4f_T i = v4f_set(1.f, -1.234f, 0.f, 3.14156f); 77 v4f_T j; 78 float ref[4]; 79 80 CHKV4_FUNC_EPS(i, exp, 1.e-6f); 81 CHKV4_FUNC_EPS(i, exp2, 1.e-6f); 82 83 j = v4f_exp10(i); 84 ref[0] = (float)exp2(LOG2E * LN10 * v4f_x(i)); 85 ref[1] = (float)exp2(LOG2E * LN10 * v4f_y(i)); 86 ref[2] = (float)exp2(LOG2E * LN10 * v4f_z(i)); 87 ref[3] = (float)exp2(LOG2E * LN10 * v4f_w(i)); 88 CHKV4_EPS(j, ref, 1.e-6f); 89 } 90 91 static void 92 test_log(void) 93 { 94 const v4f_T i = v4f_set(4.675f, 3.14f, 9.99999f, 1.234e-13f); 95 96 CHKV4_FUNC_EPS(i, log, 1.e-6f); 97 CHKV4_FUNC_EPS(i, log2, 1.e-6f); 98 CHKV4_FUNC_EPS(i, log10, 1.e-6f); 99 } 100 101 static void 102 test_misc(void) 103 { 104 v4f_T i, j, k; 105 float ref[4]; 106 107 i = v4f_set(-1.2345f, 9.3e-7f, 3.879e9f, -10.56f); 108 j = v4f_set(7.89e-9f, 0.12f, -4.9e10f, 3.14f); 109 k = v4f_copysign(i, j); 110 ref[0] = (float)copysign(v4f_x(i), v4f_x(j)); 111 ref[1] = (float)copysign(v4f_y(i), v4f_y(j)); 112 ref[2] = (float)copysign(v4f_z(i), v4f_z(j)); 113 ref[3] = (float)copysign(v4f_w(i), v4f_w(j)); 114 CHKV4_EPS(k, ref, 1.e-6f); 115 116 CHKV4_FUNC_EPS(i, floor, 1.e-6f); 117 118 k = v4f_pow(v4f_abs(i), j); 119 ref[0] = (float)pow(fabsf(v4f_x(i)), v4f_x(j)); 120 ref[1] = (float)pow(fabsf(v4f_y(i)), v4f_y(j)); 121 ref[2] = (float)pow(fabsf(v4f_z(i)), v4f_z(j)); 122 ref[3] = (float)pow(fabsf(v4f_w(i)), v4f_w(j)); 123 CHKV4_EPS(k, ref, 1.e-6f); 124 } 125 126 int 127 main(int argc, char** argv) 128 { 129 (void)argc, (void)argv; 130 131 test_trigo(); 132 test_exp(); 133 test_log(); 134 test_misc(); 135 136 return 0; 137 } 138