algebramix_doc 0.3
|
00001 00002 /****************************************************************************** 00003 * MODULE : structured_block.hpp 00004 * DESCRIPTION: block algorithms for structured matrices 00005 * COPYRIGHT : (C) 2009 Joris van der Hoeven 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 00013 #ifndef __MMX__STRUCTURED_BLOCK__HPP 00014 #define __MMX__STRUCTURED_BLOCK__HPP 00015 #include <algebramix/structured_naive.hpp> 00016 #include <algebramix/matrix_block.hpp> 00017 00018 namespace mmx { 00019 00020 /****************************************************************************** 00021 * Multiplication of structured matrices 00022 ******************************************************************************/ 00023 00024 struct matrix_structured_multiply {}; 00025 00026 template<typename V> 00027 struct implementation<matrix_structured_multiply,V,matrix_naive>: 00028 public implementation<matrix_multiply,V> 00029 { 00030 typedef implementation<matrix_multiply,V> Mat; 00031 typedef implementation<vector_linear,V> Vec; 00032 00033 static inline 00034 half_size (nat n) { 00035 return (n+1) >> 1; 00036 } 00037 00038 template<typename Op, 00039 typename TD, typename T1, typename T2, 00040 typename D , typename S1, typename S2> static void 00041 smul (D* d, const S1* s1, const S2* s2, 00042 nat r, nat rr, nat l, nat ll, nat c, nat cc); 00043 00044 template<typename TD, typename T1, typename T2> 00045 struct structured_helper { 00046 template<typename Op, typename D, typename S1, typename S2> static void 00047 mul (D* d, const S1* s1, const S2* s2, 00048 nat r, nat rr, nat l, nat ll, nat c, nat cc) { 00049 typedef typename Op::acc_op Acc; 00050 if (l == 0) Mat::clr<Op> (d, r, rr, c, cc); 00051 else if (l == 1) Op::set_op (*d, *s1, *s2); 00052 else { 00053 nat hr= half_size (r); 00054 nat hl= half_size (l); 00055 nat hc= half_size (c); 00056 00057 smul<Op, typename TD::ul, typename T1::ul, typename T2::ul> 00058 (d, 00059 s1, 00060 s2, 00061 hr, rr, hl, ll, hc, cc); 00062 smul<Acc, typename TD::ul, typename T1::ur, typename T2::ll> 00063 (d, 00064 s1 + Mat::index (0, hl, rr, ll), 00065 s2 + Mat::index (hl, 0, ll, cc), 00066 hr, rr, ll - hl, ll, hc, cc); 00067 smul<Op, typename TD::ur, typename T1::ul, typename T2::ur> 00068 (d + Mat::index (0, hc, rr, cc), 00069 s1, 00070 s2 + Mat::index (0, hc, ll, cc), 00071 hr, rr, hl, ll, cc - hc, cc); 00072 smul<Acc, typename TD::ur, typename T1::ur, typename T2::lr> 00073 (d + Mat::index (0, hc, rr, cc), 00074 s1 + Mat::index (0, hl, rr, ll), 00075 s2 + Mat::index (hl, hc, ll, cc), 00076 hr, rr, ll - hl, ll, cc - hc, cc); 00077 00078 smul<Op, typename TD::ll, typename T1::lr, typename T2::ll> 00079 (d + Mat::index (hr, 0, rr, cc), 00080 s1 + Mat::index (hr, hl, rr, ll), 00081 s2 + Mat::index (hl, 0, ll, cc), 00082 rr - hr, rr, ll - hl, ll, hc, cc); 00083 smul<Acc, typename TD::ll, typename T1::ll, typename T2::ul> 00084 (d + Mat::index (hr, 0, rr, cc), 00085 s1 + Mat::index (hr, 0, rr, ll), 00086 s2, 00087 rr - hr, rr, hl, ll, hc, cc); 00088 smul<Op, typename TD::lr, typename T1::lr, typename T2::lr> 00089 (d + Mat::index (hr, hc, rr, cc), 00090 s1 + Mat::index (hr, hl, rr, ll), 00091 s2 + Mat::index (hl, hc, ll, cc), 00092 rr - hr, rr, ll - hl, ll, cc - hc, cc); 00093 smul<Acc, typename TD::lr, typename T1::ll, typename T2::ur> 00094 (d + Mat::index (hr, hc, rr, cc), 00095 s1 + Mat::index (hr, 0, rr, ll), 00096 s2 + Mat::index (0, hc, ll, cc), 00097 rr - hr, rr, hl, ll, cc - hc, cc); 00098 } 00099 } 00100 }; 00101 00102 struct noop_helper { 00103 template<typename Op, typename D, typename S1, typename S2> 00104 static inline void 00105 mul (D* d, const S1* s1, const S2* s2, 00106 nat r, nat rr, nat l, nat ll, nat c, nat cc) { 00107 (void) d; (void) s1; (void) s2; 00108 (void) r; (void) rr; (void) l; (void) ll; (void) c; (void) cc; 00109 } 00110 }; 00111 00112 template<typename T1, typename T2> 00113 struct structured_helper<zero_matrix,T1,T2>: public noop_helper {}; 00114 00115 template<typename TD, typename T2> 00116 struct structured_helper<TD,zero_matrix,T2>: public noop_helper {}; 00117 00118 template<typename TD, typename T1> 00119 struct structured_helper<TD,T1,zero_matrix>: public noop_helper {}; 00120 00121 template<typename TD> 00122 struct structured_helper<TD,zero_matrix,zero_matrix>: public noop_helper {}; 00123 00124 template<typename T1> 00125 struct structured_helper<zero_matrix,T1,zero_matrix>: public noop_helper {}; 00126 00127 template<typename T2> 00128 struct structured_helper<zero_matrix,zero_matrix,T2>: public noop_helper {}; 00129 00130 template<> 00131 struct structured_helper<zero_matrix,zero_matrix,zero_matrix>: 00132 public noop_helper {}; 00133 00134 template<typename Op, 00135 typename TD, typename T1, typename T2, 00136 typename D, typename S1, typename S2> static inline void 00137 smul (D* d, const S1* s1, const S2* s2, 00138 nat r, nat rr, nat l, nat ll, nat c, nat cc) { 00139 structured_helper<TD,T1,T2>::template mul<Op> 00140 (d, s1, s2, r, rr, l, ll, c, cc); 00141 } 00142 00143 }; // implementation<matrix_structured,V,matrix_naive> 00144 00145 } // namespace mmx 00146 #endif //__MMX__STRUCTURED_BLOCK__HPP