bareiss.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     bareiss.cpp -- See declarations in bareiss.hpp.
00004 
00005     This file is a part of the Arageli library.
00006 
00007     Copyright (C) Anna Bestaeva, 2006
00008 
00009 *****************************************************************************/
00010 
00017 #include "config.hpp"
00018 
00019 #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || \
00020     defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_bareiss)
00021 
00022 #include <cstddef>
00023 
00024 #include "factory.hpp"
00025 #include "cmp.hpp"
00026 #include "vector.hpp"
00027 
00028 #include "bareiss.hpp"
00029 
00030 #include "std_import.hpp"
00031 
00032 
00033 namespace Arageli
00034 {
00035 
00036 
00037 template
00038 <
00039     typename MA,
00040     typename MB,
00041     typename MQ,
00042     typename Basis,
00043     typename T_det
00044 >
00045 void bareiss
00046 (
00047     const MA& A, MB& B, MQ& Q,
00048     Basis& basis, T_det& det
00049 )
00050 {
00051     typedef typename MB::element_type T_B;
00052     
00053     std::size_t m = A.nrows(), n = A.ncols();
00054     Q.assign_eye(m);
00055     basis.resize(0);
00056     det = unit(det);
00057     T_B d = unit(d);
00058     B = A;
00059             
00060     for(std::size_t i = 0, j = 0; i < m && j < n; j++)
00061     {   T_B max = null(B(0, 0));
00062         std::size_t i_max = i;
00063         
00064         for(std::size_t ii = i; ii < m; ii++)if(abs(B(ii, j)) > max)
00065         {   max = abs(B(ii, j));
00066             i_max = ii;
00067         }
00068         
00069         if(is_null(max)){/*det = null(det);*/continue;}
00070         
00071         if(i != i_max)
00072         {  B.swap_rows(i, i_max);
00073            Q.swap_rows(i, i_max);
00074            opposite(&det);
00075         }
00076 
00077         if(is_negative(B(i, j)))    
00078         {  B.mult_row(i, -1);
00079            Q.mult_row(i, -1);
00080            opposite(&det);  
00081         }                  
00082         
00083         T_B pivot = B(i, j);
00084 
00085         for(std::size_t ii = 0; ii < m; ii++)if(ii != i)
00086         {   T_B alpha = B(ii, j);
00087             B.mult_row(ii, pivot);
00088             B.addmult_rows(ii, i,  -alpha);
00089             B.div_row(ii, d);
00090 
00091             Q.mult_row(ii, pivot);
00092             Q.addmult_rows(ii, i,  -alpha);
00093             Q.div_row(ii, d);
00094         }
00095 
00096         d = B(i, j);
00097         basis.push_back(j);
00098         i++;
00099         
00100     } 
00101     det *= d;
00102 }
00103 
00104 
00105 template
00106 <
00107     typename MA,
00108     typename MP,
00109     typename MQ,
00110     typename Rank,
00111     typename T_det
00112 >
00113 void bareiss_pq
00114 (
00115     const MA& A, MP& P, MQ& Q,
00116     Rank& rank, T_det& det
00117 )
00118 {   
00119     typedef typename MA::element_type T_A;
00120 
00121     std::size_t m = A.nrows(), n = A.ncols();
00122     MA B = A;//matrix<T_A, false> B = A;
00123     P.assign_eye(m);
00124     Q.assign_eye(n);
00125     rank = null(rank);
00126     det = unit(det);
00127     T_A d = unit(d);
00128                 
00129     for(std::size_t r = 0; r < std::min(m, n); r++)
00130     {   T_A max = null(B(0, 0));
00131         std::size_t i_max = r, j_max = r, j = r;
00132         
00133         while(is_null(max) && j < n)
00134         {     for (std::size_t i = r; i < m; i++)
00135                if (abs(B(i, j)) > max)
00136                {   max = abs(B(i, j));
00137                    i_max = i;
00138                    j_max = j;
00139                }
00140               j++;
00141         }
00142         
00143         if(is_null(max)) break;
00144         
00145         if(r != i_max)
00146         {  B.swap_rows(r, i_max);
00147            P.swap_rows(r, i_max);
00148            opposite(&det);
00149         }
00150 
00151         if(r != j_max)
00152         {  B.swap_cols(r, j_max);
00153            Q.swap_cols(r, j_max);
00154            opposite(&det);
00155         }
00156 
00157         if(is_negative(B(r, r)))    
00158         {  B.mult_row(r, -1);
00159            P.mult_row(r, -1);
00160            opposite(&det);  
00161         }                  
00162         
00163         T_A pivot = B(r, r);
00164 
00165         for(std::size_t i = r + 1; i < m; i++)
00166         {   T_A alpha = B(i, r);
00167             B.mult_row(i, pivot);
00168             B.addmult_rows(i, r, -alpha);
00169             B.div_row(i, d);
00170         }
00171 
00172         d = B(r, r);
00173         rank++; 
00174     } 
00175     det *= d;
00176 }
00177 
00178 
00179 
00180 template <typename MA> MA adjoint (const MA& A)
00181 {
00182     // Why false/true:
00183     //matrix<T, false> B;
00184     //matrix<T, true> Q;
00185 
00186     MA B, Q;
00187     vector<std::size_t, false> basis;
00188     typename MA::element_type det;
00189 
00190     bareiss(A, B, Q, basis, det);
00191 
00192     return Q;
00193 }
00194 
00195 
00196 template 
00197 <
00198     typename MA,
00199     typename MP,
00200     typename T_det
00201 >
00202 void adjoint (const MA& A, MP& P, T_det& det)
00203 {
00204     //matrix<T_A, false> B;
00205     MA B;
00206     vector<std::size_t, false> basis;
00207     bareiss(A, B, P, basis, det);
00208 }
00209 
00210 
00211 template <typename MA>
00212 typename MA::element_type det_brs (const MA& A)
00213 {
00214     typename MA::size_type rank;
00215     MA P, Q;//matrix<T, false>  P, Q;
00216     typename MA::element_type det;
00217 
00218     bareiss_pq(A, P, Q, rank, det);
00219 
00220     return det;
00221 }
00222 
00223 
00224 template <typename MA>
00225 typename MA::size_type rank_brs (const MA& A)
00226 {   
00227     typename MA::size_type rank;
00228     MA P, Q;
00229     typename MA::element_type det;
00230 
00231     bariess(A, P, Q, rank, det);
00232 
00233     return rank;
00234 }
00235 
00236 
00237 }
00238 
00239 
00240 #endif  // #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || ...

Generated on Thu Aug 31 17:38:04 2006 for Arageli by  doxygen 1.4.7