algebramix_doc 0.3
|
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