Main Page | Class List | File List | Class Members | File Members

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   value_multiply(*ip,*p1,*p2);
00372   p1++; p2++;
00373   for(i=1;i<length;i++) {
00374     value_addmul(*ip, *p1, *p2);
00375     p1++; p2++;
00376   }
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 

Generated on Thu Sep 4 15:28:58 2008 for polylib by doxygen 1.3.5