first cut of complete VQ utilities
[platform/upstream/libvorbis.git] / vq / metrics.c
1 /********************************************************************
2  *                                                                  *
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.                            *
7  *                                                                  *
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/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: function calls to collect codebook metrics
15  last mod: $Id: metrics.c,v 1.1 2000/01/06 13:57:13 xiphmont Exp $
16
17  ********************************************************************/
18
19
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <math.h>
23 #include "bookutil.h"
24
25 /* set up metrics */
26
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.;
32
33 double *histogram=NULL;
34 double *histogram_errorsq=NULL;
35 double *histogram_distance=NULL;
36 double *histogram_hi=NULL;
37 double *histogram_lo=NULL;
38
39 double count=0.;
40
41 int histerrsort(const void *a, const void *b){
42   double av=histogram_distance[*((long *)a)];
43   double bv=histogram_distance[*((long *)b)];
44   if(av<bv)return(-1);
45   return(1);
46 }
47
48 void process_preprocess(codebook *b,char *basename){
49   histogram=calloc(b->entries,sizeof(double));
50   histogram_distance=calloc(b->entries,sizeof(double));
51   histogram_errorsq=calloc(b->entries*b->dim,sizeof(double));
52   histogram_hi=calloc(b->entries*b->dim,sizeof(double));
53   histogram_lo=calloc(b->entries*b->dim,sizeof(double));
54 }
55
56 void process_postprocess(codebook *b,char *basename){
57   int i,j,k;
58   char *buffer=alloca(strlen(basename)+80);
59
60   fprintf(stderr,"Done.  Processed %ld data points for %ld entries:\n",
61           (long)count,b->entries);
62   fprintf(stderr,"\tglobal mean amplitude: %g\n",
63           meanamplitude_acc/(count*b->dim));
64   fprintf(stderr,"\tglobal mean squared amplitude: %g\n",
65           sqrt(meanamplitudesq_acc/(count*b->dim)));
66
67   fprintf(stderr,"\tglobal mean error: %g\n",
68           meanerror_acc/(count*b->dim));
69   fprintf(stderr,"\tglobal mean squared error: %g\n",
70           sqrt(meanerrorsq_acc/(count*b->dim)));
71   fprintf(stderr,"\tglobal mean deviation: %g\n",
72           meandev_acc/(count*b->dim));
73   {
74     FILE *out;
75     sprintf(buffer,"%s-fit.m",basename);
76     out=fopen(buffer,"w");
77     if(!out){
78       fprintf(stderr,"Could not open file %s for writing\n",buffer);
79       exit(1);
80     }
81
82     for(i=0;i<b->entries;i++){
83       for(k=0;k<b->dim;k++){
84         fprintf(out,"%d, %g, %g\n",
85                 i*b->dim+k,(b->valuelist+i*b->dim)[k],
86                 sqrt((histogram_errorsq+i*b->dim)[k]/histogram[i]));
87       }
88     }
89     fclose(out);
90
91     sprintf(buffer,"%s-worst.m",basename);
92     out=fopen(buffer,"w");
93     if(!out){
94       fprintf(stderr,"Could not open file %s for writing\n",buffer);
95       exit(1);
96     }
97
98     for(i=0;i<b->entries;i++){
99       for(k=0;k<b->dim;k++){
100         fprintf(out,"%d, %g, %g, %g\n",
101                 i*b->dim+k,(b->valuelist+i*b->dim)[k],
102                 (b->valuelist+i*b->dim)[k]+(histogram_lo+i*b->dim)[k],
103                 (b->valuelist+i*b->dim)[k]+(histogram_hi+i*b->dim)[k]);
104       }
105     }
106     fclose(out);
107   }
108
109   {
110     FILE *out;
111     long *index=alloca(sizeof(long)*b->entries);
112     sprintf(buffer,"%s-distance.m",basename);
113     out=fopen(buffer,"w");
114     if(!out){
115       fprintf(stderr,"Could not open file %s for writing\n",buffer);
116       exit(1);
117     }
118     for(j=0;j<b->entries;j++){
119       if(histogram[j])histogram_distance[j]/=histogram[j];
120       index[j]=j;
121     }
122
123     qsort(index,b->entries,sizeof(long),histerrsort);
124
125     for(j=0;j<b->entries;j++)
126       for(k=0;k<histogram[index[j]];k++)
127         fprintf(out,"%g,\n",histogram_distance[index[j]]);
128     fclose(out);
129                 
130   }
131
132 }
133
134 void process_vector(codebook *b,double *a){
135   int entry=codebook_entry(b,a);
136   double *e=b->valuelist+b->dim*entry;
137   int i;
138   double amplitude=0.;
139   double distance=0.;
140   double base=0.;
141   for(i=0;i<b->dim;i++){
142     double error=a[i]-e[i];
143     if(b->q_sequencep){
144       amplitude=a[i]-base;
145       base=a[i];
146     }else
147       amplitude=a[i];
148     
149     meanamplitude_acc+=fabs(amplitude);
150     meanamplitudesq_acc+=amplitude*amplitude;
151     meanerror_acc+=fabs(error);
152     meanerrorsq_acc+=error*error;
153     
154     if(amplitude)
155       meandev_acc+=fabs((a[i]-e[i])/amplitude);
156     else
157       meandev_acc+=fabs(a[i]-e[i]); /* yeah, yeah */
158     
159     histogram_errorsq[entry*b->dim+i]+=error*error;
160     if(histogram[entry]==0 || histogram_hi[entry*b->dim+i]<error)
161       histogram_hi[entry*b->dim+i]=error;
162     if(histogram[entry]==0 || histogram_lo[entry*b->dim+i]>error)
163       histogram_lo[entry*b->dim+i]=error;
164     distance+=error*error;
165   }
166
167   histogram[entry]++;  
168   histogram_distance[entry]+=sqrt(distance);
169
170   if((long)(count++)%100)spinnit("working.... lines: ",count);
171 }
172
173 void process_usage(void){
174   fprintf(stderr,
175           "usage: vqmetrics <codebook>.vqh datafile.vqd [datafile.vqd]...\n\n"
176           "       data can be taken on stdin.  Output goes to output files:\n"
177           "       basename-fit.m:      gnuplot: mean square error by entry value\n"
178           "       basename-worst.m:    gnuplot: worst error by entry value\n"
179           "       basename-distance.m: gnuplot file showing distance probability\n"
180           "\n");
181
182 }