rsimd

Make SIMD instruction sets easier to use
git clone git://git.meso-star.fr/rsimd.git
Log | Files | Refs | README | LICENSE

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