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