synaps/linalg/SousMatMax.h

00001 /*************************************************************************
00002 *      This file is part of the source code of SYNAPS.                   *
00003 *      O. Ruatta, GALAAD, INRIA                                          *
00004 **************************************************************************
00005 $Id: SousMatMax.h,v 1.1 2005/07/11 08:33:34 mourrain Exp $
00006 **********************************************************************/
00007 #ifndef SYNAPS_LINALG_SOUSMATMAX_H
00008 #define SYNAPS_LINALG_SOUSMATMAX_H
00009 //----------------------------------------------------------------------
00010 #include <stdio.h>
00011 #include <list>
00012 #include <cmath>
00013 #include <synaps/init.h>
00014 #include <synaps/bignum.h>
00015 #include <synaps/linalg.h>
00016 #include <synaps/mpol.h>
00017 #include <synaps/mpol/bezoutian.h>
00018 
00019 
00020 
00021 __BEGIN_NAMESPACE_SYNAPS
00022 
00023 //-----------------------------------------------------------------------
00024 
00027 template<class A, class B>
00028 void PermuteLig(A &M, B &IR, const typename A::size_type a, const typename A::size_type b)
00029 {
00030   typedef typename A::size_type size_type; 
00031   typedef typename A::value_type value_type;
00032   M.swaprow(a,b);
00033   typename B::size_type tmp;
00034   tmp = IR[a];
00035   IR[a] = IR[b];
00036   IR[b] = tmp;
00037 }
00038 
00039 
00042 template<class A, class B>
00043 void PermuteCol(A &M, B &IC, const typename A::size_type a, const typename A::size_type b)
00044 {
00045   typedef typename A::size_type size_type; 
00046   typedef typename A::value_type value_type;
00047   M.swapcol(a,b);
00048   typename B::size_type tmp;
00049   tmp = IC[a];
00050   IC[a] = IC[b];
00051   IC[b] = tmp;
00052 }
00053 
00055 template<class A, class B> 
00056 void CherchePivot(A & M, B &IR, B &IC, const typename A::size_type & ind, int & TesT)
00057 {
00058   // Si on rentre dans cette fonction on a M(ind,ind) = 0
00059   typedef typename A::size_type size_type;
00060   typedef typename A::value_type value_type;
00061   size_type indr = ind;
00062   size_type indc = ind;
00063   size_type NbRow = M.nbrow();
00064   size_type NbCol = M.nbcol();
00065   TesT = 0; //car M(ind,ind) = 0
00066   while((TesT == 0) && (indc < NbCol)){
00067     indr = ind;
00068     while((TesT == 0) && (indr < NbRow)){
00069       if (M(indr,indc) != 0){
00070         TesT = 1;
00071         PermuteLig(M,IR,ind,indr);
00072         PermuteCol(M,IC,ind,indc);
00073       }
00074       indr++;
00075     }
00076     indc++;
00077   }
00078   //A la fin de cette procedure, TesT = 0 <=> pas de pivot non nul
00079 }
00080 
00081 
00082 
00090 template<class A, class B>
00091 typename A::size_type FieldGaussElim(const A & MM, B &IndRow , B &IndCol)
00092 {
00093   typedef typename A::size_type size_type; 
00094   typedef typename A::value_type value_type;
00095   A M = MM;
00096   size_type NbRow, NbCol, SizeMin, ind, Rang;
00097   NbRow = MM.nbrow();
00098   NbCol = MM.nbcol();
00099   SizeMin = std::min(NbRow,NbCol);
00100   value_type tmp, pivot;
00101   ind = 0;
00102   int TesT = 1;
00103   Rang = 0;
00104   while((TesT != 0) && (ind < SizeMin)){
00105     // On suppose que le bloc d'indice [0..ind-1,0..ind-1] est deja triangulaire 
00106     // Si le pivot suppose est nul
00107     if(M(ind,ind) == 0){
00108       //Alors on cherche un nouveau pivot
00109       CherchePivot(M, IndRow, IndCol, ind, TesT);
00110     }
00111     // Si il existe un nouveau pivot
00112     if(TesT != 0){
00113       //On stocke le nouveau pivot
00114       pivot = M(ind,ind);
00115       // On elimine pqr un pivot brutal
00116       for(size_type i = ind+1; i < NbRow; i++){
00117         if(M(i,ind) != 0){
00118           tmp = value_type(-1)*M(i,ind)/pivot;
00119           M.addrow(i,ind,tmp);
00120         }
00121       }
00122       // Comme on a un nouveau pivot non nul, on incremente le rang
00123       Rang++;
00124     }
00125     //On passe au pivot suivant si il y a lieu de le faire
00126     ind++;
00127   }
00128 
00129   //cout<<"Est-ce bien triangulaire ?\n"<<M<<endl;
00130   // On retourne le rang de la matrice
00131   return(Rang);
00132 }
00133 
00134 
00137 template<class A, class B>
00138 B SousMatMax(const A & M, const B & MM)
00139 {
00140   typedef typename A::size_type size_type; 
00141   typedef typename A::value_type value_type;
00142 
00143   int NbRow = M.nbrow();
00144   int NbCol = M.nbcol();
00145   
00147   VectDse<int> IndRow(NbRow);
00148   VectDse<int> IndCol(NbCol);
00149   
00151   for(int i = 0; i < NbRow; i++){
00152     IndRow[i] = i;
00153   }
00154   for(int i = 0; i < NbCol; i++){
00155     IndCol[i] = i;
00156   }
00157 
00159   size_type Rang = FieldGaussElim(M, IndRow , IndCol);
00160 
00161   //cout<<"le rang -> "<<Rang<<endl;
00162 
00163   int rang = Rang;
00164   
00165   B Resultat(rang, rang);
00166   
00168   for(int i=0; i < rang; i++){
00169     for(int j=0; j < rang; j++){
00170       Resultat(i,j) = MM(IndRow[i],IndCol[j]);
00171     }
00172   }
00173 
00174   //cout<<"le resultat de SousMatMax ->"<<endl<<Resultat<<endl;
00175   
00176   return Resultat;
00177 }
00178 
00179 __END_NAMESPACE_SYNAPS
00180 
00181 #endif // SYNAPS_LINALG_SOUSMATMAX_H
00182 
00183 
00184 

SYNAPS DOCUMENTATION
logo