00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_DENSE2D_INCLUDE
00013 #define MTL_DENSE2D_INCLUDE
00014
00015 #include <algorithm>
00016 #include <boost/type_traits.hpp>
00017 #include <boost/mpl/if.hpp>
00018 #include <boost/utility/enable_if.hpp>
00019
00020 #include <boost/numeric/mtl/mtl_fwd.hpp>
00021 #include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp>
00022 #include <boost/numeric/mtl/matrix/base_sub_matrix.hpp>
00023 #include <boost/numeric/mtl/matrix/all_mat_expr.hpp>
00024 #include <boost/numeric/mtl/matrix/operators.hpp>
00025 #include <boost/numeric/mtl/detail/contiguous_memory_block.hpp>
00026 #include <boost/numeric/mtl/operation/set_to_zero.hpp>
00027 #include <boost/numeric/mtl/operation/compute_factors.hpp>
00028 #include <boost/numeric/mtl/operation/clone.hpp>
00029 #include <boost/numeric/mtl/utility/common_include.hpp>
00030 #include <boost/numeric/mtl/utility/is_static.hpp>
00031 #include <boost/numeric/mtl/utility/irange.hpp>
00032 #include <boost/numeric/mtl/utility/dense_el_cursor.hpp>
00033 #include <boost/numeric/mtl/utility/strided_dense_el_cursor.hpp>
00034 #include <boost/numeric/mtl/utility/strided_dense_el_iterator.hpp>
00035 #include <boost/numeric/linear_algebra/identity.hpp>
00036
00037
00038 namespace mtl { namespace traits { namespace detail {
00039 template <typename, typename, bool> struct dense2D_iterator_range_generator;
00040 }}}
00041
00042 namespace mtl { namespace matrix {
00043
00044
00045 using std::size_t;
00046
00047
00048 template <typename Value, typename Parameters> class dense2D;
00049 class dense2D_indexer;
00050
00051
00052 struct dense2D_sub_ctor {};
00053
00054
00055 class dense2D_indexer
00056 {
00057
00058 size_t offset(size_t ldim, size_t r, size_t c, row_major) const
00059 {
00060 return r * ldim + c;
00061 }
00062 size_t offset(size_t ldim, size_t r, size_t c, col_major) const
00063 {
00064 return c * ldim + r;
00065 }
00066
00067 size_t row(size_t offset, size_t ldim, row_major) const
00068 {
00069 return offset / ldim;
00070 }
00071 size_t row(size_t offset, size_t ldim, col_major) const
00072 {
00073 return offset % ldim;
00074 }
00075
00076 size_t col(size_t offset, size_t ldim, row_major) const
00077 {
00078 return offset % ldim;
00079 }
00080 size_t col(size_t offset, size_t ldim, col_major) const
00081 {
00082 return offset / ldim;
00083 }
00084
00085 public:
00086 template <typename Value, class Parameters>
00087 size_t operator() (const dense2D<Value, Parameters>& ma, size_t r, size_t c) const
00088 {
00089 typedef dense2D<Value, Parameters> matrix_type;
00090
00091 typename matrix_type::index_type my_index;
00092 size_t my_r= index::change_from(my_index, r);
00093 size_t my_c= index::change_from(my_index, c);
00094 return offset(ma.ldim, my_r, my_c, typename matrix_type::orientation());
00095 }
00096
00097 template <typename Value, class Parameters>
00098 size_t row(const dense2D<Value, Parameters>& ma,
00099 typename dense2D<Value, Parameters>::key_type key) const
00100 {
00101 typedef dense2D<Value, Parameters> matrix_type;
00102
00103 size_t r= row(ma.offset(key), ma.ldim, typename matrix_type::orientation());
00104 return index::change_to(typename matrix_type::index_type(), r);
00105 }
00106
00107 template <typename Value, class Parameters>
00108 size_t col(const dense2D<Value, Parameters>& ma,
00109 typename dense2D<Value, Parameters>::key_type key) const
00110 {
00111 typedef dense2D<Value, Parameters> matrix_type;
00112
00113 size_t c= col(ma.offset(key), ma.ldim, typename matrix_type::orientation());
00114 return index::change_to(typename matrix_type::index_type(), c);
00115 }
00116 template <typename, typename> friend class dense2D;
00117 };
00118
00119
00120 namespace detail
00121 {
00122
00123
00124
00125 template <typename Parameters, bool Enable>
00126 struct dense2D_array_size {
00127 static std::size_t const value= 0;
00128 };
00129
00130 template <typename Parameters>
00131 struct dense2D_array_size<Parameters, true>
00132 {
00133 typedef typename Parameters::dimensions dimensions;
00134 BOOST_STATIC_ASSERT((dimensions::is_static));
00135 static std::size_t const value= dimensions::Num_Rows * dimensions::Num_Cols;
00136 };
00137
00138
00139 template <typename Matrix, bool on_stack>
00140 struct ref_on_stack
00141 {
00142 typedef Matrix type;
00143 };
00144
00145 template <typename Matrix>
00146 struct ref_on_stack<Matrix, true>
00147 {
00148 typedef const Matrix& type;
00149 };
00150
00151 }
00152
00153
00154
00155 template <typename Value, typename Parameters = parameters<> >
00156 class dense2D
00157 : public base_sub_matrix<Value, Parameters>,
00158 public mtl::detail::contiguous_memory_block< Value, Parameters::on_stack,
00159 detail::dense2D_array_size<Parameters, Parameters::on_stack>::value >,
00160 public crtp_base_matrix< dense2D<Value, Parameters>, Value, std::size_t >,
00161 public mat_expr< dense2D<Value, Parameters> >
00162 {
00163 typedef dense2D self;
00164 typedef base_sub_matrix<Value, Parameters> super;
00165 typedef mtl::detail::contiguous_memory_block<Value, Parameters::on_stack,
00166 detail::dense2D_array_size<Parameters, Parameters::on_stack>::value> memory_base;
00167 typedef mat_expr< dense2D<Value, Parameters> > expr_base;
00168 typedef crtp_base_matrix< self, Value, std::size_t > crtp_base;
00169 typedef crtp_matrix_assign< self, Value, std::size_t > assign_base;
00170 public:
00171 typedef Parameters parameters;
00172 typedef typename Parameters::orientation orientation;
00173 typedef typename Parameters::index index_type;
00174 typedef typename Parameters::dimensions dim_type;
00175 typedef Value value_type;
00176 typedef const value_type& const_reference;
00177 typedef value_type& reference;
00178
00179 typedef const value_type* const_pointer_type;
00180 typedef const_pointer_type key_type;
00181 typedef std::size_t size_type;
00182 typedef dense_el_cursor<Value> el_cursor_type;
00183 typedef dense2D_indexer indexer_type;
00184
00185
00186
00187 typedef self sub_matrix_type;
00188
00189 protected:
00190
00191 void set_nnz() { this->my_nnz = this->num_rows() * this->num_cols(); }
00192 void set_ldim(row_major) { ldim= this->num_cols(); }
00193 void set_ldim(col_major) { ldim= this->num_rows(); }
00194 void set_ldim() { set_ldim(orientation()); }
00195
00196 void init()
00197 {
00198 set_nnz(); set_ldim();
00199 }
00200
00201 public:
00202
00203 dense2D() : super(), memory_base(dim_type().num_rows() * dim_type().num_cols())
00204 {
00205 init();
00206 }
00207
00208
00209 explicit dense2D(mtl::non_fixed::dimensions d)
00210 : super(d), memory_base(d.num_rows() * d.num_cols())
00211 {
00212 init();
00213 }
00214
00215 explicit dense2D(size_type num_rows, size_type num_cols)
00216 : super(dim_type(num_rows, num_cols)),
00217 memory_base(num_rows * num_cols)
00218 {
00219 init();
00220 }
00221
00222
00223 explicit dense2D(mtl::non_fixed::dimensions d, value_type* a)
00224 : super(d), memory_base(a, d.num_rows() * d.num_cols())
00225 {
00226 init();
00227 }
00228
00229
00230 explicit dense2D(size_type num_rows, size_type num_cols, value_type* a)
00231 : super(mtl::non_fixed::dimensions(num_rows, num_cols)), memory_base(a, num_rows * num_cols)
00232 {
00233 init();
00234 }
00235
00236
00237
00238 explicit dense2D(value_type* a)
00239 : super(), memory_base(a, dim_type().num_rows() * dim_type().num_cols())
00240 {
00241 BOOST_STATIC_ASSERT((dim_type::is_static));
00242 init();
00243 }
00244
00245
00246 dense2D(const self& m)
00247 : super(dim_type(m.num_rows(), m.num_cols())),
00248 memory_base(m)
00249 {
00250
00251 this->my_nnz= m.my_nnz; ldim= m.ldim;
00252 }
00253
00254 explicit dense2D(const self& m, clone_ctor)
00255 : super(mtl::non_fixed::dimensions(m.num_rows(), m.num_cols())),
00256 memory_base(m, clone_ctor())
00257 {
00258 init();
00259 *this= m;
00260 }
00261
00262 template <typename MatrixSrc>
00263 explicit dense2D(const MatrixSrc& src)
00264 : super(), memory_base(dim_type().num_rows() * dim_type().num_cols())
00265 {
00266 init();
00267 *this= src;
00268 }
00269
00270
00271 template <typename MatrixSrc>
00272 dense2D(MatrixSrc& matrix, dense2D_sub_ctor,
00273 size_type begin_r, size_type end_r, size_type begin_c, size_type end_c)
00274 : super(mtl::non_fixed::dimensions(matrix.num_rows(), matrix.num_cols())),
00275 memory_base(matrix.data, (end_r - begin_r) * (end_c - begin_c), true)
00276 {
00277 sub_matrix_constructor(matrix, begin_r, end_r, begin_c, end_c, boost::mpl::bool_<memory_base::on_stack>());
00278 }
00279
00280 private:
00281 template <typename MatrixSrc>
00282 void sub_matrix_constructor(MatrixSrc& matrix, size_type begin_r, size_type end_r,
00283 size_type begin_c, size_type end_c, boost::mpl::false_)
00284 {
00285 matrix.check_ranges(begin_r, end_r, begin_c, end_c);
00286
00287 if(end_r <= begin_r || end_c <= begin_c)
00288 set_ranges(0, 0);
00289 else {
00290
00291 this->data += matrix.indexer(matrix, begin_r, begin_c);
00292 set_ranges(end_r - begin_r, end_c - begin_c);
00293 }
00294 this->my_nnz= matrix.my_nnz; ldim= matrix.ldim;
00295 }
00296
00297 template <typename MatrixSrc>
00298 void sub_matrix_constructor(MatrixSrc& matrix, size_type begin_r, size_type end_r,
00299 size_type begin_c, size_type end_c, boost::mpl::true_)
00300 {
00301 MTL_THROW(logic_error("Matrices cannot be used as sub-matrices!"));
00302 }
00303
00304 public:
00305 self& operator=(typename detail::ref_on_stack<self, memory_base::on_stack>::type src)
00306 {
00307 return self_assign(src, boost::mpl::bool_<memory_base::on_stack>());
00308 }
00309
00310 private:
00311
00312 self& self_assign(self& src, boost::mpl::false_)
00313 {
00314
00315 assert(this != &src);
00316
00317
00318 check_dim(src.num_rows(), src.num_cols());
00319 if (this->category == memory_base::view || src.category == memory_base::view)
00320 matrix_copy(src, *this);
00321 else {
00322 if (this->num_rows() != src.num_rows() || this->num_cols() != src.num_cols()) {
00323 super::change_dim(src.num_rows(), src.num_cols());
00324 init();
00325 }
00326 memory_base::move_assignment(src);
00327 }
00328
00329 return *this;
00330 }
00331
00332
00333 self& self_assign(const self& src, boost::mpl::true_)
00334 {
00335 if (this != &src) {
00336 check_dim(src.num_rows(), src.num_cols());
00337 matrix_copy(src, *this);
00338 }
00339 return *this;
00340 }
00341 public:
00342
00343
00344 using assign_base::operator=;
00345
00346 void change_dim(size_type r, size_type c, bool keep_data = false)
00347 {
00348 change_dim(r, c, keep_data, mtl::traits::is_static<self>());
00349 }
00350
00351 private:
00352 void change_dim(size_type r, size_type c, bool keep_data, boost::mpl::false_)
00353 {
00354 if (r == this->num_rows() && c == this->num_cols())
00355 return;
00356
00357 self temp;
00358 if (keep_data) {
00359 temp.super::change_dim(this->num_rows(), this->num_cols());
00360 temp.init();
00361 temp.memory_base::move_assignment(*this);
00362 }
00363 memory_base::realloc(r*c);
00364 super::change_dim(r, c);
00365 init();
00366 if (keep_data) {
00367 if (r > temp.num_rows() || c > temp.num_cols()){
00368 set_to_zero(*this);
00369 #if 0
00370 irange rr(0, std::min(r,temp.num_rows())), cr(0, std::min(c,temp.num_cols()));
00371 *this[rr][cr]= temp[rr][cr];
00372 #endif
00373 sub_matrix(*this,0,std::min(r,temp.num_rows()),0,std::min(c,temp.num_cols()))
00374 = sub_matrix(temp,0,std::min(r,temp.num_rows()),0,std::min(c,temp.num_cols()));
00375 } else {
00376 #if 0
00377 irange rr(0, r);
00378 irange rc(0, c);
00379
00380 *this = sub_matrix(temp, 0, r, 0, c);
00381 #endif
00382 *this = temp[irange(0, r)][irange(0, c)];
00383 }
00384 }
00385 }
00386
00387 void change_dim(size_type r, size_type c, bool, boost::mpl::true_)
00388 {
00389 assert(r == this->num_rows() && c == this->num_cols());
00390 }
00391
00392 public:
00393 bool check_indices(size_t r, size_t c) const
00394 {
00395 return r >= this->begin_row() && r < this->end_row() && c >= this->begin_col() && c < this->end_col();
00396 }
00397
00398
00399 const_reference operator() (size_t r, size_t c) const
00400 {
00401 MTL_DEBUG_THROW_IF(r < 0 || r >= this->num_rows() || c < 0 || c >= this->num_cols(), index_out_of_range());
00402 return this->data[indexer(*this, r, c)];
00403 }
00404
00405 value_type& operator() (size_t r, size_t c)
00406 {
00407 MTL_DEBUG_THROW_IF(r < 0 || r >= this->num_rows() || c < 0 || c >= this->num_cols(), index_out_of_range());
00408 return this->data[indexer(*this, r, c)];
00409 }
00410
00411
00412 size_t c_offset(size_t r, size_t c) const
00413 {
00414 return indexer.offset(ldim, r, c, orientation());
00415 }
00416
00417 size_type get_ldim() const
00418 {
00419 return ldim;
00420 }
00421
00422 friend void swap(self& matrix1, self& matrix2)
00423 {
00424 swap(static_cast<memory_base&>(matrix1), static_cast<memory_base&>(matrix2));
00425 swap(static_cast<super&>(matrix1), static_cast<super&>(matrix2));
00426 std::swap(matrix1.ldim, matrix2.ldim);
00427 }
00428
00429 void crop() {}
00430
00431 #if 0
00432 private:
00433
00434 size_type vector_size(const irange& range, size_type maximum)
00435 {
00436 using std::min;
00437 size_type finish= min(range.finish(), maximum);
00438 return range.start() < finish ? finish - range.start() : 0;
00439 }
00440
00441 public:
00442 typename RowInMatrix<Ref>::type sub_vector(size_type row, const irange& col_range)
00443 #endif
00444
00445 protected:
00446
00447
00448 void set_ranges(size_type begin_r, size_type end_r, size_type begin_c, size_type end_c)
00449 {
00450 super::set_ranges(begin_r, end_r, begin_c, end_c);
00451 set_nnz();
00452 }
00453
00454
00455 void set_ranges(size_type num_rows, size_type num_cols)
00456 {
00457 set_ranges(this->begin_row(), this->begin_row() + num_rows,
00458 this->begin_col(), this->begin_col() + num_cols);
00459 }
00460
00461 public:
00462
00463 indexer_type indexer;
00464
00465 friend class dense2D_indexer;
00466
00467 #if !defined(_MSC_VER) || _MSC_VER != 1400 // Bug in MSVC 2005
00468 template <typename> friend struct sub_matrix_t;
00469 template <typename, typename> friend struct mtl::traits::range_generator;
00470 template <typename, typename, bool> friend struct mtl::traits::detail::dense2D_iterator_range_generator;
00471
00472 protected:
00473 #endif
00474
00475
00476
00477 size_type ldim;
00478
00479 };
00480
00481
00482
00483
00484
00485
00486 template <typename Value, typename Parameters>
00487 typename dense2D<Value, Parameters>::size_type
00488 inline num_rows(const dense2D<Value, Parameters>& matrix)
00489 {
00490 return matrix.num_rows();
00491 }
00492
00493 template <typename Value, typename Parameters>
00494 typename dense2D<Value, Parameters>::size_type
00495 inline num_cols(const dense2D<Value, Parameters>& matrix)
00496 {
00497 return matrix.num_cols();
00498 }
00499
00500 template <typename Value, typename Parameters>
00501 typename dense2D<Value, Parameters>::size_type
00502 inline size(const dense2D<Value, Parameters>& matrix)
00503 {
00504 return matrix.num_cols() * matrix.num_rows();
00505 }
00506
00507
00508 }}
00509
00510
00511 namespace mtl { namespace traits {
00512
00513
00514
00515 using mtl::matrix::dense2D;
00516
00517
00518
00519
00520
00521
00522 template <typename Value, typename Parameters>
00523 struct range_generator<glas::tag::all, dense2D<Value, Parameters> >
00524 : detail::dense_element_range_generator<dense2D<Value, Parameters>,
00525 dense_el_cursor<Value>, complexity_classes::linear_cached>
00526 {};
00527
00528 template <typename Value, typename Parameters>
00529 struct range_generator<glas::tag::nz, dense2D<Value, Parameters> >
00530 : detail::dense_element_range_generator<dense2D<Value, Parameters>,
00531 dense_el_cursor<Value>, complexity_classes::linear_cached>
00532 {};
00533
00534 namespace detail
00535 {
00536
00537
00538 template <typename Orientation> struct dense2D_rc {};
00539 template<> struct dense2D_rc<row_major>
00540 {
00541 typedef complexity_classes::linear_cached type;
00542 };
00543 template<> struct dense2D_rc<col_major>
00544 {
00545 typedef complexity_classes::linear type;
00546 };
00547
00548
00549 template <typename Orientation> struct dense2D_cc
00550 : dense2D_rc<typename transposed_orientation<Orientation>::type>
00551 {};
00552 }
00553
00554 template <typename Value, typename Parameters>
00555 struct range_generator<glas::tag::row, dense2D<Value, Parameters> >
00556 : detail::all_rows_range_generator<dense2D<Value, Parameters>,
00557 typename detail::dense2D_rc<typename Parameters::orientation>::type>
00558 {};
00559
00560
00561 template <typename Value, typename Parameters>
00562 struct range_generator<glas::tag::nz,
00563 detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::row, 2> >
00564 {
00565 typedef dense2D<Value, Parameters> matrix;
00566 typedef typename matrix::size_type size_type;
00567 typedef detail::sub_matrix_cursor<matrix, glas::tag::row, 2> cursor;
00568
00569
00570 typedef typename detail::dense2D_rc<typename Parameters::orientation>::type complexity;
00571 static int const level = 1;
00572
00573 typedef typename boost::mpl::if_<
00574 boost::is_same<typename Parameters::orientation, row_major>
00575 , dense_el_cursor<Value>
00576 , strided_dense_el_cursor<Value>
00577 >::type type;
00578
00579 private:
00580
00581 type dispatch(cursor const& c, size_type col, row_major)
00582 {
00583 return type(c.ref, c.key, col);
00584 }
00585 type dispatch(cursor const& c, size_type col, col_major)
00586 {
00587 return type(c.ref, c.key, col, c.ref.ldim);
00588 }
00589
00590 public:
00591
00592 type begin(cursor const& c)
00593 {
00594 return dispatch(c, c.ref.begin_col(), typename matrix::orientation());
00595 }
00596 type end(cursor const& c)
00597 {
00598 return dispatch(c, c.ref.end_col(), typename matrix::orientation());
00599 }
00600 type lower_bound(cursor const& c, size_type position)
00601 {
00602 return dispatch(c, std::min(c.ref.end_col(), position), typename matrix::orientation());
00603 }
00604 };
00605
00606 template <typename Value, typename Parameters>
00607 struct range_generator<glas::tag::all,
00608 detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::row, 2> >
00609 : range_generator<glas::tag::nz,
00610 detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::row, 2> >
00611 {};
00612
00613
00614 template <typename Value, typename Parameters>
00615 struct range_generator<glas::tag::col, dense2D<Value, Parameters> >
00616 : detail::all_cols_range_generator<dense2D<Value, Parameters>,
00617 typename detail::dense2D_cc<typename Parameters::orientation>::type>
00618 {};
00619
00620
00621 template <typename Value, typename Parameters>
00622 struct range_generator<glas::tag::nz,
00623 detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::col, 2> >
00624 {
00625 typedef dense2D<Value, Parameters> matrix;
00626 typedef typename matrix::size_type size_type;
00627 typedef detail::sub_matrix_cursor<matrix, glas::tag::col, 2> cursor;
00628 typedef typename detail::dense2D_cc<typename Parameters::orientation>::type complexity;
00629 static int const level = 1;
00630
00631 typedef typename boost::mpl::if_<
00632 boost::is_same<typename Parameters::orientation, col_major>
00633 , dense_el_cursor<Value>
00634 , strided_dense_el_cursor<Value>
00635 >::type type;
00636
00637
00638 private:
00639
00640 type dispatch(cursor const& c, size_type row, col_major)
00641 {
00642 return type(c.ref, row, c.key);
00643 }
00644 type dispatch(cursor const& c, size_type row, row_major)
00645 {
00646 return type(c.ref, row, c.key, c.ref.ldim);
00647 }
00648
00649 public:
00650
00651 type begin(cursor const& c)
00652 {
00653 return dispatch(c, c.ref.begin_row(), typename matrix::orientation());
00654 }
00655 type end(cursor const& c)
00656 {
00657 return dispatch(c, c.ref.end_row(), typename matrix::orientation());
00658 }
00659 type lower_bound(cursor const& c, size_type position)
00660 {
00661 return dispatch(c, std::min(c.ref.end_row(), position), typename matrix::orientation());
00662 }
00663 };
00664
00665 template <typename Value, typename Parameters>
00666 struct range_generator<glas::tag::all,
00667 detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::col, 2> >
00668 : public range_generator<glas::tag::nz,
00669 detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::col, 2> >
00670 {};
00671
00672
00673
00674
00675
00676
00677 namespace detail {
00678
00679
00680 template <typename OuterTag, typename Orientation>
00681 struct major_traversal
00682 {
00683 static const bool value= false;
00684 };
00685
00686 template <> struct major_traversal<glas::tag::row, row_major>
00687 {
00688 static const bool value= true;
00689 };
00690
00691 template <> struct major_traversal<glas::tag::col, col_major>
00692 {
00693 static const bool value= true;
00694 };
00695
00696
00697 template <typename OuterTag, typename Matrix, bool is_const>
00698 struct dense2D_iterator_range_generator
00699 {
00700 typedef Matrix matrix_type;
00701 typedef typename matrix_type::size_type size_type;
00702 typedef typename matrix_type::value_type value_type;
00703 typedef typename matrix_type::parameters parameters;
00704 typedef detail::sub_matrix_cursor<matrix_type, OuterTag, 2> cursor;
00705
00706
00707 typedef typename boost::mpl::if_<
00708 major_traversal<OuterTag, typename parameters::orientation>
00709 , complexity_classes::linear_cached
00710 , complexity_classes::linear
00711 >::type complexity;
00712 static int const level = 1;
00713
00714
00715 typedef typename boost::mpl::if_<
00716 major_traversal<OuterTag, typename parameters::orientation>
00717 , typename boost::mpl::if_c<
00718 is_const
00719 , const value_type*
00720 , value_type*
00721 >::type
00722 , typename boost::mpl::if_c<
00723 is_const
00724 , strided_dense_el_const_iterator<value_type>
00725 , strided_dense_el_iterator<value_type>
00726 >::type
00727 >::type type;
00728
00729 private:
00730
00731 type dispatch(cursor const& c, size_type row, size_type col, complexity_classes::linear_cached)
00732 {
00733 matrix_type& ma= const_cast<matrix_type&>(c.ref);
00734 return ma.elements() + ma.indexer(ma, row, col);
00735 }
00736
00737
00738 type dispatch(cursor const& c, size_type row, size_type col, complexity_classes::linear)
00739 {
00740
00741 matrix_type& ref= const_cast<matrix_type&>(c.ref);
00742 return type(ref, row, col, ref.ldim);
00743 }
00744
00745 type begin_dispatch(cursor const& c, glas::tag::row)
00746 {
00747 return dispatch(c, c.key, c.ref.begin_col(), complexity());
00748 }
00749
00750 type end_dispatch(cursor const& c, glas::tag::row)
00751 {
00752 return dispatch(c, c.key, c.ref.end_col(), complexity());
00753 }
00754
00755
00756 type begin_dispatch(cursor const& c, glas::tag::col)
00757 {
00758 return dispatch(c, c.ref.begin_row(), c.key, complexity());
00759 }
00760
00761 type end_dispatch(cursor const& c, glas::tag::col)
00762 {
00763 return dispatch(c, c.ref.end_row(), c.key, complexity());
00764 }
00765
00766 public:
00767
00768 type begin(cursor const& c)
00769 {
00770 return begin_dispatch(c, OuterTag());
00771 }
00772
00773 type end(cursor const& c)
00774 {
00775 return end_dispatch(c, OuterTag());
00776 }
00777 };
00778
00779 }
00780
00781
00782 template <typename Value, typename Parameters, typename OuterTag>
00783 struct range_generator<tag::iter::nz,
00784 detail::sub_matrix_cursor<dense2D<Value, Parameters>, OuterTag, 2> >
00785 : public detail::dense2D_iterator_range_generator<OuterTag, dense2D<Value, Parameters>, false>
00786 {};
00787
00788 template <typename Value, typename Parameters, typename OuterTag>
00789 struct range_generator<tag::iter::all,
00790 detail::sub_matrix_cursor<dense2D<Value, Parameters>, OuterTag, 2> >
00791 : public detail::dense2D_iterator_range_generator<OuterTag, dense2D<Value, Parameters>, false>
00792 {};
00793
00794 template <typename Value, typename Parameters, typename OuterTag>
00795 struct range_generator<tag::const_iter::nz,
00796 detail::sub_matrix_cursor<dense2D<Value, Parameters>, OuterTag, 2> >
00797 : public detail::dense2D_iterator_range_generator<OuterTag, dense2D<Value, Parameters>, true>
00798 {};
00799
00800 template <typename Value, typename Parameters, typename OuterTag>
00801 struct range_generator<tag::const_iter::all,
00802 detail::sub_matrix_cursor<dense2D<Value, Parameters>, OuterTag, 2> >
00803 : public detail::dense2D_iterator_range_generator<OuterTag, dense2D<Value, Parameters>, true>
00804 {};
00805
00806
00807 }}
00808
00809 namespace mtl { namespace matrix {
00810
00811
00812
00813
00814
00815 template <typename Value, typename Parameters>
00816 struct sub_matrix_t<dense2D<Value, Parameters> >
00817 {
00818 typedef dense2D<Value, Parameters> matrix_type;
00819
00820 typedef parameters<typename Parameters::orientation> para_type;
00821
00822 typedef dense2D<Value, para_type> sub_matrix_type;
00823 typedef sub_matrix_type const const_sub_matrix_type;
00824 typedef typename matrix_type::size_type size_type;
00825
00826 sub_matrix_type operator()(matrix_type& matrix, size_type begin_r, size_type end_r, size_type begin_c, size_type end_c)
00827 {
00828 return sub_matrix_type(matrix, dense2D_sub_ctor(), begin_r, end_r, begin_c, end_c);
00829 }
00830
00831 const_sub_matrix_type
00832 operator()(matrix_type const& matrix, size_type begin_r, size_type end_r, size_type begin_c, size_type end_c)
00833 {
00834
00835 sub_matrix_type tmp((*this)(const_cast<matrix_type&>(matrix), begin_r, end_r, begin_c, end_c));
00836 return tmp;
00837 }
00838 };
00839
00840 }}
00841
00842 namespace mtl {
00843
00844
00845 template <typename Value, typename Parameters>
00846 struct is_clonable< mtl::dense2D<Value, Parameters> > : boost::mpl::true_ {};
00847
00848 }
00849
00850
00851
00852 namespace math {
00853
00854
00855 template <typename Value, typename Parameters>
00856 struct identity_t< mult<mtl::dense2D<Value, Parameters> >, mtl::dense2D<Value, Parameters> >
00857 : public std::binary_function< mult<mtl::dense2D<Value, Parameters> >,
00858 mtl::dense2D<Value, Parameters>,
00859 mtl::dense2D<Value, Parameters> >
00860 {
00861 typedef mtl::dense2D<Value, Parameters> matrix_type;
00862
00863 matrix_type operator() (const mult<matrix_type>&, const matrix_type& ref) const
00864 {
00865 matrix_type tmp(ref);
00866 tmp= zero(matrix_type::value_type());
00867 return tmp;
00868 }
00869 };
00870
00871 }
00872
00873
00874 #endif // MTL_DENSE2D_INCLUDE
00875
00876
00877
00878
00879
00880
00881