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

NormalForms.c

Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <polylib/polylib.h>
00003 
00004 /* nota bene: on stocke les matrices par lignes */
00005 /* nota bene: matrices are stored in row major order */
00006 
00007 /*------------------------------------------------------------------------
00008         change les signes de la ligne i de la matrice A
00009         change the sign of row i of matrix A
00010 ------------------------------------------------------------------------*/
00011 
00012 static void moins_l(Value *a,int i,int n,int p) {
00013   
00014   int k;
00015   Value *c;
00016   
00017   c=a+(i-1)*p;
00018   
00019   for(k=1; k<=p; k++) {
00020     value_oppose(*c,*c);
00021     c++;
00022   }
00023   return;
00024 } /* moins_l */
00025 
00026 /*------------------------------------------------------------------------
00027         change les signes de la colonne i de la matrice A
00028         change the sign of column i of matrix A
00029 ------------------------------------------------------------------------*/
00030 
00031 static void moins_c(Value *a,int i,int n,int p) {
00032   
00033   int k;
00034   Value *c;
00035   
00036   c=a+(i-1);
00037   
00038   for(k=1;k<=n;k++) {
00039     value_oppose(*c,*c);
00040     c=c+p;
00041   }
00042   return;
00043 } /* moins_c */
00044 
00045 /*------------------------------------------------------------------------
00046         echange les lignes i et j de la matrice A
00047         exchange row i and j of matrix A
00048 ------------------------------------------------------------------------*/
00049 
00050 static void echange_l(Value *a,int i,int j,int n,int p) {       
00051   
00052   int k;
00053   Value s;
00054   Value *c1,*c2;
00055   
00056   value_init(s);
00057   c1=a+(i-1)*p;
00058   c2=a+(j-1)*p;
00059   
00060   for(k=1;k<=p;k++) {
00061     value_assign(s,*c1);
00062     value_assign(*c1,*c2);
00063     value_assign(*c2,s);
00064     c1++;
00065     c2++;
00066   }
00067   value_clear(s);
00068   return;
00069 } /* echange_l */ 
00070 
00071 /*------------------------------------------------------------------------
00072         echange les colonnes i et j de la matrice A
00073         exchange columns i and j of matrix A
00074 ------------------------------------------------------------------------*/
00075 
00076 static void echange_c(Value *a,int i,int j,int n,int p) {       
00077   
00078   int k;
00079   Value s;
00080   Value *c1,*c2;
00081 
00082   value_init(s);
00083   c1=a+(i-1);
00084   c2=a+(j-1);
00085   
00086   for(k=1;k<=n;k++) {   
00087     value_assign(s,*c1);
00088     value_assign(*c1,*c2);
00089     value_assign(*c2,s);
00090     c1=c1+p;
00091     c2=c2+p;
00092   }
00093   value_clear(s);
00094   return;
00095 } /* echange_c */
00096 
00097 /*------------------------------------------------------------------------
00098         A est une matrice de taille n*p
00099         on ajoute a la ligne i, x fois la ligne j
00100         A is a matrix of size n*p
00101         we add x times the row j to the row i
00102 ------------------------------------------------------------------------*/
00103 
00104 static void ligne(Value *a,int i,int j,Value x,int n,int p) {   
00105  
00106   int k;
00107   Value *c1,*c2;
00108 
00109   c1=a+(i-1)*p;
00110   c2=a+(j-1)*p;
00111   
00112   for(k=1;k<=p;k++) {
00113 
00114     value_addmul(*c1, x, *c2);
00115     c1++;
00116     c2++;
00117   }
00118   return;
00119 } /* ligne */
00120 
00121 /*------------------------------------------------------------------------
00122         A est une matrice de taille n*p
00123         on ajoute a la colonne i, x fois la colonne j
00124         A is a matrix of size n*p
00125         we add x times the column j to the column i
00126 
00127 ------------------------------------------------------------------------*/
00128 
00129 static void colonne(Value *a,int i,int j,Value x,int n,int p) { 
00130   
00131   int k;
00132   Value *c1,*c2;
00133 
00134   c1=a+(i-1);
00135   c2=a+(j-1);
00136   
00137   for(k=1;k<=n;k++) {
00138     value_addmul(*c1, x, *c2);
00139     c1=c1+p;
00140     c2=c2+p;
00141   }
00142   return;
00143 } /* colonne */
00144         
00145 /*----------------------------------------------------------------------
00146         trouve le numero de colonne du plus petit element non nul de 
00147         la ligne q, d'indice superieur a q, de la matrice A,  mais
00148         renvoie zero si tous les elements sont nuls sauf le qieme.
00149 
00150         find the column number (greater than q) of the smallest non
00151         null element of row q . it returns 
00152         0 if all the last elements of row q are null except the qth
00153 
00154 ----------------------------------------------------------------------*/
00155 
00156 static int petit_l(Value *a,int n,int p,int q) {
00157   
00158   int numero=0, k, tousnuls;
00159   Value minus, comp;
00160   Value *c;
00161 
00162   value_init(minus); value_init(comp);
00163   c=a+(q-1)*p+(p-1);
00164   tousnuls=1;
00165   for(k=p;k>q;k--) {
00166     value_absolute(comp,*c);
00167     if (value_notzero_p(comp)) {        
00168       if (tousnuls==1) {        
00169         value_assign(minus,comp);
00170         numero=k;
00171         tousnuls=0;
00172       }
00173       else if (value_ge(minus,comp)) {
00174         value_assign(minus,comp);
00175         numero=k;
00176       }
00177     }
00178     c--;
00179   }  
00180   if (tousnuls==1) {
00181     value_clear(minus); value_clear(comp);
00182     return(0);
00183   }  
00184   else  {
00185     value_absolute(comp,*c);
00186     if ((value_notzero_p(comp))&&(value_ge(minus,comp))) {
00187       value_clear(minus); value_clear(comp);
00188       return(q);
00189     }  
00190     else {
00191       value_clear(minus); value_clear(comp);
00192       return(numero);
00193     }  
00194   }
00195 } /* petit_l */ 
00196         
00197 /*----------------------------------------------------------------------
00198         trouve le numero de ligne du plus petit element non nul de 
00199         la colonne q, d'indice superieur a q, de la matrice A,  mais
00200         renvoie zero si tous les elements sont nuls sauf le qieme.
00201 
00202         find the row number (greater than q) of the smallest non
00203         null element of column q . it returns 
00204         0 if all the last elements of column q are null except the qth
00205 
00206 ----------------------------------------------------------------------*/
00207 
00208 static int petit_c(Value *a,int n,int p,int q) {
00209   
00210   int numero=0, k, tousnuls;  
00211   Value minus, comp;
00212   Value *c;
00213   
00214   value_init(minus); value_init(comp);
00215   c = a+q-1+p*(n-1);
00216   tousnuls=1;
00217   for(k=n;k>q;k--) {
00218     value_absolute(comp,*c);
00219     if (value_notzero_p(comp)) {        
00220       if (tousnuls==1) {        
00221         value_assign(minus,comp);
00222         numero=k;
00223         tousnuls=0;
00224       }
00225       else if (value_ge(minus,comp)) {
00226         value_assign(minus,comp);
00227         numero=k;
00228       }
00229     }
00230     c=c-p;
00231   }
00232   
00233   if (tousnuls==1) {
00234     value_clear(minus); value_clear(comp);
00235     return(0);
00236   }  
00237   else {
00238     value_absolute(comp,*c);
00239     if ((value_notzero_p(comp)) && (value_ge(minus,comp))) {
00240       value_clear(minus); value_clear(comp);
00241       return(q);
00242     }  
00243     else {
00244       value_clear(minus); value_clear(comp);
00245       return(numero);
00246     }  
00247   }
00248 } /* petit_c */
00249         
00250 /*-----------------------------------------------------------------------
00251         A est initialisee a une matrice "identite" de taille n*p
00252         A is initialized to an "identity" matrix of size n*p
00253 -----------------------------------------------------------------------*/
00254 
00255 static void identite(Value *a,int n,int p) {
00256   
00257   int i,j;
00258   Value *b;
00259   
00260   b = a;
00261   for(i=1;i<=n;i++) {
00262     for(j=1;j<=p;j++) {
00263       if (i==j) 
00264         value_set_si(*b,1);
00265       else 
00266         value_set_si(*b,0);
00267       b++;
00268     }
00269   }
00270   return;
00271 } /* identite */
00272 
00273 /*-----------------------------------------------------------------------
00274   transpose la sous-matrice de A dont les indices sont
00275   superieurs ou egaux a q
00276   transposition of the sub-matrix of A composed of the elements 
00277   whose indices are greater or equal to q
00278 -----------------------------------------------------------------------*/
00279 
00280 static void transpose(Value *a,int n,int q) {
00281   
00282   int i;
00283   Value val;
00284   Value *b,*c;
00285 
00286   value_init(val);
00287   if (q<n) {
00288     b=a+(q-1)+(q-1)*n;
00289     c=b;
00290     for(i=q+1;i<=n;i++) {       
00291       b++;
00292       c=c+n;
00293       value_assign(val,*b);
00294       value_assign(*b,*c);
00295       value_assign(*c,val);
00296     }
00297     transpose(a,n,q+1);
00298   }
00299   value_clear(val);
00300   return;
00301 } /* transpose */
00302 
00303 /*----------------------------------------------------------------------
00304         trouve le numero de colonne du premier element non divisible 
00305         par val dans la sous-matrice d'indices > q mais renvoie 0 sinon
00306         
00307         find the column number of the first non-divisible by val element
00308         in the sub-matrix of a composed of the elements of indices >q.
00309         Return 0 is there is no such element
00310 ----------------------------------------------------------------------*/
00311 
00312 static int encore(Value *a,int n,int p,int q,Value val) {
00313   
00314   int k,l;
00315   Value comp, tmp;
00316   Value *c;
00317 
00318   if ((q>=n)||(q>=p)) return(0);
00319   
00320   value_init(comp); value_init(tmp); 
00321   c=a+q*p+q;
00322   k=q+1;
00323   l=q+1;
00324   while (k<=n) {
00325     value_absolute(comp,*c);
00326     if (value_zero_p(val)) {
00327       if (value_notzero_p(comp)) { 
00328         value_clear(comp);
00329         value_clear(tmp);
00330         return(l);
00331       } 
00332     }
00333     else {
00334       value_modulus(tmp,comp,val);
00335       if (value_notzero_p(tmp)) {
00336         value_clear(comp);
00337         value_clear(tmp);
00338         return(l);
00339       }
00340     }  
00341     if (l==p) {
00342       k=k+1;
00343       l=q+1;
00344       c=c+q+1;
00345     }
00346     else {
00347       l++;
00348       c++;
00349     }
00350   }
00351   value_clear(comp);
00352   value_clear(tmp);
00353   return(0);
00354 } /* encore */
00355 
00356 /*----------------------------------------------------------------------
00357         transforme la matrice A (de taille n*p), a partir de la position 
00358         q*q en sa forme de smith, les matrices b et c subissant les memes 
00359         transformations respectivement sur les lignes et colonnes
00360 
00361         transform the matrix A (size n*p), from position (q,q) into 
00362         its smith normal form. the same transformations are applied to 
00363         matrices b and c, respectively on rows and on columns
00364 ----------------------------------------------------------------------*/
00365 
00366 static void smith(Value *a,Value *b,Value *c,Value *b_inverse,Value *c_inverse,int n,int p,int q) {
00367   
00368   int i,k,fini;
00369   Value x, pivot, tmp, x_inv;
00370   Value *f;
00371   
00372   value_init(pivot); value_init(tmp); 
00373   value_init(x); value_init(x_inv);
00374   
00375   if ((q<=n)&&(q<=p)) {
00376     fini = 1;
00377     
00378     while (fini!=0) {
00379       i=petit_c(a,n,p,q);
00380       while (i!=0) {
00381         if (i!=q) {
00382           echange_l(a,i,q,n,p);
00383           echange_l(b,i,q,n,n);
00384           echange_c(b_inverse,i,q,n,n);
00385         }       
00386         f=a+(q-1)+(q-1)*p;
00387         value_assign(pivot,*f);
00388         if (value_neg_p(pivot)) {
00389           moins_l(a,q,n,p);
00390           moins_l(b,q,n,n);
00391           moins_c(b_inverse,q,n,n);
00392           value_oppose(pivot,pivot);
00393         }       
00394         for(k=q+1;k<=n;k++) {   
00395           f=f+p;
00396           if (value_notzero_p(*f)) {
00397             value_division(x,*f,pivot);
00398             value_modulus(tmp,*f,pivot);
00399             if (value_neg_p(tmp)) 
00400               value_decrement(x,x);
00401             value_oppose(x_inv,x);
00402             ligne(a,k,q,x_inv,n,p);
00403             ligne(b,k,q,x_inv,n,n);
00404             colonne(b_inverse,q,k,x,n,n);       
00405           }             
00406         }       
00407         i=petit_c(a,n,p,q);
00408       }       
00409       fini=0;
00410       i=petit_l(a,n,p,q);
00411       while (i!=0) {
00412         if (i!=q) {
00413           echange_c(a,i,q,n,p);
00414           echange_c(c,i,q,p,p);
00415           echange_l(c_inverse,i,q,p,p);
00416           fini=1;
00417         }       
00418         f=a+(q-1)+(q-1)*p;
00419         value_assign(pivot,*f);
00420         if (value_neg_p(pivot)) {
00421           moins_c(a,q,n,p);
00422           moins_c(c,q,p,p);
00423           moins_l(c_inverse,q,p,p);
00424           value_oppose(pivot,pivot);
00425         }       
00426         for(k=q+1;k<=p;k++) {   
00427           f++;
00428           if (value_notzero_p(*f)) {
00429             value_division(x,*f,pivot);
00430             value_modulus(tmp,*f,pivot);
00431             if (value_neg_p(tmp)) 
00432               value_decrement(x,x);
00433             value_oppose(x_inv,x);
00434             colonne(a,k,q,x_inv,n,p);
00435             colonne(c,k,q,x_inv,p,p);   
00436             ligne(c_inverse,q,k,x,p,p);
00437           }             
00438         }       
00439         i=petit_l(a,n,p,q);
00440       } 
00441     }
00442     value_assign(pivot,*(a+(q-1)+(q-1)*p));
00443     if (value_neg_p(pivot)) {
00444       moins_l(a,q,n,p);
00445       moins_l(b,q,n,n);
00446       moins_c(b_inverse,q,n,n);
00447       value_oppose(pivot,pivot);
00448     }
00449     
00450     i=encore(a,n,p,q,pivot);
00451     if (i!=0) {
00452       value_set_si(x,1);
00453       value_set_si(x_inv,-1);
00454       colonne(a,q,i,x,n,p);
00455       colonne(c,q,i,x,p,p);
00456       ligne(c_inverse,i,q,x_inv,p,p);
00457       smith(a,b,c,b_inverse,c_inverse,n,p,q);
00458     }   
00459     else smith(a,b,c,b_inverse,c_inverse,n,p,q+1);
00460   }
00461   value_clear(pivot); value_clear(tmp);
00462   value_clear(x); value_clear(x_inv);
00463   
00464   return;
00465 } /* smith */ 
00466 
00467 /*----------------------------------------------------------------------
00468         decompose la matrice A en le produit d'une matrice B
00469         unimodulaire et d'une matrice triangulaire superieure
00470         D est l'inverse de B
00471         Decompose the matrix A in the product of a matrix B unimodular
00472         and a matrix upper triangular, D is the inverse of B
00473 ----------------------------------------------------------------------*/
00474 
00475 static void hermite(Value *a,Value *b,Value *d,int n,int p,int q) {
00476   
00477   int i,k;
00478   Value x, pivot, x_inv, tmp;
00479   Value *c1;
00480 
00481   value_init(pivot);  value_init(tmp);
00482   value_init(x); value_init(x_inv);
00483 
00484   if ((q<=p)&&(q<=n)) {
00485     i=petit_c(a,n,p,q);    
00486     while (i!=0) {
00487       if (i!=q) {
00488         echange_l(a,i,q,n,p);
00489         echange_c(b,i,q,n,n);
00490         echange_l(d,i,q,n,n);
00491       }
00492       
00493       c1=a+(q-1)+(q-1)*p;
00494       value_assign(pivot,*c1);
00495       if (value_neg_p(pivot)) {
00496         moins_l(a,q,n,p);
00497         moins_l(d,q,n,n);
00498         moins_c(b,q,n,n);
00499         value_oppose(pivot,pivot);
00500       }      
00501       for(k=q+1;k<=n;k++) {     
00502         c1=c1+p;
00503         if (value_notzero_p(*c1)) {
00504           value_division(x,*c1,pivot);
00505           value_modulus(tmp,*c1,pivot);
00506           if (value_neg_p(tmp)) 
00507             value_decrement(x,x);
00508           value_oppose(x_inv,x);
00509           ligne(a,k,q,x_inv,n,p);
00510           colonne(b,q,k,x,n,n); 
00511           ligne(d,k,q,x_inv,n,n);
00512         }               
00513       }      
00514       i=petit_c(a,n,p,q);       
00515     }    
00516     c1=a+(q-1);
00517     value_assign(pivot,*(c1+(q-1)*p));
00518     if (value_neg_p(pivot)) {
00519       moins_l(a,q,n,p);
00520       moins_l(d,q,n,n);
00521       moins_c(b,q,n,n);
00522       value_oppose(pivot,pivot);
00523     }    
00524     if (value_notzero_p(pivot)) {
00525       for(k=1;k<q;k++) {
00526         if (value_notzero_p(*c1)) {
00527           value_division(x,*c1,pivot);
00528           value_modulus(tmp,*c1,pivot);
00529           if (value_neg_p(tmp)) 
00530             value_decrement(x,x);
00531           value_oppose(x_inv,x);
00532           ligne(a,k,q,x_inv,n,p);
00533           colonne(b,q,k,x,n,n); 
00534           ligne(d,k,q,x_inv,n,n);
00535         }
00536         c1=c1+p;                
00537       }
00538     }    
00539     hermite(a,b,d,n,p,q+1);
00540   }     
00541   value_clear(pivot); value_clear(tmp);
00542   value_clear(x); value_clear(x_inv);
00543   return;
00544 } /* hermite */
00545         
00546 /*----------------------------------------------------------------------
00547   B est une g_base de dimension n dont les p premiers vecteurs
00548   colonnes sont colineaires aux vecteurs colonnes de A
00549   C est l'invers de B
00550   
00551   B is an integral (g_base ?) of dimension n whose p first columns
00552   vectors are proportionnal to the column vectors of A. C is the
00553   inverse of B.
00554   ----------------------------------------------------------------------*/
00555 
00556 /** Convert PolmattoDarmat :
00557 ***  This function converts the matrix of a Polylib to a int * as necessary
00558 ***    for the functions in Darte's implementation.
00559 ***
00560 ***  Input  : A Polylib Matrix ( a pointer to it );
00561 ***  Output : An int * with the matrix copied into it
00562 **/
00563 static Value *ConvertPolMattoDarMat(Matrix *A ) {
00564   
00565   int i,j;
00566   Value *result;
00567   
00568   result = (Value *)malloc(sizeof(Value) * A->NbRows * A->NbColumns);
00569   for(i=0;i<A->NbRows * A->NbColumns;i++)
00570     value_init(result[i]);
00571 
00572   for (i = 0; i < A->NbRows; i++)
00573     for (j = 0 ;  j < A->NbColumns; j++)
00574       value_assign(result[i*A->NbColumns + j],A->p[i][j]);
00575   return result;
00576 } /* ConvertPolMattoDarMat */
00577 
00578 /** Convert DarmattoPolmat
00579 ***   This function converts the matrix from Darte representation to a matrix
00580 ***    in PolyLib.
00581 ***
00582 ***   Input  : The matrix (a pointer to it),  number of Rows, number of columns
00583 ***   Output : The matrix of the PolyLib 
00584 ***
00585 **/
00586 
00587 static Matrix *ConvertDarMattoPolMat (Value *A, int NbRows, int NbCols) {
00588   
00589   int i,j;
00590   Matrix *result;
00591   
00592   result = Matrix_Alloc(NbRows, NbCols);
00593   
00594   for (i = 0; i < NbRows; i ++)
00595     for (j = 0; j < NbCols; j ++)
00596       value_assign(result->p[i][j],A[i*NbCols + j]);  
00597   return result;
00598 } /* ConvertDarMattoPolMat */
00599 
00600 /**
00601 *** Smith : This function takes a Matrix A of dim n * l as its input 
00602 ***         and returns the three matrices U, V and Product such that
00603 ***         A = U * Product * V, where U is an unimodular matrix of dimension
00604 ***         n * n and V is an unimodular matrix of dimension l * l.
00605 ***         Product is a diagonal matrix of dimension n * l.
00606 ***     
00607 ***         We use Alan Darte's implementation of Smith for computing
00608 ***         the Smith Normal Form 
00609 **/
00610  
00611 void Smith (Matrix *A, Matrix **U, Matrix **V, Matrix **Product) {
00612   
00613   int i;
00614   Value *a, *u, *v, *u_inv, *v_inv;
00615   Matrix *temp;
00616   
00617   u = (Value *) malloc(sizeof(Value) * (A->NbRows) * (A->NbRows));
00618   v = (Value *) malloc(sizeof(Value) * A->NbColumns * A->NbColumns);  
00619   u_inv = (Value *) malloc(sizeof(Value) * A->NbRows * A->NbRows);
00620   v_inv = (Value *) malloc(sizeof(Value) * A->NbColumns * A->NbColumns);
00621 
00622   for (i=0;i < (A->NbRows * A->NbRows);i++)
00623     value_init(u[i]);
00624   for (i=0;i < (A->NbColumns * A->NbColumns);i++)
00625     value_init(v[i]);
00626   for (i=0;i < (A->NbRows * A->NbRows);i++)
00627     value_init(u_inv[i]);
00628   for (i=0;i < (A->NbColumns * A->NbColumns);i++)
00629     value_init(v_inv[i]);
00630   
00631   identite(u,A->NbRows,A->NbRows);
00632   identite(u_inv,A->NbRows,A->NbRows);
00633   identite(v, A->NbColumns,A->NbColumns);
00634   identite(v_inv,A->NbColumns,A->NbColumns);
00635   
00636   a = ConvertPolMattoDarMat(A);  
00637   smith(a,u,v,u_inv,v_inv,A->NbRows,A->NbColumns,1);  
00638   *Product = ConvertDarMattoPolMat(a,A->NbRows,A->NbColumns);
00639   temp = ConvertDarMattoPolMat(u,A->NbRows, A->NbRows);
00640   *U= Matrix_Alloc(temp->NbRows, temp->NbColumns);
00641   Matrix_Inverse(temp, *U);
00642   Matrix_Free(temp);
00643   
00644   temp = ConvertDarMattoPolMat(v,A->NbColumns, A->NbColumns);
00645   *V= Matrix_Alloc(temp->NbRows, temp->NbColumns);
00646   Matrix_Inverse(temp, *V);
00647   Matrix_Free(temp);
00648 
00649   for (i=0;i < (A->NbRows * A->NbRows);i++)
00650     value_clear(u[i]);
00651   for (i=0;i < (A->NbColumns * A->NbColumns);i++)
00652     value_clear(v[i]);
00653   for (i=0;i < (A->NbRows * A->NbRows);i++)
00654     value_clear(u_inv[i]);
00655   for (i=0;i < (A->NbColumns * A->NbColumns);i++)
00656     value_clear(v_inv[i]);    
00657   free (a);
00658   free (u); free (v);
00659   free (u_inv); free (v_inv);  
00660   return;
00661 } /* Smith */
00662 
00663 /** Hermite :
00664 ***   This function takes a Matrix as its input and finds its HNF 
00665 ***    ( Left form )
00666 ***
00667 ***   Input  : A Matrix A (The Matrix A is not necessarily a Polylib matrix.
00668 ***             It is just a matrix as far as Hermite is concerned. It
00669 ***             does not even check if the matrix is a Polylib matrix or not) 
00670 ***   Output : The Hnf matrix H and the Unimodular matrix U such that
00671 ***               A = H * U.
00672 ***
00673 ***   We use Alan Darte's implementation of Hermite to compute the HNF.
00674 ***   Alan Darte's implementation computes the Upper Triangular HNF.
00675 ***   So We work on the fact that if A = H * U then 
00676 ***       A (transpose) = U(transpose) * H (transpose)
00677 ***       There are a set of interface functions written in Interface.c
00678 ***        which convert a matrix from Polylib representationt to that of
00679 ***        Alan Darte's and vice versa.
00680 ***     
00681 ***   This Function Does the Following
00682 ***    Step 1 : Given the matrix A it finds its Transpose.
00683 ***    Step 2 : Finds the HNF (Right Form) using Alan Darte's Algorithm.
00684 ***    Step 3 : The H1 and U1 obtained in Step2 are both Transposed to get
00685 ***              the actual H and U such that A = HU.
00686 **/
00687 void Hermite (Matrix *A, Matrix **H, Matrix **U) {
00688   
00689   int i;
00690   Matrix *transpose, *tempH, *tempU ;
00691   Value *darte_matA, *darte_identite, *darte_id_inv;
00692   
00693   transpose = Transpose(A);
00694   darte_matA = ConvertPolMattoDarMat(transpose);
00695   
00696   darte_identite = (Value *)malloc(sizeof(Value) * A->NbColumns* A->NbColumns);
00697   darte_id_inv = (Value *) malloc(sizeof(Value) * A->NbColumns*A->NbColumns);
00698   for (i=0; i< A->NbColumns * A->NbColumns; i++)
00699     value_init(darte_identite[i]);
00700   for (i=0; i< A->NbColumns * A->NbColumns; i++)
00701     value_init(darte_id_inv[i]);
00702   
00703   identite(darte_identite, transpose->NbRows, transpose->NbRows);
00704   identite(darte_id_inv, transpose->NbRows, transpose->NbRows);  
00705   hermite(darte_matA, darte_identite, darte_id_inv,A->NbColumns,A->NbRows, 1); 
00706   Matrix_Free (transpose);
00707   transpose = ConvertDarMattoPolMat(darte_matA, A->NbColumns, A->NbRows);
00708   tempU = ConvertDarMattoPolMat(darte_identite, A->NbColumns, A->NbColumns);
00709   
00710   /* Finding H Transpose */
00711   tempH = Transpose(transpose);  
00712   Matrix_Free(transpose);
00713   
00714   /* Finding U Transpose */
00715   transpose = Transpose(tempU);
00716   
00717   H[0] = Matrix_Copy(tempH);
00718   U[0] = Matrix_Copy(transpose);
00719     
00720   Matrix_Free (tempH);
00721   Matrix_Free (transpose);
00722   Matrix_Free (tempU);
00723   
00724   for (i=0; i< A->NbRows * A->NbColumns; i++)
00725     value_clear(darte_matA[i]);
00726   for (i=0; i< A->NbColumns * A->NbColumns; i++)
00727     value_clear(darte_identite[i]);
00728   for (i=0; i< A->NbColumns * A->NbColumns; i++)
00729     value_clear(darte_id_inv[i]);
00730   free (darte_matA);
00731   free (darte_identite);
00732   free (darte_id_inv);
00733   return;
00734 } /* Hermite */
00735 
00736 

Generated on Mon Sep 12 15:15:11 2005 for polylib by doxygen 1.3.5