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