Fix CMake include install directory
[platform/upstream/libvorbis.git] / vq / distribution.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7  *                                                                  *
8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
9  * by the Xiph.Org Foundation http://www.xiph.org/                  *
10  *                                                                  *
11  ********************************************************************
12
13  function: utility for finding the distribution in a data set
14
15  ********************************************************************/
16
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <math.h>
20 #include <string.h>
21 #include <errno.h>
22 #include "bookutil.h"
23
24 /* command line:
25    distribution file.vqd
26 */
27
28 int ascend(const void *a,const void *b){
29   return(**((long **)a)-**((long **)b));
30 }
31
32 int main(int argc,char *argv[]){
33   FILE *in;
34   long lines=0;
35   float min;
36   float max;
37   long bins=-1;
38   int flag=0;
39   long *countarray;
40   long total=0;
41   char *line;
42
43   if(argv[1]==NULL){
44     fprintf(stderr,"Usage: distribution {data.vqd [bins]| book.vqh} \n\n");
45     exit(1);
46   }
47   if(argv[2]!=NULL)
48     bins=atoi(argv[2])-1;
49
50   in=fopen(argv[1],"r");
51   if(!in){
52     fprintf(stderr,"Could not open input file %s\n",argv[1]);
53     exit(1);
54   }
55
56   if(strrchr(argv[1],'.') && strcmp(strrchr(argv[1],'.'),".vqh")==0){
57     /* load/decode a book */
58
59     codebook *b=codebook_load(argv[1]);
60     static_codebook *c=(static_codebook *)(b->c);
61     float delta;
62     int i;
63     fclose(in);
64
65     switch(c->maptype){
66     case 0:
67       printf("entropy codebook only; no mappings\n");
68       exit(0);
69       break;
70     case 1:
71       bins=_book_maptype1_quantvals(c);
72       break;
73     case 2:
74       bins=c->entries*c->dim;
75       break;
76     }
77
78     max=min=_float32_unpack(c->q_min);
79     delta=_float32_unpack(c->q_delta);
80
81     for(i=0;i<bins;i++){
82       float val=c->quantlist[i]*delta+min;
83       if(val>max)max=val;
84     }
85
86     printf("Minimum scalar value: %f\n",min);
87     printf("Maximum scalar value: %f\n",max);
88
89     switch(c->maptype){
90     case 1:
91       {
92         /* lattice codebook.  dump it. */
93         int j,k;
94         long maxcount=0;
95         long **sort=calloc(bins,sizeof(long *));
96         long base=c->lengthlist[0];
97         countarray=calloc(bins,sizeof(long));
98
99         for(i=0;i<bins;i++)sort[i]=c->quantlist+i;
100         qsort(sort,bins,sizeof(long *),ascend);
101
102         for(i=0;i<b->entries;i++)
103           if(c->lengthlist[i]>base)base=c->lengthlist[i];
104
105         /* dump a full, correlated count */
106         for(j=0;j<b->entries;j++){
107           if(c->lengthlist[j]){
108             int indexdiv=1;
109             printf("%4d: ",j);
110             for(k=0;k<b->dim;k++){
111               int index= (j/indexdiv)%bins;
112               printf("%+3.1f,", c->quantlist[index]*_float32_unpack(c->q_delta)+
113                      _float32_unpack(c->q_min));
114               indexdiv*=bins;
115             }
116             printf("\t|");
117             for(k=0;k<base-c->lengthlist[j];k++)printf("*");
118             printf("\n");
119           }
120         }
121
122         /* do a rough count */
123         for(j=0;j<b->entries;j++){
124           int indexdiv=1;
125           for(k=0;k<b->dim;k++){
126             if(c->lengthlist[j]){
127               int index= (j/indexdiv)%bins;
128               countarray[index]+=(1<<(base-c->lengthlist[j]));
129               indexdiv*=bins;
130             }
131           }
132         }
133
134         /* dump the count */
135
136         {
137           long maxcount=0,i,j;
138           for(i=0;i<bins;i++)
139             if(countarray[i]>maxcount)maxcount=countarray[i];
140
141           for(i=0;i<bins;i++){
142             int ptr=sort[i]-c->quantlist;
143             int stars=rint(50./maxcount*countarray[ptr]);
144             printf("%+08f (%8ld) |",c->quantlist[ptr]*delta+min,countarray[ptr]);
145             for(j=0;j<stars;j++)printf("*");
146             printf("\n");
147           }
148         }
149       }
150       break;
151     case 2:
152       {
153         /* trained, full mapping codebook. */
154         printf("Can't do probability dump of a trained [type 2] codebook (yet)\n");
155       }
156       break;
157     }
158   }else{
159     /* load/count a data file */
160
161     /* do it the simple way; two pass. */
162     line=setup_line(in);
163     while(line){
164       float code;
165       char buf[80];
166       lines++;
167
168       sprintf(buf,"getting min/max (%.2f::%.2f). lines...",min,max);
169       if(!(lines&0xff))spinnit(buf,lines);
170
171       while(!flag && sscanf(line,"%f",&code)==1){
172         line=strchr(line,',');
173         min=max=code;
174         flag=1;
175       }
176
177       while(line && sscanf(line,"%f",&code)==1){
178         line=strchr(line,',');
179         if(line)line++;
180         if(code<min)min=code;
181         if(code>max)max=code;
182       }
183
184       line=setup_line(in);
185     }
186
187     if(bins<1){
188       if((int)(max-min)==min-max){
189         bins=max-min;
190       }else{
191         bins=25;
192       }
193     }
194
195     printf("\r                                                     \r");
196     printf("Minimum scalar value: %f\n",min);
197     printf("Maximum scalar value: %f\n",max);
198
199     if(argv[2]){
200
201       printf("\n counting hits into %ld bins...\n",bins+1);
202       countarray=calloc(bins+1,sizeof(long));
203
204       rewind(in);
205       line=setup_line(in);
206       while(line){
207         float code;
208         lines--;
209         if(!(lines&0xff))spinnit("counting distribution. lines so far...",lines);
210
211         while(line && sscanf(line,"%f",&code)==1){
212           line=strchr(line,',');
213           if(line)line++;
214
215           code-=min;
216           code/=(max-min);
217           code*=bins;
218           countarray[(int)rint(code)]++;
219           total++;
220         }
221
222         line=setup_line(in);
223       }
224
225       /* make a pretty graph */
226       {
227         long maxcount=0,i,j;
228         for(i=0;i<bins+1;i++)
229           if(countarray[i]>maxcount)maxcount=countarray[i];
230
231         printf("\r                                                     \r");
232         printf("Total scalars: %ld\n",total);
233         for(i=0;i<bins+1;i++){
234           int stars=rint(50./maxcount*countarray[i]);
235           printf("%08f (%8ld) |",(max-min)/bins*i+min,countarray[i]);
236           for(j=0;j<stars;j++)printf("*");
237           printf("\n");
238         }
239       }
240     }
241
242     fclose(in);
243
244   }
245   printf("\nDone.\n");
246   exit(0);
247 }