]> git.jsancho.org Git - lugaru.git/blob - Dependencies/libvorbis/vq/metrics.c
CMake: Purge all the bundled dependencies
[lugaru.git] / Dependencies / libvorbis / vq / metrics.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: function calls to collect codebook metrics
14  last mod: $Id: metrics.c 16037 2009-05-26 21:10:58Z xiphmont $
15
16  ********************************************************************/
17
18
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <math.h>
22 #include "bookutil.h"
23
24 /* collect the following metrics:
25
26    mean and mean squared amplitude
27    mean and mean squared error 
28    mean and mean squared error (per sample) by entry
29    worst case fit by entry
30    entry cell size
31    hits by entry
32    total bits
33    total samples
34    (average bits per sample)*/
35    
36
37 /* set up metrics */
38
39 float meanamplitude_acc=0.f;
40 float meanamplitudesq_acc=0.f;
41 float meanerror_acc=0.f;
42 float meanerrorsq_acc=0.f;
43
44 float **histogram=NULL;
45 float **histogram_error=NULL;
46 float **histogram_errorsq=NULL;
47 float **histogram_hi=NULL;
48 float **histogram_lo=NULL;
49 float bits=0.f;
50 float count=0.f;
51
52 static float *_now(codebook *c, int i){
53   return c->valuelist+i*c->c->dim;
54 }
55
56 int books=0;
57
58 void process_preprocess(codebook **bs,char *basename){
59   int i;
60   while(bs[books])books++;
61   
62   if(books){
63     histogram=_ogg_calloc(books,sizeof(float *));
64     histogram_error=_ogg_calloc(books,sizeof(float *));
65     histogram_errorsq=_ogg_calloc(books,sizeof(float *));
66     histogram_hi=_ogg_calloc(books,sizeof(float *));
67     histogram_lo=_ogg_calloc(books,sizeof(float *));
68   }else{
69     fprintf(stderr,"Specify at least one codebook\n");
70     exit(1);
71   }
72
73   for(i=0;i<books;i++){
74     codebook *b=bs[i];
75     histogram[i]=_ogg_calloc(b->entries,sizeof(float));
76     histogram_error[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
77     histogram_errorsq[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
78     histogram_hi[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
79     histogram_lo[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
80   }
81 }
82
83 static float _dist(int el,float *a, float *b){
84   int i;
85   float acc=0.f;
86   for(i=0;i<el;i++){
87     float val=(a[i]-b[i]);
88     acc+=val*val;
89   }
90   return acc;
91 }
92
93 void cell_spacing(codebook *c){
94   int j,k;
95   float min=-1.f,max=-1.f,mean=0.f,meansq=0.f;
96   long total=0;
97
98   /* minimum, maximum, mean, ms cell spacing */
99   for(j=0;j<c->c->entries;j++){
100     if(c->c->lengthlist[j]>0){
101       float localmin=-1.;
102       for(k=0;k<c->c->entries;k++){
103         if(c->c->lengthlist[k]>0){
104           float this=_dist(c->c->dim,_now(c,j),_now(c,k));
105           if(j!=k &&
106              (localmin==-1 || this<localmin))
107             localmin=this;
108         }
109       }
110       
111       if(min==-1 || localmin<min)min=localmin;
112       if(max==-1 || localmin>max)max=localmin;
113       mean+=sqrt(localmin);
114       meansq+=localmin;
115       total++;
116     }
117   }
118   
119   fprintf(stderr,"\tminimum cell spacing (closest side): %g\n",sqrt(min));
120   fprintf(stderr,"\tmaximum cell spacing (closest side): %g\n",sqrt(max));
121   fprintf(stderr,"\tmean closest side spacing: %g\n",mean/total);
122   fprintf(stderr,"\tmean sq closest side spacing: %g\n",sqrt(meansq/total));
123 }
124
125 void process_postprocess(codebook **bs,char *basename){
126   int i,k,book;
127   char *buffer=alloca(strlen(basename)+80);
128
129   fprintf(stderr,"Done.  Processed %ld data points:\n\n",
130           (long)count);
131
132   fprintf(stderr,"Global statistics:******************\n\n");
133
134   fprintf(stderr,"\ttotal samples: %ld\n",(long)count);
135   fprintf(stderr,"\ttotal bits required to code: %ld\n",(long)bits);
136   fprintf(stderr,"\taverage bits per sample: %g\n\n",bits/count);
137
138   fprintf(stderr,"\tmean sample amplitude: %g\n",
139           meanamplitude_acc/count);
140   fprintf(stderr,"\tmean squared sample amplitude: %g\n\n",
141           sqrt(meanamplitudesq_acc/count));
142
143   fprintf(stderr,"\tmean code error: %g\n",
144           meanerror_acc/count);
145   fprintf(stderr,"\tmean squared code error: %g\n\n",
146           sqrt(meanerrorsq_acc/count));
147
148   for(book=0;book<books;book++){
149     FILE *out;
150     codebook *b=bs[book];
151     int n=b->c->entries;
152     int dim=b->c->dim;
153
154     fprintf(stderr,"Book %d statistics:------------------\n",book);
155
156     cell_spacing(b);
157
158     sprintf(buffer,"%s-%d-mse.m",basename,book);
159     out=fopen(buffer,"w");
160     if(!out){
161       fprintf(stderr,"Could not open file %s for writing\n",buffer);
162       exit(1);
163     }
164     
165     for(i=0;i<n;i++){
166       for(k=0;k<dim;k++){
167         fprintf(out,"%d, %g, %g\n",
168                 i*dim+k,(b->valuelist+i*dim)[k],
169                 sqrt((histogram_errorsq[book]+i*dim)[k]/histogram[book][i]));
170       }
171     }
172     fclose(out);
173       
174     sprintf(buffer,"%s-%d-me.m",basename,book);
175     out=fopen(buffer,"w");
176     if(!out){
177       fprintf(stderr,"Could not open file %s for writing\n",buffer);
178       exit(1);
179     }
180     
181     for(i=0;i<n;i++){
182       for(k=0;k<dim;k++){
183         fprintf(out,"%d, %g, %g\n",
184                 i*dim+k,(b->valuelist+i*dim)[k],
185                 (histogram_error[book]+i*dim)[k]/histogram[book][i]);
186       }
187     }
188     fclose(out);
189
190     sprintf(buffer,"%s-%d-worst.m",basename,book);
191     out=fopen(buffer,"w");
192     if(!out){
193       fprintf(stderr,"Could not open file %s for writing\n",buffer);
194       exit(1);
195     }
196     
197     for(i=0;i<n;i++){
198       for(k=0;k<dim;k++){
199         fprintf(out,"%d, %g, %g, %g\n",
200                 i*dim+k,(b->valuelist+i*dim)[k],
201                 (b->valuelist+i*dim)[k]+(histogram_lo[book]+i*dim)[k],
202                 (b->valuelist+i*dim)[k]+(histogram_hi[book]+i*dim)[k]);
203       }
204     }
205     fclose(out);
206   }
207 }
208
209 float process_one(codebook *b,int book,float *a,int dim,int step,int addmul,
210                    float base){
211   int j,entry;
212   float amplitude=0.f;
213
214   if(book==0){
215     float last=base;
216     for(j=0;j<dim;j++){
217       amplitude=a[j*step]-(b->c->q_sequencep?last:0);
218       meanamplitude_acc+=fabs(amplitude);
219       meanamplitudesq_acc+=amplitude*amplitude;
220       count++;
221       last=a[j*step];
222     }
223   }
224
225   if(b->c->q_sequencep){
226     float temp;
227     for(j=0;j<dim;j++){
228       temp=a[j*step];
229       a[j*step]-=base;
230     }
231     base=temp;
232   }
233
234   entry=vorbis_book_besterror(b,a,step,addmul);
235
236   if(entry==-1){
237     fprintf(stderr,"Internal error: _best returned -1.\n");
238     exit(1);
239   }
240   
241   histogram[book][entry]++;  
242   bits+=vorbis_book_codelen(b,entry);
243           
244   for(j=0;j<dim;j++){
245     float error=a[j*step];
246
247     if(book==books-1){
248       meanerror_acc+=fabs(error);
249       meanerrorsq_acc+=error*error;
250     }
251     histogram_errorsq[book][entry*dim+j]+=error*error;
252     histogram_error[book][entry*dim+j]+=fabs(error);
253     if(histogram[book][entry]==0 || histogram_hi[book][entry*dim+j]<error)
254       histogram_hi[book][entry*dim+j]=error;
255     if(histogram[book][entry]==0 || histogram_lo[book][entry*dim+j]>error)
256       histogram_lo[book][entry*dim+j]=error;
257   }
258   return base;
259 }
260
261
262 void process_vector(codebook **bs,int *addmul,int inter,float *a,int n){
263   int bi;
264   int i;
265
266   for(bi=0;bi<books;bi++){
267     codebook *b=bs[bi];
268     int dim=b->dim;
269     float base=0.f;
270
271     if(inter){
272       for(i=0;i<n/dim;i++)
273         base=process_one(b,bi,a+i,dim,n/dim,addmul[bi],base);
274     }else{
275       for(i=0;i<=n-dim;i+=dim)
276         base=process_one(b,bi,a+i,dim,1,addmul[bi],base);
277     }
278   }
279   
280   if((long)(count)%100)spinnit("working.... samples: ",count);
281 }
282
283 void process_usage(void){
284   fprintf(stderr,
285           "usage: vqmetrics [-i] +|*<codebook>.vqh [ +|*<codebook.vqh> ]... \n"
286           "                 datafile.vqd [datafile.vqd]...\n\n"
287           "       data can be taken on stdin.  -i indicates interleaved coding.\n"
288           "       Output goes to output files:\n"
289           "       basename-me.m:       gnuplot: mean error by entry value\n"
290           "       basename-mse.m:      gnuplot: mean square error by entry value\n"
291           "       basename-worst.m:    gnuplot: worst error by entry value\n"
292           "       basename-distance.m: gnuplot file showing distance probability\n"
293           "\n");
294
295 }