00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_TRANSPOSED_VIEW_INCLUDE
00013 #define MTL_TRANSPOSED_VIEW_INCLUDE
00014
00015 #include <boost/shared_ptr.hpp>
00016 #include <boost/mpl/if.hpp>
00017 #include <boost/type_traits.hpp>
00018
00019 #include <boost/numeric/mtl/mtl_fwd.hpp>
00020 #include <boost/numeric/mtl/utility/category.hpp>
00021 #include <boost/numeric/mtl/utility/property_map_impl.hpp>
00022 #include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp>
00023 #include <boost/numeric/mtl/operation/sub_matrix.hpp>
00024 #include <boost/numeric/mtl/matrix/mat_expr.hpp>
00025
00026 namespace mtl { namespace matrix {
00027
00028
00029
00030 template <class T> struct transposed_orientation {};
00031
00032 template<> struct transposed_orientation<tag::row_major>
00033 {
00034 typedef tag::col_major type;
00035 };
00036
00037 template<> struct transposed_orientation<tag::col_major>
00038 {
00039 typedef tag::row_major type;
00040 };
00041
00042
00043
00044 template <class Matrix>
00045 struct transposed_view
00046 : public boost::mpl::if_<
00047 boost::is_const<Matrix>
00048 , const_crtp_base_matrix< const transposed_view<const Matrix>,
00049 typename Matrix::value_type, typename Matrix::size_type >
00050 , crtp_base_matrix< transposed_view<Matrix>,
00051 typename Matrix::value_type, typename Matrix::size_type >
00052 >::type,
00053 public matrix::mat_expr< transposed_view<Matrix> >
00054 {
00055 typedef transposed_view self;
00056 typedef mat_expr< self > expr_base;
00057 typedef Matrix other;
00058
00059 typedef typename transposed_orientation<typename Matrix::orientation>::type orientation;
00060 typedef typename Matrix::index_type index_type;
00061 typedef typename Matrix::value_type value_type;
00062 typedef typename Matrix::const_reference const_reference;
00063 typedef typename Matrix::key_type key_type;
00064 typedef typename Matrix::size_type size_type;
00065 typedef typename Matrix::dim_type::transposed_type dim_type;
00066 typedef matrix::parameters<orientation, index_type, dim_type> parameters;
00067
00068 typedef typename boost::mpl::if_<boost::is_const<Matrix>,
00069 const_reference,
00070 value_type&
00071 >::type access_type;
00072
00073 typedef typename boost::mpl::if_<boost::is_const<Matrix>,
00074 const Matrix&,
00075 Matrix&
00076 >::type ref_type;
00077 typedef const Matrix& const_ref_type;
00078
00079
00080 transposed_view (ref_type ref) : ref(ref) {}
00081
00082 transposed_view (boost::shared_ptr<Matrix> p) : my_copy(p), ref(*p) {}
00083
00084 const_reference operator() (size_type r, size_type c) const
00085 {
00086 return ref(c, r);
00087 }
00088
00089 access_type operator() (size_type r, size_type c)
00090 {
00091 return ref(c, r);
00092 }
00093
00094 size_type dim1() const
00095 {
00096 return ref.dim2();
00097 }
00098 size_type dim2() const
00099 {
00100 return ref.dim1();
00101 }
00102
00103 dim_type dimensions() const
00104 {
00105 return ref.dimensions().transpose();
00106 }
00107
00108 size_type begin_row() const
00109 {
00110 return ref.begin_col();
00111 }
00112
00113 size_type end_row() const
00114 {
00115 return ref.end_col();
00116 }
00117
00118 size_type begin_col() const
00119 {
00120 return ref.begin_row();
00121 }
00122
00123 size_type end_col() const
00124 {
00125 return ref.end_row();
00126 }
00127
00128 size_type nnz() const
00129 {
00130 return ref.nnz();
00131 }
00132
00133 friend size_type inline num_rows(const self& A)
00134 {
00135 using mtl::matrix::num_cols; return num_cols(A.ref);
00136 }
00137 friend size_type inline num_cols(const self& A)
00138 {
00139 using mtl::matrix::num_rows; return num_rows(A.ref);
00140 }
00141 friend size_type inline size(const self& A)
00142 {
00143 using mtl::matrix::num_rows; using mtl::matrix::num_cols;
00144 return num_rows(A.ref) * num_rows(A.ref);
00145 }
00146
00147 protected:
00148 boost::shared_ptr<Matrix> my_copy;
00149 public:
00150 ref_type ref;
00151 };
00152
00153
00154
00155
00156
00157
00158
00159 template <typename Matrix>
00160 struct sub_matrix_t< transposed_view<Matrix> >
00161 {
00162 typedef transposed_view<Matrix> matrix_type;
00163 typedef typename boost::remove_const<Matrix>::type tmp_type;
00164
00165
00166 typedef transposed_view<typename sub_matrix_t<tmp_type>::sub_matrix_type> sub_matrix_type;
00167 typedef transposed_view<typename sub_matrix_t<tmp_type>::const_sub_matrix_type> const_sub_matrix_type;
00168 typedef typename matrix_type::size_type size_type;
00169
00170 sub_matrix_type operator()(matrix_type& A, size_type begin_r, size_type end_r, size_type begin_c, size_type end_c)
00171 {
00172 typedef typename sub_matrix_t<Matrix>::sub_matrix_type ref_sub_type;
00173 typedef boost::shared_ptr<ref_sub_type> pointer_type;
00174
00175
00176
00177 pointer_type p(new ref_sub_type(sub_matrix(A.ref, begin_c, end_c, begin_r, end_r)));
00178 return sub_matrix_type(p);
00179 }
00180
00181 const_sub_matrix_type operator()(matrix_type const& A, size_type begin_r, size_type end_r,
00182 size_type begin_c, size_type end_c)
00183 {
00184 typedef typename sub_matrix_t<Matrix>::const_sub_matrix_type ref_sub_type;
00185 typedef boost::shared_ptr<ref_sub_type> pointer_type;
00186
00187
00188
00189 pointer_type p(new ref_sub_type(sub_matrix(A.ref, begin_c, end_c, begin_r, end_r)));
00190 return const_sub_matrix_type(p);
00191 }
00192
00193 };
00194
00195 }}
00196
00197 namespace mtl { namespace traits {
00198
00199
00200 namespace detail {
00201
00202 template <class Matrix, class Ref>
00203 struct transposed_row
00204 {
00205 typedef typename Matrix::key_type key_type;
00206 typedef typename Matrix::size_type size_type;
00207
00208 transposed_row(mtl::matrix::transposed_view<Ref> const& transposed_matrix)
00209 : its_col(transposed_matrix.ref) {}
00210
00211 size_type operator() (key_type const& key) const
00212 {
00213 return its_col(key);
00214 }
00215
00216 protected:
00217 typename col<typename boost::remove_const<Matrix>::type>::type its_col;
00218 };
00219
00220
00221 template <class Matrix, class Ref>
00222 struct transposed_col
00223 {
00224 typedef typename Matrix::key_type key_type;
00225 typedef typename Matrix::size_type size_type;
00226
00227 transposed_col(mtl::matrix::transposed_view<Ref> const& transposed_matrix)
00228 : its_row(transposed_matrix.ref) {}
00229
00230 size_type operator() (key_type const& key) const
00231 {
00232 return its_row(key);
00233 }
00234
00235 protected:
00236 typename row<typename boost::remove_const<Matrix>::type>::type its_row;
00237 };
00238
00239 }
00240
00241 template <class Matrix>
00242 struct row<matrix::transposed_view<Matrix> >
00243 {
00244 typedef detail::transposed_row<Matrix, Matrix> type;
00245 };
00246
00247 template <class Matrix>
00248 struct col<matrix::transposed_view<Matrix> >
00249 {
00250 typedef detail::transposed_col<Matrix, Matrix> type;
00251 };
00252
00253 template <class Matrix>
00254 struct const_value<mtl::matrix::transposed_view<Matrix> >
00255 {
00256 typedef mtl::detail::const_value_from_other<mtl::matrix::transposed_view<Matrix> > type;
00257 };
00258
00259
00260 template <class Matrix>
00261 struct value<mtl::matrix::transposed_view<Matrix> >
00262 {
00263 typedef mtl::detail::value_from_other<mtl::matrix::transposed_view<Matrix> > type;
00264 };
00265
00266
00267
00268
00269
00270
00271 namespace detail
00272 {
00273 template <class UseTag, class Matrix>
00274 struct range_transposer_impl
00275 {
00276 typedef range_generator<UseTag, typename boost::remove_const<Matrix>::type> generator;
00277
00278 typedef typename generator::complexity complexity;
00279 typedef typename generator::type type;
00280 static int const level = generator::level;
00281 type begin(mtl::matrix::transposed_view<Matrix> const& m)
00282 {
00283 return generator().begin(m.ref);
00284 }
00285 type end(mtl::matrix::transposed_view<Matrix> const& m)
00286 {
00287 return generator().end(m.ref);
00288 }
00289 };
00290
00291
00292
00293
00294 template <class UseTag, class Matrix>
00295 struct range_transposer
00296 : boost::mpl::if_<
00297 boost::is_same<typename range_generator<UseTag, typename boost::remove_const<Matrix>::type>::complexity,
00298 complexity_classes::infinite>
00299 , range_generator<tag::unsupported, Matrix>
00300 , range_transposer_impl<UseTag, Matrix>
00301 >::type {};
00302 }
00303
00304
00305 template <class Matrix>
00306 struct range_generator<glas::tag::col, matrix::transposed_view<Matrix> >
00307 : detail::range_transposer<glas::tag::row, Matrix>
00308 {};
00309
00310 template <class Matrix>
00311 struct range_generator<glas::tag::row, matrix::transposed_view<Matrix> >
00312 : detail::range_transposer<glas::tag::col, Matrix>
00313 {};
00314
00315
00316
00317 template <class Matrix>
00318 struct range_generator<tag::major, matrix::transposed_view<Matrix> >
00319 : detail::range_transposer<tag::major, Matrix>
00320 {};
00321
00322
00323
00324 template <class Tag, class Matrix>
00325 struct range_generator<Tag, matrix::transposed_view<Matrix> >
00326 : detail::range_transposer<Tag, Matrix>
00327 {};
00328
00329
00330
00331 }}
00332
00333 #endif // MTL_TRANSPOSED_VIEW_INCLUDE
00334
00335
00336