File indexing completed on 2025-01-18 09:43:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef _BOOST_UBLAS_BANDED_
0014 #define _BOOST_UBLAS_BANDED_
0015
0016 #include <boost/numeric/ublas/matrix.hpp>
0017 #include <boost/numeric/ublas/detail/temporary.hpp>
0018
0019
0020
0021 namespace boost { namespace numeric { namespace ublas {
0022
0023
0024 namespace hidden {
0025
0026
0027
0028
0029
0030
0031
0032
0033 template <class LayoutType>
0034 class banded_indexing { };
0035
0036
0037
0038
0039 template <>
0040 class banded_indexing<column_major_tag> {
0041 public:
0042
0043 template <class T>
0044 BOOST_UBLAS_INLINE static T size(T , T size2) {
0045 return size2;
0046 }
0047
0048
0049
0050
0051
0052
0053 template <class T>
0054 BOOST_UBLAS_INLINE static T get_index(T , T size2, T lower, T upper, T i, T j) {
0055 return column_major::element (upper + i - j, lower + 1 + upper, j, size2);
0056 }
0057 };
0058
0059
0060
0061
0062 template <>
0063 class banded_indexing<row_major_tag> {
0064 public:
0065
0066 template <class T>
0067 BOOST_UBLAS_INLINE static T size(T size1, T ) {
0068 return size1;
0069 }
0070
0071
0072
0073
0074
0075
0076 template <class T>
0077 BOOST_UBLAS_INLINE static T get_index(T size1, T , T lower, T upper, T i, T j) {
0078 return row_major::element (i, size1, lower + j - i, lower + 1 + upper);
0079 }
0080 };
0081
0082 }
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 template<class T, class L, class A>
0097 class banded_matrix:
0098 public matrix_container<banded_matrix<T, L, A> > {
0099
0100 typedef T *pointer;
0101 typedef L layout_type;
0102 typedef banded_matrix<T, L, A> self_type;
0103
0104
0105
0106 public:
0107 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0108 using matrix_container<self_type>::operator ();
0109 #endif
0110 typedef typename A::size_type size_type;
0111 typedef typename A::difference_type difference_type;
0112 typedef T value_type;
0113 typedef const T &const_reference;
0114 typedef T &reference;
0115 typedef A array_type;
0116 typedef const matrix_reference<const self_type> const_closure_type;
0117 typedef matrix_reference<self_type> closure_type;
0118 typedef vector<T, A> vector_temporary_type;
0119 typedef matrix<T, L, A> matrix_temporary_type;
0120 typedef packed_tag storage_category;
0121 typedef typename L::orientation_category orientation_category;
0122
0123 private:
0124 public:
0125
0126
0127 BOOST_UBLAS_INLINE
0128 banded_matrix ():
0129 matrix_container<self_type> (),
0130 size1_ (0), size2_ (0),
0131 lower_ (0), upper_ (0), data_ (0) {}
0132 BOOST_UBLAS_INLINE
0133 banded_matrix (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0):
0134 matrix_container<self_type> (),
0135 size1_ (size1), size2_ (size2),
0136 lower_ (lower), upper_ (upper),
0137 #if defined(BOOST_UBLAS_OWN_BANDED) || (BOOST_UBLAS_LEGACY_BANDED)
0138 data_ ((std::max) (size1, size2) * (lower + 1 + upper))
0139 #else
0140 data_ ( hidden::banded_indexing<orientation_category>::size(size1, size2) * (lower + 1 + upper))
0141 #endif
0142 {
0143 }
0144 BOOST_UBLAS_INLINE
0145 banded_matrix (size_type size1, size_type size2, size_type lower, size_type upper, const array_type &data):
0146 matrix_container<self_type> (),
0147 size1_ (size1), size2_ (size2),
0148 lower_ (lower), upper_ (upper), data_ (data) {}
0149 BOOST_UBLAS_INLINE
0150 banded_matrix (const banded_matrix &m):
0151 matrix_container<self_type> (),
0152 size1_ (m.size1_), size2_ (m.size2_),
0153 lower_ (m.lower_), upper_ (m.upper_), data_ (m.data_) {}
0154 template<class AE>
0155 BOOST_UBLAS_INLINE
0156 banded_matrix (const matrix_expression<AE> &ae, size_type lower = 0, size_type upper = 0):
0157 matrix_container<self_type> (),
0158 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()),
0159 lower_ (lower), upper_ (upper),
0160 #if defined(BOOST_UBLAS_OWN_BANDED) || (BOOST_UBLAS_LEGACY_BANDED)
0161 data_ ((std::max) (size1_, size2_) * (lower_ + 1 + upper_))
0162 #else
0163 data_ ( hidden::banded_indexing<orientation_category>::size(size1_, size2_) * (lower_ + 1 + upper_))
0164 #endif
0165 {
0166 matrix_assign<scalar_assign> (*this, ae);
0167 }
0168
0169
0170 BOOST_UBLAS_INLINE
0171 size_type size1 () const {
0172 return size1_;
0173 }
0174 BOOST_UBLAS_INLINE
0175 size_type size2 () const {
0176 return size2_;
0177 }
0178 BOOST_UBLAS_INLINE
0179 size_type lower () const {
0180 return lower_;
0181 }
0182 BOOST_UBLAS_INLINE
0183 size_type upper () const {
0184 return upper_;
0185 }
0186
0187
0188 BOOST_UBLAS_INLINE
0189 const array_type &data () const {
0190 return data_;
0191 }
0192 BOOST_UBLAS_INLINE
0193 array_type &data () {
0194 return data_;
0195 }
0196
0197 #if !defined (BOOST_UBLAS_OWN_BANDED)||(BOOST_UBLAS_LEGACY_BANDED)
0198 BOOST_UBLAS_INLINE
0199 bool is_element_in_band(size_type i, size_type j) const{
0200
0201 return (upper_+i >= j) && i <= ( j + lower_);
0202 }
0203 #endif
0204
0205 BOOST_UBLAS_INLINE
0206 void resize (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0, bool preserve = true) {
0207 if (preserve) {
0208 self_type temporary (size1, size2, lower, upper);
0209 detail::matrix_resize_preserve<layout_type> (*this, temporary);
0210 }
0211 else {
0212 data ().resize ((std::max) (size1, size2) * (lower + 1 + upper));
0213 size1_ = size1;
0214 size2_ = size2;
0215 lower_ = lower;
0216 upper_ = upper;
0217 }
0218 }
0219
0220 BOOST_UBLAS_INLINE
0221 void resize_packed_preserve (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0) {
0222 size1_ = size1;
0223 size2_ = size2;
0224 lower_ = lower;
0225 upper_ = upper;
0226 data ().resize ((std::max) (size1, size2) * (lower + 1 + upper), value_type ());
0227 }
0228
0229
0230 BOOST_UBLAS_INLINE
0231 const_reference operator () (size_type i, size_type j) const {
0232 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
0233 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
0234 #ifdef BOOST_UBLAS_OWN_BANDED
0235 const size_type k = (std::max) (i, j);
0236 const size_type l = lower_ + j - i;
0237 if (k < (std::max) (size1_, size2_) &&
0238 l < lower_ + 1 + upper_)
0239 return data () [layout_type::element (k, (std::max) (size1_, size2_),
0240 l, lower_ + 1 + upper_)];
0241 #elif BOOST_UBLAS_LEGACY_BANDED
0242 const size_type k = j;
0243 const size_type l = upper_ + i - j;
0244 if (k < size2_ &&
0245 l < lower_ + 1 + upper_)
0246 return data () [layout_type::element (k, size2_,
0247 l, lower_ + 1 + upper_)];
0248 #else
0249
0250 if ( is_element_in_band( i, j) ) {
0251 return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
0252 }
0253 #endif
0254 return zero_;
0255 }
0256
0257 BOOST_UBLAS_INLINE
0258 reference at_element (size_type i, size_type j) {
0259 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
0260 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
0261 #ifdef BOOST_UBLAS_OWN_BANDED
0262 const size_type k = (std::max) (i, j);
0263 const size_type l = lower_ + j - i;
0264 return data () [layout_type::element (k, (std::max) (size1_, size2_),
0265 l, lower_ + 1 + upper_)];
0266 #elif BOOST_UBLAS_LEGACY_BANDED
0267 const size_type k = j;
0268 const size_type l = upper_ + i - j;
0269 if (! (k < size2_ &&
0270 l < lower_ + 1 + upper_) ) {
0271 bad_index ().raise ();
0272
0273 }
0274 return data () [layout_type::element (k, size2_,
0275 l, lower_ + 1 + upper_)];
0276 #else
0277
0278 BOOST_UBLAS_CHECK(is_element_in_band( i, j) , bad_index());
0279 return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
0280 #endif
0281 }
0282 BOOST_UBLAS_INLINE
0283 reference operator () (size_type i, size_type j) {
0284 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
0285 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
0286 #ifdef BOOST_UBLAS_OWN_BANDED
0287 const size_type k = (std::max) (i, j);
0288 const size_type l = lower_ + j - i;
0289 if (! (k < (std::max) (size1_, size2_) &&
0290 l < lower_ + 1 + upper_) ) {
0291 bad_index ().raise ();
0292
0293 }
0294 return data () [layout_type::element (k, (std::max) (size1_, size2_),
0295 l, lower_ + 1 + upper_)];
0296 #elif BOOST_UBLAS_LEGACY_BANDED
0297 const size_type k = j;
0298 const size_type l = upper_ + i - j;
0299 if (! (k < size2_ &&
0300 l < lower_ + 1 + upper_) ) {
0301 bad_index ().raise ();
0302
0303 }
0304 return data () [layout_type::element (k, size2_,
0305 l, lower_ + 1 + upper_)];
0306 #else
0307
0308 BOOST_UBLAS_CHECK( is_element_in_band( i, j) , bad_index());
0309 return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
0310 #endif
0311
0312 }
0313
0314
0315 BOOST_UBLAS_INLINE
0316 reference insert_element (size_type i, size_type j, const_reference t) {
0317 return (operator () (i, j) = t);
0318 }
0319 BOOST_UBLAS_INLINE
0320 void erase_element (size_type i, size_type j) {
0321 operator () (i, j) = value_type();
0322 }
0323
0324
0325 BOOST_UBLAS_INLINE
0326 void clear () {
0327 std::fill (data ().begin (), data ().end (), value_type());
0328 }
0329
0330
0331 BOOST_UBLAS_INLINE
0332 banded_matrix &operator = (const banded_matrix &m) {
0333 size1_ = m.size1_;
0334 size2_ = m.size2_;
0335 lower_ = m.lower_;
0336 upper_ = m.upper_;
0337 data () = m.data ();
0338 return *this;
0339 }
0340 BOOST_UBLAS_INLINE
0341 banded_matrix &assign_temporary (banded_matrix &m) {
0342 swap (m);
0343 return *this;
0344 }
0345 template<class AE>
0346 BOOST_UBLAS_INLINE
0347 banded_matrix &operator = (const matrix_expression<AE> &ae) {
0348 self_type temporary (ae, lower_, upper_);
0349 return assign_temporary (temporary);
0350 }
0351 template<class AE>
0352 BOOST_UBLAS_INLINE
0353 banded_matrix &assign (const matrix_expression<AE> &ae) {
0354 matrix_assign<scalar_assign> (*this, ae);
0355 return *this;
0356 }
0357 template<class AE>
0358 BOOST_UBLAS_INLINE
0359 banded_matrix& operator += (const matrix_expression<AE> &ae) {
0360 self_type temporary (*this + ae, lower_, upper_);
0361 return assign_temporary (temporary);
0362 }
0363 template<class AE>
0364 BOOST_UBLAS_INLINE
0365 banded_matrix &plus_assign (const matrix_expression<AE> &ae) {
0366 matrix_assign<scalar_plus_assign> (*this, ae);
0367 return *this;
0368 }
0369 template<class AE>
0370 BOOST_UBLAS_INLINE
0371 banded_matrix& operator -= (const matrix_expression<AE> &ae) {
0372 self_type temporary (*this - ae, lower_, upper_);
0373 return assign_temporary (temporary);
0374 }
0375 template<class AE>
0376 BOOST_UBLAS_INLINE
0377 banded_matrix &minus_assign (const matrix_expression<AE> &ae) {
0378 matrix_assign<scalar_minus_assign> (*this, ae);
0379 return *this;
0380 }
0381 template<class AT>
0382 BOOST_UBLAS_INLINE
0383 banded_matrix& operator *= (const AT &at) {
0384 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
0385 return *this;
0386 }
0387 template<class AT>
0388 BOOST_UBLAS_INLINE
0389 banded_matrix& operator /= (const AT &at) {
0390 matrix_assign_scalar<scalar_divides_assign> (*this, at);
0391 return *this;
0392 }
0393
0394
0395 BOOST_UBLAS_INLINE
0396 void swap (banded_matrix &m) {
0397 if (this != &m) {
0398 std::swap (size1_, m.size1_);
0399 std::swap (size2_, m.size2_);
0400 std::swap (lower_, m.lower_);
0401 std::swap (upper_, m.upper_);
0402 data ().swap (m.data ());
0403 }
0404 }
0405 BOOST_UBLAS_INLINE
0406 friend void swap (banded_matrix &m1, banded_matrix &m2) {
0407 m1.swap (m2);
0408 }
0409
0410
0411 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0412 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
0413 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
0414 typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
0415 typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
0416 #else
0417 class const_iterator1;
0418 class iterator1;
0419 class const_iterator2;
0420 class iterator2;
0421 #endif
0422 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
0423 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
0424 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
0425 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
0426
0427
0428 BOOST_UBLAS_INLINE
0429 const_iterator1 find1 (int rank, size_type i, size_type j) const {
0430 if (rank == 1) {
0431 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
0432 i = (std::max) (i, lower_i);
0433 size_type upper_i = (std::min) (j + 1 + lower_, size1_);
0434 i = (std::min) (i, upper_i);
0435 }
0436 return const_iterator1 (*this, i, j);
0437 }
0438 BOOST_UBLAS_INLINE
0439 iterator1 find1 (int rank, size_type i, size_type j) {
0440 if (rank == 1) {
0441 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
0442 i = (std::max) (i, lower_i);
0443 size_type upper_i = (std::min) (j + 1 + lower_, size1_);
0444 i = (std::min) (i, upper_i);
0445 }
0446 return iterator1 (*this, i, j);
0447 }
0448 BOOST_UBLAS_INLINE
0449 const_iterator2 find2 (int rank, size_type i, size_type j) const {
0450 if (rank == 1) {
0451 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
0452 j = (std::max) (j, lower_j);
0453 size_type upper_j = (std::min) (i + 1 + upper_, size2_);
0454 j = (std::min) (j, upper_j);
0455 }
0456 return const_iterator2 (*this, i, j);
0457 }
0458 BOOST_UBLAS_INLINE
0459 iterator2 find2 (int rank, size_type i, size_type j) {
0460 if (rank == 1) {
0461 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
0462 j = (std::max) (j, lower_j);
0463 size_type upper_j = (std::min) (i + 1 + upper_, size2_);
0464 j = (std::min) (j, upper_j);
0465 }
0466 return iterator2 (*this, i, j);
0467 }
0468
0469
0470
0471 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0472 class const_iterator1:
0473 public container_const_reference<banded_matrix>,
0474 public random_access_iterator_base<packed_random_access_iterator_tag,
0475 const_iterator1, value_type> {
0476 public:
0477 typedef typename banded_matrix::value_type value_type;
0478 typedef typename banded_matrix::difference_type difference_type;
0479 typedef typename banded_matrix::const_reference reference;
0480 typedef const typename banded_matrix::pointer pointer;
0481
0482 typedef const_iterator2 dual_iterator_type;
0483 typedef const_reverse_iterator2 dual_reverse_iterator_type;
0484
0485
0486 BOOST_UBLAS_INLINE
0487 const_iterator1 ():
0488 container_const_reference<self_type> (), it1_ (), it2_ () {}
0489 BOOST_UBLAS_INLINE
0490 const_iterator1 (const self_type &m, size_type it1, size_type it2):
0491 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
0492 BOOST_UBLAS_INLINE
0493 const_iterator1 (const iterator1 &it):
0494 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
0495
0496
0497 BOOST_UBLAS_INLINE
0498 const_iterator1 &operator ++ () {
0499 ++ it1_;
0500 return *this;
0501 }
0502 BOOST_UBLAS_INLINE
0503 const_iterator1 &operator -- () {
0504 -- it1_;
0505 return *this;
0506 }
0507 BOOST_UBLAS_INLINE
0508 const_iterator1 &operator += (difference_type n) {
0509 it1_ += n;
0510 return *this;
0511 }
0512 BOOST_UBLAS_INLINE
0513 const_iterator1 &operator -= (difference_type n) {
0514 it1_ -= n;
0515 return *this;
0516 }
0517 BOOST_UBLAS_INLINE
0518 difference_type operator - (const const_iterator1 &it) const {
0519 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0520 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0521 return it1_ - it.it1_;
0522 }
0523
0524
0525 BOOST_UBLAS_INLINE
0526 const_reference operator * () const {
0527 return (*this) () (it1_, it2_);
0528 }
0529 BOOST_UBLAS_INLINE
0530 const_reference operator [] (difference_type n) const {
0531 return *(*this + n);
0532 }
0533
0534 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0535 BOOST_UBLAS_INLINE
0536 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0537 typename self_type::
0538 #endif
0539 const_iterator2 begin () const {
0540 return (*this) ().find2 (1, it1_, 0);
0541 }
0542 BOOST_UBLAS_INLINE
0543 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0544 typename self_type::
0545 #endif
0546 const_iterator2 cbegin () const {
0547 return begin ();
0548 }
0549 BOOST_UBLAS_INLINE
0550 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0551 typename self_type::
0552 #endif
0553 const_iterator2 end () const {
0554 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
0555 }
0556 BOOST_UBLAS_INLINE
0557 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0558 typename self_type::
0559 #endif
0560 const_iterator2 cend () const {
0561 return end ();
0562 }
0563 BOOST_UBLAS_INLINE
0564 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0565 typename self_type::
0566 #endif
0567 const_reverse_iterator2 rbegin () const {
0568 return const_reverse_iterator2 (end ());
0569 }
0570 BOOST_UBLAS_INLINE
0571 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0572 typename self_type::
0573 #endif
0574 const_reverse_iterator2 crbegin () const {
0575 return rbegin ();
0576 }
0577 BOOST_UBLAS_INLINE
0578 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0579 typename self_type::
0580 #endif
0581 const_reverse_iterator2 rend () const {
0582 return const_reverse_iterator2 (begin ());
0583 }
0584 BOOST_UBLAS_INLINE
0585 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0586 typename self_type::
0587 #endif
0588 const_reverse_iterator2 crend () const {
0589 return rend ();
0590 }
0591 #endif
0592
0593
0594 BOOST_UBLAS_INLINE
0595 size_type index1 () const {
0596 return it1_;
0597 }
0598 BOOST_UBLAS_INLINE
0599 size_type index2 () const {
0600 return it2_;
0601 }
0602
0603
0604 BOOST_UBLAS_INLINE
0605 const_iterator1 &operator = (const const_iterator1 &it) {
0606 container_const_reference<self_type>::assign (&it ());
0607 it1_ = it.it1_;
0608 it2_ = it.it2_;
0609 return *this;
0610 }
0611
0612
0613 BOOST_UBLAS_INLINE
0614 bool operator == (const const_iterator1 &it) const {
0615 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0616 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0617 return it1_ == it.it1_;
0618 }
0619 BOOST_UBLAS_INLINE
0620 bool operator < (const const_iterator1 &it) const {
0621 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0622 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0623 return it1_ < it.it1_;
0624 }
0625
0626 private:
0627 size_type it1_;
0628 size_type it2_;
0629 };
0630 #endif
0631
0632 BOOST_UBLAS_INLINE
0633 const_iterator1 begin1 () const {
0634 return find1 (0, 0, 0);
0635 }
0636 BOOST_UBLAS_INLINE
0637 const_iterator1 cbegin1 () const {
0638 return begin1 ();
0639 }
0640 BOOST_UBLAS_INLINE
0641 const_iterator1 end1 () const {
0642 return find1 (0, size1_, 0);
0643 }
0644 BOOST_UBLAS_INLINE
0645 const_iterator1 cend1 () const {
0646 return end1 ();
0647 }
0648
0649 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0650 class iterator1:
0651 public container_reference<banded_matrix>,
0652 public random_access_iterator_base<packed_random_access_iterator_tag,
0653 iterator1, value_type> {
0654 public:
0655 typedef typename banded_matrix::value_type value_type;
0656 typedef typename banded_matrix::difference_type difference_type;
0657 typedef typename banded_matrix::reference reference;
0658 typedef typename banded_matrix::pointer pointer;
0659
0660 typedef iterator2 dual_iterator_type;
0661 typedef reverse_iterator2 dual_reverse_iterator_type;
0662
0663
0664 BOOST_UBLAS_INLINE
0665 iterator1 ():
0666 container_reference<self_type> (), it1_ (), it2_ () {}
0667 BOOST_UBLAS_INLINE
0668 iterator1 (self_type &m, size_type it1, size_type it2):
0669 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
0670
0671
0672 BOOST_UBLAS_INLINE
0673 iterator1 &operator ++ () {
0674 ++ it1_;
0675 return *this;
0676 }
0677 BOOST_UBLAS_INLINE
0678 iterator1 &operator -- () {
0679 -- it1_;
0680 return *this;
0681 }
0682 BOOST_UBLAS_INLINE
0683 iterator1 &operator += (difference_type n) {
0684 it1_ += n;
0685 return *this;
0686 }
0687 BOOST_UBLAS_INLINE
0688 iterator1 &operator -= (difference_type n) {
0689 it1_ -= n;
0690 return *this;
0691 }
0692 BOOST_UBLAS_INLINE
0693 difference_type operator - (const iterator1 &it) const {
0694 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0695 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0696 return it1_ - it.it1_;
0697 }
0698
0699
0700 BOOST_UBLAS_INLINE
0701 reference operator * () const {
0702 return (*this) ().at_element (it1_, it2_);
0703 }
0704 BOOST_UBLAS_INLINE
0705 reference operator [] (difference_type n) const {
0706 return *(*this + n);
0707 }
0708
0709 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0710 BOOST_UBLAS_INLINE
0711 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0712 typename self_type::
0713 #endif
0714 iterator2 begin () const {
0715 return (*this) ().find2 (1, it1_, 0);
0716 }
0717 BOOST_UBLAS_INLINE
0718 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0719 typename self_type::
0720 #endif
0721 iterator2 end () const {
0722 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
0723 }
0724
0725 BOOST_UBLAS_INLINE
0726 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0727 typename self_type::
0728 #endif
0729 reverse_iterator2 rbegin () const {
0730 return reverse_iterator2 (end ());
0731 }
0732 BOOST_UBLAS_INLINE
0733 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0734 typename self_type::
0735 #endif
0736 reverse_iterator2 rend () const {
0737 return reverse_iterator2 (begin ());
0738 }
0739 #endif
0740
0741
0742 BOOST_UBLAS_INLINE
0743 size_type index1 () const {
0744 return it1_;
0745 }
0746 BOOST_UBLAS_INLINE
0747 size_type index2 () const {
0748 return it2_;
0749 }
0750
0751
0752 BOOST_UBLAS_INLINE
0753 iterator1 &operator = (const iterator1 &it) {
0754 container_reference<self_type>::assign (&it ());
0755 it1_ = it.it1_;
0756 it2_ = it.it2_;
0757 return *this;
0758 }
0759
0760
0761 BOOST_UBLAS_INLINE
0762 bool operator == (const iterator1 &it) const {
0763 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0764 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0765 return it1_ == it.it1_;
0766 }
0767 BOOST_UBLAS_INLINE
0768 bool operator < (const iterator1 &it) const {
0769 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0770 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0771 return it1_ < it.it1_;
0772 }
0773
0774 private:
0775 size_type it1_;
0776 size_type it2_;
0777
0778 friend class const_iterator1;
0779 };
0780 #endif
0781
0782 BOOST_UBLAS_INLINE
0783 iterator1 begin1 () {
0784 return find1 (0, 0, 0);
0785 }
0786 BOOST_UBLAS_INLINE
0787 iterator1 end1 () {
0788 return find1 (0, size1_, 0);
0789 }
0790
0791 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0792 class const_iterator2:
0793 public container_const_reference<banded_matrix>,
0794 public random_access_iterator_base<packed_random_access_iterator_tag,
0795 const_iterator2, value_type> {
0796 public:
0797 typedef typename banded_matrix::value_type value_type;
0798 typedef typename banded_matrix::difference_type difference_type;
0799 typedef typename banded_matrix::const_reference reference;
0800 typedef const typename banded_matrix::pointer pointer;
0801
0802 typedef const_iterator1 dual_iterator_type;
0803 typedef const_reverse_iterator1 dual_reverse_iterator_type;
0804
0805
0806 BOOST_UBLAS_INLINE
0807 const_iterator2 ():
0808 container_const_reference<self_type> (), it1_ (), it2_ () {}
0809 BOOST_UBLAS_INLINE
0810 const_iterator2 (const self_type &m, size_type it1, size_type it2):
0811 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
0812 BOOST_UBLAS_INLINE
0813 const_iterator2 (const iterator2 &it):
0814 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
0815
0816
0817 BOOST_UBLAS_INLINE
0818 const_iterator2 &operator ++ () {
0819 ++ it2_;
0820 return *this;
0821 }
0822 BOOST_UBLAS_INLINE
0823 const_iterator2 &operator -- () {
0824 -- it2_;
0825 return *this;
0826 }
0827 BOOST_UBLAS_INLINE
0828 const_iterator2 &operator += (difference_type n) {
0829 it2_ += n;
0830 return *this;
0831 }
0832 BOOST_UBLAS_INLINE
0833 const_iterator2 &operator -= (difference_type n) {
0834 it2_ -= n;
0835 return *this;
0836 }
0837 BOOST_UBLAS_INLINE
0838 difference_type operator - (const const_iterator2 &it) const {
0839 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0840 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
0841 return it2_ - it.it2_;
0842 }
0843
0844
0845 BOOST_UBLAS_INLINE
0846 const_reference operator * () const {
0847 return (*this) () (it1_, it2_);
0848 }
0849 BOOST_UBLAS_INLINE
0850 const_reference operator [] (difference_type n) const {
0851 return *(*this + n);
0852 }
0853
0854 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0855 BOOST_UBLAS_INLINE
0856 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0857 typename self_type::
0858 #endif
0859 const_iterator1 begin () const {
0860 return (*this) ().find1 (1, 0, it2_);
0861 }
0862 BOOST_UBLAS_INLINE
0863 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0864 typename self_type::
0865 #endif
0866 const_iterator1 cbegin () const {
0867 return begin ();
0868 }
0869 BOOST_UBLAS_INLINE
0870 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0871 typename self_type::
0872 #endif
0873 const_iterator1 end () const {
0874 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
0875 }
0876 BOOST_UBLAS_INLINE
0877 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0878 typename self_type::
0879 #endif
0880 const_iterator1 cend () const {
0881 return end();
0882 }
0883
0884 BOOST_UBLAS_INLINE
0885 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0886 typename self_type::
0887 #endif
0888 const_reverse_iterator1 rbegin () const {
0889 return const_reverse_iterator1 (end ());
0890 }
0891 BOOST_UBLAS_INLINE
0892 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0893 typename self_type::
0894 #endif
0895 const_reverse_iterator1 crbegin () const {
0896 return rbegin ();
0897 }
0898 BOOST_UBLAS_INLINE
0899 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0900 typename self_type::
0901 #endif
0902 const_reverse_iterator1 rend () const {
0903 return const_reverse_iterator1 (begin ());
0904 }
0905 BOOST_UBLAS_INLINE
0906 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0907 typename self_type::
0908 #endif
0909 const_reverse_iterator1 crend () const {
0910 return rend ();
0911 }
0912 #endif
0913
0914
0915 BOOST_UBLAS_INLINE
0916 size_type index1 () const {
0917 return it1_;
0918 }
0919 BOOST_UBLAS_INLINE
0920 size_type index2 () const {
0921 return it2_;
0922 }
0923
0924
0925 BOOST_UBLAS_INLINE
0926 const_iterator2 &operator = (const const_iterator2 &it) {
0927 container_const_reference<self_type>::assign (&it ());
0928 it1_ = it.it1_;
0929 it2_ = it.it2_;
0930 return *this;
0931 }
0932
0933
0934 BOOST_UBLAS_INLINE
0935 bool operator == (const const_iterator2 &it) const {
0936 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0937 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
0938 return it2_ == it.it2_;
0939 }
0940 BOOST_UBLAS_INLINE
0941 bool operator < (const const_iterator2 &it) const {
0942 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0943 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
0944 return it2_ < it.it2_;
0945 }
0946
0947 private:
0948 size_type it1_;
0949 size_type it2_;
0950 };
0951 #endif
0952
0953 BOOST_UBLAS_INLINE
0954 const_iterator2 begin2 () const {
0955 return find2 (0, 0, 0);
0956 }
0957 BOOST_UBLAS_INLINE
0958 const_iterator2 cbegin2 () const {
0959 return begin2 ();
0960 }
0961 BOOST_UBLAS_INLINE
0962 const_iterator2 end2 () const {
0963 return find2 (0, 0, size2_);
0964 }
0965 BOOST_UBLAS_INLINE
0966 const_iterator2 cend2 () const {
0967 return end2 ();
0968 }
0969
0970 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0971 class iterator2:
0972 public container_reference<banded_matrix>,
0973 public random_access_iterator_base<packed_random_access_iterator_tag,
0974 iterator2, value_type> {
0975 public:
0976 typedef typename banded_matrix::value_type value_type;
0977 typedef typename banded_matrix::difference_type difference_type;
0978 typedef typename banded_matrix::reference reference;
0979 typedef typename banded_matrix::pointer pointer;
0980
0981 typedef iterator1 dual_iterator_type;
0982 typedef reverse_iterator1 dual_reverse_iterator_type;
0983
0984
0985 BOOST_UBLAS_INLINE
0986 iterator2 ():
0987 container_reference<self_type> (), it1_ (), it2_ () {}
0988 BOOST_UBLAS_INLINE
0989 iterator2 (self_type &m, size_type it1, size_type it2):
0990 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
0991
0992
0993 BOOST_UBLAS_INLINE
0994 iterator2 &operator ++ () {
0995 ++ it2_;
0996 return *this;
0997 }
0998 BOOST_UBLAS_INLINE
0999 iterator2 &operator -- () {
1000 -- it2_;
1001 return *this;
1002 }
1003 BOOST_UBLAS_INLINE
1004 iterator2 &operator += (difference_type n) {
1005 it2_ += n;
1006 return *this;
1007 }
1008 BOOST_UBLAS_INLINE
1009 iterator2 &operator -= (difference_type n) {
1010 it2_ -= n;
1011 return *this;
1012 }
1013 BOOST_UBLAS_INLINE
1014 difference_type operator - (const iterator2 &it) const {
1015 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1016 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1017 return it2_ - it.it2_;
1018 }
1019
1020
1021 BOOST_UBLAS_INLINE
1022 reference operator * () const {
1023 return (*this) ().at_element (it1_, it2_);
1024 }
1025 BOOST_UBLAS_INLINE
1026 reference operator [] (difference_type n) const {
1027 return *(*this + n);
1028 }
1029
1030 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1031 BOOST_UBLAS_INLINE
1032 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1033 typename self_type::
1034 #endif
1035 iterator1 begin () const {
1036 return (*this) ().find1 (1, 0, it2_);
1037 }
1038 BOOST_UBLAS_INLINE
1039 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1040 typename self_type::
1041 #endif
1042 iterator1 end () const {
1043 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
1044 }
1045 BOOST_UBLAS_INLINE
1046 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1047 typename self_type::
1048 #endif
1049 reverse_iterator1 rbegin () const {
1050 return reverse_iterator1 (end ());
1051 }
1052 BOOST_UBLAS_INLINE
1053 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1054 typename self_type::
1055 #endif
1056 reverse_iterator1 rend () const {
1057 return reverse_iterator1 (begin ());
1058 }
1059 #endif
1060
1061
1062 BOOST_UBLAS_INLINE
1063 size_type index1 () const {
1064 return it1_;
1065 }
1066 BOOST_UBLAS_INLINE
1067 size_type index2 () const {
1068 return it2_;
1069 }
1070
1071
1072 BOOST_UBLAS_INLINE
1073 iterator2 &operator = (const iterator2 &it) {
1074 container_reference<self_type>::assign (&it ());
1075 it1_ = it.it1_;
1076 it2_ = it.it2_;
1077 return *this;
1078 }
1079
1080
1081 BOOST_UBLAS_INLINE
1082 bool operator == (const iterator2 &it) const {
1083 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1084 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1085 return it2_ == it.it2_;
1086 }
1087 BOOST_UBLAS_INLINE
1088 bool operator < (const iterator2 &it) const {
1089 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1090 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1091 return it2_ < it.it2_;
1092 }
1093
1094 private:
1095 size_type it1_;
1096 size_type it2_;
1097
1098 friend class const_iterator2;
1099 };
1100 #endif
1101
1102 BOOST_UBLAS_INLINE
1103 iterator2 begin2 () {
1104 return find2 (0, 0, 0);
1105 }
1106 BOOST_UBLAS_INLINE
1107 iterator2 end2 () {
1108 return find2 (0, 0, size2_);
1109 }
1110
1111
1112
1113 BOOST_UBLAS_INLINE
1114 const_reverse_iterator1 rbegin1 () const {
1115 return const_reverse_iterator1 (end1 ());
1116 }
1117 BOOST_UBLAS_INLINE
1118 const_reverse_iterator1 crbegin1 () const {
1119 return rbegin1 ();
1120 }
1121 BOOST_UBLAS_INLINE
1122 const_reverse_iterator1 rend1 () const {
1123 return const_reverse_iterator1 (begin1 ());
1124 }
1125 BOOST_UBLAS_INLINE
1126 const_reverse_iterator1 crend1 () const {
1127 return rend1 ();
1128 }
1129
1130 BOOST_UBLAS_INLINE
1131 reverse_iterator1 rbegin1 () {
1132 return reverse_iterator1 (end1 ());
1133 }
1134 BOOST_UBLAS_INLINE
1135 reverse_iterator1 rend1 () {
1136 return reverse_iterator1 (begin1 ());
1137 }
1138
1139 BOOST_UBLAS_INLINE
1140 const_reverse_iterator2 rbegin2 () const {
1141 return const_reverse_iterator2 (end2 ());
1142 }
1143 BOOST_UBLAS_INLINE
1144 const_reverse_iterator2 crbegin2 () const {
1145 return rbegin2 ();
1146 }
1147 BOOST_UBLAS_INLINE
1148 const_reverse_iterator2 rend2 () const {
1149 return const_reverse_iterator2 (begin2 ());
1150 }
1151 BOOST_UBLAS_INLINE
1152 const_reverse_iterator2 crend2 () const {
1153 return rend2 ();
1154 }
1155
1156 BOOST_UBLAS_INLINE
1157 reverse_iterator2 rbegin2 () {
1158 return reverse_iterator2 (end2 ());
1159 }
1160 BOOST_UBLAS_INLINE
1161 reverse_iterator2 rend2 () {
1162 return reverse_iterator2 (begin2 ());
1163 }
1164
1165 private:
1166 size_type size1_;
1167 size_type size2_;
1168 size_type lower_;
1169 size_type upper_;
1170 array_type data_;
1171 typedef const value_type const_value_type;
1172 static const_value_type zero_;
1173 };
1174
1175 template<class T, class L, class A>
1176 typename banded_matrix<T, L, A>::const_value_type banded_matrix<T, L, A>::zero_ = value_type();
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194 template<class T, class L, class A>
1195 class diagonal_matrix:
1196 public banded_matrix<T, L, A> {
1197 public:
1198 typedef typename A::size_type size_type;
1199 typedef banded_matrix<T, L, A> matrix_type;
1200 typedef A array_type;
1201
1202
1203 BOOST_UBLAS_INLINE
1204 diagonal_matrix ():
1205 matrix_type () {}
1206 BOOST_UBLAS_INLINE
1207 diagonal_matrix (size_type size):
1208 matrix_type (size, size) {}
1209 BOOST_UBLAS_INLINE
1210 diagonal_matrix (size_type size, const array_type& data):
1211 matrix_type (size, size, 0, 0, data) {}
1212 BOOST_UBLAS_INLINE
1213 diagonal_matrix (size_type size1, size_type size2):
1214 matrix_type (size1, size2) {}
1215 template<class AE>
1216 BOOST_UBLAS_INLINE
1217 diagonal_matrix (const matrix_expression<AE> &ae):
1218 matrix_type (ae) {}
1219 BOOST_UBLAS_INLINE
1220 ~diagonal_matrix () {}
1221
1222
1223 BOOST_UBLAS_INLINE
1224 diagonal_matrix &operator = (const diagonal_matrix &m) {
1225 matrix_type::operator = (m);
1226 return *this;
1227 }
1228 template<class AE>
1229 BOOST_UBLAS_INLINE
1230 diagonal_matrix &operator = (const matrix_expression<AE> &ae) {
1231 matrix_type::operator = (ae);
1232 return *this;
1233 }
1234 };
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248 template<class M>
1249 class banded_adaptor:
1250 public matrix_expression<banded_adaptor<M> > {
1251
1252 typedef banded_adaptor<M> self_type;
1253
1254 public:
1255 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1256 using matrix_expression<self_type>::operator ();
1257 #endif
1258 typedef const M const_matrix_type;
1259 typedef M matrix_type;
1260 typedef typename M::size_type size_type;
1261 typedef typename M::difference_type difference_type;
1262 typedef typename M::value_type value_type;
1263 typedef typename M::const_reference const_reference;
1264 typedef typename boost::mpl::if_<boost::is_const<M>,
1265 typename M::const_reference,
1266 typename M::reference>::type reference;
1267 typedef typename boost::mpl::if_<boost::is_const<M>,
1268 typename M::const_closure_type,
1269 typename M::closure_type>::type matrix_closure_type;
1270 typedef const self_type const_closure_type;
1271 typedef self_type closure_type;
1272
1273
1274
1275 typedef typename storage_restrict_traits<typename M::storage_category,
1276 packed_proxy_tag>::storage_category storage_category;
1277 typedef typename M::orientation_category orientation_category;
1278
1279
1280 BOOST_UBLAS_INLINE
1281 banded_adaptor (matrix_type &data, size_type lower = 0, size_type upper = 0):
1282 matrix_expression<self_type> (),
1283 data_ (data), lower_ (lower), upper_ (upper) {}
1284 BOOST_UBLAS_INLINE
1285 banded_adaptor (const banded_adaptor &m):
1286 matrix_expression<self_type> (),
1287 data_ (m.data_), lower_ (m.lower_), upper_ (m.upper_) {}
1288
1289
1290 BOOST_UBLAS_INLINE
1291 size_type size1 () const {
1292 return data_.size1 ();
1293 }
1294 BOOST_UBLAS_INLINE
1295 size_type size2 () const {
1296 return data_.size2 ();
1297 }
1298 BOOST_UBLAS_INLINE
1299 size_type lower () const {
1300 return lower_;
1301 }
1302 BOOST_UBLAS_INLINE
1303 size_type upper () const {
1304 return upper_;
1305 }
1306
1307
1308 BOOST_UBLAS_INLINE
1309 const matrix_closure_type &data () const {
1310 return data_;
1311 }
1312 BOOST_UBLAS_INLINE
1313 matrix_closure_type &data () {
1314 return data_;
1315 }
1316
1317 #if !defined (BOOST_UBLAS_OWN_BANDED)||(BOOST_UBLAS_LEGACY_BANDED)
1318 BOOST_UBLAS_INLINE
1319 bool is_element_in_band(size_type i, size_type j) const{
1320
1321 return (upper_+i >= j) && i <= ( j + lower_);
1322 }
1323 #endif
1324
1325
1326 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
1327 BOOST_UBLAS_INLINE
1328 const_reference operator () (size_type i, size_type j) const {
1329 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1330 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1331 #ifdef BOOST_UBLAS_OWN_BANDED
1332 size_type k = (std::max) (i, j);
1333 size_type l = lower_ + j - i;
1334 if (k < (std::max) (size1 (), size2 ()) &&
1335 l < lower_ + 1 + upper_)
1336 return data () (i, j);
1337 #elif BOOST_UBLAS_LEGACY_BANDED
1338 size_type k = j;
1339 size_type l = upper_ + i - j;
1340 if (k < size2 () &&
1341 l < lower_ + 1 + upper_)
1342 return data () (i, j);
1343 #else
1344 if (is_element_in_band( i, j))
1345 return data () (i, j);
1346 #endif
1347 return zero_;
1348 }
1349 BOOST_UBLAS_INLINE
1350 reference operator () (size_type i, size_type j) {
1351 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1352 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1353 #ifdef BOOST_UBLAS_OWN_BANDED
1354 size_type k = (std::max) (i, j);
1355 size_type l = lower_ + j - i;
1356 if (k < (std::max) (size1 (), size2 ()) &&
1357 l < lower_ + 1 + upper_)
1358 return data () (i, j);
1359 #elif BOOST_UBLAS_LEGACY_BANDED
1360 size_type k = j;
1361 size_type l = upper_ + i - j;
1362 if (k < size2 () &&
1363 l < lower_ + 1 + upper_)
1364 return data () (i, j);
1365 #else
1366 if (is_element_in_band( i, j))
1367 return data () (i, j);
1368 #endif
1369 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
1370 bad_index ().raise ();
1371 #endif
1372 return const_cast<reference>(zero_);
1373 }
1374 #else
1375 BOOST_UBLAS_INLINE
1376 reference operator () (size_type i, size_type j) const {
1377 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1378 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1379 #ifdef BOOST_UBLAS_OWN_BANDED
1380 size_type k = (std::max) (i, j);
1381 size_type l = lower_ + j - i;
1382 if (k < (std::max) (size1 (), size2 ()) &&
1383 l < lower_ + 1 + upper_)
1384 return data () (i, j);
1385 #elif BOOST_UBLAS_LEGACY_BANDED
1386 size_type k = j;
1387 size_type l = upper_ + i - j;
1388 if (k < size2 () &&
1389 l < lower_ + 1 + upper_)
1390 return data () (i, j);
1391 #else
1392 if (is_element_in_band( i, j))
1393 return data () (i, j);
1394 #endif
1395 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
1396 bad_index ().raise ();
1397 #endif
1398 return const_cast<reference>(zero_);
1399 }
1400 #endif
1401
1402
1403 BOOST_UBLAS_INLINE
1404 banded_adaptor &operator = (const banded_adaptor &m) {
1405 matrix_assign<scalar_assign> (*this, m);
1406 return *this;
1407 }
1408 BOOST_UBLAS_INLINE
1409 banded_adaptor &assign_temporary (banded_adaptor &m) {
1410 *this = m;
1411 return *this;
1412 }
1413 template<class AE>
1414 BOOST_UBLAS_INLINE
1415 banded_adaptor &operator = (const matrix_expression<AE> &ae) {
1416 matrix_assign<scalar_assign> (*this, matrix<value_type> (ae));
1417 return *this;
1418 }
1419 template<class AE>
1420 BOOST_UBLAS_INLINE
1421 banded_adaptor &assign (const matrix_expression<AE> &ae) {
1422 matrix_assign<scalar_assign> (*this, ae);
1423 return *this;
1424 }
1425 template<class AE>
1426 BOOST_UBLAS_INLINE
1427 banded_adaptor& operator += (const matrix_expression<AE> &ae) {
1428 matrix_assign<scalar_assign> (*this, matrix<value_type> (*this + ae));
1429 return *this;
1430 }
1431 template<class AE>
1432 BOOST_UBLAS_INLINE
1433 banded_adaptor &plus_assign (const matrix_expression<AE> &ae) {
1434 matrix_assign<scalar_plus_assign> (*this, ae);
1435 return *this;
1436 }
1437 template<class AE>
1438 BOOST_UBLAS_INLINE
1439 banded_adaptor& operator -= (const matrix_expression<AE> &ae) {
1440 matrix_assign<scalar_assign> (*this, matrix<value_type> (*this - ae));
1441 return *this;
1442 }
1443 template<class AE>
1444 BOOST_UBLAS_INLINE
1445 banded_adaptor &minus_assign (const matrix_expression<AE> &ae) {
1446 matrix_assign<scalar_minus_assign> (*this, ae);
1447 return *this;
1448 }
1449 template<class AT>
1450 BOOST_UBLAS_INLINE
1451 banded_adaptor& operator *= (const AT &at) {
1452 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
1453 return *this;
1454 }
1455 template<class AT>
1456 BOOST_UBLAS_INLINE
1457 banded_adaptor& operator /= (const AT &at) {
1458 matrix_assign_scalar<scalar_divides_assign> (*this, at);
1459 return *this;
1460 }
1461
1462
1463 BOOST_UBLAS_INLINE
1464 bool same_closure (const banded_adaptor &ba) const {
1465 return (*this).data ().same_closure (ba.data ());
1466 }
1467
1468
1469 BOOST_UBLAS_INLINE
1470 void swap (banded_adaptor &m) {
1471 if (this != &m) {
1472 BOOST_UBLAS_CHECK (lower_ == m.lower_, bad_size ());
1473 BOOST_UBLAS_CHECK (upper_ == m.upper_, bad_size ());
1474 matrix_swap<scalar_swap> (*this, m);
1475 }
1476 }
1477 BOOST_UBLAS_INLINE
1478 friend void swap (banded_adaptor &m1, banded_adaptor &m2) {
1479 m1.swap (m2);
1480 }
1481
1482
1483 private:
1484
1485 typedef typename M::const_iterator1 const_subiterator1_type;
1486 typedef typename boost::mpl::if_<boost::is_const<M>,
1487 typename M::const_iterator1,
1488 typename M::iterator1>::type subiterator1_type;
1489 typedef typename M::const_iterator2 const_subiterator2_type;
1490 typedef typename boost::mpl::if_<boost::is_const<M>,
1491 typename M::const_iterator2,
1492 typename M::iterator2>::type subiterator2_type;
1493
1494 public:
1495 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1496 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
1497 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
1498 typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
1499 typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
1500 #else
1501 class const_iterator1;
1502 class iterator1;
1503 class const_iterator2;
1504 class iterator2;
1505 #endif
1506 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
1507 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
1508 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
1509 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
1510
1511
1512 BOOST_UBLAS_INLINE
1513 const_iterator1 find1 (int rank, size_type i, size_type j) const {
1514 if (rank == 1) {
1515 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
1516 i = (std::max) (i, lower_i);
1517 size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
1518 i = (std::min) (i, upper_i);
1519 }
1520 return const_iterator1 (*this, data ().find1 (rank, i, j));
1521 }
1522 BOOST_UBLAS_INLINE
1523 iterator1 find1 (int rank, size_type i, size_type j) {
1524 if (rank == 1) {
1525 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
1526 i = (std::max) (i, lower_i);
1527 size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
1528 i = (std::min) (i, upper_i);
1529 }
1530 return iterator1 (*this, data ().find1 (rank, i, j));
1531 }
1532 BOOST_UBLAS_INLINE
1533 const_iterator2 find2 (int rank, size_type i, size_type j) const {
1534 if (rank == 1) {
1535 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
1536 j = (std::max) (j, lower_j);
1537 size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
1538 j = (std::min) (j, upper_j);
1539 }
1540 return const_iterator2 (*this, data ().find2 (rank, i, j));
1541 }
1542 BOOST_UBLAS_INLINE
1543 iterator2 find2 (int rank, size_type i, size_type j) {
1544 if (rank == 1) {
1545 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
1546 j = (std::max) (j, lower_j);
1547 size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
1548 j = (std::min) (j, upper_j);
1549 }
1550 return iterator2 (*this, data ().find2 (rank, i, j));
1551 }
1552
1553
1554
1555 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1556 class const_iterator1:
1557 public container_const_reference<banded_adaptor>,
1558 public random_access_iterator_base<typename iterator_restrict_traits<
1559 typename const_subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
1560 const_iterator1, value_type> {
1561 public:
1562 typedef typename const_subiterator1_type::value_type value_type;
1563 typedef typename const_subiterator1_type::difference_type difference_type;
1564 typedef typename const_subiterator1_type::reference reference;
1565 typedef typename const_subiterator1_type::pointer pointer;
1566
1567 typedef const_iterator2 dual_iterator_type;
1568 typedef const_reverse_iterator2 dual_reverse_iterator_type;
1569
1570
1571 BOOST_UBLAS_INLINE
1572 const_iterator1 ():
1573 container_const_reference<self_type> (), it1_ () {}
1574 BOOST_UBLAS_INLINE
1575 const_iterator1 (const self_type &m, const const_subiterator1_type &it1):
1576 container_const_reference<self_type> (m), it1_ (it1) {}
1577 BOOST_UBLAS_INLINE
1578 const_iterator1 (const iterator1 &it):
1579 container_const_reference<self_type> (it ()), it1_ (it.it1_) {}
1580
1581
1582 BOOST_UBLAS_INLINE
1583 const_iterator1 &operator ++ () {
1584 ++ it1_;
1585 return *this;
1586 }
1587 BOOST_UBLAS_INLINE
1588 const_iterator1 &operator -- () {
1589 -- it1_;
1590 return *this;
1591 }
1592 BOOST_UBLAS_INLINE
1593 const_iterator1 &operator += (difference_type n) {
1594 it1_ += n;
1595 return *this;
1596 }
1597 BOOST_UBLAS_INLINE
1598 const_iterator1 &operator -= (difference_type n) {
1599 it1_ -= n;
1600 return *this;
1601 }
1602 BOOST_UBLAS_INLINE
1603 difference_type operator - (const const_iterator1 &it) const {
1604 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1605 return it1_ - it.it1_;
1606 }
1607
1608
1609 BOOST_UBLAS_INLINE
1610 const_reference operator * () const {
1611 size_type i = index1 ();
1612 size_type j = index2 ();
1613 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
1614 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
1615 #ifdef BOOST_UBLAS_OWN_BANDED
1616 size_type k = (std::max) (i, j);
1617 size_type l = (*this) ().lower () + j - i;
1618 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
1619 l < (*this) ().lower () + 1 + (*this) ().upper ())
1620 return *it1_;
1621 #else
1622 size_type k = j;
1623 size_type l = (*this) ().upper () + i - j;
1624 if (k < (*this) ().size2 () &&
1625 l < (*this) ().lower () + 1 + (*this) ().upper ())
1626 return *it1_;
1627 #endif
1628 return (*this) () (i, j);
1629 }
1630 BOOST_UBLAS_INLINE
1631 const_reference operator [] (difference_type n) const {
1632 return *(*this + n);
1633 }
1634
1635 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1636 BOOST_UBLAS_INLINE
1637 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1638 typename self_type::
1639 #endif
1640 const_iterator2 begin () const {
1641 return (*this) ().find2 (1, index1 (), 0);
1642 }
1643 BOOST_UBLAS_INLINE
1644 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1645 typename self_type::
1646 #endif
1647 const_iterator2 cbegin () const {
1648 return begin ();
1649 }
1650 BOOST_UBLAS_INLINE
1651 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1652 typename self_type::
1653 #endif
1654 const_iterator2 end () const {
1655 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
1656 }
1657 BOOST_UBLAS_INLINE
1658 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1659 typename self_type::
1660 #endif
1661 const_iterator2 cend () const {
1662 return end ();
1663 }
1664 BOOST_UBLAS_INLINE
1665 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1666 typename self_type::
1667 #endif
1668 const_reverse_iterator2 rbegin () const {
1669 return const_reverse_iterator2 (end ());
1670 }
1671 BOOST_UBLAS_INLINE
1672 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1673 typename self_type::
1674 #endif
1675 const_reverse_iterator2 crbegin () const {
1676 return rbegin ();
1677 }
1678 BOOST_UBLAS_INLINE
1679 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1680 typename self_type::
1681 #endif
1682 const_reverse_iterator2 rend () const {
1683 return const_reverse_iterator2 (begin ());
1684 }
1685 BOOST_UBLAS_INLINE
1686 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1687 typename self_type::
1688 #endif
1689 const_reverse_iterator2 crend () const {
1690 return rend ();
1691 }
1692 #endif
1693
1694
1695 BOOST_UBLAS_INLINE
1696 size_type index1 () const {
1697 return it1_.index1 ();
1698 }
1699 BOOST_UBLAS_INLINE
1700 size_type index2 () const {
1701 return it1_.index2 ();
1702 }
1703
1704
1705 BOOST_UBLAS_INLINE
1706 const_iterator1 &operator = (const const_iterator1 &it) {
1707 container_const_reference<self_type>::assign (&it ());
1708 it1_ = it.it1_;
1709 return *this;
1710 }
1711
1712
1713 BOOST_UBLAS_INLINE
1714 bool operator == (const const_iterator1 &it) const {
1715 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1716 return it1_ == it.it1_;
1717 }
1718 BOOST_UBLAS_INLINE
1719 bool operator < (const const_iterator1 &it) const {
1720 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1721 return it1_ < it.it1_;
1722 }
1723
1724 private:
1725 const_subiterator1_type it1_;
1726 };
1727 #endif
1728
1729 BOOST_UBLAS_INLINE
1730 const_iterator1 begin1 () const {
1731 return find1 (0, 0, 0);
1732 }
1733 BOOST_UBLAS_INLINE
1734 const_iterator1 cbegin1 () const {
1735 return begin1 ();
1736 }
1737 BOOST_UBLAS_INLINE
1738 const_iterator1 end1 () const {
1739 return find1 (0, size1 (), 0);
1740 }
1741 BOOST_UBLAS_INLINE
1742 const_iterator1 cend1 () const {
1743 return end1 ();
1744 }
1745
1746 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1747 class iterator1:
1748 public container_reference<banded_adaptor>,
1749 public random_access_iterator_base<typename iterator_restrict_traits<
1750 typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
1751 iterator1, value_type> {
1752 public:
1753 typedef typename subiterator1_type::value_type value_type;
1754 typedef typename subiterator1_type::difference_type difference_type;
1755 typedef typename subiterator1_type::reference reference;
1756 typedef typename subiterator1_type::pointer pointer;
1757
1758 typedef iterator2 dual_iterator_type;
1759 typedef reverse_iterator2 dual_reverse_iterator_type;
1760
1761
1762 BOOST_UBLAS_INLINE
1763 iterator1 ():
1764 container_reference<self_type> (), it1_ () {}
1765 BOOST_UBLAS_INLINE
1766 iterator1 (self_type &m, const subiterator1_type &it1):
1767 container_reference<self_type> (m), it1_ (it1) {}
1768
1769
1770 BOOST_UBLAS_INLINE
1771 iterator1 &operator ++ () {
1772 ++ it1_;
1773 return *this;
1774 }
1775 BOOST_UBLAS_INLINE
1776 iterator1 &operator -- () {
1777 -- it1_;
1778 return *this;
1779 }
1780 BOOST_UBLAS_INLINE
1781 iterator1 &operator += (difference_type n) {
1782 it1_ += n;
1783 return *this;
1784 }
1785 BOOST_UBLAS_INLINE
1786 iterator1 &operator -= (difference_type n) {
1787 it1_ -= n;
1788 return *this;
1789 }
1790 BOOST_UBLAS_INLINE
1791 difference_type operator - (const iterator1 &it) const {
1792 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1793 return it1_ - it.it1_;
1794 }
1795
1796
1797 BOOST_UBLAS_INLINE
1798 reference operator * () const {
1799 size_type i = index1 ();
1800 size_type j = index2 ();
1801 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
1802 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
1803 #ifdef BOOST_UBLAS_OWN_BANDED
1804 size_type k = (std::max) (i, j);
1805 size_type l = (*this) ().lower () + j - i;
1806 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
1807 l < (*this) ().lower () + 1 + (*this) ().upper ())
1808 return *it1_;
1809 #else
1810 size_type k = j;
1811 size_type l = (*this) ().upper () + i - j;
1812 if (k < (*this) ().size2 () &&
1813 l < (*this) ().lower () + 1 + (*this) ().upper ())
1814 return *it1_;
1815 #endif
1816 return (*this) () (i, j);
1817 }
1818 BOOST_UBLAS_INLINE
1819 reference operator [] (difference_type n) const {
1820 return *(*this + n);
1821 }
1822
1823 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1824 BOOST_UBLAS_INLINE
1825 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1826 typename self_type::
1827 #endif
1828 iterator2 begin () const {
1829 return (*this) ().find2 (1, index1 (), 0);
1830 }
1831 BOOST_UBLAS_INLINE
1832 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1833 typename self_type::
1834 #endif
1835 iterator2 end () const {
1836 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
1837 }
1838 BOOST_UBLAS_INLINE
1839 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1840 typename self_type::
1841 #endif
1842 reverse_iterator2 rbegin () const {
1843 return reverse_iterator2 (end ());
1844 }
1845 BOOST_UBLAS_INLINE
1846 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1847 typename self_type::
1848 #endif
1849 reverse_iterator2 rend () const {
1850 return reverse_iterator2 (begin ());
1851 }
1852 #endif
1853
1854
1855 BOOST_UBLAS_INLINE
1856 size_type index1 () const {
1857 return it1_.index1 ();
1858 }
1859 BOOST_UBLAS_INLINE
1860 size_type index2 () const {
1861 return it1_.index2 ();
1862 }
1863
1864
1865 BOOST_UBLAS_INLINE
1866 iterator1 &operator = (const iterator1 &it) {
1867 container_reference<self_type>::assign (&it ());
1868 it1_ = it.it1_;
1869 return *this;
1870 }
1871
1872
1873 BOOST_UBLAS_INLINE
1874 bool operator == (const iterator1 &it) const {
1875 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1876 return it1_ == it.it1_;
1877 }
1878 BOOST_UBLAS_INLINE
1879 bool operator < (const iterator1 &it) const {
1880 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1881 return it1_ < it.it1_;
1882 }
1883
1884 private:
1885 subiterator1_type it1_;
1886
1887 friend class const_iterator1;
1888 };
1889 #endif
1890
1891 BOOST_UBLAS_INLINE
1892 iterator1 begin1 () {
1893 return find1 (0, 0, 0);
1894 }
1895 BOOST_UBLAS_INLINE
1896 iterator1 end1 () {
1897 return find1 (0, size1 (), 0);
1898 }
1899
1900 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1901 class const_iterator2:
1902 public container_const_reference<banded_adaptor>,
1903 public random_access_iterator_base<packed_random_access_iterator_tag,
1904 const_iterator2, value_type> {
1905 public:
1906 typedef typename iterator_restrict_traits<typename const_subiterator2_type::iterator_category,
1907 packed_random_access_iterator_tag>::iterator_category iterator_category;
1908 typedef typename const_subiterator2_type::value_type value_type;
1909 typedef typename const_subiterator2_type::difference_type difference_type;
1910 typedef typename const_subiterator2_type::reference reference;
1911 typedef typename const_subiterator2_type::pointer pointer;
1912
1913 typedef const_iterator1 dual_iterator_type;
1914 typedef const_reverse_iterator1 dual_reverse_iterator_type;
1915
1916
1917 BOOST_UBLAS_INLINE
1918 const_iterator2 ():
1919 container_const_reference<self_type> (), it2_ () {}
1920 BOOST_UBLAS_INLINE
1921 const_iterator2 (const self_type &m, const const_subiterator2_type &it2):
1922 container_const_reference<self_type> (m), it2_ (it2) {}
1923 BOOST_UBLAS_INLINE
1924 const_iterator2 (const iterator2 &it):
1925 container_const_reference<self_type> (it ()), it2_ (it.it2_) {}
1926
1927
1928 BOOST_UBLAS_INLINE
1929 const_iterator2 &operator ++ () {
1930 ++ it2_;
1931 return *this;
1932 }
1933 BOOST_UBLAS_INLINE
1934 const_iterator2 &operator -- () {
1935 -- it2_;
1936 return *this;
1937 }
1938 BOOST_UBLAS_INLINE
1939 const_iterator2 &operator += (difference_type n) {
1940 it2_ += n;
1941 return *this;
1942 }
1943 BOOST_UBLAS_INLINE
1944 const_iterator2 &operator -= (difference_type n) {
1945 it2_ -= n;
1946 return *this;
1947 }
1948 BOOST_UBLAS_INLINE
1949 difference_type operator - (const const_iterator2 &it) const {
1950 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1951 return it2_ - it.it2_;
1952 }
1953
1954
1955 BOOST_UBLAS_INLINE
1956 const_reference operator * () const {
1957 size_type i = index1 ();
1958 size_type j = index2 ();
1959 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
1960 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
1961 #ifdef BOOST_UBLAS_OWN_BANDED
1962 size_type k = (std::max) (i, j);
1963 size_type l = (*this) ().lower () + j - i;
1964 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
1965 l < (*this) ().lower () + 1 + (*this) ().upper ())
1966 return *it2_;
1967 #else
1968 size_type k = j;
1969 size_type l = (*this) ().upper () + i - j;
1970 if (k < (*this) ().size2 () &&
1971 l < (*this) ().lower () + 1 + (*this) ().upper ())
1972 return *it2_;
1973 #endif
1974 return (*this) () (i, j);
1975 }
1976 BOOST_UBLAS_INLINE
1977 const_reference operator [] (difference_type n) const {
1978 return *(*this + n);
1979 }
1980
1981 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1982 BOOST_UBLAS_INLINE
1983 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1984 typename self_type::
1985 #endif
1986 const_iterator1 begin () const {
1987 return (*this) ().find1 (1, 0, index2 ());
1988 }
1989 BOOST_UBLAS_INLINE
1990 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1991 typename self_type::
1992 #endif
1993 const_iterator1 cbegin () const {
1994 return begin ();
1995 }
1996 BOOST_UBLAS_INLINE
1997 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1998 typename self_type::
1999 #endif
2000 const_iterator1 end () const {
2001 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
2002 }
2003 BOOST_UBLAS_INLINE
2004 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2005 typename self_type::
2006 #endif
2007 const_iterator1 cend () const {
2008 return end ();
2009 }
2010 BOOST_UBLAS_INLINE
2011 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2012 typename self_type::
2013 #endif
2014 const_reverse_iterator1 rbegin () const {
2015 return const_reverse_iterator1 (end ());
2016 }
2017 BOOST_UBLAS_INLINE
2018 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2019 typename self_type::
2020 #endif
2021 const_reverse_iterator1 crbegin () const {
2022 return rbegin ();
2023 }
2024 BOOST_UBLAS_INLINE
2025 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2026 typename self_type::
2027 #endif
2028 const_reverse_iterator1 rend () const {
2029 return const_reverse_iterator1 (begin ());
2030 }
2031 BOOST_UBLAS_INLINE
2032 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2033 typename self_type::
2034 #endif
2035 const_reverse_iterator1 crend () const {
2036 return rend ();
2037 }
2038 #endif
2039
2040
2041 BOOST_UBLAS_INLINE
2042 size_type index1 () const {
2043 return it2_.index1 ();
2044 }
2045 BOOST_UBLAS_INLINE
2046 size_type index2 () const {
2047 return it2_.index2 ();
2048 }
2049
2050
2051 BOOST_UBLAS_INLINE
2052 const_iterator2 &operator = (const const_iterator2 &it) {
2053 container_const_reference<self_type>::assign (&it ());
2054 it2_ = it.it2_;
2055 return *this;
2056 }
2057
2058
2059 BOOST_UBLAS_INLINE
2060 bool operator == (const const_iterator2 &it) const {
2061 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2062 return it2_ == it.it2_;
2063 }
2064 BOOST_UBLAS_INLINE
2065 bool operator < (const const_iterator2 &it) const {
2066 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2067 return it2_ < it.it2_;
2068 }
2069
2070 private:
2071 const_subiterator2_type it2_;
2072 };
2073 #endif
2074
2075 BOOST_UBLAS_INLINE
2076 const_iterator2 begin2 () const {
2077 return find2 (0, 0, 0);
2078 }
2079 BOOST_UBLAS_INLINE
2080 const_iterator2 cbegin2 () const {
2081 return begin2 ();
2082 }
2083 BOOST_UBLAS_INLINE
2084 const_iterator2 end2 () const {
2085 return find2 (0, 0, size2 ());
2086 }
2087 BOOST_UBLAS_INLINE
2088 const_iterator2 cend2 () const {
2089 return end2 ();
2090 }
2091
2092 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
2093 class iterator2:
2094 public container_reference<banded_adaptor>,
2095 public random_access_iterator_base<typename iterator_restrict_traits<
2096 typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
2097 iterator2, value_type> {
2098 public:
2099 typedef typename subiterator2_type::value_type value_type;
2100 typedef typename subiterator2_type::difference_type difference_type;
2101 typedef typename subiterator2_type::reference reference;
2102 typedef typename subiterator2_type::pointer pointer;
2103
2104 typedef iterator1 dual_iterator_type;
2105 typedef reverse_iterator1 dual_reverse_iterator_type;
2106
2107
2108 BOOST_UBLAS_INLINE
2109 iterator2 ():
2110 container_reference<self_type> (), it2_ () {}
2111 BOOST_UBLAS_INLINE
2112 iterator2 (self_type &m, const subiterator2_type &it2):
2113 container_reference<self_type> (m), it2_ (it2) {}
2114
2115
2116 BOOST_UBLAS_INLINE
2117 iterator2 &operator ++ () {
2118 ++ it2_;
2119 return *this;
2120 }
2121 BOOST_UBLAS_INLINE
2122 iterator2 &operator -- () {
2123 -- it2_;
2124 return *this;
2125 }
2126 BOOST_UBLAS_INLINE
2127 iterator2 &operator += (difference_type n) {
2128 it2_ += n;
2129 return *this;
2130 }
2131 BOOST_UBLAS_INLINE
2132 iterator2 &operator -= (difference_type n) {
2133 it2_ -= n;
2134 return *this;
2135 }
2136 BOOST_UBLAS_INLINE
2137 difference_type operator - (const iterator2 &it) const {
2138 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2139 return it2_ - it.it2_;
2140 }
2141
2142
2143 BOOST_UBLAS_INLINE
2144 reference operator * () const {
2145 size_type i = index1 ();
2146 size_type j = index2 ();
2147 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
2148 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
2149 #ifdef BOOST_UBLAS_OWN_BANDED
2150 size_type k = (std::max) (i, j);
2151 size_type l = (*this) ().lower () + j - i;
2152 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
2153 l < (*this) ().lower () + 1 + (*this) ().upper ())
2154 return *it2_;
2155 #else
2156 size_type k = j;
2157 size_type l = (*this) ().upper () + i - j;
2158 if (k < (*this) ().size2 () &&
2159 l < (*this) ().lower () + 1 + (*this) ().upper ())
2160 return *it2_;
2161 #endif
2162 return (*this) () (i, j);
2163 }
2164 BOOST_UBLAS_INLINE
2165 reference operator [] (difference_type n) const {
2166 return *(*this + n);
2167 }
2168
2169 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
2170 BOOST_UBLAS_INLINE
2171 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2172 typename self_type::
2173 #endif
2174 iterator1 begin () const {
2175 return (*this) ().find1 (1, 0, index2 ());
2176 }
2177 BOOST_UBLAS_INLINE
2178 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2179 typename self_type::
2180 #endif
2181 iterator1 end () const {
2182 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
2183 }
2184 BOOST_UBLAS_INLINE
2185 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2186 typename self_type::
2187 #endif
2188 reverse_iterator1 rbegin () const {
2189 return reverse_iterator1 (end ());
2190 }
2191 BOOST_UBLAS_INLINE
2192 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2193 typename self_type::
2194 #endif
2195 reverse_iterator1 rend () const {
2196 return reverse_iterator1 (begin ());
2197 }
2198 #endif
2199
2200
2201 BOOST_UBLAS_INLINE
2202 size_type index1 () const {
2203 return it2_.index1 ();
2204 }
2205 BOOST_UBLAS_INLINE
2206 size_type index2 () const {
2207 return it2_.index2 ();
2208 }
2209
2210
2211 BOOST_UBLAS_INLINE
2212 iterator2 &operator = (const iterator2 &it) {
2213 container_reference<self_type>::assign (&it ());
2214 it2_ = it.it2_;
2215 return *this;
2216 }
2217
2218
2219 BOOST_UBLAS_INLINE
2220 bool operator == (const iterator2 &it) const {
2221 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2222 return it2_ == it.it2_;
2223 }
2224 BOOST_UBLAS_INLINE
2225 bool operator < (const iterator2 &it) const {
2226 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2227 return it2_ < it.it2_;
2228 }
2229
2230 private:
2231 subiterator2_type it2_;
2232
2233 friend class const_iterator2;
2234 };
2235 #endif
2236
2237 BOOST_UBLAS_INLINE
2238 iterator2 begin2 () {
2239 return find2 (0, 0, 0);
2240 }
2241 BOOST_UBLAS_INLINE
2242 iterator2 end2 () {
2243 return find2 (0, 0, size2 ());
2244 }
2245
2246
2247
2248 BOOST_UBLAS_INLINE
2249 const_reverse_iterator1 rbegin1 () const {
2250 return const_reverse_iterator1 (end1 ());
2251 }
2252 BOOST_UBLAS_INLINE
2253 const_reverse_iterator1 crbegin1 () const {
2254 return rbegin1 ();
2255 }
2256 BOOST_UBLAS_INLINE
2257 const_reverse_iterator1 rend1 () const {
2258 return const_reverse_iterator1 (begin1 ());
2259 }
2260 BOOST_UBLAS_INLINE
2261 const_reverse_iterator1 crend1 () const {
2262 return rend1 ();
2263 }
2264
2265 BOOST_UBLAS_INLINE
2266 reverse_iterator1 rbegin1 () {
2267 return reverse_iterator1 (end1 ());
2268 }
2269 BOOST_UBLAS_INLINE
2270 reverse_iterator1 rend1 () {
2271 return reverse_iterator1 (begin1 ());
2272 }
2273
2274 BOOST_UBLAS_INLINE
2275 const_reverse_iterator2 rbegin2 () const {
2276 return const_reverse_iterator2 (end2 ());
2277 }
2278 BOOST_UBLAS_INLINE
2279 const_reverse_iterator2 crbegin2 () const {
2280 return rbegin2 ();
2281 }
2282 BOOST_UBLAS_INLINE
2283 const_reverse_iterator2 rend2 () const {
2284 return const_reverse_iterator2 (begin2 ());
2285 }
2286 BOOST_UBLAS_INLINE
2287 const_reverse_iterator2 crend2 () const {
2288 return rend2 ();
2289 }
2290
2291 BOOST_UBLAS_INLINE
2292 reverse_iterator2 rbegin2 () {
2293 return reverse_iterator2 (end2 ());
2294 }
2295 BOOST_UBLAS_INLINE
2296 reverse_iterator2 rend2 () {
2297 return reverse_iterator2 (begin2 ());
2298 }
2299
2300 private:
2301 matrix_closure_type data_;
2302 size_type lower_;
2303 size_type upper_;
2304 typedef const value_type const_value_type;
2305 static const_value_type zero_;
2306 };
2307
2308
2309 template <class M>
2310 struct vector_temporary_traits< banded_adaptor<M> >
2311 : vector_temporary_traits< M > {} ;
2312 template <class M>
2313 struct vector_temporary_traits< const banded_adaptor<M> >
2314 : vector_temporary_traits< M > {} ;
2315
2316 template <class M>
2317 struct matrix_temporary_traits< banded_adaptor<M> >
2318 : matrix_temporary_traits< M > {} ;
2319 template <class M>
2320 struct matrix_temporary_traits< const banded_adaptor<M> >
2321 : matrix_temporary_traits< M > {} ;
2322
2323
2324 template<class M>
2325 typename banded_adaptor<M>::const_value_type banded_adaptor<M>::zero_ = value_type();
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339 template<class M>
2340 class diagonal_adaptor:
2341 public banded_adaptor<M> {
2342 public:
2343 typedef M matrix_type;
2344 typedef banded_adaptor<M> adaptor_type;
2345
2346
2347 BOOST_UBLAS_INLINE
2348 diagonal_adaptor ():
2349 adaptor_type () {}
2350 BOOST_UBLAS_INLINE
2351 diagonal_adaptor (matrix_type &data):
2352 adaptor_type (data) {}
2353 BOOST_UBLAS_INLINE
2354 ~diagonal_adaptor () {}
2355
2356
2357 BOOST_UBLAS_INLINE
2358 diagonal_adaptor &operator = (const diagonal_adaptor &m) {
2359 adaptor_type::operator = (m);
2360 return *this;
2361 }
2362 template<class AE>
2363 BOOST_UBLAS_INLINE
2364 diagonal_adaptor &operator = (const matrix_expression<AE> &ae) {
2365 adaptor_type::operator = (ae);
2366 return *this;
2367 }
2368 };
2369
2370 }}}
2371
2372 #endif