00001
00002
00003
00004
00005
00006
00007
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)){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;
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
00183
00184
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
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;
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) || ...