00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__MATRIX_BAREISS__HPP
00014 #define __MMX__MATRIX_BAREISS__HPP
00015 #include <algebramix/matrix.hpp>
00016
00017 namespace mmx {
00018 #define TMPL template<typename C>
00019
00020
00021
00022
00023
00024 template<typename V>
00025 struct matrix_bareiss: public V {
00026 typedef typename V::Vec Vec;
00027 typedef matrix_bareiss<typename V::Naive> Naive;
00028 typedef matrix_bareiss<typename V::Positive> Positive;
00029 typedef matrix_bareiss<typename V::No_simd> No_simd;
00030 typedef matrix_bareiss<typename V::No_thread> No_thread;
00031 typedef matrix_bareiss<typename V::No_scaled> No_scaled;
00032 };
00033
00034 template<typename F, typename V, typename W>
00035 struct implementation<F,V,matrix_bareiss<W> >:
00036 public implementation<F,V,W> {};
00037
00038
00039
00040
00041
00042 template<typename V,typename W>
00043 struct implementation<matrix_determinant,V,matrix_bareiss<W> >:
00044 public implementation<matrix_echelon,V>
00045 {
00046 typedef implementation<matrix_linear,V> Mat;
00047
00048 TMPL static void
00049 bareiss_pivoting (C& d, C* m, nat r, nat c) {
00050 nat l= 0, i;
00051 int s= 1;
00052 set_as (d, 1);
00053 for (nat k= 0; k < min (r, c) && l < r; k++) {
00054 for (i= l; i < r && Mat::entry (m, i, k, r, c) == 0; i++) {}
00055 if (i < r) {
00056 if (i != l) {
00057 s *= -1;
00058 Mat::row_swap (m, i, l, r, c);
00059 }
00060 for (i = l+1; i < r; i++) {
00061 C si= Mat::entry (m, i, k, r, c);
00062 C sl= Mat::entry (m, l, k, r, c);
00063 Mat::row_combine_sub (m, i, sl, l, si, r, c);
00064 Mat::row_div (m, d, i, r, c);
00065 }
00066 d= Mat::entry (m, l, k, r, c);
00067 l++;
00068 }
00069 }
00070 d= Mat::entry (m, r-1, c-1, r, c);
00071 if (s == -1) d= -d; }
00072
00073 TMPL static void
00074 det (C& r, const C* m, nat n) {
00075 if (n == 0) { set_as (r, 1); return; }
00076 nat len_c= aligned_size<C,V> (n * n);
00077 C* c= mmx_new<C> (len_c);
00078 Mat::copy (c, m, n, n);
00079 bareiss_pivoting (r, c, n, n);
00080 mmx_delete<C> (c, len_c); }
00081 };
00082
00083 #undef TMPL
00084 }
00085 #endif //__MMX__MATRIX_BAREISS__HPP