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