00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_SMAT_SMAT_MULT_INCLUDE
00013 #define MTL_SMAT_SMAT_MULT_INCLUDE
00014
00015 #include <boost/numeric/mtl/mtl_fwd.hpp>
00016 #include <boost/numeric/mtl/matrix/compressed2D.hpp>
00017 #include <boost/numeric/mtl/matrix/parameter.hpp>
00018 #include <boost/numeric/mtl/utility/tag.hpp>
00019 #include <boost/numeric/mtl/operation/mult_assign_mode.hpp>
00020
00021 namespace mtl {
00022
00023 template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign>
00024 inline void smat_smat_mult(const MatrixA& a, const MatrixB& b, MatrixC& c, Assign,
00025 tag::row_major,
00026 tag::row_major)
00027 {
00028 if (Assign::init_to_zero) set_to_zero(c);
00029
00030
00031 double ava= num_rows(a) ? double(a.nnz()) / num_rows(a) : 0,
00032 avb= num_rows(b) ? double(b.nnz()) / num_rows(b) : 0;
00033
00034
00035 typedef typename Collection<MatrixC>::value_type c_value_type;
00036 typedef typename operations::update_assign_mode<Assign, c_value_type>::type Updater;
00037
00038
00039 matrix::inserter<MatrixC, Updater> ins(c, int( ava * avb * 1.2 ));
00040
00041 typename traits::row<MatrixA>::type row_a(a);
00042 typename traits::col<MatrixA>::type col_a(a);
00043 typename traits::const_value<MatrixA>::type value_a(a);
00044
00045 typename traits::col<MatrixB>::type col_b(b);
00046 typename traits::const_value<MatrixB>::type value_b(b);
00047
00048 typedef typename traits::range_generator<tag::row, MatrixA>::type cursor_type;
00049 cursor_type cursor = begin<tag::row>(a), cend = end<tag::row>(a);
00050 for (unsigned ra= 0; cursor != cend; ++ra, ++cursor) {
00051
00052 typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type;
00053 for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) {
00054 typename Collection<MatrixA>::size_type ca= col_a(*icursor);
00055 typename Collection<MatrixA>::value_type va= value_a(*icursor);
00056
00057
00058 typedef typename traits::range_generator<tag::row, MatrixB>::type b_cursor_type;
00059 b_cursor_type b_cursor = begin<tag::row>(b);
00060 b_cursor+= ca;
00061
00062
00063 typedef typename traits::range_generator<tag::nz, b_cursor_type>::type ib_cursor_type;
00064 for (ib_cursor_type ib_cursor = begin<tag::nz>(b_cursor), ib_cend = end<tag::nz>(b_cursor);
00065 ib_cursor != ib_cend; ++ib_cursor) {
00066 typename Collection<MatrixB>::size_type cb= col_b(*ib_cursor);
00067 typename Collection<MatrixB>::value_type vb= value_b(*ib_cursor);
00068 ins(ra, cb) << va * vb;
00069 }
00070 }
00071 }
00072 }
00073
00074 template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign>
00075 inline void smat_smat_mult(const MatrixA& a, const MatrixB& b, MatrixC& c, Assign,
00076 tag::col_major,
00077 tag::col_major)
00078 {
00079 if (Assign::init_to_zero) set_to_zero(c);
00080
00081
00082 double ava= double(a.nnz()) / num_cols(a), avb= double(b.nnz()) / num_cols(b);
00083
00084
00085 typedef typename Collection<MatrixC>::value_type c_value_type;
00086 typedef typename operations::update_assign_mode<Assign, c_value_type>::type Updater;
00087
00088
00089 matrix::inserter<MatrixC, Updater> ins(c, int( ava * avb * 1.2 ));
00090
00091 typename traits::row<MatrixA>::type row_a(a);
00092 typename traits::col<MatrixA>::type col_a(a);
00093 typename traits::const_value<MatrixA>::type value_a(a);
00094
00095 typename traits::row<MatrixB>::type row_b(b);
00096 typename traits::col<MatrixB>::type col_b(b);
00097 typename traits::const_value<MatrixB>::type value_b(b);
00098
00099 typedef typename traits::range_generator<tag::col, MatrixB>::type cursor_type;
00100 cursor_type cursor = begin<tag::col>(b), cend = end<tag::col>(b);
00101 for (unsigned cb= 0; cursor != cend; ++cb, ++cursor) {
00102
00103 typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type;
00104 for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) {
00105 typename Collection<MatrixB>::size_type rb= row_b(*icursor);
00106 typename Collection<MatrixB>::value_type vb= value_b(*icursor);
00107
00108
00109 typedef typename traits::range_generator<tag::col, MatrixA>::type a_cursor_type;
00110 a_cursor_type a_cursor = begin<tag::col>(a);
00111 a_cursor+= rb;
00112
00113
00114 typedef typename traits::range_generator<tag::nz, a_cursor_type>::type ia_cursor_type;
00115 for (ia_cursor_type ia_cursor = begin<tag::nz>(a_cursor), ia_cend = end<tag::nz>(a_cursor);
00116 ia_cursor != ia_cend; ++ia_cursor) {
00117 typename Collection<MatrixA>::size_type ra= row_a(*ia_cursor);
00118 typename Collection<MatrixA>::value_type va= value_a(*ia_cursor);
00119 ins(ra, cb) << va * vb;
00120 }
00121 }
00122 }
00123 }
00124
00125
00126 template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign>
00127 inline void smat_smat_mult(const MatrixA& a, const MatrixB& b, MatrixC& c, Assign,
00128 tag::col_major,
00129 tag::row_major)
00130 {
00131 if (Assign::init_to_zero) set_to_zero(c);
00132
00133
00134 double ava= double(a.nnz()) / num_rows(a), avb= double(b.nnz()) / num_rows(b);
00135
00136
00137 typedef typename Collection<MatrixC>::value_type c_value_type;
00138 typedef typename operations::update_assign_mode<Assign, c_value_type>::type Updater;
00139
00140
00141 matrix::inserter<MatrixC, Updater> ins(c, int( ava * avb * 1.2 ));
00142
00143 typename traits::row<MatrixA>::type row_a(a);
00144 typename traits::col<MatrixA>::type col_a(a);
00145 typename traits::const_value<MatrixA>::type value_a(a);
00146
00147 typename traits::row<MatrixB>::type row_b(b);
00148 typename traits::col<MatrixB>::type col_b(b);
00149 typename traits::const_value<MatrixB>::type value_b(b);
00150
00151 typedef typename traits::range_generator<tag::col, MatrixA>::type a_cursor_type;
00152 a_cursor_type a_cursor = begin<tag::col>(a), a_cend = end<tag::col>(a);
00153
00154 typedef typename traits::range_generator<tag::row, MatrixB>::type b_cursor_type;
00155 b_cursor_type b_cursor = begin<tag::row>(b);
00156
00157 for (unsigned ca= 0; a_cursor != a_cend; ++ca, ++a_cursor, ++b_cursor) {
00158
00159
00160 typedef typename traits::range_generator<tag::nz, a_cursor_type>::type ia_cursor_type;
00161 for (ia_cursor_type ia_cursor = begin<tag::nz>(a_cursor), ia_cend = end<tag::nz>(a_cursor);
00162 ia_cursor != ia_cend; ++ia_cursor)
00163 {
00164 typename Collection<MatrixA>::size_type ra= row_a(*ia_cursor);
00165 typename Collection<MatrixA>::value_type va= value_a(*ia_cursor);
00166
00167
00168 typedef typename traits::range_generator<tag::nz, b_cursor_type>::type ib_cursor_type;
00169 for (ib_cursor_type ib_cursor = begin<tag::nz>(b_cursor), ib_cend = end<tag::nz>(b_cursor);
00170 ib_cursor != ib_cend; ++ib_cursor)
00171 {
00172 typename Collection<MatrixB>::size_type cb= col_b(*ib_cursor);
00173 typename Collection<MatrixB>::value_type vb= value_b(*ib_cursor);
00174 ins(ra, cb) << va * vb;
00175 }
00176 }
00177 }
00178 }
00179
00180
00181 template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign>
00182 inline void smat_smat_mult(const MatrixA& a, const MatrixB& b, MatrixC& c, Assign,
00183 tag::row_major,
00184 tag::col_major)
00185 {
00186
00187 compressed2D<typename Collection<MatrixB>::value_type, matrix::parameters<> > b_copy(num_rows(b), num_cols(b));
00188 b_copy= b;
00189 smat_smat_mult(a, b_copy, c, Assign(), tag::row_major(), tag::row_major());
00190 }
00191
00192 }
00193
00194 #endif // MTL_SMAT_SMAT_MULT_INCLUDE