blob: bed52328cd7e26c862c6a0279a4958e4a1d7549b [file] [log] [blame]
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +11001/* (C) 2007 Timothy B. Terriberry */
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +11002/*
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions
5 are met:
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +11006
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +11007 - Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +11009
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110010 - Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +110013
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110014 - Neither the name of the Xiph.org Foundation nor the names of its
15 contributors may be used to endorse or promote products derived from
16 this software without specific prior written permission.
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +110017
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
22 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*/
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110030#include <stdlib.h>
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110031#include "cwrs.h"
32
33/*Returns the numer of ways of choosing _m elements from a set of size _n with
34 replacement when a sign bit is needed for each unique element.*/
35#if 0
Jean-Marc Valinabe043f2008-01-31 14:26:29 +110036static celt_uint32_t ncwrs(int _n,int _m){
37 static celt_uint32_t c[32][32];
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110038 if(_n<0||_m<0)return 0;
39 if(!c[_n][_m]){
40 if(_m<=0)c[_n][_m]=1;
41 else if(_n>0)c[_n][_m]=ncwrs(_n-1,_m)+ncwrs(_n,_m-1)+ncwrs(_n-1,_m-1);
42 }
43 return c[_n][_m];
44}
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110045#else
Jean-Marc Valinabe043f2008-01-31 14:26:29 +110046celt_uint32_t ncwrs(int _n,int _m){
47 celt_uint32_t ret;
48 celt_uint32_t f;
49 celt_uint32_t d;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110050 int i;
51 if(_n<0||_m<0)return 0;
52 if(_m==0)return 1;
53 if(_n==0)return 0;
54 ret=0;
55 f=_n;
56 d=1;
57 for(i=1;i<=_m;i++){
58 ret+=f*d<<i;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110059 f=(f*(_n-i))/(i+1);
60 d=(d*(_m-i))/i;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110061 }
62 return ret;
63}
64#endif
65
Jean-Marc Valinf8db8002007-12-11 14:52:56 +110066celt_uint64_t ncwrs64(int _n,int _m){
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +110067 celt_uint64_t ret;
68 celt_uint64_t f;
69 celt_uint64_t d;
70 int i;
71 if(_n<0||_m<0)return 0;
72 if(_m==0)return 1;
73 if(_n==0)return 0;
74 ret=0;
75 f=_n;
76 d=1;
77 for(i=1;i<=_m;i++){
78 ret+=f*d<<i;
79 f=(f*(_n-i))/(i+1);
80 d=(d*(_m-i))/i;
81 }
82 return ret;
Jean-Marc Valinf8db8002007-12-11 14:52:56 +110083}
84
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110085/*Returns the _i'th combination of _m elements chosen from a set of size _n
86 with associated sign bits.
87 _x: Returns the combination with elements sorted in ascending order.
88 _s: Returns the associated sign bits.*/
Jean-Marc Valinabe043f2008-01-31 14:26:29 +110089void cwrsi(int _n,int _m,celt_uint32_t _i,int *_x,int *_s){
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +110090 int j;
91 int k;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110092 for(k=j=0;k<_m;k++){
Jean-Marc Valinabe043f2008-01-31 14:26:29 +110093 celt_uint32_t pn;
94 celt_uint32_t p;
95 celt_uint32_t t;
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +110096 p=ncwrs(_n-j,_m-k-1);
97 pn=ncwrs(_n-j-1,_m-k-1);
98 p+=pn;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +110099 if(k>0){
100 t=p>>1;
101 if(t<=_i||_s[k-1])_i+=t;
102 }
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100103 while(p<=_i){
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100104 _i-=p;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100105 j++;
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100106 p=pn;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100107 pn=ncwrs(_n-j-1,_m-k-1);
108 p+=pn;
109 }
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100110 t=p>>1;
111 _s[k]=_i>=t;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100112 _x[k]=j;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100113 if(_s[k])_i-=t;
114 }
115}
116
117/*Returns the index of the given combination of _m elements chosen from a set
118 of size _n with associated sign bits.
119 _x: The combination with elements sorted in ascending order.
120 _s: The associated sign bits.*/
Jean-Marc Valinabe043f2008-01-31 14:26:29 +1100121celt_uint32_t icwrs(int _n,int _m,const int *_x,const int *_s){
122 celt_uint32_t i;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100123 int j;
124 int k;
125 i=0;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100126 for(k=j=0;k<_m;k++){
Jean-Marc Valinabe043f2008-01-31 14:26:29 +1100127 celt_uint32_t pn;
128 celt_uint32_t p;
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100129 p=ncwrs(_n-j,_m-k-1);
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100130 pn=ncwrs(_n-j-1,_m-k-1);
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100131 p+=pn;
132 if(k>0)p>>=1;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100133 while(j<_x[k]){
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100134 i+=p;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100135 j++;
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100136 p=pn;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100137 pn=ncwrs(_n-j-1,_m-k-1);
138 p+=pn;
139 }
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100140 if((k==0||_x[k]!=_x[k-1])&&_s[k])i+=p>>1;
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100141 }
142 return i;
143}
144
Jean-Marc Valinf8db8002007-12-11 14:52:56 +1100145/*Returns the _i'th combination of _m elements chosen from a set of size _n
146 with associated sign bits.
147 _x: Returns the combination with elements sorted in ascending order.
148 _s: Returns the associated sign bits.*/
149void cwrsi64(int _n,int _m,celt_uint64_t _i,int *_x,int *_s){
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100150 int j;
151 int k;
152 for(k=j=0;k<_m;k++){
153 celt_uint64_t pn;
154 celt_uint64_t p;
155 celt_uint64_t t;
156 p=ncwrs64(_n-j,_m-k-1);
157 pn=ncwrs64(_n-j-1,_m-k-1);
158 p+=pn;
159 if(k>0){
160 t=p>>1;
161 if(t<=_i||_s[k-1])_i+=t;
162 }
163 while(p<=_i){
164 _i-=p;
165 j++;
166 p=pn;
Jean-Marc Valinf8db8002007-12-11 14:52:56 +1100167 pn=ncwrs64(_n-j-1,_m-k-1);
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100168 p+=pn;
169 }
170 t=p>>1;
171 _s[k]=_i>=t;
172 _x[k]=j;
173 if(_s[k])_i-=t;
174 }
Jean-Marc Valinf8db8002007-12-11 14:52:56 +1100175}
176
177/*Returns the index of the given combination of _m elements chosen from a set
178 of size _n with associated sign bits.
179 _x: The combination with elements sorted in ascending order.
180 _s: The associated sign bits.*/
181celt_uint64_t icwrs64(int _n,int _m,const int *_x,const int *_s){
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100182 celt_uint64_t i;
183 int j;
184 int k;
185 i=0;
186 for(k=j=0;k<_m;k++){
187 celt_uint64_t pn;
188 celt_uint64_t p;
189 p=ncwrs64(_n-j,_m-k-1);
190 pn=ncwrs64(_n-j-1,_m-k-1);
191 p+=pn;
192 if(k>0)p>>=1;
193 while(j<_x[k]){
194 i+=p;
195 j++;
196 p=pn;
Jean-Marc Valinf8db8002007-12-11 14:52:56 +1100197 pn=ncwrs64(_n-j-1,_m-k-1);
Timothy B. Terriberry71c9bbf2008-01-01 07:18:06 +1100198 p+=pn;
199 }
200 if((k==0||_x[k]!=_x[k-1])&&_s[k])i+=p>>1;
201 }
202 return i;
Jean-Marc Valinf8db8002007-12-11 14:52:56 +1100203}
204
Timothy B. Terriberryc4541ae2007-12-03 11:51:29 +1100205/*Converts a combination _x of _m unit pulses with associated sign bits _s into
206 a pulse vector _y of length _n.
207 _y: Returns the vector of pulses.
208 _x: The combination with elements sorted in ascending order.
209 _s: The associated sign bits.*/
210void comb2pulse(int _n,int _m,int *_y,const int *_x,const int *_s){
211 int j;
212 int k;
213 int n;
214 for(k=j=0;k<_m;k+=n){
215 for(n=1;k+n<_m&&_x[k+n]==_x[k];n++);
216 while(j<_x[k])_y[j++]=0;
217 _y[j++]=_s[k]?-n:n;
218 }
219 while(j<_n)_y[j++]=0;
220}
221
222/*Converts a pulse vector vector _y of length _n into a combination of _m unit
223 pulses with associated sign bits _s.
224 _x: Returns the combination with elements sorted in ascending order.
225 _s: Returns the associated sign bits.
226 _y: The vector of pulses, whose sum of absolute values must be _m.*/
227void pulse2comb(int _n,int _m,int *_x,int *_s,const int *_y){
228 int j;
229 int k;
230 for(k=j=0;j<_n;j++){
231 if(_y[j]){
232 int n;
233 int s;
234 n=abs(_y[j]);
235 s=_y[j]<0;
236 for(;n-->0;k++){
237 _x[k]=j;
238 _s[k]=s;
239 }
240 }
241 }
242}
243