00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_MATRIX_BANDED_VIEW_INCLUDE
00013 #define MTL_MATRIX_BANDED_VIEW_INCLUDE
00014
00015 #include <boost/shared_ptr.hpp>
00016 #include <boost/numeric/mtl/mtl_fwd.hpp>
00017 #include <boost/numeric/mtl/utility/category.hpp>
00018 #include <boost/numeric/mtl/utility/range_generator.hpp>
00019 #include <boost/numeric/mtl/utility/property_map.hpp>
00020 #include <boost/numeric/mtl/utility/parameters.hpp>
00021 #include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp>
00022 #include <boost/numeric/mtl/matrix/base_matrix.hpp>
00023 #include <boost/numeric/mtl/operation/sfunctor.hpp>
00024 #include <boost/numeric/mtl/matrix/mat_expr.hpp>
00025 #include <boost/numeric/mtl/matrix/map_view.hpp>
00026 #include <boost/numeric/linear_algebra/identity.hpp>
00027
00028
00029
00030
00031
00032
00033 namespace mtl { namespace matrix {
00034
00035
00036 namespace detail {
00037 template <typename> struct banded_value;
00038 template <typename, typename> struct mapped_value;
00039 }
00040
00041
00042 template <typename Matrix>
00043 struct banded_view
00044 : public const_crtp_base_matrix< banded_view<Matrix>,
00045 typename Matrix::value_type, typename Matrix::size_type >,
00046 public mat_expr< banded_view<Matrix> >,
00047 public base_matrix<typename Matrix::value_type,
00048 typename mtl::traits::parameters<Matrix>::type>
00049 {
00050 typedef banded_view self;
00051 typedef mat_expr< self > expr_base;
00052 typedef typename mtl::traits::parameters<Matrix>::type parameters;
00053
00054 typedef base_matrix<typename Matrix::value_type, parameters> base;
00055
00056 typedef Matrix other;
00057 typedef typename Matrix::orientation orientation;
00058 typedef typename Matrix::index_type index_type;
00059
00060
00061 typedef typename Matrix::value_type value_type;
00062 typedef typename Matrix::const_reference const_reference;
00063
00064 typedef typename Matrix::key_type key_type;
00065 typedef typename Matrix::size_type size_type;
00066 typedef typename Matrix::dim_type dim_type;
00067
00068 typedef long int bsize_type;
00069
00070 banded_view(const other& ref, bsize_type begin, bsize_type end)
00071 : base(dim_type(mtl::matrix::num_rows(ref), mtl::matrix::num_cols(ref))), ref(ref), begin(begin), end(end)
00072 {}
00073
00074 banded_view(boost::shared_ptr<Matrix> p, bsize_type begin, bsize_type end)
00075 : base(dim_type(mtl::matrix::num_rows(*p), mtl::matrix::num_cols(*p))), my_copy(p), ref(*p), begin(begin), end(end)
00076 {}
00077
00078 value_type operator() (size_type r, size_type c) const
00079 {
00080 using math::zero;
00081 bsize_type bc= static_cast<bsize_type>(c), br= static_cast<bsize_type>(r),
00082 band= bc - br;
00083
00084 value_type v= ref(r, c);
00085 return begin <= band && band < end ? v : zero(v);
00086 }
00087
00088
00089 bsize_type get_begin() const { return begin; }
00090 bsize_type get_end() const { return end; }
00091
00092 template <typename> friend struct detail::banded_value;
00093 template <typename, typename> friend struct detail::map_value;
00094
00095
00096 friend size_type inline num_rows(const self& A)
00097 {
00098 using mtl::matrix::num_rows; return num_rows(A.ref);
00099 }
00100 friend size_type inline num_cols(const self& A)
00101 {
00102 using mtl::matrix::num_cols; return num_cols(A.ref);
00103 }
00104 friend size_type inline size(const self& A)
00105 {
00106 using mtl::matrix::num_rows; using mtl::matrix::num_cols;
00107 return num_rows(A.ref) * num_rows(A.ref);
00108 }
00109
00110 protected:
00111 boost::shared_ptr<Matrix> my_copy;
00112 public:
00113 const other& ref;
00114 bsize_type begin, end;
00115 };
00116
00117
00118
00119
00120
00121
00122 template <typename Matrix>
00123 struct sub_matrix_t< mtl::matrix::banded_view<Matrix> >
00124 {
00125 typedef mtl::matrix::banded_view<Matrix> view_type;
00126
00127
00128 typedef typename sub_matrix_t<Matrix>::sub_matrix_type ref_sub_type;
00129 typedef mtl::matrix::banded_view<ref_sub_type> const_sub_matrix_type;
00130 typedef mtl::matrix::banded_view<ref_sub_type> sub_matrix_type;
00131 typedef typename view_type::size_type size_type;
00132
00133 sub_matrix_type operator()(view_type const& view, size_type begin_r, size_type end_r,
00134 size_type begin_c, size_type end_c)
00135 {
00136 typedef boost::shared_ptr<ref_sub_type> pointer_type;
00137
00138
00139
00140 pointer_type p(new ref_sub_type(sub_matrix(view.ref, begin_r, end_r, begin_c, end_c)));
00141 return sub_matrix_type(p, view.begin, view.end);
00142 }
00143 };
00144
00145
00146 }}
00147
00148
00149
00150
00151 namespace mtl { namespace traits {
00152
00153 using mtl::matrix::banded_view;
00154
00155 template <typename Matrix>
00156 struct row<banded_view<Matrix> >
00157 {
00158
00159 typedef detail::mapped_row<sfunctor::identity<typename Matrix::value_type>, Matrix> type;
00160 };
00161
00162 template <typename Matrix>
00163 struct col<banded_view<Matrix> >
00164 {
00165
00166 typedef detail::mapped_col<sfunctor::identity<typename Matrix::value_type>, Matrix> type;
00167 };
00168
00169 namespace detail {
00170
00171 template <typename Matrix>
00172 struct banded_value
00173 {
00174 typedef typename Matrix::key_type key_type;
00175 typedef typename Matrix::value_type value_type;
00176 typedef banded_view<Matrix> view_type;
00177
00178 banded_value(view_type const& view)
00179 : view(view), its_row(view.ref), its_col(view.ref), its_value(view.ref)
00180 {}
00181
00182 value_type operator() (key_type const& key)
00183 {
00184 using math::zero;
00185 typedef typename view_type::bsize_type bsize_type;
00186
00187 bsize_type br= static_cast<bsize_type>(its_row(key)),
00188 bc= static_cast<bsize_type>(its_col(key)),
00189 band= bc - br;
00190
00191 const value_type v= its_value(key);
00192
00193 return view.get_begin() <= band && band < view.get_end() ? v : zero(v);
00194 }
00195
00196 protected:
00197 view_type const& view;
00198 typename row<Matrix>::type its_row;
00199 typename col<Matrix>::type its_col;
00200 typename const_value<Matrix>::type its_value;
00201 };
00202
00203 }
00204
00205 template <typename Matrix>
00206 struct const_value<banded_view<Matrix> >
00207 {
00208 typedef detail::banded_value<Matrix> type;
00209 };
00210
00211
00212
00213
00214
00215
00216 template <typename Tag, typename Matrix>
00217 struct range_generator<Tag, banded_view<Matrix> >
00218 : public detail::referred_range_generator<banded_view<Matrix>, range_generator<Tag, Matrix> >
00219 {};
00220
00221 #if 0 // It is more complicated than this because referred_range_generator returns Matrix's cursor and we
00222
00223 template <typename Matrix>
00224 struct range_generator<glas::tag::nz,
00225 typename detail::referred_range_generator<banded_view<Matrix>, range_generator<Tag, Matrix> >::type>
00226
00227 detail::sub_matrix_cursor<banded_view<Matrix>, glas::tag::row, 2> >
00228 {
00229 typedef range_generator<glas::tag::row, banded_view<Matrix> > collection_type;
00230 typedef range_generator<glas::tag::nz, range_generator<glas::tag::row, Matrix> > other_generator;
00231 static int const level = other_generator::level;
00232 typedef typename other_generator::type type;
00233
00234 type begin(const collection_type& c)
00235 {
00236 return
00237
00238
00239 typedef typename range_generator<glas::tag::nz, detail::sub_matrix_cursor<Matrix>, glas::tag::row, 2>::type type;
00240 #endif
00241
00242
00243
00244 template <typename Matrix>
00245 struct range_generator<tag::major, banded_view<Matrix> >
00246 : public detail::referred_range_generator<banded_view<Matrix>, range_generator<tag::major, Matrix> >
00247 {};
00248
00249
00250
00251
00252
00253
00254 }}
00255
00256
00257 #endif // MTL_MATRIX_BANDED_VIEW_INCLUDE