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-1999 *
9 * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: build a VQ codebook
15 author: Monty <xiphmont@mit.edu>
16 modifications by: Monty
17 last modification date: Dec 09 1999
19 ********************************************************************/
21 /* This code is *not* part of libvorbis. It is used to generate
22 trained codebooks offline and then spit the results into a
23 pregenerated codebook that is compiled into libvorbis. It is an
24 expensive (but good) algorithm. Run it on big iron. */
26 /* There are so many optimizations to explore in *both* stages that
27 considering the undertaking is almost withering. For now, we brute
36 /* Codebook generation happens in two steps:
38 1) Train the codebook with data collected from the encoder: We use
39 one of a few error metrics (which represent the distance between a
40 given data point and a candidate point in the training set) to
41 divide the training set up into cells representing roughly equal
42 probability of occurring.
44 2) Generate the codebook and auxiliary data from the trained data set
47 /* Codebook training ****************************************************
49 * The basic idea here is that a VQ codebook is like an m-dimensional
50 * foam with n bubbles. The bubbles compete for space/volume and are
51 * 'pressurized' [biased] according to some metric. The basic alg
52 * iterates through allowing the bubbles to compete for space until
53 * they converge (if the damping is dome properly) on a steady-state
54 * solution. Individual input points, collected from libvorbis, are
55 * used to train the algorithm monte-carlo style. */
76 double (*metric_func) (struct vqgen *v,double *a,double *b);
79 /* internal helpers *****************************************************/
80 #define vN(data,i) (data+v->elements*i)
82 double *_point(vqgen *v,long ptr){
83 return v->pointlist+(v->elements*ptr);
86 double *_now(vqgen *v,long ptr){
87 return v->entrylist+(v->elements*ptr);
90 /* default metric; squared 'distance' from desired value. */
91 double _dist_sq(vqgen *v,double *a, double *b){
96 double val=(a[i]-b[i]);
102 /* A metric for LSP codes */
103 /* candidate,actual */
104 double _dist_and_pos(vqgen *v,double *b, double *a){
110 double actualdist=(a[i]-lastb);
111 double testdist=(b[i]-lastb);
112 if(actualdist>0 && testdist>0){
114 if(actualdist>testdist)
115 val=actualdist/testdist-1.;
117 val=testdist/actualdist-1.;
127 /* *must* be beefed up. */
128 void _vqgen_seed(vqgen *v){
129 memcpy(v->entrylist,v->pointlist,sizeof(double)*v->entries*v->elements);
132 /* External calls *******************************************************/
134 void vqgen_init(vqgen *v,int elements,int entries,
135 double (*metric)(vqgen *,double *, double *),
137 memset(v,0,sizeof(vqgen));
139 v->elements=elements;
142 v->pointlist=malloc(v->allocated*v->elements*sizeof(double));
143 v->first=malloc(v->allocated*sizeof(long));
144 v->second=malloc(v->allocated*sizeof(long));
147 v->entrylist=malloc(v->entries*v->elements*sizeof(double));
148 v->assigned=malloc(v->entries*sizeof(long));
149 v->bias=calloc(v->entries,sizeof(double));
151 v->metric_func=metric;
153 v->metric_func=_dist_and_pos;
156 void vqgen_addpoint(vqgen *v, double *p){
157 if(v->points>=v->allocated){
159 v->pointlist=realloc(v->pointlist,v->allocated*v->elements*sizeof(double));
160 v->first=realloc(v->first,v->allocated*sizeof(long));
161 v->second=realloc(v->second,v->allocated*sizeof(long));
164 memcpy(_point(v,v->points),p,sizeof(double)*v->elements);
166 if(v->points==v->entries)_vqgen_seed(v);
169 double vqgen_iterate(vqgen *v){
171 double fdesired=(double)v->points/v->entries;
172 long desired=fdesired;
175 double *new=malloc(sizeof(double)*v->entries*v->elements);
176 long *nearcount=malloc(v->entries*sizeof(long));
177 double *nearbias=malloc(v->entries*desired*sizeof(double));
184 sprintf(buff,"cells%d.m",v->it);
185 cells=fopen(buff,"w");
186 sprintf(buff,"assig%d.m",v->it);
187 assig=fopen(buff,"w");
188 sprintf(buff,"bias%d.m",v->it);
189 bias=fopen(buff,"w");
192 fprintf(stderr,"Pass #%d... ",v->it);
195 fprintf(stderr,"generation requires at least two entries\n");
199 /* fill in nearest points for entries */
200 /*memset(v->bias,0,sizeof(double)*v->entries);*/
201 memset(nearcount,0,sizeof(long)*v->entries);
202 memset(v->assigned,0,sizeof(long)*v->entries);
203 for(i=0;i<v->points;i++){
204 double *ppt=_point(v,i);
205 double firstmetric=v->metric_func(v,_now(v,0),ppt)+v->bias[0];
206 double secondmetric=v->metric_func(v,_now(v,1),ppt)+v->bias[1];
209 if(firstmetric>secondmetric){
210 double temp=firstmetric;
211 firstmetric=secondmetric;
217 for(j=2;j<v->entries;j++){
218 double thismetric=v->metric_func(v,_now(v,j),_point(v,i))+v->bias[j];
219 if(thismetric<secondmetric){
220 if(thismetric<firstmetric){
221 secondmetric=firstmetric;
222 secondentry=firstentry;
223 firstmetric=thismetric;
226 secondmetric=thismetric;
233 meterror+=firstmetric-v->bias[firstentry];
234 /* set up midpoints for next iter */
236 for(k=0;k<v->elements;k++)
237 vN(new,j)[k]+=_point(v,i)[k];
239 for(k=0;k<v->elements;k++)
240 vN(new,j)[k]=_point(v,i)[k];
244 fprintf(cells,"%g %g\n%g %g\n\n",
245 _now(v,j)[0],_now(v,j)[1],
246 _point(v,i)[0],_point(v,i)[1]);
249 for(j=0;j<v->entries;j++){
252 double *nearbiasptr=nearbias+desired*j;
253 long k=nearcount[j]-1;
255 /* 'thismetric' is to be the bias value necessary in the current
256 arrangement for entry j to capture point i */
258 /* use the secondary entry as the threshhold */
259 thismetric=secondmetric-v->metric_func(v,_now(v,j),_point(v,i));
261 /* use the primary entry as the threshhold */
262 thismetric=firstmetric-v->metric_func(v,_now(v,j),_point(v,i));
265 if(k>=0 && thismetric>nearbiasptr[k]){
267 /* start at the end and search backward for where this entry
270 for(;k>0;k--) if(nearbiasptr[k-1]>=thismetric)break;
272 /* insert at k. Shift and inject. */
273 memmove(nearbiasptr+k+1,nearbiasptr+k,(desired-k-1)*sizeof(double));
274 nearbiasptr[k]=thismetric;
276 if(nearcount[j]<desired)nearcount[j]++;
279 if(nearcount[j]<desired){
280 /* we checked the thresh earlier. We know this is the
282 nearbiasptr[nearcount[j]++]=thismetric;
288 /* inflate/deflate */
289 for(i=0;i<v->entries;i++)
290 v->bias[i]=nearbias[(i+1)*desired-1];
292 /* last, assign midpoints */
293 for(j=0;j<v->entries;j++){
294 asserror+=fabs(v->assigned[j]-fdesired);
296 for(k=0;k<v->elements;k++)
297 _now(v,j)[k]=vN(new,j)[k]/v->assigned[j];
299 fprintf(assig,"%ld\n",v->assigned[j]);
300 fprintf(bias,"%g\n",v->bias[j]);
304 fprintf(stderr,": dist %g(%g) metric error=%g \n",
305 asserror/v->entries,fdesired,meterror/v->points);
319 /* Building a codebook from trained set **********************************
321 The codebook in raw form is technically finished once it's trained.
322 However, we want to finalize the representative codebook values for
323 each entry and generate auxiliary information to optimize encoding.
324 We generate the auxiliary coding tree using collected data,
325 probably the same data as in the original training */
327 /* At each recursion, the data set is split in half. Cells with data
328 points on side A go into set A, same with set B. The sets may
329 overlap. If the cell overlaps the deviding line only very slightly
330 (provided parameter), we may choose to ignore the overlap in order
331 to pare the tree down */
333 typedef struct vqbook{
340 /* auxiliary encoding/decoding information */
344 /* auxiliary encoding information */
355 int iascsort(const void *a,const void *b){
356 double av=sortvals[*((long *)a) * els];
357 double bv=sortvals[*((long *)b) * els];
362 /* goes through the split, but just counts it and returns a metric*/
363 void lp_count(vqgen *v,long *entryindex,long entries,
364 long *pointindex,long points,
365 long *entryA,long *entryB,
366 double *n, double c, double slack,
367 long *entriesA,long *entriesB,long *entriesC){
371 memset(entryA,0,sizeof(long)*entries);
372 memset(entryB,0,sizeof(long)*entries);
374 for(i=0;i<points;i++){
375 double *ppt=_point(v,pointindex[i]);
377 double firstmetric=_dist_sq(v,_now(v,entryindex[0]),ppt);
380 for(j=1;j<entries;j++){
381 double thismetric=_dist_sq(v,_now(v,entryindex[j]),ppt);
382 if(thismetric<firstmetric){
383 firstmetric=thismetric;
388 /* count point split */
389 for(k=0;k<v->elements;k++)
390 position+=ppt[k]*n[k];
392 entryA[firstentry]++;
394 entryB[firstentry]++;
398 /* look to see if entries are in the slack zone */
399 /* The entry splitting isn't total, so that storage has to be
400 allocated for recursion. Reuse the entryA/entryB vectors */
401 for(j=0;j<entries;j++){
402 long total=entryA[j]+entryB[j];
403 if((double)entryA[j]/total<slack){
405 }else if((double)entryB[j]/total<slack){
408 if(entryA[j] && entryB[j])C++;
409 if(entryA[j])entryA[A++]=entryindex[j];
410 if(entryB[j])entryB[B++]=entryindex[j];
417 void pq_in_out(vqgen *v,double *n,double *c,double *p,double *q){
420 for(k=0;k<v->elements;k++){
421 double center=(p[k]+q[k])/2.;
422 n[k]=(center-q[k])*2.;
427 void pq_center_out(vqgen *v,double *n,double *c,double *center,double *q){
430 for(k=0;k<v->elements;k++){
431 n[k]=(center[k]-q[k])*2.;
436 int lp_split(vqgen *v,vqbook *b,
437 long *entryindex,long entries,
438 long *pointindex,long points,
439 long depth,double slack){
441 /* The encoder, regardless of book, will be using a straight
442 euclidian distance-to-point metric to determine closest point.
443 Thus we split the cells using the same (we've already trained the
444 codebook set spacing and distribution using special metrics and
445 even a midpoint division won't disturb the basic properties) */
452 long *entryA=calloc(entries,sizeof(long));
453 long *entryB=calloc(entries,sizeof(long));
460 p=alloca(sizeof(double)*v->elements);
461 q=alloca(sizeof(double)*v->elements);
462 n=alloca(sizeof(double)*v->elements);
463 memset(p,0,sizeof(double)*v->elements);
465 /* We need to find the dividing hyperplane. find the median of each
466 axis as the centerpoint and the normal facing farthest point */
468 /* more than one way to do this part. For small sets, we can brute
472 /* try every pair possibility */
477 for(i=0;i<entries-1;i++){
478 for(j=i+1;j<entries;j++){
479 pq_in_out(v,n,&c,_now(v,entryindex[i]),_now(v,entryindex[j]));
480 lp_count(v,entryindex,entries,
484 &entriesA,&entriesB,&entriesC);
485 this=(entriesA-entriesC)*(entriesB-entriesC);
494 pq_in_out(v,n,&c,_now(v,entryindex[besti]),_now(v,entryindex[bestj]));
499 /* try COG/normal and furthest pairs */
501 for(k=0;k<v->elements;k++){
502 /* just sort the index array */
503 sortvals=v->pointlist+k;
505 qsort(pointindex,points,sizeof(long),iascsort);
507 p[k]=v->pointlist[(pointindex[points/2])*v->elements+k];
509 p[k]=(v->pointlist[(pointindex[points/2])*v->elements+k]+
510 v->pointlist[(pointindex[points/2-1])*v->elements+k])/2.;
514 /* try every normal, but just for distance */
515 for(j=0;j<entries;j++){
516 double *ppj=_now(v,entryindex[j]);
517 double this=_dist_sq(v,p,ppj);
524 pq_center_out(v,n,&c,p,_point(v,pointindex[bestj]));
529 /* find cells enclosing points */
530 /* count A/B points */
532 lp_count(v,entryindex,entries,
536 &entriesA,&entriesB,&entriesC);
538 /* the point index is split evenly, so we do an Order n
539 rearrangement into A first/B last and just pass it on */
546 for(k=0;k<v->elements;k++)
547 position+=_point(v,pointindex[Aptr])[k]*n[k];
548 if(position<=0.)break; /* not in A */
553 for(k=0;k<v->elements;k++)
554 position+=_point(v,pointindex[Bptr])[k]*n[k];
555 if(position>0.)break; /* not in B */
559 long temp=pointindex[Aptr];
560 pointindex[Aptr]=pointindex[Bptr];
561 pointindex[Bptr]=temp;
567 fprintf(stderr,"split: total=%ld depth=%ld set A=%ld:%ld:%ld=B\n",
568 entries,depth,entriesA-entriesC,entriesC,entriesB-entriesC);
570 long thisaux=b->aux++;
571 if(b->aux>=b->alloc){
573 b->ptr0=realloc(b->ptr0,sizeof(long)*b->alloc);
574 b->ptr1=realloc(b->ptr1,sizeof(long)*b->alloc);
575 b->n=realloc(b->n,sizeof(double)*b->elements*b->alloc);
576 b->c=realloc(b->c,sizeof(double)*b->alloc);
579 memcpy(b->n+b->elements*thisaux,n,sizeof(double)*v->elements);
584 b->ptr0[thisaux]=entryA[0];
586 b->ptr0[thisaux]= -b->aux;
587 ret=lp_split(v,b,entryA,entriesA,pointindex,pointsA,depth+1,slack);
591 b->ptr1[thisaux]=entryB[0];
593 b->ptr1[thisaux]= -b->aux;
594 ret=lp_split(v,b,entryB,entriesB,pointindex+pointsA,points-pointsA,
603 int vqenc_entry(vqbook *b,double *val){
606 double c= -b->c[ptr];
607 double *nptr=b->n+b->elements*ptr;
608 for(k=0;k<b->elements;k++)
619 void vqgen_book(vqgen *v,vqbook *b){
621 long *entryindex=malloc(sizeof(double)*v->entries);
622 long *pointindex=malloc(sizeof(double)*v->points);
624 memset(b,0,sizeof(vqbook));
625 for(i=0;i<v->entries;i++)entryindex[i]=i;
626 for(i=0;i<v->points;i++)pointindex[i]=i;
627 b->elements=v->elements;
628 b->entries=v->entries;
630 b->ptr0=malloc(sizeof(long)*b->alloc);
631 b->ptr1=malloc(sizeof(long)*b->alloc);
632 b->n=malloc(sizeof(double)*b->elements*b->alloc);
633 b->c=malloc(sizeof(double)*b->alloc);
635 b->valuelist=malloc(sizeof(double)*b->elements*b->entries);
636 b->codelist=malloc(sizeof(long)*b->entries);
637 b->lengthlist=malloc(b->entries*sizeof(long));
639 /* first, generate the encoding decision heirarchy */
640 lp_split(v,b,entryindex,v->entries, pointindex,v->points,0,0);
642 /* run all training points through the decision tree to get a final
645 long *probability=calloc(b->entries*2,sizeof(long));
646 for(i=0;i<v->points;i++){
647 int ret=vqenc_entry(b,v->pointlist+i*v->elements);
651 for(i=0;i<b->entries;i++){
652 fprintf(stderr,"point %ld: %ld\n",i,probability[i]);
657 /* generate the codewords (short to long) */
663 static double testset24[48]={
667 static double testset256[1024]={
668 0.334427,0.567149,0.749324,0.838460,
669 0.212558,0.435792,0.661945,0.781195,
670 0.316791,0.551190,0.700236,0.813437,
671 0.240661,0.398754,0.570649,0.666909,
672 0.233216,0.549751,0.715668,0.844393,
673 0.275589,0.460791,0.687872,0.786855,
674 0.145195,0.478688,0.678451,0.788536,
675 0.332491,0.577111,0.770913,0.875295,
676 0.162683,0.250422,0.399770,0.688120,
677 0.301578,0.424074,0.595725,0.829533,
678 0.118704,0.276233,0.492329,0.605532,
679 0.240679,0.468862,0.670704,0.809156,
680 0.109799,0.227123,0.533265,0.686982,
681 0.119657,0.423823,0.597676,0.710405,
682 0.207444,0.437121,0.671331,0.809054,
683 0.222787,0.324523,0.466905,0.652758,
684 0.117279,0.268017,0.410036,0.593785,
685 0.316531,0.493867,0.642588,0.815791,
686 0.218069,0.315630,0.554662,0.749348,
687 0.152218,0.412864,0.664135,0.814275,
688 0.144242,0.221503,0.457281,0.631403,
689 0.290454,0.458806,0.603994,0.751802,
690 0.236719,0.341259,0.586677,0.707653,
691 0.257617,0.406941,0.602074,0.696609,
692 0.141833,0.254061,0.523788,0.701270,
693 0.136685,0.333920,0.515585,0.642137,
694 0.191560,0.485163,0.665121,0.755073,
695 0.086062,0.375207,0.623168,0.763659,
696 0.184017,0.404999,0.609708,0.746118,
697 0.208200,0.414804,0.618734,0.732746,
698 0.184643,0.390701,0.666137,0.791445,
699 0.216594,0.519656,0.713291,0.810097,
700 0.118095,0.361088,0.577184,0.667553,
701 0.243858,0.394640,0.550682,0.774866,
702 0.266410,0.430656,0.629812,0.729035,
703 0.140187,0.323258,0.534031,0.762617,
704 0.097902,0.230404,0.382920,0.707036,
705 0.197244,0.424752,0.578097,0.741857,
706 0.216830,0.460883,0.622823,0.747350,
707 0.096586,0.252731,0.471721,0.766199,
708 0.385920,0.650477,0.846797,0.972222,
709 0.249895,0.442701,0.706660,0.824760,
710 0.207781,0.355197,0.538083,0.686972,
711 0.166064,0.261252,0.493243,0.642141,
712 0.146441,0.385197,0.595104,0.739789,
713 0.207555,0.311523,0.533963,0.666395,
714 0.172735,0.455702,0.624525,0.713503,
715 0.132351,0.420175,0.528877,0.716175,
716 0.113027,0.270164,0.462866,0.653668,
717 0.306970,0.575262,0.785717,0.942889,
718 0.122649,0.451363,0.652393,0.749624,
719 0.337459,0.561671,0.713605,0.878091,
720 0.154890,0.324078,0.469466,0.677888,
721 0.242478,0.420602,0.651274,0.762209,
722 0.162266,0.401114,0.639885,0.769255,
723 0.275493,0.500799,0.753756,0.884563,
724 0.219840,0.410217,0.634590,0.784979,
725 0.197822,0.418074,0.514919,0.784821,
726 0.176855,0.327821,0.624861,0.768299,
727 0.187133,0.373303,0.614062,0.764326,
728 0.148866,0.339151,0.571398,0.693017,
729 0.126516,0.364169,0.643363,0.784478,
730 0.176790,0.354609,0.553963,0.728466,
731 0.169151,0.294951,0.559738,0.718315,
732 0.189233,0.369137,0.615112,0.736337,
733 0.211442,0.459206,0.587994,0.715496,
734 0.203544,0.332755,0.496152,0.707495,
735 0.264950,0.377661,0.601633,0.738910,
736 0.144156,0.332387,0.533986,0.858065,
737 0.236705,0.493254,0.646422,0.780372,
738 0.247066,0.480770,0.725958,0.847099,
739 0.121273,0.415837,0.575449,0.785059,
740 0.109050,0.326623,0.585313,0.725416,
741 0.079853,0.281243,0.579608,0.721251,
742 0.164131,0.452931,0.608512,0.772505,
743 0.183958,0.382443,0.595812,0.708979,
744 0.232813,0.460979,0.612592,0.785098,
745 0.372632,0.625661,0.794886,0.915078,
746 0.197199,0.422499,0.630676,0.764479,
747 0.112259,0.228495,0.423574,0.529402,
748 0.313775,0.495449,0.684949,0.906438,
749 0.121923,0.272895,0.590304,0.762871,
750 0.114215,0.298370,0.523344,0.690963,
751 0.195814,0.446435,0.567172,0.888808,
752 0.292057,0.491911,0.707296,0.836253,
753 0.198244,0.410661,0.555814,0.699832,
754 0.152291,0.332174,0.609291,0.732500,
755 0.051002,0.303083,0.609333,0.769208,
756 0.086086,0.233029,0.475899,0.590504,
757 0.096449,0.366927,0.502638,0.761407,
758 0.256632,0.423960,0.650693,0.805566,
759 0.235739,0.542293,0.776812,0.939851,
760 0.210050,0.310752,0.439640,0.760752,
761 0.168588,0.352547,0.620034,0.811813,
762 0.217251,0.438798,0.704758,0.854804,
763 0.112327,0.304063,0.583490,0.813809,
764 0.183413,0.263207,0.503397,0.753610,
765 0.241265,0.367568,0.648774,0.795899,
766 0.262796,0.558878,0.784660,0.908486,
767 0.221425,0.479136,0.683794,0.830981,
768 0.325039,0.573201,0.837740,0.994924,
769 0.263655,0.636322,0.878818,1.052555,
770 0.228884,0.510746,0.742781,0.903443,
771 0.169799,0.354550,0.667261,0.880659,
772 0.429209,0.689908,0.942083,1.075538,
773 0.178843,0.393247,0.698620,0.846058,
774 0.410735,0.684575,0.900212,1.026610,
775 0.212082,0.407634,0.677794,0.824167,
776 0.183638,0.456984,0.701680,0.828091,
777 0.198668,0.290621,0.586525,0.796566,
778 0.212584,0.394786,0.624992,0.756258,
779 0.218545,0.327989,0.671635,0.851695,
780 0.118076,0.487280,0.758482,0.920421,
781 0.184608,0.426118,0.642211,0.797123,
782 0.248725,0.534657,0.737666,0.869414,
783 0.075312,0.218113,0.574791,0.767607,
784 0.184571,0.487955,0.742725,0.865892,
785 0.148818,0.284078,0.481156,0.816008,
786 0.205061,0.336518,0.506794,0.610053,
787 0.054274,0.238425,0.414471,0.577301,
788 0.082819,0.289140,0.632090,0.789039,
789 0.095066,0.249569,0.666867,0.857491,
790 0.129159,0.215969,0.524985,0.808056,
791 0.120949,0.473613,0.723959,0.844274,
792 0.225445,0.469240,0.781258,0.937501,
793 0.190737,0.487420,0.664112,0.798043,
794 0.249655,0.533041,0.808386,0.984218,
795 0.236544,0.473767,0.723955,0.872327,
796 0.093351,0.432384,0.672316,0.803956,
797 0.171295,0.491945,0.662536,0.844976,
798 0.165080,0.389674,0.533508,0.664579,
799 0.224994,0.356513,0.535555,0.640525,
800 0.158366,0.244279,0.437682,0.579242,
801 0.267249,0.423934,0.542629,0.635151,
802 0.105840,0.183727,0.395015,0.546705,
803 0.128701,0.214397,0.323019,0.569708,
804 0.205691,0.367797,0.491331,0.579727,
805 0.136376,0.295543,0.461283,0.567165,
806 0.090912,0.326863,0.449785,0.549052,
807 0.280052,0.463123,0.590556,0.676314,
808 0.053220,0.327610,0.496921,0.611028,
809 0.074906,0.374797,0.563476,0.691693,
810 0.064942,0.286131,0.414479,0.492806,
811 0.303210,0.504309,0.652008,0.744313,
812 0.322904,0.532050,0.682097,0.777012,
813 0.247437,0.397965,0.504882,0.680784,
814 0.076782,0.185773,0.355825,0.478750,
815 0.170565,0.428925,0.587157,0.683893,
816 0.186692,0.282933,0.468043,0.583405,
817 0.286847,0.489852,0.626934,0.714018,
818 0.196398,0.333200,0.447551,0.551070,
819 0.061757,0.242351,0.503337,0.676114,
820 0.119199,0.359308,0.514024,0.595332,
821 0.282369,0.428107,0.549797,0.721344,
822 0.120772,0.328758,0.465806,0.797635,
823 0.251676,0.385411,0.692374,0.930173,
824 0.265590,0.605988,0.828534,0.964088,
825 0.118910,0.347784,0.690580,0.839342,
826 0.148664,0.429126,0.564376,0.640949,
827 0.273239,0.395545,0.492952,0.803872,
828 0.085855,0.175468,0.449037,0.649337,
829 0.101341,0.351796,0.455442,0.645061,
830 0.181516,0.301506,0.381633,0.628656,
831 0.165340,0.385706,0.549717,0.787060,
832 0.102530,0.247439,0.362454,0.570843,
833 0.115626,0.291845,0.411639,0.730918,
834 0.130168,0.402586,0.531264,0.842151,
835 0.312057,0.497535,0.608141,0.933018,
836 0.061317,0.329143,0.457434,0.717368,
837 0.260419,0.364385,0.522931,0.733634,
838 0.287346,0.448695,0.703337,0.864549,
839 0.158190,0.329088,0.444748,0.609073,
840 0.057217,0.172765,0.500069,0.763990,
841 0.185582,0.346521,0.426838,0.724792,
842 0.152203,0.253061,0.580445,0.835384,
843 0.223681,0.376501,0.463553,0.758668,
844 0.153621,0.385013,0.482490,0.723052,
845 0.165862,0.300622,0.515314,0.628741,
846 0.087543,0.300967,0.529657,0.641654,
847 0.257693,0.367954,0.453859,0.654989,
848 0.077763,0.391224,0.586210,0.846828,
849 0.140653,0.296311,0.431419,0.524173,
850 0.276106,0.566792,0.723587,0.928366,
851 0.345768,0.530982,0.711197,1.011075,
852 0.328643,0.578965,0.775015,1.036448,
853 0.295489,0.451392,0.541007,0.831967,
854 0.249971,0.517649,0.662078,0.872210,
855 0.171802,0.382312,0.492482,0.629808,
856 0.192277,0.478000,0.611564,0.846436,
857 0.217769,0.335272,0.508986,0.813008,
858 0.265875,0.429911,0.625892,0.958544,
859 0.183329,0.299421,0.565539,0.885282,
860 0.311307,0.432098,0.756371,0.937483,
861 0.153908,0.264165,0.391052,0.502304,
862 0.267528,0.476930,0.862271,1.099421,
863 0.221527,0.513611,0.684819,0.993058,
864 0.220330,0.352263,0.575808,0.823017,
865 0.084526,0.372939,0.705268,0.879314,
866 0.179752,0.287765,0.507176,0.683204,
867 0.234005,0.381653,0.537092,0.887657,
868 0.068805,0.135538,0.363455,0.732055,
869 0.266267,0.440971,0.719076,1.025917,
870 0.169728,0.426510,0.670186,0.982939,
871 0.248443,0.463944,0.736167,0.898651,
872 0.074789,0.155652,0.601987,0.864470,
873 0.394203,0.665959,0.950879,1.183016,
874 0.056927,0.247163,0.620166,0.886961,
875 0.081110,0.260015,0.725344,0.969987,
876 0.187566,0.605658,0.907862,1.113592,
877 0.188174,0.417467,0.746757,0.912718,
878 0.214944,0.444902,0.813762,1.006999,
879 0.177305,0.322288,0.623538,0.972940,
880 0.108933,0.560083,0.892489,1.105198,
881 0.326010,0.486890,0.808596,1.012135,
882 0.507702,0.815903,1.085892,1.267201,
883 0.121027,0.368451,0.715029,1.000456,
884 0.424229,0.713942,0.971720,1.123569,
885 0.158148,0.411905,0.812352,1.057000,
886 0.330896,0.639677,0.814721,1.083593,
887 0.116143,0.314050,0.643242,0.928001,
888 0.228088,0.364437,0.747642,1.045211,
889 0.457076,0.783579,1.021362,1.174221,
890 0.069613,0.430727,0.845847,1.061835,
891 0.343281,0.553869,0.865545,1.077270,
892 0.152973,0.304560,0.642854,0.830441,
893 0.157602,0.568564,0.815800,1.036183,
894 0.104003,0.505075,0.796932,0.999392,
895 0.377220,0.622243,0.901761,1.072988,
896 0.060039,0.378222,0.710910,0.939836,
897 0.220206,0.539490,0.849893,1.056103,
898 0.116884,0.454544,0.627779,0.924877,
899 0.293087,0.633251,0.927781,1.114120,
900 0.234659,0.458666,0.693916,0.925308,
901 0.271802,0.385786,0.661508,0.862002,
902 0.185212,0.282842,0.431237,0.663853,
903 0.152441,0.280173,0.711942,0.961418,
904 0.264191,0.647776,0.976337,1.171963,
905 0.227340,0.567363,0.753334,1.049249,
906 0.173306,0.508941,0.761828,0.970236,
907 0.271942,0.496903,0.759621,0.963074,
908 0.187050,0.355811,0.752185,0.952287,
909 0.172003,0.363447,0.486011,0.829142,
910 0.364755,0.598200,0.868222,1.025048,
911 0.226504,0.432744,0.649002,0.852690,
912 0.200857,0.436929,0.651778,0.905448,
913 0.137860,0.385245,0.609566,0.867573,
914 0.217881,0.368030,0.601419,0.954770,
915 0.199237,0.398640,0.593487,0.830535,
916 0.324623,0.518989,0.782275,0.926822,
917 0.245185,0.419081,0.717432,0.883462,
918 0.277741,0.494080,0.765001,0.915227,
919 0.200418,0.463680,0.705028,0.875441,
920 0.171638,0.526057,0.697163,0.915452,
921 0.142351,0.416539,0.707280,0.876499,
922 0.178309,0.553184,0.777786,0.903243,
923 0.335361,0.540299,0.812589,0.965039,
928 int main(int argc,char *argv[]){
929 FILE *in=fopen(argv[1],"r");
935 vqgen_init(&v,4,256,_dist_and_pos,0.);
937 while(fgets(buffer,160,in)){
939 if(sscanf(buffer,"%lf %lf %lf %lf",
941 vqgen_addpoint(&v,a);
945 /*for(i=0;i<200;i++){
949 for(i=0;i<v.entries;i++){
951 for(j=0;j<v.elements;j++)
952 printf("%f,",_now(&v,i)[j]);
959 memcpy(v.entrylist,testset256,sizeof(testset256));