Blame vq/metrics.c

Packit 06404a
/********************************************************************
Packit 06404a
 *                                                                  *
Packit 06404a
 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
Packit 06404a
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
Packit 06404a
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
Packit 06404a
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
Packit 06404a
 *                                                                  *
Packit 06404a
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
Packit 06404a
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
Packit 06404a
 *                                                                  *
Packit 06404a
 ********************************************************************
Packit 06404a
Packit 06404a
 function: function calls to collect codebook metrics
Packit 06404a
 last mod: $Id: metrics.c 16037 2009-05-26 21:10:58Z xiphmont $
Packit 06404a
Packit 06404a
 ********************************************************************/
Packit 06404a
Packit 06404a
Packit 06404a
#include <stdlib.h>
Packit 06404a
#include <unistd.h>
Packit 06404a
#include <math.h>
Packit 06404a
#include "bookutil.h"
Packit 06404a
Packit 06404a
/* collect the following metrics:
Packit 06404a
Packit 06404a
   mean and mean squared amplitude
Packit 06404a
   mean and mean squared error 
Packit 06404a
   mean and mean squared error (per sample) by entry
Packit 06404a
   worst case fit by entry
Packit 06404a
   entry cell size
Packit 06404a
   hits by entry
Packit 06404a
   total bits
Packit 06404a
   total samples
Packit 06404a
   (average bits per sample)*/
Packit 06404a
   
Packit 06404a
Packit 06404a
/* set up metrics */
Packit 06404a
Packit 06404a
float meanamplitude_acc=0.f;
Packit 06404a
float meanamplitudesq_acc=0.f;
Packit 06404a
float meanerror_acc=0.f;
Packit 06404a
float meanerrorsq_acc=0.f;
Packit 06404a
Packit 06404a
float **histogram=NULL;
Packit 06404a
float **histogram_error=NULL;
Packit 06404a
float **histogram_errorsq=NULL;
Packit 06404a
float **histogram_hi=NULL;
Packit 06404a
float **histogram_lo=NULL;
Packit 06404a
float bits=0.f;
Packit 06404a
float count=0.f;
Packit 06404a
Packit 06404a
static float *_now(codebook *c, int i){
Packit 06404a
  return c->valuelist+i*c->c->dim;
Packit 06404a
}
Packit 06404a
Packit 06404a
int books=0;
Packit 06404a
Packit 06404a
void process_preprocess(codebook **bs,char *basename){
Packit 06404a
  int i;
Packit 06404a
  while(bs[books])books++;
Packit 06404a
  
Packit 06404a
  if(books){
Packit 06404a
    histogram=_ogg_calloc(books,sizeof(float *));
Packit 06404a
    histogram_error=_ogg_calloc(books,sizeof(float *));
Packit 06404a
    histogram_errorsq=_ogg_calloc(books,sizeof(float *));
Packit 06404a
    histogram_hi=_ogg_calloc(books,sizeof(float *));
Packit 06404a
    histogram_lo=_ogg_calloc(books,sizeof(float *));
Packit 06404a
  }else{
Packit 06404a
    fprintf(stderr,"Specify at least one codebook\n");
Packit 06404a
    exit(1);
Packit 06404a
  }
Packit 06404a
Packit 06404a
  for(i=0;i
Packit 06404a
    codebook *b=bs[i];
Packit 06404a
    histogram[i]=_ogg_calloc(b->entries,sizeof(float));
Packit 06404a
    histogram_error[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
Packit 06404a
    histogram_errorsq[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
Packit 06404a
    histogram_hi[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
Packit 06404a
    histogram_lo[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
Packit 06404a
  }
Packit 06404a
}
Packit 06404a
Packit 06404a
static float _dist(int el,float *a, float *b){
Packit 06404a
  int i;
Packit 06404a
  float acc=0.f;
Packit 06404a
  for(i=0;i
Packit 06404a
    float val=(a[i]-b[i]);
Packit 06404a
    acc+=val*val;
Packit 06404a
  }
Packit 06404a
  return acc;
Packit 06404a
}
Packit 06404a
Packit 06404a
void cell_spacing(codebook *c){
Packit 06404a
  int j,k;
Packit 06404a
  float min=-1.f,max=-1.f,mean=0.f,meansq=0.f;
Packit 06404a
  long total=0;
Packit 06404a
Packit 06404a
  /* minimum, maximum, mean, ms cell spacing */
Packit 06404a
  for(j=0;j<c->c->entries;j++){
Packit 06404a
    if(c->c->lengthlist[j]>0){
Packit 06404a
      float localmin=-1.;
Packit 06404a
      for(k=0;k<c->c->entries;k++){
Packit 06404a
        if(c->c->lengthlist[k]>0){
Packit 06404a
          float this=_dist(c->c->dim,_now(c,j),_now(c,k));
Packit 06404a
          if(j!=k &&
Packit 06404a
             (localmin==-1 || this
Packit 06404a
            localmin=this;
Packit 06404a
        }
Packit 06404a
      }
Packit 06404a
      
Packit 06404a
      if(min==-1 || localmin
Packit 06404a
      if(max==-1 || localmin>max)max=localmin;
Packit 06404a
      mean+=sqrt(localmin);
Packit 06404a
      meansq+=localmin;
Packit 06404a
      total++;
Packit 06404a
    }
Packit 06404a
  }
Packit 06404a
  
Packit 06404a
  fprintf(stderr,"\tminimum cell spacing (closest side): %g\n",sqrt(min));
Packit 06404a
  fprintf(stderr,"\tmaximum cell spacing (closest side): %g\n",sqrt(max));
Packit 06404a
  fprintf(stderr,"\tmean closest side spacing: %g\n",mean/total);
Packit 06404a
  fprintf(stderr,"\tmean sq closest side spacing: %g\n",sqrt(meansq/total));
Packit 06404a
}
Packit 06404a
Packit 06404a
void process_postprocess(codebook **bs,char *basename){
Packit 06404a
  int i,k,book;
Packit 06404a
  char *buffer=alloca(strlen(basename)+80);
Packit 06404a
Packit 06404a
  fprintf(stderr,"Done.  Processed %ld data points:\n\n",
Packit 06404a
          (long)count);
Packit 06404a
Packit 06404a
  fprintf(stderr,"Global statistics:******************\n\n");
Packit 06404a
Packit 06404a
  fprintf(stderr,"\ttotal samples: %ld\n",(long)count);
Packit 06404a
  fprintf(stderr,"\ttotal bits required to code: %ld\n",(long)bits);
Packit 06404a
  fprintf(stderr,"\taverage bits per sample: %g\n\n",bits/count);
Packit 06404a
Packit 06404a
  fprintf(stderr,"\tmean sample amplitude: %g\n",
Packit 06404a
          meanamplitude_acc/count);
Packit 06404a
  fprintf(stderr,"\tmean squared sample amplitude: %g\n\n",
Packit 06404a
          sqrt(meanamplitudesq_acc/count));
Packit 06404a
Packit 06404a
  fprintf(stderr,"\tmean code error: %g\n",
Packit 06404a
          meanerror_acc/count);
Packit 06404a
  fprintf(stderr,"\tmean squared code error: %g\n\n",
Packit 06404a
          sqrt(meanerrorsq_acc/count));
Packit 06404a
Packit 06404a
  for(book=0;book
Packit 06404a
    FILE *out;
Packit 06404a
    codebook *b=bs[book];
Packit 06404a
    int n=b->c->entries;
Packit 06404a
    int dim=b->c->dim;
Packit 06404a
Packit 06404a
    fprintf(stderr,"Book %d statistics:------------------\n",book);
Packit 06404a
Packit 06404a
    cell_spacing(b);
Packit 06404a
Packit 06404a
    sprintf(buffer,"%s-%d-mse.m",basename,book);
Packit 06404a
    out=fopen(buffer,"w");
Packit 06404a
    if(!out){
Packit 06404a
      fprintf(stderr,"Could not open file %s for writing\n",buffer);
Packit 06404a
      exit(1);
Packit 06404a
    }
Packit 06404a
    
Packit 06404a
    for(i=0;i
Packit 06404a
      for(k=0;k
Packit 06404a
        fprintf(out,"%d, %g, %g\n",
Packit 06404a
                i*dim+k,(b->valuelist+i*dim)[k],
Packit 06404a
                sqrt((histogram_errorsq[book]+i*dim)[k]/histogram[book][i]));
Packit 06404a
      }
Packit 06404a
    }
Packit 06404a
    fclose(out);
Packit 06404a
      
Packit 06404a
    sprintf(buffer,"%s-%d-me.m",basename,book);
Packit 06404a
    out=fopen(buffer,"w");
Packit 06404a
    if(!out){
Packit 06404a
      fprintf(stderr,"Could not open file %s for writing\n",buffer);
Packit 06404a
      exit(1);
Packit 06404a
    }
Packit 06404a
    
Packit 06404a
    for(i=0;i
Packit 06404a
      for(k=0;k
Packit 06404a
        fprintf(out,"%d, %g, %g\n",
Packit 06404a
                i*dim+k,(b->valuelist+i*dim)[k],
Packit 06404a
                (histogram_error[book]+i*dim)[k]/histogram[book][i]);
Packit 06404a
      }
Packit 06404a
    }
Packit 06404a
    fclose(out);
Packit 06404a
Packit 06404a
    sprintf(buffer,"%s-%d-worst.m",basename,book);
Packit 06404a
    out=fopen(buffer,"w");
Packit 06404a
    if(!out){
Packit 06404a
      fprintf(stderr,"Could not open file %s for writing\n",buffer);
Packit 06404a
      exit(1);
Packit 06404a
    }
Packit 06404a
    
Packit 06404a
    for(i=0;i
Packit 06404a
      for(k=0;k
Packit 06404a
        fprintf(out,"%d, %g, %g, %g\n",
Packit 06404a
                i*dim+k,(b->valuelist+i*dim)[k],
Packit 06404a
                (b->valuelist+i*dim)[k]+(histogram_lo[book]+i*dim)[k],
Packit 06404a
                (b->valuelist+i*dim)[k]+(histogram_hi[book]+i*dim)[k]);
Packit 06404a
      }
Packit 06404a
    }
Packit 06404a
    fclose(out);
Packit 06404a
  }
Packit 06404a
}
Packit 06404a
Packit 06404a
float process_one(codebook *b,int book,float *a,int dim,int step,int addmul,
Packit 06404a
                   float base){
Packit 06404a
  int j,entry;
Packit 06404a
  float amplitude=0.f;
Packit 06404a
Packit 06404a
  if(book==0){
Packit 06404a
    float last=base;
Packit 06404a
    for(j=0;j
Packit 06404a
      amplitude=a[j*step]-(b->c->q_sequencep?last:0);
Packit 06404a
      meanamplitude_acc+=fabs(amplitude);
Packit 06404a
      meanamplitudesq_acc+=amplitude*amplitude;
Packit 06404a
      count++;
Packit 06404a
      last=a[j*step];
Packit 06404a
    }
Packit 06404a
  }
Packit 06404a
Packit 06404a
  if(b->c->q_sequencep){
Packit 06404a
    float temp;
Packit 06404a
    for(j=0;j
Packit 06404a
      temp=a[j*step];
Packit 06404a
      a[j*step]-=base;
Packit 06404a
    }
Packit 06404a
    base=temp;
Packit 06404a
  }
Packit 06404a
Packit 06404a
  entry=vorbis_book_besterror(b,a,step,addmul);
Packit 06404a
Packit 06404a
  if(entry==-1){
Packit 06404a
    fprintf(stderr,"Internal error: _best returned -1.\n");
Packit 06404a
    exit(1);
Packit 06404a
  }
Packit 06404a
  
Packit 06404a
  histogram[book][entry]++;  
Packit 06404a
  bits+=vorbis_book_codelen(b,entry);
Packit 06404a
          
Packit 06404a
  for(j=0;j
Packit 06404a
    float error=a[j*step];
Packit 06404a
Packit 06404a
    if(book==books-1){
Packit 06404a
      meanerror_acc+=fabs(error);
Packit 06404a
      meanerrorsq_acc+=error*error;
Packit 06404a
    }
Packit 06404a
    histogram_errorsq[book][entry*dim+j]+=error*error;
Packit 06404a
    histogram_error[book][entry*dim+j]+=fabs(error);
Packit 06404a
    if(histogram[book][entry]==0 || histogram_hi[book][entry*dim+j]
Packit 06404a
      histogram_hi[book][entry*dim+j]=error;
Packit 06404a
    if(histogram[book][entry]==0 || histogram_lo[book][entry*dim+j]>error)
Packit 06404a
      histogram_lo[book][entry*dim+j]=error;
Packit 06404a
  }
Packit 06404a
  return base;
Packit 06404a
}
Packit 06404a
Packit 06404a
Packit 06404a
void process_vector(codebook **bs,int *addmul,int inter,float *a,int n){
Packit 06404a
  int bi;
Packit 06404a
  int i;
Packit 06404a
Packit 06404a
  for(bi=0;bi
Packit 06404a
    codebook *b=bs[bi];
Packit 06404a
    int dim=b->dim;
Packit 06404a
    float base=0.f;
Packit 06404a
Packit 06404a
    if(inter){
Packit 06404a
      for(i=0;i
Packit 06404a
        base=process_one(b,bi,a+i,dim,n/dim,addmul[bi],base);
Packit 06404a
    }else{
Packit 06404a
      for(i=0;i<=n-dim;i+=dim)
Packit 06404a
        base=process_one(b,bi,a+i,dim,1,addmul[bi],base);
Packit 06404a
    }
Packit 06404a
  }
Packit 06404a
  
Packit 06404a
  if((long)(count)%100)spinnit("working.... samples: ",count);
Packit 06404a
}
Packit 06404a
Packit 06404a
void process_usage(void){
Packit 06404a
  fprintf(stderr,
Packit 06404a
          "usage: vqmetrics [-i] +|*<codebook>.vqh [ +|*<codebook.vqh> ]... \n"
Packit 06404a
          "                 datafile.vqd [datafile.vqd]...\n\n"
Packit 06404a
          "       data can be taken on stdin.  -i indicates interleaved coding.\n"
Packit 06404a
          "       Output goes to output files:\n"
Packit 06404a
          "       basename-me.m:       gnuplot: mean error by entry value\n"
Packit 06404a
          "       basename-mse.m:      gnuplot: mean square error by entry value\n"
Packit 06404a
          "       basename-worst.m:    gnuplot: worst error by entry value\n"
Packit 06404a
          "       basename-distance.m: gnuplot file showing distance probability\n"
Packit 06404a
          "\n");
Packit 06404a
Packit 06404a
}