algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/matrix_bareiss.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : matrix_bareiss.hpp
00004 * DESCRIPTION: Bareiss pivoting for dense matrices
00005 * COPYRIGHT  : (C) 2008 Bernard Mourrain
00006 *******************************************************************************
00007 * This software falls under the GNU general public license and comes WITHOUT
00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00009 * If you don't have this file, write to the Free Software Foundation, Inc.,
00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00011 ******************************************************************************/
00012 #ifndef __MMX_MATRIX_BAREISS_HPP
00013 #define __MMX_MATRIX_BAREISS_HPP
00014 
00015 #include <algebramix/matrix.hpp>
00016 
00017 namespace mmx {
00018 
00019 #define TMPL template<typename Scalar, typename V>
00020 #define Matrix matrix<Scalar,V>
00021 #define nbrow rows
00022 #define nbcol cols
00023 
00024 /*********************************************************************
00025 * Pivoting
00026 **********************************************************************/
00027 
00034 TMPL
00035 Scalar bareiss_pivoting(Matrix & A, unsigned & r)
00036 {
00037   typedef unsigned size_t;
00038   r=0;
00039   size_t nr = nbrow(A), nc = nbcol(A);
00040   size_t i;//,j;
00041   int s = 1;
00042   Scalar d=1;// t;
00043   for(size_t k=0; k< min (nr, nc) && r < nr; k++) 
00044   {
00045     for(i=r; i<nr && ( A(i,k) == 0);i++);
00046 
00047     //  for(j=i+1; j<nr; j++) {
00048     //       if(A(j,k) !=0 && size(A(j, k)) < size(A(i,k))){
00049     //          i=j;
00050     //       }
00051     //   }
00052     if(i < nr) {
00053       if( i != r) {
00054         s *= -1;
00055         swap_row(A,i,r); 
00056         // swap_row(A,i,r,k,nc);
00057         // for(j=k;j<nc;j++) {swap (A(i,j), A(r,j));    }
00058       }
00059       for(i = r+1;i<nr;i++) {
00060         rows_linsub(A,i,A(r,k),r,A(i,k));
00061         // rows_combine(A,i,A(r,k),r,-A(i,k),0,nr,k+1,nc);
00062         row_div(A,d,i);
00063 //      for(j=k+1;j<nc;j++) {
00064 //        A(i,j) = (A(i,j)*A(r,k) - A(r,j)*A(i,k));
00065 //        A(i,j) /= d;
00066 //      }
00067         A(i, k) = 0;
00068       }
00069       d = A(r, k);
00070       r++;
00071     }
00072   }
00073   if(s==-1)
00074     return -A(nr-1,nc-1);
00075   else
00076     return  A(nr-1,nc-1);
00077 }
00078 
00079 //--------------------------------------------------------------------
00080 TMPL inline
00081 Scalar bareiss_pivoting(Matrix & A)
00082 {
00083   unsigned rk=0; return bareiss_pivoting(A,rk);
00084 }
00085 
00086 //----------------------------------------------------------------------
00093 TMPL
00094 void bareiss_extended_pivoting(Matrix & A, Matrix& P, unsigned & r)
00095 {
00096   typedef unsigned size_t;
00097   r=0;
00098   size_t nr = nbrow(A), nc = nbcol(A);
00099   ASSERT(nbrow(A)==nbrow(P),"number of rows of A and P don't match");
00100   size_t i;//,j;
00101   int s = 1;
00102   Scalar d=1;// t;
00103   for(size_t k=0; k< min (nr, nc) && r < nr; k++) {
00104     for(i=r; i<nr && (A(i,k) == 0);i++);
00105 
00106     // for(j=i+1; j<nr; j++) {
00107 //       if(A(j,k) !=0){// && size(A(j, k)) < size(A(i,k))){
00108 //              i=j;
00109 //       }
00110 //     }
00111     if(i < nr) {
00112       if( i != r) {
00113         s *= -1;
00114         swap_row(A,i,r);
00115         //      swap_row(A,i,r,k,nc);
00116         swap_row(P,i,r);
00117         //      swap_row(P,i,r,0,nbcol(P));
00118         // for(j=k;j<nc;j++) { swap (A(i,j), A(r,j));   }
00119       }
00120       for(i = r+1;i<nr;i++) {
00121         rows_linsub(P,i,A(r,k),r,A(i,k));
00122         //      rows_combine(P,i,A(r,k),r,-A(i,k),0,nbrow(P),0,nbcol(P));
00123         rows_linsub(A,i,A(r,k),r,A(i,k));
00124         //      rows_combine(A,i,A(r,k),r,-A(i,k),0,nr,k+1,nc);
00125 
00126         A(i, k) = 0;
00127         row_div(A,d,i);
00128         row_div(P,d,i);
00129 
00130       }
00131       d= A(r, k);
00132       r++;
00133     }
00134   }
00135 }
00136 //--------------------------------------------------------------------
00137 TMPL inline 
00138 Scalar bareiss_extended_pivoting(Matrix & A, Matrix& P) 
00139 {
00140   unsigned r=0; bareiss_extended_pivoting(A,P,r);
00141 }
00142 
00143 /******************************************************************************
00144 * Applications
00145 ******************************************************************************/
00146 
00147 TMPL unsigned
00148 bareiss_rank (const Matrix& m) {
00149   //  ASSERT (is_non_scalar (m), "non-scalar matrix expected");
00150   Matrix c (copy (m));
00151   unsigned r;
00152   bareiss_pivoting (c, r); //0, 0, nbrow(c), nbcol(c));
00153   return r;
00154 }
00155 //--------------------------------------------------------------------
00157 TMPL Matrix
00158 bareiss_triangulate (const Matrix& m) 
00159 {
00160   //  ASSERT (is_non_scalar (m), "non-scalar matrix expected");
00161   typedef Scalar C;
00162   Matrix c (copy (m));
00163   (void) bareiss_pivoting (c);
00164   return c;
00165 }
00166 
00167 //--------------------------------------------------------------------
00169 TMPL Matrix
00170 bareiss_cokernel (const Matrix& m) {
00171   //  ASSERT (is_non_scalar (m), "non-scalar matrix expected");
00172   Matrix c (copy (m));
00173   unsigned nr =nbrow(c);//, nc = nbcol(c);;
00174   Matrix p =identity_matrix<Scalar>(nr);
00175   unsigned rk=0;
00176   bareiss_extended_pivoting(c,p,rk);
00177   return range (p, rk, 0, nr, nr);
00178 }
00179 //--------------------------------------------------------------------
00185 TMPL Matrix
00186 bareiss_kernel (const Matrix& m) {
00187   //  ASSERT (is_non_scalar (m), "non-scalar matrix expected");
00188   Matrix c =transpose(m);
00189   unsigned nr =nbrow(c);//, nc = nbcol(c);
00190   Matrix p =identity_matrix<Scalar>(nr);
00191   unsigned rk=0;
00192   bareiss_extended_pivoting(c,p,rk);
00193 
00194   p = range (p, rk, 0, nr, nr);
00195   //  in_place_transpose(p);
00196   return transpose(p);
00197 }
00198 //--------------------------------------------------------------------
00199 TMPL Matrix
00200 bareiss_image (const Matrix& m) {
00201   //  ASSERT (is_non_scalar (m), "non-scalar matrix expected");
00202   Matrix c = transpose(m);
00203   unsigned 
00204     //    nr=nbrow(c), 
00205     nc=nbcol(c), rk;
00206 
00207   bareiss_pivoting(c,rk);
00208   c = range (c, 0, 0, rk, nc);
00209   return transpose(c);
00210 }
00211 //--------------------------------------------------------------------
00212 TMPL Matrix
00213 bareiss_coimage (const Matrix& m) {
00214   //  ASSERT (is_non_scalar (m), "non-scalar matrix expected");
00215 
00216   Matrix c (copy (m));
00217   unsigned 
00218     //    nr=nbrow(c), 
00219     nc=nbcol(c), rk;
00220   bareiss_pivoting(c,rk);
00221   return range (c, 0, 0, rk, nc);
00222 }
00223 
00224 //--------------------------------------------------------------------
00225 TMPL Scalar 
00226 bareiss_det (const Matrix& m) {
00227   //  ASSERT (is_non_scalar (m), "non-scalar matrix expected");
00228   ASSERT (nbcol(m) == nbrow(m), "square matrix expected");
00229   Matrix c (copy (m));
00230   unsigned r;
00231   return bareiss_pivoting (c, r);
00232 }
00233 //--------------------------------------------------------------------
00234 
00235 TMPL Matrix
00236 bareiss_krylov (const Matrix& m, const Matrix& v) {
00237   //  ASSERT (is_non_scalar (m), "non-scalar matrix expected");
00238   ASSERT (is_square_matrix (m), "square matrix expected");
00239   Matrix r= bareiss_image (v);
00240   Matrix p= m*r;
00241   while (true) {
00242     unsigned rk= nbrow (r);
00243     r= bareiss_image (horizontal_join (r, p));
00244     if (nbrow (r) <= rk) return r;
00245     p = m*p;
00246   }
00247 }
00248 //====================================================================
00249 }//end of namespace mmx
00250 //====================================================================
00251 #undef Scalar
00252 #undef TMPL
00253 #endif //mmx_matrix_bareiss_hpp
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines