1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
9 * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: function calls to collect codebook metrics
15 last mod: $Id: metrics.c,v 1.6 2000/02/16 16:18:37 xiphmont Exp $
17 ********************************************************************/
27 double meanamplitude_acc=0.;
28 double meanamplitudesq_acc=0.;
29 double meanerror_acc=0.;
30 double meanerrorsq_acc=0.;
31 double meandev_acc=0.;
33 double *histogram=NULL;
34 double *histogram_error=NULL;
35 double *histogram_errorsq=NULL;
36 double *histogram_distance=NULL;
37 double *histogram_hi=NULL;
38 double *histogram_lo=NULL;
46 static double *_now(codebook *c, int i){
47 return c->valuelist+i*c->c->dim;
50 int histerrsort(const void *a, const void *b){
51 double av=histogram_distance[*((long *)a)];
52 double bv=histogram_distance[*((long *)b)];
57 void process_preprocess(codebook **bs,char *basename){
59 codebook *b=bs[books];
62 work=malloc(sizeof(double)*dim);
65 fprintf(stderr,"Each codebook in a cascade must have the same dimensional order\n");
73 const static_codebook *b=bs[books-1]->c;
74 histogram=calloc(b->entries,sizeof(double));
75 histogram_distance=calloc(b->entries,sizeof(double));
76 histogram_errorsq=calloc(b->entries*dim,sizeof(double));
77 histogram_error=calloc(b->entries*dim,sizeof(double));
78 histogram_hi=calloc(b->entries*dim,sizeof(double));
79 histogram_lo=calloc(b->entries*dim,sizeof(double));
81 fprintf(stderr,"Specify at least one codebook\n");
86 static double _dist(int el,double *a, double *b){
90 double val=(a[i]-b[i]);
96 void cell_spacing(codebook **b){
99 double min,max,mean=0.,meansq=0.;
102 fprintf(stderr,"\nCell spacing for book %d:\n",i);
104 /* minimum, maximum, mean, ms cell spacing */
105 for(j=0;j<c->c->entries;j++){
107 for(k=0;k<c->c->entries;k++){
108 double this=_dist(c->c->dim,_now(c,j),_now(c,k));
110 (localmin==-1 || this<localmin))
114 if(j==0 || localmin<min)min=localmin;
115 if(j==0 || localmin>max)max=localmin;
116 mean+=sqrt(localmin);
120 fprintf(stderr,"\tminimum cell spacing (closest side): %g\n",sqrt(min));
121 fprintf(stderr,"\tmaximum cell spacing (closest side): %g\n",sqrt(max));
122 fprintf(stderr,"\tmean closest side spacing: %g\n",mean/c->c->entries);
123 fprintf(stderr,"\tmean sq closest side spacing: %g\n",sqrt(meansq/c->c->entries));
127 void process_postprocess(codebook **b,char *basename){
129 char *buffer=alloca(strlen(basename)+80);
130 codebook *bb=b[books-1];
132 fprintf(stderr,"Done. Processed %ld data points for %ld entries:\n",
133 (long)count,bb->c->entries);
134 fprintf(stderr,"\tglobal mean amplitude: %g\n",
135 meanamplitude_acc/(count*dim));
136 fprintf(stderr,"\tglobal mean squared amplitude: %g\n",
137 sqrt(meanamplitudesq_acc/(count*dim)));
139 fprintf(stderr,"\tglobal mean error: %g\n",
140 meanerror_acc/(count*dim));
141 fprintf(stderr,"\tglobal mean squared error: %g\n",
142 sqrt(meanerrorsq_acc/(count*dim)));
143 fprintf(stderr,"\tglobal mean deviation: %g\n",
144 meandev_acc/(count*dim));
151 sprintf(buffer,"%s-mse.m",basename);
152 out=fopen(buffer,"w");
154 fprintf(stderr,"Could not open file %s for writing\n",buffer);
158 for(i=0;i<bb->c->entries;i++){
159 for(k=0;k<bb->c->dim;k++){
160 fprintf(out,"%ld, %g, %g\n",
161 i*bb->c->dim+k,(bb->valuelist+i*bb->c->dim)[k],
162 sqrt((histogram_errorsq+i*bb->c->dim)[k]/histogram[i]));
167 sprintf(buffer,"%s-me.m",basename);
168 out=fopen(buffer,"w");
170 fprintf(stderr,"Could not open file %s for writing\n",buffer);
174 for(i=0;i<bb->c->entries;i++){
175 for(k=0;k<bb->c->dim;k++){
176 fprintf(out,"%ld, %g, %g\n",
177 i*bb->c->dim+k,(bb->valuelist+i*bb->c->dim)[k],
178 (histogram_error+i*bb->c->dim)[k]/histogram[i]);
183 sprintf(buffer,"%s-worst.m",basename);
184 out=fopen(buffer,"w");
186 fprintf(stderr,"Could not open file %s for writing\n",buffer);
190 for(i=0;i<bb->c->entries;i++){
191 for(k=0;k<bb->c->dim;k++){
192 fprintf(out,"%ld, %g, %g, %g\n",
193 i*bb->c->dim+k,(bb->valuelist+i*bb->c->dim)[k],
194 (bb->valuelist+i*bb->c->dim)[k]+(histogram_lo+i*bb->c->dim)[k],
195 (bb->valuelist+i*bb->c->dim)[k]+(histogram_hi+i*bb->c->dim)[k]);
203 long *index=alloca(sizeof(long)*bb->c->entries);
204 sprintf(buffer,"%s-distance.m",basename);
205 out=fopen(buffer,"w");
207 fprintf(stderr,"Could not open file %s for writing\n",buffer);
210 for(j=0;j<bb->c->entries;j++){
211 if(histogram[j])histogram_distance[j]/=histogram[j];
215 qsort(index,bb->c->entries,sizeof(long),histerrsort);
217 for(j=0;j<bb->c->entries;j++)
218 for(k=0;k<histogram[index[j]];k++)
219 fprintf(out,"%g,\n",histogram_distance[index[j]]);
225 void process_vector(codebook **bs,double *a){
233 memcpy(work,a,sizeof(double)*dim);
235 for(bi=0;bi<books;bi++){
237 entry=codebook_entry(b,work);
238 e=b->valuelist+b->c->dim*entry;
239 for(i=0;i<b->c->dim;i++)work[i]-=e[i];
243 double error=work[i];
244 if(bs[0]->c->q_sequencep){
250 meanamplitude_acc+=fabs(amplitude);
251 meanamplitudesq_acc+=amplitude*amplitude;
252 meanerror_acc+=fabs(error);
253 meanerrorsq_acc+=error*error;
256 meandev_acc+=fabs(error/amplitude);
258 meandev_acc+=fabs(error); /* yeah, yeah */
260 histogram_errorsq[entry*dim+i]+=error*error;
261 histogram_error[entry*dim+i]+=fabs(error);
262 if(histogram[entry]==0 || histogram_hi[entry*dim+i]<error)
263 histogram_hi[entry*dim+i]=error;
264 if(histogram[entry]==0 || histogram_lo[entry*dim+i]>error)
265 histogram_lo[entry*dim+i]=error;
266 distance+=error*error;
270 histogram_distance[entry]+=sqrt(distance);
272 if((long)(count++)%100)spinnit("working.... lines: ",count);
275 void process_usage(void){
277 "usage: vqmetrics <codebook>.vqh datafile.vqd [datafile.vqd]...\n\n"
278 " data can be taken on stdin. Output goes to output files:\n"
279 " basename-me.m: gnuplot: mean error by entry value\n"
280 " basename-mse.m: gnuplot: mean square error by entry value\n"
281 " basename-worst.m: gnuplot: worst error by entry value\n"
282 " basename-distance.m: gnuplot file showing distance probability\n"