Merge branch 'exp_analysis7'
[opus.git] / celt / tests / test_unit_mathops.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #ifndef CUSTOM_MODES
6 #define CUSTOM_MODES
7 #endif
8
9 #define CELT_C
10
11 #include "mathops.c"
12 #include "entenc.c"
13 #include "entdec.c"
14 #include "entcode.c"
15 #include "bands.c"
16 #include "vq.c"
17 #include "cwrs.c"
18 #include <stdio.h>
19 #include <math.h>
20
21 #ifdef FIXED_POINT
22 #define WORD "%d"
23 #else
24 #define WORD "%f"
25 #endif
26
27 int ret = 0;
28
29 void testdiv(void)
30 {
31    opus_int32 i;
32    for (i=1;i<=327670;i++)
33    {
34       double prod;
35       opus_val32 val;
36       val = celt_rcp(i);
37 #ifdef FIXED_POINT
38       prod = (1./32768./65526.)*val*i;
39 #else
40       prod = val*i;
41 #endif
42       if (fabs(prod-1) > .00025)
43       {
44          fprintf (stderr, "div failed: 1/%d="WORD" (product = %f)\n", i, val, prod);
45          ret = 1;
46       }
47    }
48 }
49
50 void testsqrt(void)
51 {
52    opus_int32 i;
53    for (i=1;i<=1000000000;i++)
54    {
55       double ratio;
56       opus_val16 val;
57       val = celt_sqrt(i);
58       ratio = val/sqrt(i);
59       if (fabs(ratio - 1) > .0005 && fabs(val-sqrt(i)) > 2)
60       {
61          fprintf (stderr, "sqrt failed: sqrt(%d)="WORD" (ratio = %f)\n", i, val, ratio);
62          ret = 1;
63       }
64       i+= i>>10;
65    }
66 }
67
68 void testbitexactcos(void)
69 {
70    int i;
71    opus_int32 min_d,max_d,last,chk;
72    chk=max_d=0;
73    last=min_d=32767;
74    for(i=64;i<=16320;i++)
75    {
76       opus_int32 d;
77       opus_int32 q=bitexact_cos(i);
78       chk ^= q*i;
79       d = last - q;
80       if (d>max_d)max_d=d;
81       if (d<min_d)min_d=d;
82       last = q;
83    }
84    if ((chk!=89408644)||(max_d!=5)||(min_d!=0)||(bitexact_cos(64)!=32767)||
85        (bitexact_cos(16320)!=200)||(bitexact_cos(8192)!=23171))
86    {
87       fprintf (stderr, "bitexact_cos failed\n");
88       ret = 1;
89    }
90 }
91
92 void testbitexactlog2tan(void)
93 {
94    int i,fail;
95    opus_int32 min_d,max_d,last,chk;
96    fail=chk=max_d=0;
97    last=min_d=15059;
98    for(i=64;i<8193;i++)
99    {
100       opus_int32 d;
101       opus_int32 mid=bitexact_cos(i);
102       opus_int32 side=bitexact_cos(16384-i);
103       opus_int32 q=bitexact_log2tan(mid,side);
104       chk ^= q*i;
105       d = last - q;
106       if (q!=-1*bitexact_log2tan(side,mid))
107         fail = 1;
108       if (d>max_d)max_d=d;
109       if (d<min_d)min_d=d;
110       last = q;
111    }
112    if ((chk!=15821257)||(max_d!=61)||(min_d!=-2)||fail||
113        (bitexact_log2tan(32767,200)!=15059)||(bitexact_log2tan(30274,12540)!=2611)||
114        (bitexact_log2tan(23171,23171)!=0))
115    {
116       fprintf (stderr, "bitexact_log2tan failed\n");
117       ret = 1;
118    }
119 }
120
121 #ifndef FIXED_POINT
122 void testlog2(void)
123 {
124    float x;
125    for (x=0.001;x<1677700.0;x+=(x/8.0))
126    {
127       float error = fabs((1.442695040888963387*log(x))-celt_log2(x));
128       if (error>0.0009)
129       {
130          fprintf (stderr, "celt_log2 failed: fabs((1.442695040888963387*log(x))-celt_log2(x))>0.001 (x = %f, error = %f)\n", x,error);
131          ret = 1;
132       }
133    }
134 }
135
136 void testexp2(void)
137 {
138    float x;
139    for (x=-11.0;x<24.0;x+=0.0007)
140    {
141       float error = fabs(x-(1.442695040888963387*log(celt_exp2(x))));
142       if (error>0.0002)
143       {
144          fprintf (stderr, "celt_exp2 failed: fabs(x-(1.442695040888963387*log(celt_exp2(x))))>0.0005 (x = %f, error = %f)\n", x,error);
145          ret = 1;
146       }
147    }
148 }
149
150 void testexp2log2(void)
151 {
152    float x;
153    for (x=-11.0;x<24.0;x+=0.0007)
154    {
155       float error = fabs(x-(celt_log2(celt_exp2(x))));
156       if (error>0.001)
157       {
158          fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_log2(celt_exp2(x))))>0.001 (x = %f, error = %f)\n", x,error);
159          ret = 1;
160       }
161    }
162 }
163 #else
164 void testlog2(void)
165 {
166    opus_val32 x;
167    for (x=8;x<1073741824;x+=(x>>3))
168    {
169       float error = fabs((1.442695040888963387*log(x/16384.0))-celt_log2(x)/1024.0);
170       if (error>0.003)
171       {
172          fprintf (stderr, "celt_log2 failed: x = %ld, error = %f\n", (long)x,error);
173          ret = 1;
174       }
175    }
176 }
177
178 void testexp2(void)
179 {
180    opus_val16 x;
181    for (x=-32768;x<15360;x++)
182    {
183       float error1 = fabs(x/1024.0-(1.442695040888963387*log(celt_exp2(x)/65536.0)));
184       float error2 = fabs(exp(0.6931471805599453094*x/1024.0)-celt_exp2(x)/65536.0);
185       if (error1>0.0002&&error2>0.00004)
186       {
187          fprintf (stderr, "celt_exp2 failed: x = "WORD", error1 = %f, error2 = %f\n", x,error1,error2);
188          ret = 1;
189       }
190    }
191 }
192
193 void testexp2log2(void)
194 {
195    opus_val32 x;
196    for (x=8;x<65536;x+=(x>>3))
197    {
198       float error = fabs(x-0.25*celt_exp2(celt_log2(x)))/16384;
199       if (error>0.004)
200       {
201          fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_exp2(celt_log2(x))))>0.001 (x = %ld, error = %f)\n", (long)x,error);
202          ret = 1;
203       }
204    }
205 }
206
207 void testilog2(void)
208 {
209    opus_val32 x;
210    for (x=1;x<=268435455;x+=127)
211    {
212       opus_val32 lg;
213       opus_val32 y;
214
215       lg = celt_ilog2(x);
216       if (lg<0 || lg>=31)
217       {
218          printf("celt_ilog2 failed: 0<=celt_ilog2(x)<31 (x = %d, celt_ilog2(x) = %d)\n",x,lg);
219          ret = 1;
220       }
221       y = 1<<lg;
222
223       if (x<y || (x>>1)>=y)
224       {
225          printf("celt_ilog2 failed: 2**celt_ilog2(x)<=x<2**(celt_ilog2(x)+1) (x = %d, 2**celt_ilog2(x) = %d)\n",x,y);
226          ret = 1;
227       }
228    }
229 }
230 #endif
231
232 int main(void)
233 {
234    testbitexactcos();
235    testbitexactlog2tan();
236    testdiv();
237    testsqrt();
238    testlog2();
239    testexp2();
240    testexp2log2();
241 #ifdef FIXED_POINT
242    testilog2();
243 #endif
244    return ret;
245 }