80a385c8beae7250b639bb68e8123a1c37a56c27
[platform/upstream/libvorbis.git] / vq / run.c
1 #define CODEBOOK _vq_book_lsp_256_32_44100_8
2 #include "lsp_256_32_44100_8.vqh"
3 /********************************************************************
4  *                                                                  *
5  * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
6  * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
7  * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
8  * PLEASE READ THESE TERMS DISTRIBUTING.                            *
9  *                                                                  *
10  * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
11  * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
12  * http://www.xiph.org/                                             *
13  *                                                                  *
14  ********************************************************************
15
16  function: utility main for loading/testing/running finished codebooks
17  last mod: $Id: run.c,v 1.3 2000/01/05 03:11:11 xiphmont Exp $
18
19  ********************************************************************/
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <math.h>
24 #include <string.h>
25 #include <errno.h>
26
27 /* this is a bit silly; it's a C stub used by a Perl script to build a
28    quick executable against the chosen codebook and run tests */
29
30 static char *linebuffer=NULL;
31 static int  lbufsize=0;
32 static char *rline(FILE *in){
33   long sofar=0;
34   if(feof(in))return NULL;
35
36   while(1){
37     int gotline=0;
38
39     while(!gotline){
40       if(sofar>=lbufsize){
41         if(!lbufsize){  
42           lbufsize=1024;
43           linebuffer=malloc(lbufsize);
44         }else{
45           lbufsize*=2;
46           linebuffer=realloc(linebuffer,lbufsize);
47         }
48       }
49       {
50         long c=fgetc(in);
51         switch(c){
52         case '\n':
53         case EOF:
54           gotline=1;
55           break;
56         default:
57           linebuffer[sofar++]=c;
58           linebuffer[sofar]='\0';
59           break;
60         }
61       }
62     }
63     
64     if(linebuffer[0]=='#'){
65       sofar=0;
66     }else{
67       return(linebuffer);
68     }
69   }
70 }
71
72 void vqbook_unquantize(vqbook *b){
73   long j,k;
74   double mindel=float24_unpack(b->min);
75   double delta=float24_unpack(b->delta);
76   if(!b->valuelist)b->valuelist=malloc(sizeof(double)*b->entries*b->dim);
77   
78   for(j=0;j<b->entries;j++){
79     double last=0.;
80     for(k=0;k<b->dim;k++){
81       double val=b->quantlist[j*b->dim+k]*delta+last+mindel;
82       b->valuelist[j*b->dim+k]=val;
83       if(b->sequencep)last=val;
84
85     }
86   }
87 }
88
89 double _ssqe(int el,double *a, double *b){
90   int i;
91   double acc=0.;
92   for(i=0;i<el;i++){
93     double val=(a[i]-b[i]);
94     acc+=val*val;
95   }
96   return acc;
97 }
98
99
100 /* command line:
101    run outbase [-m] [-s <start>,<n>] datafile [-s <start>,<n>] [datafile...]
102
103    produces: outbase-residue.m (error between input data and chosen codewords;
104                                 can be used to cascade)
105              outbase-cells.m   (2d gnuplot file of cells if -m)
106
107    currently assumes a 'sequenced' codebook wants its test data to be
108    normalized to begin at zero... */
109
110 int main(int argc,char *argv[]){
111   vqbook *b=&CODEBOOK;
112   FILE *cells=NULL;
113   FILE *residue=NULL;
114   FILE *in=NULL;
115   char *line,*name;
116   long i,j,k;
117   int start=0,num=-1;
118
119   double mean=0.,br_mean=0.,mean_count=0.;
120   
121   argv++;
122
123   if(*argv==NULL){
124     fprintf(stderr,"Need a basename.\n");
125     exit(1);
126   }
127
128   name=strdup(*argv);
129   vqbook_unquantize(b);
130
131   {
132     char buf[80];
133     snprintf(buf,80,"%s-residue.vqd",name);
134     residue=fopen(buf,"w");
135     if(!residue){
136       fprintf(stderr,"Unable to open output file %s\n",buf);
137       exit(1);
138     }
139   }   
140
141   /* parse the command line; handle things as the come */
142   argv=argv++;
143   while(*argv){
144     if(argv[0][0]=='-'){
145       /* it's an option */
146       switch(argv[0][1]){
147       case 'm':
148         {
149           char buf[80];
150           snprintf(buf,80,"%s-cells.m",name);
151           cells=fopen(buf,"w");
152           if(!cells){
153             fprintf(stderr,"Unable to open output file %s\n",buf);
154             exit(1);
155           }
156         }   
157         argv++;
158         break;
159       case 's':
160         if(!argv[1]){
161           fprintf(stderr,"Option %s missing argument.\n",argv[0]);
162           exit(1);
163         }      
164         if(sscanf(argv[1],"%d,%d",&start,&num)!=2){
165           num= -1;
166           if(sscanf(argv[1],"%d",&start)!=1){
167             fprintf(stderr,"Option %s syntax error.\n",argv[0]);
168             exit(1);
169           }
170         }
171         argv+=2;
172         break;
173       }
174     }else{
175       /* it's an input file */
176       char *file=strdup(*argv++);
177       FILE *in;
178       int cols=-1;
179
180       in=fopen(file,"r");
181       if(in==NULL){
182         fprintf(stderr,"Could not open input file %s\n",file);
183         exit(1);
184       }
185
186       while((line=rline(in))){
187         if(cols==-1){
188           char *temp=line;
189           while(*temp==' ')temp++;
190           for(cols=0;*temp;cols++){
191             while(*temp>32)temp++;
192             while(*temp==' ')temp++;
193           }
194         }
195         {
196           int i;
197           double *p=malloc(cols*sizeof(double));
198           if(start*num+b->dim>cols){
199             fprintf(stderr,"ran out of columns reading %s\n",file);
200             exit(1);
201           }
202           while(*line==' ')line++;
203           for(i=0;i<cols;i++){
204
205             /* static length buffer bug workaround */
206             char *temp=line;
207             char old;
208             while(*temp>32)temp++;
209
210             old=temp[0];
211             temp[0]='\0';
212             p[i]=atof(line);
213             temp[0]=old;
214             
215             while(*line>32)line++;
216             while(*line==' ')line++;
217           }
218           if(num<=0)num=(cols-start)/b->dim;
219           for(i=num-1;i>=0;i--){
220             int entry;
221             double *base=p+start+i*b->dim;
222
223             /* if this is a sequenced book and i||start,
224                normalize the beginning to zero */
225             if(b->sequencep && (i>0 || start>0)){
226               for(k=0;k<b->dim;k++)
227                 base[k]-= *(base-1);
228             }
229
230             /* assign the point */
231             entry=vqenc_entry(b,base);
232
233             /* accumulate metrics */
234             mean+=_ssqe(b->dim,base,b->valuelist+entry*b->dim);
235
236             /* brute force it as a sanity check of the decision
237                table... did that work better? */
238             {
239               double best=_ssqe(b->dim,base,b->valuelist);
240               int bestj=0;
241               for(j=0;j<b->entries;j++){
242                 double this=_ssqe(b->dim,base,b->valuelist+j*b->dim);
243                 if(this<best){
244                   best=this;
245                   bestj=j;
246                 }
247               }
248
249               br_mean+=best;
250             }
251
252             mean_count+=b->dim;
253
254             /* paint the cell if -m */
255             if(cells){
256               fprintf(cells,"%g %g\n%g %g\n\n",
257                       base[0],base[1],
258                       b->valuelist[0+entry*b->dim],
259                       b->valuelist[1+entry*b->dim]);
260             }
261
262             /* write cascading data */
263
264
265
266           }
267           free(p);
268         }
269       }
270       fclose(in);
271     }
272   }
273   
274   
275   fclose(residue);
276   if(cells)fclose(cells);
277
278   /* print accumulated error statistics */
279   fprintf(stderr,"results:\n\tsqrt(mean squared error) from decision tree:%g\n"
280           "\tsqrt(mean squared error) by brute force:%g\n\n",
281           sqrt(mean/mean_count),sqrt(br_mean/mean_count));
282
283   return 0;
284 }