polylib: vector.c Source File

- Main Page
- Classes
- Files

# vector.c

Go to the documentation of this file.

    00001 /* vector.c
    00002           COPYRIGHT
    00003           Both this software and its documentation are
    00004
    00005               Copyrighted 1993 by IRISA /Universite de Rennes I - France,
    00006               Copyright 1995,1996 by BYU, Provo, Utah
    00007                          all rights reserved.
    00008
    00009           Permission is granted to copy, use, and distribute
    00010           for any commercial or noncommercial purpose under the terms
    00011           of the GNU General Public license, version 2, June 1991
    00012           (see file : LICENSING).
    00013 */
    00014
    00015 #include <stdio.h>
    00016 #include <stdlib.h>
    00017 #include <polylib/polylib.h>
    00018
    00019 #ifdef MAC_OS
    00020   #define abs __abs
    00021 #endif
    00022
    00023 /*
    00024  * Compute n!
    00025  */
    00026 void Factorial(int n, Value *fact) {
    00027
    00028   int i;
    00029   Value tmp;
    00030
    00031   value_init(tmp);
    00032
    00033   value_set_si(*fact,1);
    00034   for (i=1;i<=n;i++) {
    00035     value_set_si(tmp,i);
    00036     value_multiply(*fact,*fact,tmp);
    00037   }
    00038   value_clear(tmp);
    00039 } /* Factorial */
    00040
    00041 /*
    00042  * Compute n!/(p!(n-p)!)
    00043  */
    00044 void Binomial(int n, int p, Value *result) {
    00045
    00046   int i;
    00047   Value tmp;
    00048   Value f;
    00049
    00050   value_init(tmp);value_init(f);
    00051
    00052   if (n-p<p)
    00053     p=n-p;
    00054   if (p!=0) {
    00055     value_set_si(*result,(n-p+1));
    00056     for (i=n-p+2;i<=n;i++) {
    00057       value_set_si(tmp,i);
    00058       value_multiply(*result,*result,tmp);
    00059     }
    00060     Factorial(p,&f);
    00061     value_division(*result,*result,f);
    00062   }
    00063   else
    00064     value_set_si(*result,1);
    00065   value_clear(f);value_clear(tmp);
    00066 } /* Binomial */
    00067
    00068 /*
    00069  * Return the number of ways to choose 'b' items from 'a' items, that is,
    00070  * return a!/(b!(a-b)!)
    00071  */
    00072 void CNP(int a,int b, Value *result) {
    00073
    00074   int i;
    00075   Value tmp;
    00076   value_init(tmp);
    00077
    00078   value_set_si(*result,1);
    00079
    00080   /* If number of items is less than the number to be choosen, return 1 */
    00081   if(a <= b) {
    00082     value_clear(tmp);
    00083     return;
    00084   }
    00085   for(i=a;i>b;--i) {
    00086     value_set_si(tmp,i);
    00087     value_multiply(*result,*result,tmp);
    00088   }
    00089   for(i=1;i<=(a-b);++i) {
    00090     value_set_si(tmp,i);
    00091     value_division(*result,*result,tmp);
    00092   }
    00093   value_clear(tmp);
    00094 } /* CNP */
    00095
    00096 /*
    00097  * Compute GCD of 'a' and 'b'
    00098  */
    00099 void Gcd(Value a,Value b,Value *result) {
    00100
    00101   Value acopy, bcopy;
    00102
    00103   value_init(acopy);
    00104   value_init(bcopy);
    00105   value_assign(acopy,a);
    00106   value_assign(bcopy,b);
    00107   while(value_notzero_p(acopy)) {
    00108     value_modulus(*result,bcopy,acopy);
    00109     value_assign(bcopy,acopy);
    00110     value_assign(acopy,*result);
    00111   }
    00112   value_absolute(*result,bcopy);
    00113   value_clear(acopy);
    00114   value_clear(bcopy);
    00115 } /* Gcd */
    00116
    00117 /*
    00118  * Return the smallest component index in 'p' whose value is non-zero
    00119  */
    00120 int First_Non_Zero(Value *p,unsigned length) {
    00121
    00122   Value *cp;
    00123   int i;
    00124
    00125   cp = p;
    00126   for (i=0;i<length;i++) {
    00127     if (value_notzero_p(*cp))
    00128       break;
    00129     cp++;
    00130   }
    00131   return((i==length) ? -1 : i );
    00132 } /* First_Non_Zero */
    00133
    00134 /*
    00135  * Allocate memory space for Vector
    00136  */
    00137 Vector *Vector_Alloc(unsigned length) {
    00138
    00139   int i;
    00140   Vector *vector;
    00141
    00142   vector = (Vector *)malloc(sizeof(Vector));
    00143   if (!vector) {
    00144     errormsg1("Vector_Alloc", "outofmem", "out of memory space");
    00145     return 0;
    00146   }
    00147   vector->Size=length;
    00148   vector->p=(Value *)malloc(length * sizeof(Value));
    00149   if (!vector->p) {
    00150     errormsg1("Vector_Alloc", "outofmem", "out of memory space");
    00151     free(vector);
    00152     return 0;
    00153   }
    00154   for(i=0;i<length;i++)
    00155     value_init(vector->p[i]);
    00156   return vector;
    00157 } /* Vector_Alloc */
    00158
    00159 /*
    00160  * Free the memory space occupied by Vector
    00161  */
    00162 void Vector_Free(Vector *vector) {
    00163
    00164   int i;
    00165
    00166   if (!vector) return;
    00167   for(i=0;i<vector->Size;i++)
    00168     value_clear(vector->p[i]);
    00169   free(vector->p);
    00170   free(vector);
    00171 } /* Vector_Free */
    00172
    00173 /*
    00174  * Print the contents of a Vector
    00175  */
    00176 void Vector_Print(FILE *Dst, const char *Format, Vector *vector)
    00177 {
    00178   int i;
    00179   Value *p;
    00180   unsigned length;
    00181
    00182   fprintf(Dst, "%d\n", length=vector->Size);
    00183   p = vector->p;
    00184   for (i=0;i<length;i++) {
    00185     if (Format) {
    00186       value_print(Dst,Format,*p++);
    00187     }
    00188     else {
    00189       value_print(Dst,P_VALUE_FMT,*p++);
    00190     }
    00191   }
    00192   fprintf(Dst, "\n");
    00193 } /* Vector_Print */
    00194
    00195 /*
    00196  * Read the contents of a Vector
    00197  */
    00198 Vector *Vector_Read() {
    00199
    00200   Vector *vector;
    00201   unsigned length;
    00202   int i;
    00203   char str[1024];
    00204   Value *p;
    00205
    00206   scanf("%d", &length);
    00207   vector = Vector_Alloc(length);
    00208   if (!vector) {
    00209     errormsg1("Vector_Read", "outofmem", "out of memory space");
    00210     return 0;
    00211   }
    00212   p = vector->p;
    00213   for (i=0;i<length;i++) {
    00214     scanf("%s",str);
    00215     value_read(*(p++),str);
    00216   }
    00217   return vector;
    00218 } /* Vector_Read */
    00219
    00220 /*
    00221  * Assign 'n' to each component of Vector 'p'
    00222  */
    00223 void Vector_Set(Value *p,int n,unsigned length) {
    00224
    00225   Value *cp;
    00226   int i;
    00227
    00228   cp = p;
    00229   for (i=0;i<length;i++) {
    00230     value_set_si(*cp,n);
    00231     cp++;
    00232   }
    00233   return;
    00234 } /* Vector_Set */
    00235
    00236 /*
    00237  * Exchange the components of the vectors 'p1' and 'p2' of length 'length'
    00238  */
    00239 void Vector_Exchange(Value *p1, Value *p2, unsigned length) {
    00240
    00241   int i;
    00242
    00243   for(i=0;i<length;i++) {
    00244     value_swap(p1[i],p2[i]);
    00245   }
    00246   return;
    00247 }
    00248
    00249 /*
    00250  * Copy Vector 'p1' to Vector 'p2'
    00251  */
    00252 void Vector_Copy(Value *p1,Value *p2,unsigned length) {
    00253
    00254   int i;
    00255   Value *cp1, *cp2;
    00256
    00257   cp1 = p1;
    00258   cp2 = p2;
    00259
    00260   for(i=0;i<length;i++)
    00261     value_assign(*cp2++,*cp1++);
    00262
    00263   return;
    00264 }
    00265
    00266 /*
    00267  * Add two vectors 'p1' and 'p2' and store the result in 'p3'
    00268  */
    00269 void Vector_Add(Value *p1,Value *p2,Value *p3,unsigned length) {
    00270
    00271   Value *cp1, *cp2, *cp3;
    00272   int i;
    00273
    00274   cp1=p1;
    00275   cp2=p2;
    00276   cp3=p3;
    00277   for (i=0;i<length;i++) {
    00278
    00279     /* *cp3++ = *cp1++ + *cp2++ */
    00280     value_addto(*cp3,*cp1,*cp2);
    00281     cp1++; cp2++; cp3++;
    00282   }
    00283 } /* Vector_Add */
    00284
    00285 /*
    00286  * Subtract two vectors 'p1' and 'p2' and store the result in 'p3'
    00287  */
    00288 void Vector_Sub(Value *p1,Value *p2,Value *p3,unsigned length) {
    00289
    00290   Value *cp1, *cp2, *cp3;
    00291   int i;
    00292
    00293   cp1=p1;
    00294   cp2=p2;
    00295   cp3=p3;
    00296   for (i=0;i<length;i++) {
    00297
    00298     /* *cp3++= *cp1++ - *cp2++ */
    00299     value_subtract(*cp3,*cp1,*cp2);
    00300     cp1++; cp2++; cp3++;
    00301   }
    00302 } /* Vector_Sub */
    00303
    00304 /*
    00305  * Compute Bitwise OR of Vectors 'p1' and 'p2' and store in 'p3'
    00306  */
    00307 void Vector_Or(Value *p1,Value *p2,Value *p3,unsigned length) {
    00308
    00309   Value *cp1, *cp2, *cp3;
    00310   int i;
    00311
    00312   cp1=p1;
    00313   cp2=p2;
    00314   cp3=p3;
    00315   for (i=0;i<length;i++) {
    00316
    00317     /* *cp3++=*cp1++ | *cp2++ */
    00318     value_orto(*cp3,*cp1,*cp2);
    00319     cp1++; cp2++; cp3++;
    00320   }
    00321 } /* Vector_Or */
    00322
    00323 /*
    00324  * Scale Vector 'p1' lambda times and store in 'p2'
    00325  */
    00326 void Vector_Scale(Value *p1,Value *p2,Value lambda,unsigned length) {
    00327
    00328   Value *cp1, *cp2;
    00329   int i;
    00330
    00331   cp1=p1;
    00332   cp2=p2;
    00333   for (i=0;i<length;i++) {
    00334
    00335     /* *cp2++=*cp1++ * lambda */
    00336     value_multiply(*cp2,*cp1,lambda);
    00337     cp1++; cp2++;
    00338   }
    00339 } /* Vector_Scale */
    00340
    00341 /*
    00342  * Antiscale Vector 'p1' by lambda and store in 'p2'
    00343  * Assumes all elements of 'p1' are divisble by lambda.
    00344  */
    00345 void Vector_AntiScale(Value *p1, Value *p2, Value lambda, unsigned length)
    00346 {
    00347   int i;
    00348
    00349   for (i = 0; i < length; i++)
    00350     value_divexact(p2[i], p1[i], lambda);
    00351 } /* Vector_AntiScale */
    00352
    00353 /*
    00354  * Puts negative of 'p1' in 'p2'
    00355  */
    00356 void Vector_Oppose(Value *p1, Value *p2, unsigned len)
    00357 {
    00358   unsigned i;
    00359
    00360   for (i = 0; i < len; ++i)
    00361     value_oppose(p2[i], p1[i]);
    00362 }
    00363
    00364 /*
    00365  * Return the inner product of the two Vectors 'p1' and 'p2'
    00366  */
    00367 void Inner_Product(Value *p1, Value *p2, unsigned length, Value *ip)
    00368 {
    00369   int i;
    00370
    00371   if (length != 0)
    00372     value_multiply(*ip, p1[0], p2[0]);
    00373   else
    00374     value_set_si(*ip, 0);
    00375   for(i = 1; i < length; i++)
    00376     value_addmul(*ip, p1[i], p2[i]);
    00377 } /* Inner_Product */
    00378
    00379 /*
    00380  * Return the maximum of the components of 'p'
    00381  */
    00382 void Vector_Max(Value *p,unsigned length, Value *max) {
    00383
    00384   Value *cp;
    00385   int i;
    00386
    00387   cp=p;
    00388   value_assign(*max,*cp);
    00389   cp++;
    00390   for (i=1;i<length;i++) {
    00391     value_maximum(*max,*max,*cp);
    00392     cp++;
    00393   }
    00394 } /* Vector_Max */
    00395
    00396 /*
    00397  * Return the minimum of the components of Vector 'p'
    00398  */
    00399 void Vector_Min(Value *p,unsigned length,Value *min) {
    00400
    00401   Value *cp;
    00402   int i;
    00403
    00404   cp=p;
    00405   value_assign(*min,*cp);
    00406   cp++;
    00407   for (i=1;i<length;i++) {
    00408     value_minimum(*min,*min,*cp);
    00409     cp++;
    00410   }
    00411   return;
    00412 } /* Vector_Min */
    00413
    00414 /*
    00415  * Given Vectors 'p1' and 'p2', return Vector 'p3' = lambda * p1 + mu * p2.
    00416  */
    00417 void Vector_Combine(Value *p1, Value *p2, Value *p3, Value lambda, Value mu,
    00418                     unsigned length)
    00419 {
    00420   Value tmp;
    00421   int i;
    00422
    00423   value_init(tmp);
    00424   for (i = 0; i < length; i++) {
    00425     value_multiply(tmp, lambda, p1[i]);
    00426     value_addmul(tmp, mu, p2[i]);
    00427     value_assign(p3[i], tmp);
    00428   }
    00429   value_clear(tmp);
    00430   return;
    00431 } /* Vector_Combine */
    00432
    00433 /*
    00434  * Return 1 if 'Vec1' equals 'Vec2', otherwise return 0
    00435  */
    00436 int Vector_Equal(Value *Vec1, Value *Vec2, unsigned n)
    00437 {
    00438   int i;
    00439
    00440   for (i = 0; i < n; ++i)
    00441     if (value_ne(Vec1[i], Vec2[i]))
    00442       return 0;
    00443
    00444   return 1;
    00445 } /* Vector_Equal */
    00446
    00447 /*
    00448  * Return the component of 'p' with minimum non-zero absolute value. 'index'
    00449  * points to the component index that has the minimum value. If no such value
    00450  * and index is found, Value 1 is returned.
    00451  */
    00452 void Vector_Min_Not_Zero(Value *p,unsigned length,int *index,Value *min)
    00453 {
    00454   Value aux;
    00455   int i;
    00456
    00457
    00458   i = First_Non_Zero(p, length);
    00459   if (i == -1) {
    00460     value_set_si(*min,1);
    00461     return;
    00462   }
    00463   *index = i;
    00464   value_absolute(*min, p[i]);
    00465   value_init(aux);
    00466   for (i = i+1; i < length; i++) {
    00467     if (value_zero_p(p[i]))
    00468       continue;
    00469     value_absolute(aux, p[i]);
    00470     if (value_lt(aux,*min)) {
    00471       value_assign(*min,aux);
    00472       *index = i;
    00473     }
    00474   }
    00475   value_clear(aux);
    00476 } /* Vector_Min_Not_Zero */
    00477
    00478 /*
    00479  * Return the GCD of components of Vector 'p'
    00480  */
    00481 void Vector_Gcd(Value *p,unsigned length,Value *min) {
    00482
    00483   Value *q,*cq, *cp;
    00484   int i, Not_Zero, Index_Min=0;
    00485
    00486   q  = (Value *)malloc(length*sizeof(Value));
    00487
    00488   /* Initialize all the 'Value' variables */
    00489   for(i=0;i<length;i++)
    00490     value_init(q[i]);
    00491
    00492   /* 'cp' points to vector 'p' and cq points to vector 'q' that holds the */
    00493   /* absolute value of elements of vector 'p'.                            */
    00494   cp=p;
    00495   for (cq = q,i=0;i<length;i++) {
    00496     value_absolute(*cq,*cp);
    00497     cq++;
    00498     cp++;
    00499   }
    00500   do {
    00501     Vector_Min_Not_Zero(q,length,&Index_Min,min);
    00502
    00503     /* if (*min != 1) */
    00504     if (value_notone_p(*min)) {
    00505
    00506       cq=q;
    00507       Not_Zero=0;
    00508       for (i=0;i<length;i++,cq++)
    00509         if (i!=Index_Min) {
    00510
    00511           /* Not_Zero |= (*cq %= *min) */
    00512           value_modulus(*cq,*cq,*min);
    00513           Not_Zero |= value_notzero_p(*cq);
    00514         }
    00515     }
    00516     else
    00517       break;
    00518   } while (Not_Zero);
    00519
    00520   /* Clear all the 'Value' variables */
    00521   for(i=0;i<length;i++)
    00522     value_clear(q[i]);
    00523   free(q);
    00524 } /* Vector_Gcd */
    00525
    00526 /*
    00527  * Given vectors 'p1', 'p2', and a pointer to a function returning 'Value type,
    00528  * compute p3[i] = f(p1[i],p2[i]).
    00529  */
    00530 void Vector_Map(Value *p1,Value *p2,Value *p3,unsigned length,
    00531                 Value *(*f)(Value,Value))
    00532 {
    00533   Value *cp1, *cp2, *cp3;
    00534   int i;
    00535
    00536   cp1=p1;
    00537   cp2=p2;
    00538   cp3=p3;
    00539   for(i=0;i<length;i++) {
    00540     value_assign(*cp3,*(*f)(*cp1, *cp2));
    00541     cp1++; cp2++; cp3++;
    00542   }
    00543   return;
    00544 } /* Vector_Map */
    00545
    00546 /*
    00547  * Reduce a vector by dividing it by GCD. There is no restriction on
    00548  * components of Vector 'p'. Making the last element positive is *not* OK
    00549  * for equalities.
    00550  */
    00551 void Vector_Normalize(Value *p,unsigned length) {
    00552
    00553   Value gcd;
    00554   int i;
    00555
    00556   value_init(gcd);
    00557
    00558   Vector_Gcd(p,length,&gcd);
    00559
    00560   if (value_notone_p(gcd))
    00561     Vector_AntiScale(p, p, gcd, length);
    00562
    00563   value_clear(gcd);
    00564 } /* Vector_Normalize */
    00565
    00566 /*
    00567  * Reduce a vector by dividing it by GCD and making sure its pos-th
    00568  * element is positive.
    00569  */
    00570 void Vector_Normalize_Positive(Value *p,int length,int pos) {
    00571
    00572   Value gcd;
    00573   int i;
    00574
    00575   value_init(gcd);
    00576   Vector_Gcd(p,length,&gcd);
    00577   if (value_neg_p(p[pos]))
    00578     value_oppose(gcd,gcd);
    00579   if(value_notone_p(gcd))
    00580     Vector_AntiScale(p, p, gcd, length);
    00581   value_clear(gcd);
    00582 } /* Vector_Normalize_Positive */
    00583
    00584 /*
    00585  * Reduce 'p' by operating binary function on its components successively
    00586  */
    00587 void Vector_Reduce(Value *p,unsigned length,void(*f)(Value,Value *),Value *r) {
    00588
    00589   Value *cp;
    00590   int i;
    00591
    00592   cp = p;
    00593   value_assign(*r,*cp);
    00594   for(i=1;i<length;i++) {
    00595     cp++;
    00596     (*f)(*cp,r);
    00597   }
    00598 } /* Vector_Reduce */
    00599
    00600 /*
    00601  * Sort the components of a Vector 'vector' using Heap Sort.
    00602  */
    00603 void Vector_Sort(Value *vector,unsigned n) {
    00604
    00605   int i, j;
    00606   Value temp;
    00607   Value *current_node=(Value *)0;
    00608   Value *left_son,*right_son;
    00609
    00610   value_init(temp);
    00611
    00612   for (i=(n-1)/2;i>=0;i--) {
    00613
    00614     /* Phase 1 : build the heap */
    00615     j=i;
    00616     value_assign(temp,*(vector+i));
    00617
    00618     /* While not a leaf */
    00619     while (j<=(n-1)/2) {
    00620       current_node = vector+j;
    00621       left_son = vector+(j<<1)+1;
    00622
    00623       /* If only one son */
    00624       if ((j<<1)+2>=n) {
    00625         if (value_lt(temp,*left_son)) {
    00626           value_assign(*current_node,*left_son);
    00627           j=(j<<1)+1;
    00628         }
    00629         else
    00630           break;
    00631       }
    00632       else {
    00633
    00634         /* If two sons */
    00635         right_son=left_son+1;
    00636         if (value_lt(*right_son,*left_son)) {
    00637           if (value_lt(temp,*left_son)) {
    00638             value_assign(*current_node,*left_son);
    00639             j=(j<<1)+1;
    00640           }
    00641           else
    00642             break;
    00643         }
    00644         else {
    00645           if (value_lt(temp,*right_son)) {
    00646             value_assign(*current_node,*right_son );
    00647             j=(j<<1)+2;
    00648           }
    00649           else
    00650             break;
    00651         }
    00652       }
    00653     }
    00654     value_assign(*current_node,temp);
    00655   }
    00656   for(i=n-1;i>0;i--) {
    00657
    00658     /* Phase 2 : sort the heap */
    00659     value_assign(temp, *(vector+i));
    00660     value_assign(*(vector+i),*vector);
    00661     j=0;
    00662
    00663     /* While not a leaf */
    00664     while (j<i/2) {
    00665       current_node=vector+j;
    00666       left_son=vector+(j<<1)+1;
    00667
    00668       /* If only one son */
    00669       if ((j<<1)+2>=i) {
    00670         if (value_lt(temp,*left_son)) {
    00671           value_assign(*current_node,*left_son);
    00672           j=(j<<1)+1;
    00673         }
    00674         else
    00675           break;
    00676       }
    00677       else {
    00678
    00679         /* If two sons */
    00680         right_son=left_son+1;
    00681         if (value_lt(*right_son,*left_son)) {
    00682           if (value_lt(temp,*left_son)) {
    00683             value_assign(*current_node,*left_son);
    00684             j=(j<<1)+1;
    00685           }
    00686           else
    00687             break;
    00688         }
    00689         else {
    00690           if (value_lt(temp,*right_son)) {
    00691             value_assign(*current_node,*right_son );
    00692             j=(j<<1)+2;
    00693           }
    00694           else
    00695             break;
    00696         }
    00697       }
    00698     }
    00699     value_assign(*current_node,temp);
    00700   }
    00701   value_clear(temp);
    00702   return;
    00703 } /* Vector_Sort */
    00704
    00705 /*
    00706  * Replaces constraint a x >= c by x >= ceil(c/a)
    00707  * where "a" is a common factor in the coefficients
    00708  * old is the constraint; v points to an initialized
    00709  * value that this procedure can use.
    00710  * Return non-zero if something changed.
    00711  * Result is placed in newp.
    00712  */
    00713 int ConstraintSimplify(Value *old, Value *newp, int len, Value* v)
    00714 {
    00715     /* first remove common factor of all coefficients (including "c") */
    00716     Vector_Gcd(old+1, len - 1, v);
    00717     if (value_notone_p(*v))
    00718         Vector_AntiScale(old+1, newp+1, *v, len-1);
    00719
    00720     Vector_Gcd(old+1, len - 2, v);
    00721
    00722     if (value_one_p(*v))
    00723         return 0;
    00724
    00725     Vector_AntiScale(old+1, newp+1, *v, len-2);
    00726     value_pdivision(newp[len-1], old[len-1], *v);
    00727     return 1;
    00728 }
    00729
    00730 int Vector_IsZero(Value * v, unsigned length) {
    00731   unsigned i;
    00732   if (value_notzero_p(v[0])) return 0;
    00733   else {
    00734     value_set_si(v[0], 1);
    00735     for (i=length-1; value_zero_p(v[i]); i--);
    00736     value_set_si(v[0], 0);
    00737     return (i==0);
    00738   }
    00739 }
    00740
    00741 #define MAX_CACHE_SIZE 20
    00742 static struct {
    00743   Value *p;
    00744   int   size;
    00745 } cache[MAX_CACHE_SIZE];
    00746 static int cache_size = 0;
    00747
    00748 Value* value_alloc(int want, int *got)
    00749 {
    00750     int i;
    00751     Value *p;
    00752
    00753     if (cache_size) {
    00754       int best;
    00755       for (i = 0; i < cache_size; ++i) {
    00756         if (cache[i].size >= want) {
    00757           Value *p = cache[i].p;
    00758           *got = cache[i].size;
    00759           if (--cache_size != i)
    00760             cache[i] = cache[cache_size];
    00761           Vector_Set(p, 0, want);
    00762           return p;
    00763         }
    00764         if (i == 0)
    00765           best = 0;
    00766         else if (cache[i].size > cache[best].size)
    00767           best = i;
    00768       }
    00769
    00770       p = (Value *)realloc(cache[best].p, want * sizeof(Value));
    00771       *got = cache[best].size;
    00772       if (--cache_size != best)
    00773         cache[best] = cache[cache_size];
    00774       Vector_Set(p, 0, *got);
    00775     } else {
    00776       p = (Value *)malloc(want * sizeof(Value));
    00777       *got = 0;
    00778     }
    00779
    00780     if (!p)
    00781       return p;
    00782
    00783     for (i = *got; i < want; ++i)
    00784       value_init(p[i]);
    00785     *got = want;
    00786
    00787     return p;
    00788 }
    00789
    00790 void value_free(Value *p, int size)
    00791 {
    00792     int i;
    00793
    00794     if (cache_size < MAX_CACHE_SIZE) {
    00795       cache[cache_size].p = p;
    00796       cache[cache_size].size = size;
    00797       ++cache_size;
    00798       return;
    00799     }
    00800
    00801     for (i=0; i < size; i++)
    00802       value_clear(p[i]);
    00803     free(p);
    00804 }
    00805