00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_MAP_VIEW_INCLUDE
00013 #define MTL_MAP_VIEW_INCLUDE
00014
00015 #include <boost/shared_ptr.hpp>
00016 #include <boost/numeric/mtl/utility/category.hpp>
00017 #include <boost/numeric/mtl/utility/range_generator.hpp>
00018 #include <boost/numeric/mtl/utility/property_map.hpp>
00019 #include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp>
00020 #include <boost/numeric/mtl/operation/sub_matrix.hpp>
00021 #include <boost/numeric/mtl/operation/sfunctor.hpp>
00022 #include <boost/numeric/mtl/operation/tfunctor.hpp>
00023 #include <boost/numeric/mtl/operation/conj.hpp>
00024 #include <boost/numeric/mtl/matrix/mat_expr.hpp>
00025
00026
00027
00028 namespace mtl { namespace matrix { namespace detail {
00029
00030 template <typename, typename> struct map_value;
00031 }}}
00032
00033 namespace mtl { namespace matrix {
00034
00035 template <typename Functor, typename Matrix>
00036 struct map_view
00037 : public const_crtp_base_matrix< map_view<Functor, Matrix>,
00038 typename Functor::result_type, typename Matrix::size_type >,
00039 public mat_expr< map_view<Functor, Matrix> >
00040 {
00041 typedef map_view self;
00042 typedef mat_expr< self > expr_base;
00043 typedef Matrix other;
00044 typedef const Matrix& const_ref_type;
00045 typedef typename Matrix::orientation orientation;
00046
00047 typedef typename Functor::result_type value_type;
00048 typedef typename Functor::result_type const_reference;
00049
00050 typedef typename Matrix::key_type key_type;
00051 typedef typename Matrix::size_type size_type;
00052 typedef typename Matrix::dim_type dim_type;
00053
00054 map_view (const Functor& functor, const other& ref)
00055 : expr_base(*this), functor(functor), ref(ref)
00056 {}
00057
00058 map_view (const Functor& functor, boost::shared_ptr<Matrix> p)
00059 : expr_base(*this), functor(functor), my_copy(p), ref(*p)
00060 {}
00061
00062 value_type operator() (size_type r, size_type c) const
00063 {
00064 return functor(ref(r, c));
00065 }
00066
00067 size_type dim1() const
00068 {
00069 return ref.dim1();
00070 }
00071 size_type dim2() const
00072 {
00073 return ref.dim2();
00074 }
00075
00076 dim_type dimensions() const
00077 {
00078 return ref.dimensions();
00079 }
00080
00081 size_type begin_row() const
00082 {
00083 return ref.begin_row();
00084 }
00085
00086 size_type end_row() const
00087 {
00088 return ref.end_row();
00089 }
00090
00091 size_type begin_col() const
00092 {
00093 return ref.begin_col();
00094 }
00095
00096 size_type end_col() const
00097 {
00098 return ref.end_col();
00099 }
00100
00101 size_type nnz() const
00102 {
00103 return ref.nnz();
00104 }
00105
00106 friend size_type inline num_rows(const self& A)
00107 {
00108 using mtl::matrix::num_rows; return num_rows(A.ref);
00109 }
00110 friend size_type inline num_cols(const self& A)
00111 {
00112 using mtl::matrix::num_cols; return num_cols(A.ref);
00113 }
00114 friend size_type inline size(const self& A)
00115 {
00116 using mtl::matrix::num_rows; using mtl::matrix::num_cols;
00117 return num_rows(A.ref) * num_rows(A.ref);
00118 }
00119
00120 template <typename, typename> friend struct detail::map_value;
00121
00122 protected:
00123 boost::shared_ptr<Matrix> my_copy;
00124 public:
00125 Functor functor;
00126 const other& ref;
00127 };
00128
00129
00130
00131
00132
00133
00134 template <typename Functor, typename Matrix>
00135 struct sub_matrix_t< mtl::matrix::map_view<Functor, Matrix> >
00136 {
00137 typedef mtl::matrix::map_view<Functor, Matrix> view_type;
00138
00139
00140 typedef typename sub_matrix_t<Matrix>::const_sub_matrix_type ref_sub_type;
00141 typedef mtl::matrix::map_view<Functor, ref_sub_type> const_sub_matrix_type;
00142 typedef typename view_type::size_type size_type;
00143
00144 const_sub_matrix_type operator()(view_type const& view, size_type begin_r, size_type end_r,
00145 size_type begin_c, size_type end_c)
00146 {
00147 typedef boost::shared_ptr<ref_sub_type> pointer_type;
00148
00149
00150
00151
00152 pointer_type p(new ref_sub_type(sub_matrix(view.ref, begin_r, end_r, begin_c, end_c)));
00153 return const_sub_matrix_type(view.functor, p);
00154 }
00155 };
00156
00157
00158 }}
00159
00160
00161 namespace mtl { namespace traits {
00162
00163 namespace detail {
00164
00165
00166 template <typename Functor, typename Matrix>
00167 struct map_value
00168 {
00169 typedef typename Matrix::key_type key_type;
00170 typedef typename mtl::matrix::map_view<Functor, Matrix>::value_type value_type;
00171
00172 map_value(mtl::matrix::map_view<Functor, Matrix> const& map_matrix)
00173 : map_matrix(map_matrix), its_value(map_matrix.ref)
00174 {}
00175
00176 value_type operator() (key_type const& key) const
00177 {
00178 return map_matrix.functor(its_value(key));
00179 }
00180
00181 protected:
00182 mtl::matrix::map_view<Functor, Matrix> const& map_matrix;
00183 typename mtl::traits::const_value<Matrix>::type its_value;
00184 };
00185
00186 template <typename Functor, typename Matrix>
00187 struct mapped_row
00188 {
00189 typedef typename Matrix::key_type key_type;
00190 typedef typename Matrix::size_type size_type;
00191
00192 explicit mapped_row(const mtl::matrix::map_view<Functor, Matrix>& view) : its_row(view.ref) {}
00193 explicit mapped_row(const mtl::matrix::banded_view<Matrix>& view) : its_row(view.ref) {}
00194
00195 size_type operator() (key_type const& key) const
00196 {
00197 return its_row(key);
00198 }
00199
00200 protected:
00201 typename row<Matrix>::type its_row;
00202 };
00203
00204
00205 template <typename Functor, typename Matrix>
00206 struct mapped_col
00207 {
00208 typedef typename Matrix::key_type key_type;
00209 typedef typename Matrix::size_type size_type;
00210
00211 mapped_col(const mtl::matrix::map_view<Functor, Matrix>& view) : its_col(view.ref) {}
00212 mapped_col(const mtl::matrix::banded_view<Matrix>& view) : its_col(view.ref) {}
00213
00214 size_type operator() (key_type const& key) const
00215 {
00216 return its_col(key);
00217 }
00218
00219 protected:
00220 typename col<Matrix>::type its_col;
00221 };
00222
00223 }
00224
00225 template <typename Functor, typename Matrix>
00226 struct row<mtl::matrix::map_view<Functor, Matrix> >
00227 {
00228 typedef detail::mapped_row<Functor, Matrix> type;
00229 };
00230
00231 template <typename Functor, typename Matrix>
00232 struct col<mtl::matrix::map_view<Functor, Matrix> >
00233 {
00234 typedef detail::mapped_col<Functor, Matrix> type;
00235 };
00236
00237 template <typename Functor, typename Matrix>
00238 struct const_value<mtl::matrix::map_view<Functor, Matrix> >
00239 {
00240 typedef detail::map_value<Functor, Matrix> type;
00241 };
00242
00243
00244
00245
00246
00247
00248
00249 template <typename Tag, typename Functor, typename Matrix>
00250 struct range_generator<Tag, mtl::matrix::map_view<Functor, Matrix> >
00251 : public detail::referred_range_generator<mtl::matrix::map_view<Functor, Matrix>,
00252 range_generator<Tag, Matrix> >
00253 {};
00254
00255
00256 template <typename Functor, typename Matrix>
00257 struct range_generator<tag::major, mtl::matrix::map_view<Functor, Matrix> >
00258 : public detail::referred_range_generator<mtl::matrix::map_view<Functor, Matrix>,
00259 range_generator<tag::major, Matrix> >
00260 {};
00261
00262
00263 }}
00264
00265
00266 namespace mtl { namespace matrix {
00267
00268 template <typename Scaling, typename Matrix>
00269 struct scaled_view
00270 : public map_view<tfunctor::scale<Scaling, typename Matrix::value_type>, Matrix>
00271 {
00272 typedef tfunctor::scale<Scaling, typename Matrix::value_type> functor_type;
00273 typedef map_view<functor_type, Matrix> base;
00274
00275 scaled_view(const Scaling& scaling, const Matrix& matrix)
00276 : base(functor_type(scaling), matrix)
00277 {}
00278
00279 scaled_view(const Scaling& scaling, boost::shared_ptr<Matrix> p)
00280 : base(functor_type(scaling), p)
00281 {}
00282 };
00283
00284
00285 template <typename Matrix, typename RScaling>
00286 struct rscaled_view
00287 : public map_view<tfunctor::rscale<typename Matrix::value_type,RScaling>, Matrix>
00288 {
00289 typedef tfunctor::rscale<typename Matrix::value_type, RScaling> functor_type;
00290 typedef map_view<functor_type, Matrix> base;
00291
00292 rscaled_view(const Matrix& matrix, const RScaling& rscaling)
00293 : base(functor_type(rscaling),matrix)
00294 {}
00295
00296 rscaled_view(boost::shared_ptr<Matrix> p, const RScaling& rscaling)
00297 : base(functor_type(rscaling), p)
00298 {}
00299
00300 };
00301
00302
00303 template <typename Matrix, typename Divisor>
00304 struct divide_by_view
00305 : public map_view<tfunctor::divide_by<typename Matrix::value_type,Divisor>, Matrix>
00306 {
00307 typedef tfunctor::divide_by<typename Matrix::value_type, Divisor> functor_type;
00308 typedef map_view<functor_type, Matrix> base;
00309
00310 divide_by_view(const Matrix& matrix,const Divisor& div)
00311 : base(functor_type(div), matrix)
00312 {}
00313
00314 divide_by_view(boost::shared_ptr<Matrix> p, const Divisor& div)
00315 : base(functor_type(div), p)
00316 {}
00317
00318 };
00319
00320 template <typename Matrix>
00321 struct conj_view
00322 : public map_view<mtl::sfunctor::conj<typename Matrix::value_type>, Matrix>
00323 {
00324 typedef mtl::sfunctor::conj<typename Matrix::value_type> functor_type;
00325 typedef map_view<functor_type, Matrix> base;
00326
00327 conj_view(const Matrix& matrix)
00328 : base(functor_type(), matrix)
00329 {}
00330
00331 conj_view(boost::shared_ptr<Matrix> p)
00332 : base(functor_type(), p)
00333 {}
00334 };
00335
00336 template <typename Scaling, typename Matrix>
00337 struct sub_matrix_t< mtl::matrix::scaled_view<Scaling, Matrix> >
00338 : public sub_matrix_t< mtl::matrix::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>,
00339 Matrix> >
00340 {};
00341
00342 template <typename Matrix>
00343 struct sub_matrix_t< mtl::matrix::conj_view<Matrix> >
00344 : public sub_matrix_t< mtl::matrix::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> >
00345 {};
00346
00347 template <typename Matrix, typename RScaling>
00348 struct sub_matrix_t< mtl::matrix::rscaled_view<Matrix, RScaling> >
00349 : public sub_matrix_t< mtl::matrix::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>,
00350 Matrix> >
00351 {};
00352
00353 template <typename Matrix, typename Divisor>
00354 struct sub_matrix_t< mtl::matrix::divide_by_view<Matrix, Divisor> >
00355 : public sub_matrix_t< mtl::matrix::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>,
00356 Matrix> >
00357 {};
00358
00359
00360 }}
00361
00362
00363
00364 namespace mtl { namespace traits {
00365
00366 template <typename Scaling, typename Matrix>
00367 struct row< mtl::matrix::scaled_view<Scaling, Matrix> >
00368 : public row< mtl::matrix::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>,
00369 Matrix> >
00370 {};
00371
00372 template <typename Matrix>
00373 struct row< mtl::matrix::conj_view<Matrix> >
00374 : public row< mtl::matrix::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> >
00375 {};
00376
00377 template <typename Matrix, typename RScaling>
00378 struct row< mtl::matrix::rscaled_view<Matrix, RScaling> >
00379 : public row< mtl::matrix::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>,
00380 Matrix> >
00381 {};
00382
00383 template <typename Matrix, typename Divisor>
00384 struct row< mtl::matrix::divide_by_view<Matrix, Divisor> >
00385 : public row< mtl::matrix::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>,
00386 Matrix> >
00387 {};
00388
00389
00390 template <typename Scaling, typename Matrix>
00391 struct col< mtl::matrix::scaled_view<Scaling, Matrix> >
00392 : public col< mtl::matrix::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>,
00393 Matrix> >
00394 {};
00395
00396 template <typename Matrix>
00397 struct col< mtl::matrix::conj_view<Matrix> >
00398 : public col< mtl::matrix::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> >
00399 {};
00400
00401 template <typename Matrix, typename RScaling>
00402 struct col< mtl::matrix::rscaled_view<Matrix, RScaling> >
00403 : public col< mtl::matrix::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>,
00404 Matrix> >
00405 {};
00406
00407 template <typename Matrix, typename Divisor>
00408 struct col< mtl::matrix::divide_by_view<Matrix, Divisor> >
00409 : public col< mtl::matrix::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>,
00410 Matrix> >
00411 {};
00412
00413
00414
00415
00416
00417 template <typename Scaling, typename Matrix>
00418 struct const_value< mtl::matrix::scaled_view<Scaling, Matrix> >
00419 : public const_value< mtl::matrix::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>,
00420 Matrix> >
00421 {};
00422
00423 template <typename Matrix>
00424 struct const_value< mtl::matrix::conj_view<Matrix> >
00425 : public const_value< mtl::matrix::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> >
00426 {};
00427
00428 template <typename Matrix, typename RScaling>
00429 struct const_value< mtl::matrix::rscaled_view<Matrix, RScaling> >
00430 : public const_value< mtl::matrix::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>,
00431 Matrix> >
00432 {};
00433
00434 template <typename Matrix, typename Divisor>
00435 struct const_value< mtl::matrix::divide_by_view<Matrix, Divisor> >
00436 : public const_value< mtl::matrix::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>,
00437 Matrix> >
00438 {};
00439
00440
00441
00442
00443
00444 template <typename Tag, typename Scaling, typename Matrix>
00445 struct range_generator< Tag, mtl::matrix::scaled_view<Scaling, Matrix> >
00446 : public range_generator< Tag, mtl::matrix::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>,
00447 Matrix> >
00448 {};
00449
00450 template <typename Tag, typename Matrix>
00451 struct range_generator< Tag, mtl::matrix::conj_view<Matrix> >
00452 : public range_generator< Tag, mtl::matrix::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> >
00453 {};
00454
00455 template <typename Tag, typename Matrix, typename RScaling>
00456 struct range_generator< Tag, mtl::matrix::rscaled_view<Matrix, RScaling> >
00457 : public range_generator< Tag, mtl::matrix::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>,
00458 Matrix> >
00459 {};
00460
00461 template <typename Tag, typename Matrix, typename Divisor>
00462 struct range_generator< Tag, mtl::matrix::divide_by_view<Matrix, Divisor> >
00463 : public range_generator< Tag, mtl::matrix::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>,
00464 Matrix> >
00465 {};
00466
00467
00468
00469 template <typename Scaling, typename Matrix>
00470 struct range_generator< tag::major, mtl::matrix::scaled_view<Scaling, Matrix> >
00471 : public range_generator< tag::major, mtl::matrix::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>,
00472 Matrix> >
00473 {};
00474
00475 template <typename Matrix>
00476 struct range_generator< tag::major, mtl::matrix::conj_view<Matrix> >
00477 : public range_generator< tag::major, mtl::matrix::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> >
00478 {};
00479
00480 template <typename Matrix, typename RScaling>
00481 struct range_generator< tag::major, mtl::matrix::rscaled_view<Matrix, RScaling> >
00482 : public range_generator< tag::major, mtl::matrix::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>,
00483 Matrix> >
00484 {};
00485
00486 template <typename Matrix, typename Divisor>
00487 struct range_generator< tag::major, mtl::matrix::divide_by_view<Matrix, Divisor> >
00488 : public range_generator< tag::major, mtl::matrix::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>,
00489 Matrix> >
00490 {};
00491
00492
00493
00494 }}
00495
00496
00497 #endif // MTL_MAP_VIEW_INCLUDE