Cisco optimization for x86 & fixed point
[opus.git] / celt / tests / test_unit_mathops.c
1 /* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
2                            Gregory Maxwell
3    Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
4 /*
5    Redistribution and use in source and binary forms, with or without
6    modification, are permitted provided that the following conditions
7    are met:
8
9    - Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11
12    - Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15
16    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #ifndef CUSTOM_MODES
34 #define CUSTOM_MODES
35 #endif
36
37 #define CELT_C
38
39 #include <stdio.h>
40 #include <math.h>
41 #include "mathops.c"
42 #include "entenc.c"
43 #include "entdec.c"
44 #include "entcode.c"
45 #include "bands.c"
46 #include "quant_bands.c"
47 #include "laplace.c"
48 #include "vq.c"
49 #include "cwrs.c"
50 #include "pitch.c"
51 #include "celt_lpc.c"
52
53 #if defined(OPUS_X86_MAY_HAVE_SSE4_1) || defined(OPUS_X86_MAY_HAVE_SSE2)
54 #include "x86/pitch_sse.c"
55 #if defined(OPUS_X86_MAY_HAVE_SSE4_1)
56 #include "x86/celt_lpc_sse.c"
57 #endif
58 #include "x86/x86_celt_map.c"
59 #endif
60
61 #ifdef FIXED_POINT
62 #define WORD "%d"
63 #else
64 #define WORD "%f"
65 #endif
66
67 int ret = 0;
68
69 void testdiv(void)
70 {
71    opus_int32 i;
72    for (i=1;i<=327670;i++)
73    {
74       double prod;
75       opus_val32 val;
76       val = celt_rcp(i);
77 #ifdef FIXED_POINT
78       prod = (1./32768./65526.)*val*i;
79 #else
80       prod = val*i;
81 #endif
82       if (fabs(prod-1) > .00025)
83       {
84          fprintf (stderr, "div failed: 1/%d="WORD" (product = %f)\n", i, val, prod);
85          ret = 1;
86       }
87    }
88 }
89
90 void testsqrt(void)
91 {
92    opus_int32 i;
93    for (i=1;i<=1000000000;i++)
94    {
95       double ratio;
96       opus_val16 val;
97       val = celt_sqrt(i);
98       ratio = val/sqrt(i);
99       if (fabs(ratio - 1) > .0005 && fabs(val-sqrt(i)) > 2)
100       {
101          fprintf (stderr, "sqrt failed: sqrt(%d)="WORD" (ratio = %f)\n", i, val, ratio);
102          ret = 1;
103       }
104       i+= i>>10;
105    }
106 }
107
108 void testbitexactcos(void)
109 {
110    int i;
111    opus_int32 min_d,max_d,last,chk;
112    chk=max_d=0;
113    last=min_d=32767;
114    for(i=64;i<=16320;i++)
115    {
116       opus_int32 d;
117       opus_int32 q=bitexact_cos(i);
118       chk ^= q*i;
119       d = last - q;
120       if (d>max_d)max_d=d;
121       if (d<min_d)min_d=d;
122       last = q;
123    }
124    if ((chk!=89408644)||(max_d!=5)||(min_d!=0)||(bitexact_cos(64)!=32767)||
125        (bitexact_cos(16320)!=200)||(bitexact_cos(8192)!=23171))
126    {
127       fprintf (stderr, "bitexact_cos failed\n");
128       ret = 1;
129    }
130 }
131
132 void testbitexactlog2tan(void)
133 {
134    int i,fail;
135    opus_int32 min_d,max_d,last,chk;
136    fail=chk=max_d=0;
137    last=min_d=15059;
138    for(i=64;i<8193;i++)
139    {
140       opus_int32 d;
141       opus_int32 mid=bitexact_cos(i);
142       opus_int32 side=bitexact_cos(16384-i);
143       opus_int32 q=bitexact_log2tan(mid,side);
144       chk ^= q*i;
145       d = last - q;
146       if (q!=-1*bitexact_log2tan(side,mid))
147         fail = 1;
148       if (d>max_d)max_d=d;
149       if (d<min_d)min_d=d;
150       last = q;
151    }
152    if ((chk!=15821257)||(max_d!=61)||(min_d!=-2)||fail||
153        (bitexact_log2tan(32767,200)!=15059)||(bitexact_log2tan(30274,12540)!=2611)||
154        (bitexact_log2tan(23171,23171)!=0))
155    {
156       fprintf (stderr, "bitexact_log2tan failed\n");
157       ret = 1;
158    }
159 }
160
161 #ifndef FIXED_POINT
162 void testlog2(void)
163 {
164    float x;
165    for (x=0.001;x<1677700.0;x+=(x/8.0))
166    {
167       float error = fabs((1.442695040888963387*log(x))-celt_log2(x));
168       if (error>0.0009)
169       {
170          fprintf (stderr, "celt_log2 failed: fabs((1.442695040888963387*log(x))-celt_log2(x))>0.001 (x = %f, error = %f)\n", x,error);
171          ret = 1;
172       }
173    }
174 }
175
176 void testexp2(void)
177 {
178    float x;
179    for (x=-11.0;x<24.0;x+=0.0007)
180    {
181       float error = fabs(x-(1.442695040888963387*log(celt_exp2(x))));
182       if (error>0.0002)
183       {
184          fprintf (stderr, "celt_exp2 failed: fabs(x-(1.442695040888963387*log(celt_exp2(x))))>0.0005 (x = %f, error = %f)\n", x,error);
185          ret = 1;
186       }
187    }
188 }
189
190 void testexp2log2(void)
191 {
192    float x;
193    for (x=-11.0;x<24.0;x+=0.0007)
194    {
195       float error = fabs(x-(celt_log2(celt_exp2(x))));
196       if (error>0.001)
197       {
198          fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_log2(celt_exp2(x))))>0.001 (x = %f, error = %f)\n", x,error);
199          ret = 1;
200       }
201    }
202 }
203 #else
204 void testlog2(void)
205 {
206    opus_val32 x;
207    for (x=8;x<1073741824;x+=(x>>3))
208    {
209       float error = fabs((1.442695040888963387*log(x/16384.0))-celt_log2(x)/1024.0);
210       if (error>0.003)
211       {
212          fprintf (stderr, "celt_log2 failed: x = %ld, error = %f\n", (long)x,error);
213          ret = 1;
214       }
215    }
216 }
217
218 void testexp2(void)
219 {
220    opus_val16 x;
221    for (x=-32768;x<15360;x++)
222    {
223       float error1 = fabs(x/1024.0-(1.442695040888963387*log(celt_exp2(x)/65536.0)));
224       float error2 = fabs(exp(0.6931471805599453094*x/1024.0)-celt_exp2(x)/65536.0);
225       if (error1>0.0002&&error2>0.00004)
226       {
227          fprintf (stderr, "celt_exp2 failed: x = "WORD", error1 = %f, error2 = %f\n", x,error1,error2);
228          ret = 1;
229       }
230    }
231 }
232
233 void testexp2log2(void)
234 {
235    opus_val32 x;
236    for (x=8;x<65536;x+=(x>>3))
237    {
238       float error = fabs(x-0.25*celt_exp2(celt_log2(x)))/16384;
239       if (error>0.004)
240       {
241          fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_exp2(celt_log2(x))))>0.001 (x = %ld, error = %f)\n", (long)x,error);
242          ret = 1;
243       }
244    }
245 }
246
247 void testilog2(void)
248 {
249    opus_val32 x;
250    for (x=1;x<=268435455;x+=127)
251    {
252       opus_val32 lg;
253       opus_val32 y;
254
255       lg = celt_ilog2(x);
256       if (lg<0 || lg>=31)
257       {
258          printf("celt_ilog2 failed: 0<=celt_ilog2(x)<31 (x = %d, celt_ilog2(x) = %d)\n",x,lg);
259          ret = 1;
260       }
261       y = 1<<lg;
262
263       if (x<y || (x>>1)>=y)
264       {
265          printf("celt_ilog2 failed: 2**celt_ilog2(x)<=x<2**(celt_ilog2(x)+1) (x = %d, 2**celt_ilog2(x) = %d)\n",x,y);
266          ret = 1;
267       }
268    }
269 }
270 #endif
271
272 int main(void)
273 {
274    testbitexactcos();
275    testbitexactlog2tan();
276    testdiv();
277    testsqrt();
278    testlog2();
279    testexp2();
280    testexp2log2();
281 #ifdef FIXED_POINT
282    testilog2();
283 #endif
284    return ret;
285 }