Chris@1: /******************************************************************** Chris@1: * * Chris@1: * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * Chris@1: * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * Chris@1: * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * Chris@1: * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * Chris@1: * * Chris@1: * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * Chris@1: * by the Xiph.Org Foundation http://www.xiph.org/ * Chris@1: * * Chris@1: ******************************************************************** Chris@1: Chris@1: function: utility for finding the distribution in a data set Chris@1: last mod: $Id: distribution.c 16037 2009-05-26 21:10:58Z xiphmont $ Chris@1: Chris@1: ********************************************************************/ Chris@1: Chris@1: #include Chris@1: #include Chris@1: #include Chris@1: #include Chris@1: #include Chris@1: #include "bookutil.h" Chris@1: Chris@1: /* command line: Chris@1: distribution file.vqd Chris@1: */ Chris@1: Chris@1: int ascend(const void *a,const void *b){ Chris@1: return(**((long **)a)-**((long **)b)); Chris@1: } Chris@1: Chris@1: int main(int argc,char *argv[]){ Chris@1: FILE *in; Chris@1: long lines=0; Chris@1: float min; Chris@1: float max; Chris@1: long bins=-1; Chris@1: int flag=0; Chris@1: long *countarray; Chris@1: long total=0; Chris@1: char *line; Chris@1: Chris@1: if(argv[1]==NULL){ Chris@1: fprintf(stderr,"Usage: distribution {data.vqd [bins]| book.vqh} \n\n"); Chris@1: exit(1); Chris@1: } Chris@1: if(argv[2]!=NULL) Chris@1: bins=atoi(argv[2])-1; Chris@1: Chris@1: in=fopen(argv[1],"r"); Chris@1: if(!in){ Chris@1: fprintf(stderr,"Could not open input file %s\n",argv[1]); Chris@1: exit(1); Chris@1: } Chris@1: Chris@1: if(strrchr(argv[1],'.') && strcmp(strrchr(argv[1],'.'),".vqh")==0){ Chris@1: /* load/decode a book */ Chris@1: Chris@1: codebook *b=codebook_load(argv[1]); Chris@1: static_codebook *c=(static_codebook *)(b->c); Chris@1: float delta; Chris@1: int i; Chris@1: fclose(in); Chris@1: Chris@1: switch(c->maptype){ Chris@1: case 0: Chris@1: printf("entropy codebook only; no mappings\n"); Chris@1: exit(0); Chris@1: break; Chris@1: case 1: Chris@1: bins=_book_maptype1_quantvals(c); Chris@1: break; Chris@1: case 2: Chris@1: bins=c->entries*c->dim; Chris@1: break; Chris@1: } Chris@1: Chris@1: max=min=_float32_unpack(c->q_min); Chris@1: delta=_float32_unpack(c->q_delta); Chris@1: Chris@1: for(i=0;iquantlist[i]*delta+min; Chris@1: if(val>max)max=val; Chris@1: } Chris@1: Chris@1: printf("Minimum scalar value: %f\n",min); Chris@1: printf("Maximum scalar value: %f\n",max); Chris@1: Chris@1: switch(c->maptype){ Chris@1: case 1: Chris@1: { Chris@1: /* lattice codebook. dump it. */ Chris@1: int j,k; Chris@1: long maxcount=0; Chris@1: long **sort=calloc(bins,sizeof(long *)); Chris@1: long base=c->lengthlist[0]; Chris@1: countarray=calloc(bins,sizeof(long)); Chris@1: Chris@1: for(i=0;iquantlist+i; Chris@1: qsort(sort,bins,sizeof(long *),ascend); Chris@1: Chris@1: for(i=0;ientries;i++) Chris@1: if(c->lengthlist[i]>base)base=c->lengthlist[i]; Chris@1: Chris@1: /* dump a full, correlated count */ Chris@1: for(j=0;jentries;j++){ Chris@1: if(c->lengthlist[j]){ Chris@1: int indexdiv=1; Chris@1: printf("%4d: ",j); Chris@1: for(k=0;kdim;k++){ Chris@1: int index= (j/indexdiv)%bins; Chris@1: printf("%+3.1f,", c->quantlist[index]*_float32_unpack(c->q_delta)+ Chris@1: _float32_unpack(c->q_min)); Chris@1: indexdiv*=bins; Chris@1: } Chris@1: printf("\t|"); Chris@1: for(k=0;klengthlist[j];k++)printf("*"); Chris@1: printf("\n"); Chris@1: } Chris@1: } Chris@1: Chris@1: /* do a rough count */ Chris@1: for(j=0;jentries;j++){ Chris@1: int indexdiv=1; Chris@1: for(k=0;kdim;k++){ Chris@1: if(c->lengthlist[j]){ Chris@1: int index= (j/indexdiv)%bins; Chris@1: countarray[index]+=(1<<(base-c->lengthlist[j])); Chris@1: indexdiv*=bins; Chris@1: } Chris@1: } Chris@1: } Chris@1: Chris@1: /* dump the count */ Chris@1: Chris@1: { Chris@1: long maxcount=0,i,j; Chris@1: for(i=0;imaxcount)maxcount=countarray[i]; Chris@1: Chris@1: for(i=0;iquantlist; Chris@1: int stars=rint(50./maxcount*countarray[ptr]); Chris@1: printf("%+08f (%8ld) |",c->quantlist[ptr]*delta+min,countarray[ptr]); Chris@1: for(j=0;jmax)max=code; Chris@1: } Chris@1: Chris@1: line=setup_line(in); Chris@1: } Chris@1: Chris@1: if(bins<1){ Chris@1: if((int)(max-min)==min-max){ Chris@1: bins=max-min; Chris@1: }else{ Chris@1: bins=25; Chris@1: } Chris@1: } Chris@1: Chris@1: printf("\r \r"); Chris@1: printf("Minimum scalar value: %f\n",min); Chris@1: printf("Maximum scalar value: %f\n",max); Chris@1: Chris@1: if(argv[2]){ Chris@1: Chris@1: printf("\n counting hits into %ld bins...\n",bins+1); Chris@1: countarray=calloc(bins+1,sizeof(long)); Chris@1: Chris@1: rewind(in); Chris@1: line=setup_line(in); Chris@1: while(line){ Chris@1: float code; Chris@1: lines--; Chris@1: if(!(lines&0xff))spinnit("counting distribution. lines so far...",lines); Chris@1: Chris@1: while(line && sscanf(line,"%f",&code)==1){ Chris@1: line=strchr(line,','); Chris@1: if(line)line++; Chris@1: Chris@1: code-=min; Chris@1: code/=(max-min); Chris@1: code*=bins; Chris@1: countarray[(int)rint(code)]++; Chris@1: total++; Chris@1: } Chris@1: Chris@1: line=setup_line(in); Chris@1: } Chris@1: Chris@1: /* make a pretty graph */ Chris@1: { Chris@1: long maxcount=0,i,j; Chris@1: for(i=0;imaxcount)maxcount=countarray[i]; Chris@1: Chris@1: printf("\r \r"); Chris@1: printf("Total scalars: %ld\n",total); Chris@1: for(i=0;i