1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3 * Copyright(c) 2022 Intel Corporation. All rights reserved.
4 *
5 * Author: Shriram Shastry <malladi.sastry@linux.intel.com>
6 */
7
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <stdarg.h>
11 #include <stddef.h>
12 #include <setjmp.h>
13 #include <math.h>
14 #include <cmocka.h>
15 #include <string.h>
16 #include <time.h>
17 #include <stdlib.h>
18
19 #include <sof/math/exp_fcn.h>
20 #include <sof/audio/format.h>
21 #include <rtos/string.h>
22 #include <sof/common.h>
23
24 #define ULP_TOLERANCE 5.60032793
25 #define ULP_SCALE 0.0000999999999749
26
27 static void gen_exp_testvector(double a, double b, double *r, int32_t *b_i);
28
29 /* testvector in Q4.28, -5 to +5 */
30 /*
31 * Arguments :double a
32 * double b
33 * double *r
34 * int32_t *b_i
35 * Return Type :void
36 */
gen_exp_testvector(double a,double b,double * r,int32_t * b_i)37 static void gen_exp_testvector(double a, double b, double *r, int32_t *b_i)
38 {
39 double a2;
40 double b2;
41
42 *r = a + rand() % (int32_t)(b - a + 1);
43 a2 = *r * 268435456;
44 b2 = fabs(a2);
45 if (b2 < 4503599627370496LL)
46 a2 = floor(a2 + 0.5);
47
48 if (a2 < 2147483648LL)
49 *b_i = (a2 >= -2147483648LL) ? a2 : INT32_MIN;
50 else
51 *b_i = INT32_MAX;
52 }
53
test_math_arithmetic_exponential_fixed(void ** state)54 static void test_math_arithmetic_exponential_fixed(void **state)
55 {
56 (void)state;
57
58 int32_t accum;
59 int i;
60 double a_i;
61 double max_ulp;
62 double a_tmp = -5.0123456789;
63 double b_tmp = 5.0123456789;
64 double r;
65 int32_t b_i;
66
67 srand((unsigned int)time(NULL));
68 for (i = 0; i < 256; i++) {
69 gen_exp_testvector(a_tmp, b_tmp, &r, &b_i);
70 a_i = (double)b_i / (1 << 28);
71 accum = sofm_exp_int32(b_i);
72 max_ulp = fabs(exp(a_i) - (double)accum / (1 << 23)) / ULP_SCALE;
73
74 if (max_ulp > ULP_TOLERANCE) {
75 printf("%s: ULP for %.16f: value = %.16f, Exp = %.16f\n", __func__,
76 max_ulp, (double)b_i / (1 << 28), (double)accum / (1 << 23));
77 assert_true(max_ulp <= ULP_TOLERANCE);
78 }
79 }
80 }
81
main(void)82 int main(void)
83 {
84 const struct CMUnitTest tests[] = {
85 cmocka_unit_test(test_math_arithmetic_exponential_fixed)
86 };
87
88 cmocka_set_message_output(CM_OUTPUT_TAP);
89
90 return cmocka_run_group_tests(tests, NULL, NULL);
91 }
92