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,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_substract(*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  */
00344 void Vector_AntiScale(Value *p1,Value *p2,Value lambda,unsigned length) {
00345   
00346   Value *cp1, *cp2;
00347   int i;
00348   
00349   cp1=p1;
00350   cp2=p2;
00351   for (i=0;i<length;i++) {
00352     
00353     /* *cp2++=*cp1++ / lambda; */
00354     value_division(*cp2,*cp1,lambda);
00355     cp1++; cp2++;
00356   }
00357 } /* Vector_AntiScale */
00358 
00359 /* 
00360  * Return the inner product of the two Vectors 'p1' and 'p2' 
00361  */
00362 void Inner_Product(Value *p1,Value *p2,unsigned length,Value *ip) {
00363   
00364   Value tmp;
00365   int i;
00366 
00367   value_init(tmp);
00368 
00369   //  if(length==0)
00370   //  return(VALUE_MAX);  
00371   
00372   value_multiply(*ip,*p1,*p2);
00373   p1++; p2++;
00374   for(i=1;i<length;i++) {
00375     value_multiply(tmp,*p1,*p2);
00376     value_addto(*ip,*ip,tmp);
00377     p1++; p2++;
00378   }
00379   value_clear(tmp);
00380 } /* Inner_Product */
00381 
00382 /* 
00383  * Return the maximum of the components of 'p' 
00384  */
00385 void Vector_Max(Value *p,unsigned length, Value *max) {
00386   
00387   Value *cp;
00388   int i;
00389 
00390   cp=p;
00391   value_assign(*max,*cp);
00392   cp++;
00393   for (i=1;i<length;i++) {
00394     value_maximum(*max,*max,*cp);
00395     cp++;
00396   }
00397 } /* Vector_Max */
00398 
00399 /* 
00400  * Return the minimum of the components of Vector 'p' 
00401  */
00402 void Vector_Min(Value *p,unsigned length,Value *min) {
00403   
00404   Value *cp;
00405   int i;
00406 
00407   //  if(length==0)
00408   //  return(VALUE_MAX);
00409   cp=p;
00410   value_assign(*min,*cp);
00411   cp++;
00412   for (i=1;i<length;i++) {
00413     value_minimum(*min,*min,*cp);
00414     cp++;
00415   }
00416   return;
00417 } /* Vector_Min */
00418 
00419 /* 
00420  * Given Vectors 'p1' and 'p2', return Vector 'p3' = lambda * p1 + mu * p2. 
00421  */
00422 void  Vector_Combine(Value *p1,Value *p2, Value *p3,Value lambda,Value  mu,unsigned length) {
00423   
00424   Value *cp1, *cp2, *cp3;
00425   Value tmp1, tmp2;
00426   int i;
00427   
00428   value_init(tmp1); value_init(tmp2);
00429   cp1=p1;
00430   cp2=p2;
00431   cp3=p3;
00432   
00433   for (i=0;i<length;i++) {
00434     
00435     /* tmp1 = lambda * *cp1 */
00436     value_multiply(tmp1,lambda,*cp1);
00437     
00438     /* tmp2 = mu * *cp2 */
00439     value_multiply(tmp2,mu,*cp2);
00440     
00441     /* *cp3 = tmp1 + tmp2 */
00442     value_addto(*cp3,tmp1,tmp2);
00443     cp1++; cp2++; cp3++;
00444   }
00445   value_clear(tmp1);
00446   value_clear(tmp2);
00447   return;
00448 } /* Vector_Combine */
00449 
00450 /* 
00451  * Return 1 if 'Vec1' equals 'Vec2', otherwise return 0 
00452  */
00453 int Vector_Equal(Value *Vec1,Value *Vec2,unsigned n) {
00454   
00455   int i;
00456   Value *p1, *p2;
00457   
00458   p1=Vec1;
00459   p2=Vec2;
00460   for(i=0;i<n;i++) {
00461   
00462     /* if (*p1++!=*p2++) break; */
00463     if (value_ne(*p1,*p2))
00464       break;
00465     p1++; p2++;
00466   }
00467   return (i==n);
00468 } /* Vector_Equal */
00469 
00470 /* 
00471  * Return the component of 'p' with minimum non-zero absolute value. 'index'
00472  * points to the component index that has the minimum value. If no such value
00473  * and index is found, Value 1 is returned.
00474  */
00475 void Vector_Min_Not_Zero(Value *p,unsigned length,int *index,Value *min) {
00476   
00477   Value *cp, aux;
00478   int i,j;
00479   
00480   value_init(aux);
00481   
00482   cp=p;
00483   for(i=0;i<length;i++) {
00484     if (value_notzero_p(*cp)) {
00485       value_absolute(*min,*cp);
00486       *index = i;
00487       break;
00488     }
00489     ++cp;
00490   }
00491   if (i == length) {
00492     value_set_si(*min,1);
00493     value_clear(aux);
00494     cp = NULL;
00495     return;
00496   }
00497   ++cp;
00498   for(j=i+1;j<length;j++) {
00499     value_absolute(aux,*cp);
00500     if (value_lt(aux,*min) && value_notzero_p(aux)) {
00501       value_assign(*min,aux);
00502       *index = j;
00503     }  
00504     cp++;
00505   }
00506   value_clear(aux);
00507   cp = NULL;
00508 } /* Vector_Min_Not_Zero */
00509 
00510 /* 
00511  * Return the GCD of components of Vector 'p' 
00512  */
00513 void Vector_Gcd(Value *p,unsigned length,Value *min) {
00514   
00515   Value *q,*cq, *cp;
00516   int i, Not_Zero, Index_Min=0;
00517   
00518   q  = (Value *)malloc(length*sizeof(Value));
00519 
00520   /* Initialize all the 'Value' variables */
00521   for(i=0;i<length;i++)
00522     value_init(q[i]);
00523   
00524   /* 'cp' points to vector 'p' and cq points to vector 'q' that holds the */
00525   /* absolute value of elements of vector 'p'.                            */
00526   cp=p;
00527   for (cq = q,i=0;i<length;i++) {
00528     value_absolute(*cq,*cp);    
00529     cq++;
00530     cp++;
00531   }
00532   do {   
00533     Vector_Min_Not_Zero(q,length,&Index_Min,min);
00534     
00535     /* if (*min != 1) */
00536     if (value_notone_p(*min)) {
00537       
00538       cq=q;
00539       Not_Zero=0;
00540       for (i=0;i<length;i++,cq++)
00541         if (i!=Index_Min) {
00542           
00543           /* Not_Zero |= (*cq %= *min) */
00544           value_modulus(*cq,*cq,*min);
00545           Not_Zero |= value_notzero_p(*cq);
00546         }
00547     } 
00548     else 
00549       break;
00550   } while (Not_Zero);
00551   
00552   /* Clear all the 'Value' variables */
00553   for(i=0;i<length;i++)
00554     value_clear(q[i]);
00555   free(q);
00556 } /* Vector_Gcd */
00557 
00558 /* 
00559  * Given vectors 'p1', 'p2', and a pointer to a function returning 'Value type,
00560  * compute p3[i] = f(p1[i],p2[i]).  
00561  */ 
00562 void Vector_Map(Value *p1,Value *p2,Value *p3,unsigned length,Value *(*f)()) {
00563   
00564   Value *cp1, *cp2, *cp3;
00565   int i;
00566   
00567   cp1=p1;
00568   cp2=p2;
00569   cp3=p3;
00570   for(i=0;i<length;i++) {
00571     value_assign(*cp3,*(*f)(*cp1, *cp2));
00572     cp1++; cp2++; cp3++;
00573   }
00574   return;
00575 } /* Vector_Map */
00576 
00577 /* 
00578  * Reduce a vector by dividing it by GCD. There is no restriction on 
00579  * components of Vector 'p'. Making the last element positive is *not* OK
00580  * for equalities. 
00581  */
00582 void Vector_Normalize(Value *p,unsigned length) {
00583   
00584   Value *cp, gcd,tmp;
00585   int i;
00586   
00587   value_init(tmp);value_init(gcd);
00588 
00589   Vector_Gcd(p,length,&gcd);
00590   value_set_si(tmp,1);
00591   
00592   if (value_gt(gcd,tmp)) {
00593     cp = p;    
00594     for (i=0; i<length; i++) { 
00595       
00596       /* *cp /= gcd */
00597       value_division(*cp,*cp,gcd);
00598       cp++;
00599     }
00600   }
00601   value_clear(tmp);
00602   value_clear(gcd);
00603   return;
00604 } /* Vector_Normalize */
00605 
00606 /* 
00607  * Reduce a vector by dividing it by GCD and making sure its pos-th 
00608  * element is positive.    
00609  */
00610 void Vector_Normalize_Positive(Value *p,int length,int pos) {
00611   
00612   Value gcd;
00613   int i;
00614   
00615   value_init(gcd);
00616   Vector_Gcd(p,length,&gcd);
00617   if (value_neg_p(p[pos]))
00618     value_oppose(gcd,gcd);
00619   if(value_notone_p(gcd))
00620     for(i=0; i<length; i++)
00621       value_division(p[i],p[i],gcd);
00622   value_clear(gcd);
00623 
00624   return;
00625 } /* Vector_Normalize_Positive */
00626 
00627 /* 
00628  * Reduce 'p' by operating binary function on its components successively 
00629  */
00630 void Vector_Reduce(Value *p,unsigned length,void(*f)(Value,Value *),Value *r) {
00631   
00632   Value *cp;
00633   int i;
00634   
00635   cp = p;
00636   value_assign(*r,*cp);
00637   for(i=1;i<length;i++) {
00638     cp++;
00639     (*f)(*cp,r);
00640   }
00641 } /* Vector_Reduce */
00642 
00643 /* 
00644  * Sort the components of a Vector 'vector' using Heap Sort. 
00645  */
00646 void Vector_Sort(Value *vector,unsigned n) {
00647   
00648   int i, j;
00649   Value temp;
00650   Value *current_node=(Value *)0;
00651   Value *left_son,*right_son;
00652 
00653   value_init(temp);
00654 
00655   for (i=(n-1)/2;i>=0;i--) { 
00656     
00657     /* Phase 1 : build the heap */
00658     j=i;
00659     value_assign(temp,*(vector+i));
00660     
00661     /* While not a leaf */
00662     while (j<=(n-1)/2) {
00663       current_node = vector+j;
00664       left_son = vector+(j<<1)+1;
00665 
00666       /* If only one son */
00667       if ((j<<1)+2>=n) {
00668         if (value_lt(temp,*left_son)) {
00669           value_assign(*current_node,*left_son);
00670           j=(j<<1)+1;
00671         }
00672         else
00673           break;
00674       }
00675       else {  
00676         
00677         /* If two sons */
00678         right_son=left_son+1;
00679         if (value_lt(*right_son,*left_son)) {
00680           if (value_lt(temp,*left_son)) {
00681             value_assign(*current_node,*left_son);
00682             j=(j<<1)+1;
00683           }
00684           else
00685             break;
00686         }
00687         else {
00688           if (value_lt(temp,*right_son)) {
00689             value_assign(*current_node,*right_son );
00690             j=(j<<1)+2;
00691           }
00692           else
00693             break;
00694         }
00695       }
00696     }
00697     value_assign(*current_node,temp);
00698   }
00699   for(i=n-1;i>0;i--) { 
00700     
00701     /* Phase 2 : sort the heap */
00702     value_assign(temp, *(vector+i));
00703     value_assign(*(vector+i),*vector);
00704     j=0;
00705     
00706     /* While not a leaf */
00707     while (j<i/2) {     
00708       current_node=vector+j;
00709       left_son=vector+(j<<1)+1;
00710       
00711       /* If only one son */
00712       if ((j<<1)+2>=i) {                
00713         if (value_lt(temp,*left_son)) {
00714           value_assign(*current_node,*left_son);
00715           j=(j<<1)+1;
00716         }
00717         else
00718           break;
00719       }
00720       else {
00721         
00722         /* If two sons */
00723         right_son=left_son+1;
00724         if (value_lt(*right_son,*left_son)) {
00725           if (value_lt(temp,*left_son)) {
00726             value_assign(*current_node,*left_son);
00727             j=(j<<1)+1;
00728           }
00729           else
00730             break;
00731         }
00732         else {
00733           if (value_lt(temp,*right_son)) {
00734             value_assign(*current_node,*right_son );
00735             j=(j<<1)+2;
00736           }
00737           else
00738             break;
00739         }
00740       }
00741     }
00742     value_assign(*current_node,temp);
00743   }
00744   value_clear(temp);
00745   return;
00746 } /* Vector_Sort */
00747 
00748 
00749 
00750 
00751 
00752 
00753 
00754 

Generated on Mon Sep 12 14:48:29 2005 for polylib by doxygen 1.3.5