00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _BOOST_UBLAS_BANDED_
00014 #define _BOOST_UBLAS_BANDED_
00015
00016 #include <boost/numeric/ublas/matrix.hpp>
00017 #include <boost/numeric/ublas/detail/temporary.hpp>
00018
00019
00020
00021 namespace boost { namespace numeric { namespace ublas {
00022
00035 template<class T, class L, class A>
00036 class banded_matrix:
00037 public matrix_container<banded_matrix<T, L, A> > {
00038
00039 typedef T *pointer;
00040 typedef L layout_type;
00041 typedef banded_matrix<T, L, A> self_type;
00042 public:
00043 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00044 using matrix_container<self_type>::operator ();
00045 #endif
00046 typedef typename A::size_type size_type;
00047 typedef typename A::difference_type difference_type;
00048 typedef T value_type;
00049 typedef const T &const_reference;
00050 typedef T &reference;
00051 typedef A array_type;
00052 typedef const matrix_reference<const self_type> const_closure_type;
00053 typedef matrix_reference<self_type> closure_type;
00054 typedef vector<T, A> vector_temporary_type;
00055 typedef matrix<T, L, A> matrix_temporary_type;
00056 typedef packed_tag storage_category;
00057 typedef typename L::orientation_category orientation_category;
00058
00059
00060 BOOST_UBLAS_INLINE
00061 banded_matrix ():
00062 matrix_container<self_type> (),
00063 size1_ (0), size2_ (0),
00064 lower_ (0), upper_ (0), data_ (0) {}
00065 BOOST_UBLAS_INLINE
00066 banded_matrix (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0):
00067 matrix_container<self_type> (),
00068 size1_ (size1), size2_ (size2),
00069 lower_ (lower), upper_ (upper), data_ ((std::max) (size1, size2) * (lower + 1 + upper)) {
00070 }
00071 BOOST_UBLAS_INLINE
00072 banded_matrix (size_type size1, size_type size2, size_type lower, size_type upper, const array_type &data):
00073 matrix_container<self_type> (),
00074 size1_ (size1), size2_ (size2),
00075 lower_ (lower), upper_ (upper), data_ (data) {}
00076 BOOST_UBLAS_INLINE
00077 banded_matrix (const banded_matrix &m):
00078 matrix_container<self_type> (),
00079 size1_ (m.size1_), size2_ (m.size2_),
00080 lower_ (m.lower_), upper_ (m.upper_), data_ (m.data_) {}
00081 template<class AE>
00082 BOOST_UBLAS_INLINE
00083 banded_matrix (const matrix_expression<AE> &ae, size_type lower = 0, size_type upper = 0):
00084 matrix_container<self_type> (),
00085 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()),
00086 lower_ (lower), upper_ (upper),
00087 data_ ((std::max) (size1_, size2_) * (lower_ + 1 + upper_)) {
00088 matrix_assign<scalar_assign> (*this, ae);
00089 }
00090
00091
00092 BOOST_UBLAS_INLINE
00093 size_type size1 () const {
00094 return size1_;
00095 }
00096 BOOST_UBLAS_INLINE
00097 size_type size2 () const {
00098 return size2_;
00099 }
00100 BOOST_UBLAS_INLINE
00101 size_type lower () const {
00102 return lower_;
00103 }
00104 BOOST_UBLAS_INLINE
00105 size_type upper () const {
00106 return upper_;
00107 }
00108
00109
00110 BOOST_UBLAS_INLINE
00111 const array_type &data () const {
00112 return data_;
00113 }
00114 BOOST_UBLAS_INLINE
00115 array_type &data () {
00116 return data_;
00117 }
00118
00119
00120 BOOST_UBLAS_INLINE
00121 void resize (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0, bool preserve = true) {
00122 if (preserve) {
00123 self_type temporary (size1, size2, lower, upper);
00124 detail::matrix_resize_preserve<layout_type> (*this, temporary);
00125 }
00126 else {
00127 data ().resize ((std::max) (size1, size2) * (lower + 1 + upper));
00128 size1_ = size1;
00129 size2_ = size2;
00130 lower_ = lower;
00131 upper_ = upper;
00132 }
00133 }
00134
00135 BOOST_UBLAS_INLINE
00136 void resize_packed_preserve (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0) {
00137 size1_ = size1;
00138 size2_ = size2;
00139 lower_ = lower;
00140 upper_ = upper;
00141 data ().resize ((std::max) (size1, size2) * (lower + 1 + upper), value_type ());
00142 }
00143
00144
00145 BOOST_UBLAS_INLINE
00146 const_reference operator () (size_type i, size_type j) const {
00147 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
00148 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
00149 #ifdef BOOST_UBLAS_OWN_BANDED
00150 const size_type k = (std::max) (i, j);
00151 const size_type l = lower_ + j - i;
00152 if (k < (std::max) (size1_, size2_) &&
00153 l < lower_ + 1 + upper_)
00154 return data () [layout_type::element (k, (std::max) (size1_, size2_),
00155 l, lower_ + 1 + upper_)];
00156 #else
00157 const size_type k = j;
00158 const size_type l = upper_ + i - j;
00159 if (k < size2_ &&
00160 l < lower_ + 1 + upper_)
00161 return data () [layout_type::element (k, size2_,
00162 l, lower_ + 1 + upper_)];
00163 #endif
00164 return zero_;
00165 }
00166 BOOST_UBLAS_INLINE
00167 reference at_element (size_type i, size_type j) {
00168 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
00169 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
00170 #ifdef BOOST_UBLAS_OWN_BANDED
00171 const size_type k = (std::max) (i, j);
00172 const size_type l = lower_ + j - i;
00173 return data () [layout_type::element (k, (std::max) (size1_, size2_),
00174 l, lower_ + 1 + upper_)];
00175 #else
00176 const size_type k = j;
00177 const size_type l = upper_ + i - j;
00178 return data () [layout_type::element (k, size2_,
00179 l, lower_ + 1 + upper_)];
00180 #endif
00181 }
00182 BOOST_UBLAS_INLINE
00183 reference operator () (size_type i, size_type j) {
00184 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
00185 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
00186 #ifdef BOOST_UBLAS_OWN_BANDED
00187 const size_type k = (std::max) (i, j);
00188 const size_type l = lower_ + j - i;
00189 if (! (k < (std::max) (size1_, size2_) &&
00190 l < lower_ + 1 + upper_) ) {
00191 bad_index ().raise ();
00192
00193 }
00194 return data () [layout_type::element (k, (std::max) (size1_, size2_),
00195 l, lower_ + 1 + upper_)];
00196 #else
00197 const size_type k = j;
00198 const size_type l = upper_ + i - j;
00199 if (! (k < size2_ &&
00200 l < lower_ + 1 + upper_) ) {
00201 bad_index ().raise ();
00202
00203 }
00204 return data () [layout_type::element (k, size2_,
00205 l, lower_ + 1 + upper_)];
00206 #endif
00207 }
00208
00209
00210 BOOST_UBLAS_INLINE
00211 reference insert_element (size_type i, size_type j, const_reference t) {
00212 return (operator () (i, j) = t);
00213 }
00214 BOOST_UBLAS_INLINE
00215 void erase_element (size_type i, size_type j) {
00216 operator () (i, j) = value_type();
00217 }
00218
00219
00220 BOOST_UBLAS_INLINE
00221 void clear () {
00222 std::fill (data ().begin (), data ().end (), value_type());
00223 }
00224
00225
00226 BOOST_UBLAS_INLINE
00227 banded_matrix &operator = (const banded_matrix &m) {
00228 size1_ = m.size1_;
00229 size2_ = m.size2_;
00230 lower_ = m.lower_;
00231 upper_ = m.upper_;
00232 data () = m.data ();
00233 return *this;
00234 }
00235 BOOST_UBLAS_INLINE
00236 banded_matrix &assign_temporary (banded_matrix &m) {
00237 swap (m);
00238 return *this;
00239 }
00240 template<class AE>
00241 BOOST_UBLAS_INLINE
00242 banded_matrix &operator = (const matrix_expression<AE> &ae) {
00243 self_type temporary (ae, lower_, upper_);
00244 return assign_temporary (temporary);
00245 }
00246 template<class AE>
00247 BOOST_UBLAS_INLINE
00248 banded_matrix &assign (const matrix_expression<AE> &ae) {
00249 matrix_assign<scalar_assign> (*this, ae);
00250 return *this;
00251 }
00252 template<class AE>
00253 BOOST_UBLAS_INLINE
00254 banded_matrix& operator += (const matrix_expression<AE> &ae) {
00255 self_type temporary (*this + ae, lower_, upper_);
00256 return assign_temporary (temporary);
00257 }
00258 template<class AE>
00259 BOOST_UBLAS_INLINE
00260 banded_matrix &plus_assign (const matrix_expression<AE> &ae) {
00261 matrix_assign<scalar_plus_assign> (*this, ae);
00262 return *this;
00263 }
00264 template<class AE>
00265 BOOST_UBLAS_INLINE
00266 banded_matrix& operator -= (const matrix_expression<AE> &ae) {
00267 self_type temporary (*this - ae, lower_, upper_);
00268 return assign_temporary (temporary);
00269 }
00270 template<class AE>
00271 BOOST_UBLAS_INLINE
00272 banded_matrix &minus_assign (const matrix_expression<AE> &ae) {
00273 matrix_assign<scalar_minus_assign> (*this, ae);
00274 return *this;
00275 }
00276 template<class AT>
00277 BOOST_UBLAS_INLINE
00278 banded_matrix& operator *= (const AT &at) {
00279 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
00280 return *this;
00281 }
00282 template<class AT>
00283 BOOST_UBLAS_INLINE
00284 banded_matrix& operator /= (const AT &at) {
00285 matrix_assign_scalar<scalar_divides_assign> (*this, at);
00286 return *this;
00287 }
00288
00289
00290 BOOST_UBLAS_INLINE
00291 void swap (banded_matrix &m) {
00292 if (this != &m) {
00293 std::swap (size1_, m.size1_);
00294 std::swap (size2_, m.size2_);
00295 std::swap (lower_, m.lower_);
00296 std::swap (upper_, m.upper_);
00297 data ().swap (m.data ());
00298 }
00299 }
00300 BOOST_UBLAS_INLINE
00301 friend void swap (banded_matrix &m1, banded_matrix &m2) {
00302 m1.swap (m2);
00303 }
00304
00305
00306 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00307 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
00308 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
00309 typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
00310 typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
00311 #else
00312 class const_iterator1;
00313 class iterator1;
00314 class const_iterator2;
00315 class iterator2;
00316 #endif
00317 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
00318 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
00319 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
00320 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
00321
00322
00323 BOOST_UBLAS_INLINE
00324 const_iterator1 find1 (int rank, size_type i, size_type j) const {
00325 if (rank == 1) {
00326 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
00327 i = (std::max) (i, lower_i);
00328 size_type upper_i = (std::min) (j + 1 + lower_, size1_);
00329 i = (std::min) (i, upper_i);
00330 }
00331 return const_iterator1 (*this, i, j);
00332 }
00333 BOOST_UBLAS_INLINE
00334 iterator1 find1 (int rank, size_type i, size_type j) {
00335 if (rank == 1) {
00336 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
00337 i = (std::max) (i, lower_i);
00338 size_type upper_i = (std::min) (j + 1 + lower_, size1_);
00339 i = (std::min) (i, upper_i);
00340 }
00341 return iterator1 (*this, i, j);
00342 }
00343 BOOST_UBLAS_INLINE
00344 const_iterator2 find2 (int rank, size_type i, size_type j) const {
00345 if (rank == 1) {
00346 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
00347 j = (std::max) (j, lower_j);
00348 size_type upper_j = (std::min) (i + 1 + upper_, size2_);
00349 j = (std::min) (j, upper_j);
00350 }
00351 return const_iterator2 (*this, i, j);
00352 }
00353 BOOST_UBLAS_INLINE
00354 iterator2 find2 (int rank, size_type i, size_type j) {
00355 if (rank == 1) {
00356 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
00357 j = (std::max) (j, lower_j);
00358 size_type upper_j = (std::min) (i + 1 + upper_, size2_);
00359 j = (std::min) (j, upper_j);
00360 }
00361 return iterator2 (*this, i, j);
00362 }
00363
00364
00365
00366 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00367 class const_iterator1:
00368 public container_const_reference<banded_matrix>,
00369 public random_access_iterator_base<packed_random_access_iterator_tag,
00370 const_iterator1, value_type> {
00371 public:
00372 typedef typename banded_matrix::value_type value_type;
00373 typedef typename banded_matrix::difference_type difference_type;
00374 typedef typename banded_matrix::const_reference reference;
00375 typedef const typename banded_matrix::pointer pointer;
00376
00377 typedef const_iterator2 dual_iterator_type;
00378 typedef const_reverse_iterator2 dual_reverse_iterator_type;
00379
00380
00381 BOOST_UBLAS_INLINE
00382 const_iterator1 ():
00383 container_const_reference<self_type> (), it1_ (), it2_ () {}
00384 BOOST_UBLAS_INLINE
00385 const_iterator1 (const self_type &m, size_type it1, size_type it2):
00386 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
00387 BOOST_UBLAS_INLINE
00388 const_iterator1 (const iterator1 &it):
00389 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
00390
00391
00392 BOOST_UBLAS_INLINE
00393 const_iterator1 &operator ++ () {
00394 ++ it1_;
00395 return *this;
00396 }
00397 BOOST_UBLAS_INLINE
00398 const_iterator1 &operator -- () {
00399 -- it1_;
00400 return *this;
00401 }
00402 BOOST_UBLAS_INLINE
00403 const_iterator1 &operator += (difference_type n) {
00404 it1_ += n;
00405 return *this;
00406 }
00407 BOOST_UBLAS_INLINE
00408 const_iterator1 &operator -= (difference_type n) {
00409 it1_ -= n;
00410 return *this;
00411 }
00412 BOOST_UBLAS_INLINE
00413 difference_type operator - (const const_iterator1 &it) const {
00414 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00415 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00416 return it1_ - it.it1_;
00417 }
00418
00419
00420 BOOST_UBLAS_INLINE
00421 const_reference operator * () const {
00422 return (*this) () (it1_, it2_);
00423 }
00424 BOOST_UBLAS_INLINE
00425 const_reference operator [] (difference_type n) const {
00426 return *(*this + n);
00427 }
00428
00429 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00430 BOOST_UBLAS_INLINE
00431 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00432 typename self_type::
00433 #endif
00434 const_iterator2 begin () const {
00435 return (*this) ().find2 (1, it1_, 0);
00436 }
00437 BOOST_UBLAS_INLINE
00438 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00439 typename self_type::
00440 #endif
00441 const_iterator2 end () const {
00442 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
00443 }
00444 BOOST_UBLAS_INLINE
00445 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00446 typename self_type::
00447 #endif
00448 const_reverse_iterator2 rbegin () const {
00449 return const_reverse_iterator2 (end ());
00450 }
00451 BOOST_UBLAS_INLINE
00452 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00453 typename self_type::
00454 #endif
00455 const_reverse_iterator2 rend () const {
00456 return const_reverse_iterator2 (begin ());
00457 }
00458 #endif
00459
00460
00461 BOOST_UBLAS_INLINE
00462 size_type index1 () const {
00463 return it1_;
00464 }
00465 BOOST_UBLAS_INLINE
00466 size_type index2 () const {
00467 return it2_;
00468 }
00469
00470
00471 BOOST_UBLAS_INLINE
00472 const_iterator1 &operator = (const const_iterator1 &it) {
00473 container_const_reference<self_type>::assign (&it ());
00474 it1_ = it.it1_;
00475 it2_ = it.it2_;
00476 return *this;
00477 }
00478
00479
00480 BOOST_UBLAS_INLINE
00481 bool operator == (const const_iterator1 &it) const {
00482 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00483 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00484 return it1_ == it.it1_;
00485 }
00486 BOOST_UBLAS_INLINE
00487 bool operator < (const const_iterator1 &it) const {
00488 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00489 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00490 return it1_ < it.it1_;
00491 }
00492
00493 private:
00494 size_type it1_;
00495 size_type it2_;
00496 };
00497 #endif
00498
00499 BOOST_UBLAS_INLINE
00500 const_iterator1 begin1 () const {
00501 return find1 (0, 0, 0);
00502 }
00503 BOOST_UBLAS_INLINE
00504 const_iterator1 end1 () const {
00505 return find1 (0, size1_, 0);
00506 }
00507
00508 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00509 class iterator1:
00510 public container_reference<banded_matrix>,
00511 public random_access_iterator_base<packed_random_access_iterator_tag,
00512 iterator1, value_type> {
00513 public:
00514 typedef typename banded_matrix::value_type value_type;
00515 typedef typename banded_matrix::difference_type difference_type;
00516 typedef typename banded_matrix::reference reference;
00517 typedef typename banded_matrix::pointer pointer;
00518
00519 typedef iterator2 dual_iterator_type;
00520 typedef reverse_iterator2 dual_reverse_iterator_type;
00521
00522
00523 BOOST_UBLAS_INLINE
00524 iterator1 ():
00525 container_reference<self_type> (), it1_ (), it2_ () {}
00526 BOOST_UBLAS_INLINE
00527 iterator1 (self_type &m, size_type it1, size_type it2):
00528 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
00529
00530
00531 BOOST_UBLAS_INLINE
00532 iterator1 &operator ++ () {
00533 ++ it1_;
00534 return *this;
00535 }
00536 BOOST_UBLAS_INLINE
00537 iterator1 &operator -- () {
00538 -- it1_;
00539 return *this;
00540 }
00541 BOOST_UBLAS_INLINE
00542 iterator1 &operator += (difference_type n) {
00543 it1_ += n;
00544 return *this;
00545 }
00546 BOOST_UBLAS_INLINE
00547 iterator1 &operator -= (difference_type n) {
00548 it1_ -= n;
00549 return *this;
00550 }
00551 BOOST_UBLAS_INLINE
00552 difference_type operator - (const iterator1 &it) const {
00553 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00554 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00555 return it1_ - it.it1_;
00556 }
00557
00558
00559 BOOST_UBLAS_INLINE
00560 reference operator * () const {
00561 return (*this) ().at_element (it1_, it2_);
00562 }
00563 BOOST_UBLAS_INLINE
00564 reference operator [] (difference_type n) const {
00565 return *(*this + n);
00566 }
00567
00568 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00569 BOOST_UBLAS_INLINE
00570 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00571 typename self_type::
00572 #endif
00573 iterator2 begin () const {
00574 return (*this) ().find2 (1, it1_, 0);
00575 }
00576 BOOST_UBLAS_INLINE
00577 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00578 typename self_type::
00579 #endif
00580 iterator2 end () const {
00581 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
00582 }
00583 BOOST_UBLAS_INLINE
00584 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00585 typename self_type::
00586 #endif
00587 reverse_iterator2 rbegin () const {
00588 return reverse_iterator2 (end ());
00589 }
00590 BOOST_UBLAS_INLINE
00591 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00592 typename self_type::
00593 #endif
00594 reverse_iterator2 rend () const {
00595 return reverse_iterator2 (begin ());
00596 }
00597 #endif
00598
00599
00600 BOOST_UBLAS_INLINE
00601 size_type index1 () const {
00602 return it1_;
00603 }
00604 BOOST_UBLAS_INLINE
00605 size_type index2 () const {
00606 return it2_;
00607 }
00608
00609
00610 BOOST_UBLAS_INLINE
00611 iterator1 &operator = (const iterator1 &it) {
00612 container_reference<self_type>::assign (&it ());
00613 it1_ = it.it1_;
00614 it2_ = it.it2_;
00615 return *this;
00616 }
00617
00618
00619 BOOST_UBLAS_INLINE
00620 bool operator == (const iterator1 &it) const {
00621 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00622 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00623 return it1_ == it.it1_;
00624 }
00625 BOOST_UBLAS_INLINE
00626 bool operator < (const iterator1 &it) const {
00627 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00628 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00629 return it1_ < it.it1_;
00630 }
00631
00632 private:
00633 size_type it1_;
00634 size_type it2_;
00635
00636 friend class const_iterator1;
00637 };
00638 #endif
00639
00640 BOOST_UBLAS_INLINE
00641 iterator1 begin1 () {
00642 return find1 (0, 0, 0);
00643 }
00644 BOOST_UBLAS_INLINE
00645 iterator1 end1 () {
00646 return find1 (0, size1_, 0);
00647 }
00648
00649 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00650 class const_iterator2:
00651 public container_const_reference<banded_matrix>,
00652 public random_access_iterator_base<packed_random_access_iterator_tag,
00653 const_iterator2, value_type> {
00654 public:
00655 typedef typename banded_matrix::value_type value_type;
00656 typedef typename banded_matrix::difference_type difference_type;
00657 typedef typename banded_matrix::const_reference reference;
00658 typedef const typename banded_matrix::pointer pointer;
00659
00660 typedef const_iterator1 dual_iterator_type;
00661 typedef const_reverse_iterator1 dual_reverse_iterator_type;
00662
00663
00664 BOOST_UBLAS_INLINE
00665 const_iterator2 ():
00666 container_const_reference<self_type> (), it1_ (), it2_ () {}
00667 BOOST_UBLAS_INLINE
00668 const_iterator2 (const self_type &m, size_type it1, size_type it2):
00669 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
00670 BOOST_UBLAS_INLINE
00671 const_iterator2 (const iterator2 &it):
00672 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
00673
00674
00675 BOOST_UBLAS_INLINE
00676 const_iterator2 &operator ++ () {
00677 ++ it2_;
00678 return *this;
00679 }
00680 BOOST_UBLAS_INLINE
00681 const_iterator2 &operator -- () {
00682 -- it2_;
00683 return *this;
00684 }
00685 BOOST_UBLAS_INLINE
00686 const_iterator2 &operator += (difference_type n) {
00687 it2_ += n;
00688 return *this;
00689 }
00690 BOOST_UBLAS_INLINE
00691 const_iterator2 &operator -= (difference_type n) {
00692 it2_ -= n;
00693 return *this;
00694 }
00695 BOOST_UBLAS_INLINE
00696 difference_type operator - (const const_iterator2 &it) const {
00697 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00698 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
00699 return it2_ - it.it2_;
00700 }
00701
00702
00703 BOOST_UBLAS_INLINE
00704 const_reference operator * () const {
00705 return (*this) () (it1_, it2_);
00706 }
00707 BOOST_UBLAS_INLINE
00708 const_reference operator [] (difference_type n) const {
00709 return *(*this + n);
00710 }
00711
00712 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00713 BOOST_UBLAS_INLINE
00714 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00715 typename self_type::
00716 #endif
00717 const_iterator1 begin () const {
00718 return (*this) ().find1 (1, 0, it2_);
00719 }
00720 BOOST_UBLAS_INLINE
00721 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00722 typename self_type::
00723 #endif
00724 const_iterator1 end () const {
00725 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
00726 }
00727 BOOST_UBLAS_INLINE
00728 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00729 typename self_type::
00730 #endif
00731 const_reverse_iterator1 rbegin () const {
00732 return const_reverse_iterator1 (end ());
00733 }
00734 BOOST_UBLAS_INLINE
00735 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00736 typename self_type::
00737 #endif
00738 const_reverse_iterator1 rend () const {
00739 return const_reverse_iterator1 (begin ());
00740 }
00741 #endif
00742
00743
00744 BOOST_UBLAS_INLINE
00745 size_type index1 () const {
00746 return it1_;
00747 }
00748 BOOST_UBLAS_INLINE
00749 size_type index2 () const {
00750 return it2_;
00751 }
00752
00753
00754 BOOST_UBLAS_INLINE
00755 const_iterator2 &operator = (const const_iterator2 &it) {
00756 container_const_reference<self_type>::assign (&it ());
00757 it1_ = it.it1_;
00758 it2_ = it.it2_;
00759 return *this;
00760 }
00761
00762
00763 BOOST_UBLAS_INLINE
00764 bool operator == (const const_iterator2 &it) const {
00765 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00766 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
00767 return it2_ == it.it2_;
00768 }
00769 BOOST_UBLAS_INLINE
00770 bool operator < (const const_iterator2 &it) const {
00771 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00772 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
00773 return it2_ < it.it2_;
00774 }
00775
00776 private:
00777 size_type it1_;
00778 size_type it2_;
00779 };
00780 #endif
00781
00782 BOOST_UBLAS_INLINE
00783 const_iterator2 begin2 () const {
00784 return find2 (0, 0, 0);
00785 }
00786 BOOST_UBLAS_INLINE
00787 const_iterator2 end2 () const {
00788 return find2 (0, 0, size2_);
00789 }
00790
00791 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00792 class iterator2:
00793 public container_reference<banded_matrix>,
00794 public random_access_iterator_base<packed_random_access_iterator_tag,
00795 iterator2, value_type> {
00796 public:
00797 typedef typename banded_matrix::value_type value_type;
00798 typedef typename banded_matrix::difference_type difference_type;
00799 typedef typename banded_matrix::reference reference;
00800 typedef typename banded_matrix::pointer pointer;
00801
00802 typedef iterator1 dual_iterator_type;
00803 typedef reverse_iterator1 dual_reverse_iterator_type;
00804
00805
00806 BOOST_UBLAS_INLINE
00807 iterator2 ():
00808 container_reference<self_type> (), it1_ (), it2_ () {}
00809 BOOST_UBLAS_INLINE
00810 iterator2 (self_type &m, size_type it1, size_type it2):
00811 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
00812
00813
00814 BOOST_UBLAS_INLINE
00815 iterator2 &operator ++ () {
00816 ++ it2_;
00817 return *this;
00818 }
00819 BOOST_UBLAS_INLINE
00820 iterator2 &operator -- () {
00821 -- it2_;
00822 return *this;
00823 }
00824 BOOST_UBLAS_INLINE
00825 iterator2 &operator += (difference_type n) {
00826 it2_ += n;
00827 return *this;
00828 }
00829 BOOST_UBLAS_INLINE
00830 iterator2 &operator -= (difference_type n) {
00831 it2_ -= n;
00832 return *this;
00833 }
00834 BOOST_UBLAS_INLINE
00835 difference_type operator - (const iterator2 &it) const {
00836 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00837 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
00838 return it2_ - it.it2_;
00839 }
00840
00841
00842 BOOST_UBLAS_INLINE
00843 reference operator * () const {
00844 return (*this) ().at_element (it1_, it2_);
00845 }
00846 BOOST_UBLAS_INLINE
00847 reference operator [] (difference_type n) const {
00848 return *(*this + n);
00849 }
00850
00851 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00852 BOOST_UBLAS_INLINE
00853 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00854 typename self_type::
00855 #endif
00856 iterator1 begin () const {
00857 return (*this) ().find1 (1, 0, it2_);
00858 }
00859 BOOST_UBLAS_INLINE
00860 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00861 typename self_type::
00862 #endif
00863 iterator1 end () const {
00864 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
00865 }
00866 BOOST_UBLAS_INLINE
00867 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00868 typename self_type::
00869 #endif
00870 reverse_iterator1 rbegin () const {
00871 return reverse_iterator1 (end ());
00872 }
00873 BOOST_UBLAS_INLINE
00874 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00875 typename self_type::
00876 #endif
00877 reverse_iterator1 rend () const {
00878 return reverse_iterator1 (begin ());
00879 }
00880 #endif
00881
00882
00883 BOOST_UBLAS_INLINE
00884 size_type index1 () const {
00885 return it1_;
00886 }
00887 BOOST_UBLAS_INLINE
00888 size_type index2 () const {
00889 return it2_;
00890 }
00891
00892
00893 BOOST_UBLAS_INLINE
00894 iterator2 &operator = (const iterator2 &it) {
00895 container_reference<self_type>::assign (&it ());
00896 it1_ = it.it1_;
00897 it2_ = it.it2_;
00898 return *this;
00899 }
00900
00901
00902 BOOST_UBLAS_INLINE
00903 bool operator == (const iterator2 &it) const {
00904 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00905 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
00906 return it2_ == it.it2_;
00907 }
00908 BOOST_UBLAS_INLINE
00909 bool operator < (const iterator2 &it) const {
00910 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00911 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
00912 return it2_ < it.it2_;
00913 }
00914
00915 private:
00916 size_type it1_;
00917 size_type it2_;
00918
00919 friend class const_iterator2;
00920 };
00921 #endif
00922
00923 BOOST_UBLAS_INLINE
00924 iterator2 begin2 () {
00925 return find2 (0, 0, 0);
00926 }
00927 BOOST_UBLAS_INLINE
00928 iterator2 end2 () {
00929 return find2 (0, 0, size2_);
00930 }
00931
00932
00933
00934 BOOST_UBLAS_INLINE
00935 const_reverse_iterator1 rbegin1 () const {
00936 return const_reverse_iterator1 (end1 ());
00937 }
00938 BOOST_UBLAS_INLINE
00939 const_reverse_iterator1 rend1 () const {
00940 return const_reverse_iterator1 (begin1 ());
00941 }
00942
00943 BOOST_UBLAS_INLINE
00944 reverse_iterator1 rbegin1 () {
00945 return reverse_iterator1 (end1 ());
00946 }
00947 BOOST_UBLAS_INLINE
00948 reverse_iterator1 rend1 () {
00949 return reverse_iterator1 (begin1 ());
00950 }
00951
00952 BOOST_UBLAS_INLINE
00953 const_reverse_iterator2 rbegin2 () const {
00954 return const_reverse_iterator2 (end2 ());
00955 }
00956 BOOST_UBLAS_INLINE
00957 const_reverse_iterator2 rend2 () const {
00958 return const_reverse_iterator2 (begin2 ());
00959 }
00960
00961 BOOST_UBLAS_INLINE
00962 reverse_iterator2 rbegin2 () {
00963 return reverse_iterator2 (end2 ());
00964 }
00965 BOOST_UBLAS_INLINE
00966 reverse_iterator2 rend2 () {
00967 return reverse_iterator2 (begin2 ());
00968 }
00969
00970 private:
00971 size_type size1_;
00972 size_type size2_;
00973 size_type lower_;
00974 size_type upper_;
00975 array_type data_;
00976 typedef const value_type const_value_type;
00977 static const_value_type zero_;
00978 };
00979
00980 template<class T, class L, class A>
00981 typename banded_matrix<T, L, A>::const_value_type banded_matrix<T, L, A>::zero_ = value_type();
00982
00983
00999 template<class T, class L, class A>
01000 class diagonal_matrix:
01001 public banded_matrix<T, L, A> {
01002 public:
01003 typedef typename A::size_type size_type;
01004 typedef banded_matrix<T, L, A> matrix_type;
01005 typedef A array_type;
01006
01007
01008 BOOST_UBLAS_INLINE
01009 diagonal_matrix ():
01010 matrix_type () {}
01011 BOOST_UBLAS_INLINE
01012 diagonal_matrix (size_type size):
01013 matrix_type (size, size) {}
01014 BOOST_UBLAS_INLINE
01015 diagonal_matrix (size_type size, const array_type& data):
01016 matrix_type (size, size, 0, 0, data) {}
01017 BOOST_UBLAS_INLINE
01018 diagonal_matrix (size_type size1, size_type size2):
01019 matrix_type (size1, size2) {}
01020 template<class AE>
01021 BOOST_UBLAS_INLINE
01022 diagonal_matrix (const matrix_expression<AE> &ae):
01023 matrix_type (ae) {}
01024 BOOST_UBLAS_INLINE
01025 ~diagonal_matrix () {}
01026
01027
01028 BOOST_UBLAS_INLINE
01029 diagonal_matrix &operator = (const diagonal_matrix &m) {
01030 matrix_type::operator = (m);
01031 return *this;
01032 }
01033 template<class AE>
01034 BOOST_UBLAS_INLINE
01035 diagonal_matrix &operator = (const matrix_expression<AE> &ae) {
01036 matrix_type::operator = (ae);
01037 return *this;
01038 }
01039 };
01040
01053 template<class M>
01054 class banded_adaptor:
01055 public matrix_expression<banded_adaptor<M> > {
01056
01057 typedef banded_adaptor<M> self_type;
01058 public:
01059 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
01060 using matrix_expression<self_type>::operator ();
01061 #endif
01062 typedef const M const_matrix_type;
01063 typedef M matrix_type;
01064 typedef typename M::size_type size_type;
01065 typedef typename M::difference_type difference_type;
01066 typedef typename M::value_type value_type;
01067 typedef typename M::const_reference const_reference;
01068 typedef typename boost::mpl::if_<boost::is_const<M>,
01069 typename M::const_reference,
01070 typename M::reference>::type reference;
01071 typedef typename boost::mpl::if_<boost::is_const<M>,
01072 typename M::const_closure_type,
01073 typename M::closure_type>::type matrix_closure_type;
01074 typedef const self_type const_closure_type;
01075 typedef self_type closure_type;
01076
01077
01078
01079 typedef typename storage_restrict_traits<typename M::storage_category,
01080 packed_proxy_tag>::storage_category storage_category;
01081 typedef typename M::orientation_category orientation_category;
01082
01083
01084 BOOST_UBLAS_INLINE
01085 banded_adaptor (matrix_type &data, size_type lower = 0, size_type upper = 0):
01086 matrix_expression<self_type> (),
01087 data_ (data), lower_ (lower), upper_ (upper) {}
01088 BOOST_UBLAS_INLINE
01089 banded_adaptor (const banded_adaptor &m):
01090 matrix_expression<self_type> (),
01091 data_ (m.data_), lower_ (m.lower_), upper_ (m.upper_) {}
01092
01093
01094 BOOST_UBLAS_INLINE
01095 size_type size1 () const {
01096 return data_.size1 ();
01097 }
01098 BOOST_UBLAS_INLINE
01099 size_type size2 () const {
01100 return data_.size2 ();
01101 }
01102 BOOST_UBLAS_INLINE
01103 size_type lower () const {
01104 return lower_;
01105 }
01106 BOOST_UBLAS_INLINE
01107 size_type upper () const {
01108 return upper_;
01109 }
01110
01111
01112 BOOST_UBLAS_INLINE
01113 const matrix_closure_type &data () const {
01114 return data_;
01115 }
01116 BOOST_UBLAS_INLINE
01117 matrix_closure_type &data () {
01118 return data_;
01119 }
01120
01121
01122 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
01123 BOOST_UBLAS_INLINE
01124 const_reference operator () (size_type i, size_type j) const {
01125 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
01126 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
01127 #ifdef BOOST_UBLAS_OWN_BANDED
01128 size_type k = (std::max) (i, j);
01129 size_type l = lower_ + j - i;
01130 if (k < (std::max) (size1 (), size2 ()) &&
01131 l < lower_ + 1 + upper_)
01132 return data () (i, j);
01133 #else
01134 size_type k = j;
01135 size_type l = upper_ + i - j;
01136 if (k < size2 () &&
01137 l < lower_ + 1 + upper_)
01138 return data () (i, j);
01139 #endif
01140 return zero_;
01141 }
01142 BOOST_UBLAS_INLINE
01143 reference operator () (size_type i, size_type j) {
01144 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
01145 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
01146 #ifdef BOOST_UBLAS_OWN_BANDED
01147 size_type k = (std::max) (i, j);
01148 size_type l = lower_ + j - i;
01149 if (k < (std::max) (size1 (), size2 ()) &&
01150 l < lower_ + 1 + upper_)
01151 return data () (i, j);
01152 #else
01153 size_type k = j;
01154 size_type l = upper_ + i - j;
01155 if (k < size2 () &&
01156 l < lower_ + 1 + upper_)
01157 return data () (i, j);
01158 #endif
01159 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
01160 bad_index ().raise ();
01161 #endif
01162 return const_cast<reference>(zero_);
01163 }
01164 #else
01165 BOOST_UBLAS_INLINE
01166 reference operator () (size_type i, size_type j) const {
01167 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
01168 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
01169 #ifdef BOOST_UBLAS_OWN_BANDED
01170 size_type k = (std::max) (i, j);
01171 size_type l = lower_ + j - i;
01172 if (k < (std::max) (size1 (), size2 ()) &&
01173 l < lower_ + 1 + upper_)
01174 return data () (i, j);
01175 #else
01176 size_type k = j;
01177 size_type l = upper_ + i - j;
01178 if (k < size2 () &&
01179 l < lower_ + 1 + upper_)
01180 return data () (i, j);
01181 #endif
01182 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
01183 bad_index ().raise ();
01184 #endif
01185 return const_cast<reference>(zero_);
01186 }
01187 #endif
01188
01189
01190 BOOST_UBLAS_INLINE
01191 banded_adaptor &operator = (const banded_adaptor &m) {
01192 matrix_assign<scalar_assign> (*this, m);
01193 return *this;
01194 }
01195 BOOST_UBLAS_INLINE
01196 banded_adaptor &assign_temporary (banded_adaptor &m) {
01197 *this = m;
01198 return *this;
01199 }
01200 template<class AE>
01201 BOOST_UBLAS_INLINE
01202 banded_adaptor &operator = (const matrix_expression<AE> &ae) {
01203 matrix_assign<scalar_assign> (*this, matrix<value_type> (ae));
01204 return *this;
01205 }
01206 template<class AE>
01207 BOOST_UBLAS_INLINE
01208 banded_adaptor &assign (const matrix_expression<AE> &ae) {
01209 matrix_assign<scalar_assign> (*this, ae);
01210 return *this;
01211 }
01212 template<class AE>
01213 BOOST_UBLAS_INLINE
01214 banded_adaptor& operator += (const matrix_expression<AE> &ae) {
01215 matrix_assign<scalar_assign> (*this, matrix<value_type> (*this + ae));
01216 return *this;
01217 }
01218 template<class AE>
01219 BOOST_UBLAS_INLINE
01220 banded_adaptor &plus_assign (const matrix_expression<AE> &ae) {
01221 matrix_assign<scalar_plus_assign> (*this, ae);
01222 return *this;
01223 }
01224 template<class AE>
01225 BOOST_UBLAS_INLINE
01226 banded_adaptor& operator -= (const matrix_expression<AE> &ae) {
01227 matrix_assign<scalar_assign> (*this, matrix<value_type> (*this - ae));
01228 return *this;
01229 }
01230 template<class AE>
01231 BOOST_UBLAS_INLINE
01232 banded_adaptor &minus_assign (const matrix_expression<AE> &ae) {
01233 matrix_assign<scalar_minus_assign> (*this, ae);
01234 return *this;
01235 }
01236 template<class AT>
01237 BOOST_UBLAS_INLINE
01238 banded_adaptor& operator *= (const AT &at) {
01239 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
01240 return *this;
01241 }
01242 template<class AT>
01243 BOOST_UBLAS_INLINE
01244 banded_adaptor& operator /= (const AT &at) {
01245 matrix_assign_scalar<scalar_divides_assign> (*this, at);
01246 return *this;
01247 }
01248
01249
01250 BOOST_UBLAS_INLINE
01251 bool same_closure (const banded_adaptor &ba) const {
01252 return (*this).data ().same_closure (ba.data ());
01253 }
01254
01255
01256 BOOST_UBLAS_INLINE
01257 void swap (banded_adaptor &m) {
01258 if (this != &m) {
01259 BOOST_UBLAS_CHECK (lower_ == m.lower_, bad_size ());
01260 BOOST_UBLAS_CHECK (upper_ == m.upper_, bad_size ());
01261 matrix_swap<scalar_swap> (*this, m);
01262 }
01263 }
01264 BOOST_UBLAS_INLINE
01265 friend void swap (banded_adaptor &m1, banded_adaptor &m2) {
01266 m1.swap (m2);
01267 }
01268
01269
01270 private:
01271
01272 typedef typename M::const_iterator1 const_subiterator1_type;
01273 typedef typename boost::mpl::if_<boost::is_const<M>,
01274 typename M::const_iterator1,
01275 typename M::iterator1>::type subiterator1_type;
01276 typedef typename M::const_iterator2 const_subiterator2_type;
01277 typedef typename boost::mpl::if_<boost::is_const<M>,
01278 typename M::const_iterator2,
01279 typename M::iterator2>::type subiterator2_type;
01280
01281 public:
01282 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01283 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
01284 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
01285 typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
01286 typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
01287 #else
01288 class const_iterator1;
01289 class iterator1;
01290 class const_iterator2;
01291 class iterator2;
01292 #endif
01293 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
01294 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
01295 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
01296 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
01297
01298
01299 BOOST_UBLAS_INLINE
01300 const_iterator1 find1 (int rank, size_type i, size_type j) const {
01301 if (rank == 1) {
01302 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
01303 i = (std::max) (i, lower_i);
01304 size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
01305 i = (std::min) (i, upper_i);
01306 }
01307 return const_iterator1 (*this, data ().find1 (rank, i, j));
01308 }
01309 BOOST_UBLAS_INLINE
01310 iterator1 find1 (int rank, size_type i, size_type j) {
01311 if (rank == 1) {
01312 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
01313 i = (std::max) (i, lower_i);
01314 size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
01315 i = (std::min) (i, upper_i);
01316 }
01317 return iterator1 (*this, data ().find1 (rank, i, j));
01318 }
01319 BOOST_UBLAS_INLINE
01320 const_iterator2 find2 (int rank, size_type i, size_type j) const {
01321 if (rank == 1) {
01322 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
01323 j = (std::max) (j, lower_j);
01324 size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
01325 j = (std::min) (j, upper_j);
01326 }
01327 return const_iterator2 (*this, data ().find2 (rank, i, j));
01328 }
01329 BOOST_UBLAS_INLINE
01330 iterator2 find2 (int rank, size_type i, size_type j) {
01331 if (rank == 1) {
01332 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
01333 j = (std::max) (j, lower_j);
01334 size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
01335 j = (std::min) (j, upper_j);
01336 }
01337 return iterator2 (*this, data ().find2 (rank, i, j));
01338 }
01339
01340
01341
01342 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01343 class const_iterator1:
01344 public container_const_reference<banded_adaptor>,
01345 public random_access_iterator_base<typename iterator_restrict_traits<
01346 typename const_subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
01347 const_iterator1, value_type> {
01348 public:
01349 typedef typename const_subiterator1_type::value_type value_type;
01350 typedef typename const_subiterator1_type::difference_type difference_type;
01351 typedef typename const_subiterator1_type::reference reference;
01352 typedef typename const_subiterator1_type::pointer pointer;
01353
01354 typedef const_iterator2 dual_iterator_type;
01355 typedef const_reverse_iterator2 dual_reverse_iterator_type;
01356
01357
01358 BOOST_UBLAS_INLINE
01359 const_iterator1 ():
01360 container_const_reference<self_type> (), it1_ () {}
01361 BOOST_UBLAS_INLINE
01362 const_iterator1 (const self_type &m, const const_subiterator1_type &it1):
01363 container_const_reference<self_type> (m), it1_ (it1) {}
01364 BOOST_UBLAS_INLINE
01365 const_iterator1 (const iterator1 &it):
01366 container_const_reference<self_type> (it ()), it1_ (it.it1_) {}
01367
01368
01369 BOOST_UBLAS_INLINE
01370 const_iterator1 &operator ++ () {
01371 ++ it1_;
01372 return *this;
01373 }
01374 BOOST_UBLAS_INLINE
01375 const_iterator1 &operator -- () {
01376 -- it1_;
01377 return *this;
01378 }
01379 BOOST_UBLAS_INLINE
01380 const_iterator1 &operator += (difference_type n) {
01381 it1_ += n;
01382 return *this;
01383 }
01384 BOOST_UBLAS_INLINE
01385 const_iterator1 &operator -= (difference_type n) {
01386 it1_ -= n;
01387 return *this;
01388 }
01389 BOOST_UBLAS_INLINE
01390 difference_type operator - (const const_iterator1 &it) const {
01391 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01392 return it1_ - it.it1_;
01393 }
01394
01395
01396 BOOST_UBLAS_INLINE
01397 const_reference operator * () const {
01398 size_type i = index1 ();
01399 size_type j = index2 ();
01400 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
01401 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
01402 #ifdef BOOST_UBLAS_OWN_BANDED
01403 size_type k = (std::max) (i, j);
01404 size_type l = (*this) ().lower () + j - i;
01405 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
01406 l < (*this) ().lower () + 1 + (*this) ().upper ())
01407 return *it1_;
01408 #else
01409 size_type k = j;
01410 size_type l = (*this) ().upper () + i - j;
01411 if (k < (*this) ().size2 () &&
01412 l < (*this) ().lower () + 1 + (*this) ().upper ())
01413 return *it1_;
01414 #endif
01415 return (*this) () (i, j);
01416 }
01417 BOOST_UBLAS_INLINE
01418 const_reference operator [] (difference_type n) const {
01419 return *(*this + n);
01420 }
01421
01422 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01423 BOOST_UBLAS_INLINE
01424 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01425 typename self_type::
01426 #endif
01427 const_iterator2 begin () const {
01428 return (*this) ().find2 (1, index1 (), 0);
01429 }
01430 BOOST_UBLAS_INLINE
01431 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01432 typename self_type::
01433 #endif
01434 const_iterator2 end () const {
01435 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
01436 }
01437 BOOST_UBLAS_INLINE
01438 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01439 typename self_type::
01440 #endif
01441 const_reverse_iterator2 rbegin () const {
01442 return const_reverse_iterator2 (end ());
01443 }
01444 BOOST_UBLAS_INLINE
01445 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01446 typename self_type::
01447 #endif
01448 const_reverse_iterator2 rend () const {
01449 return const_reverse_iterator2 (begin ());
01450 }
01451 #endif
01452
01453
01454 BOOST_UBLAS_INLINE
01455 size_type index1 () const {
01456 return it1_.index1 ();
01457 }
01458 BOOST_UBLAS_INLINE
01459 size_type index2 () const {
01460 return it1_.index2 ();
01461 }
01462
01463
01464 BOOST_UBLAS_INLINE
01465 const_iterator1 &operator = (const const_iterator1 &it) {
01466 container_const_reference<self_type>::assign (&it ());
01467 it1_ = it.it1_;
01468 return *this;
01469 }
01470
01471
01472 BOOST_UBLAS_INLINE
01473 bool operator == (const const_iterator1 &it) const {
01474 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01475 return it1_ == it.it1_;
01476 }
01477 BOOST_UBLAS_INLINE
01478 bool operator < (const const_iterator1 &it) const {
01479 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01480 return it1_ < it.it1_;
01481 }
01482
01483 private:
01484 const_subiterator1_type it1_;
01485 };
01486 #endif
01487
01488 BOOST_UBLAS_INLINE
01489 const_iterator1 begin1 () const {
01490 return find1 (0, 0, 0);
01491 }
01492 BOOST_UBLAS_INLINE
01493 const_iterator1 end1 () const {
01494 return find1 (0, size1 (), 0);
01495 }
01496
01497 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01498 class iterator1:
01499 public container_reference<banded_adaptor>,
01500 public random_access_iterator_base<typename iterator_restrict_traits<
01501 typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
01502 iterator1, value_type> {
01503 public:
01504 typedef typename subiterator1_type::value_type value_type;
01505 typedef typename subiterator1_type::difference_type difference_type;
01506 typedef typename subiterator1_type::reference reference;
01507 typedef typename subiterator1_type::pointer pointer;
01508
01509 typedef iterator2 dual_iterator_type;
01510 typedef reverse_iterator2 dual_reverse_iterator_type;
01511
01512
01513 BOOST_UBLAS_INLINE
01514 iterator1 ():
01515 container_reference<self_type> (), it1_ () {}
01516 BOOST_UBLAS_INLINE
01517 iterator1 (self_type &m, const subiterator1_type &it1):
01518 container_reference<self_type> (m), it1_ (it1) {}
01519
01520
01521 BOOST_UBLAS_INLINE
01522 iterator1 &operator ++ () {
01523 ++ it1_;
01524 return *this;
01525 }
01526 BOOST_UBLAS_INLINE
01527 iterator1 &operator -- () {
01528 -- it1_;
01529 return *this;
01530 }
01531 BOOST_UBLAS_INLINE
01532 iterator1 &operator += (difference_type n) {
01533 it1_ += n;
01534 return *this;
01535 }
01536 BOOST_UBLAS_INLINE
01537 iterator1 &operator -= (difference_type n) {
01538 it1_ -= n;
01539 return *this;
01540 }
01541 BOOST_UBLAS_INLINE
01542 difference_type operator - (const iterator1 &it) const {
01543 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01544 return it1_ - it.it1_;
01545 }
01546
01547
01548 BOOST_UBLAS_INLINE
01549 reference operator * () const {
01550 size_type i = index1 ();
01551 size_type j = index2 ();
01552 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
01553 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
01554 #ifdef BOOST_UBLAS_OWN_BANDED
01555 size_type k = (std::max) (i, j);
01556 size_type l = (*this) ().lower () + j - i;
01557 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
01558 l < (*this) ().lower () + 1 + (*this) ().upper ())
01559 return *it1_;
01560 #else
01561 size_type k = j;
01562 size_type l = (*this) ().upper () + i - j;
01563 if (k < (*this) ().size2 () &&
01564 l < (*this) ().lower () + 1 + (*this) ().upper ())
01565 return *it1_;
01566 #endif
01567 return (*this) () (i, j);
01568 }
01569 BOOST_UBLAS_INLINE
01570 reference operator [] (difference_type n) const {
01571 return *(*this + n);
01572 }
01573
01574 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01575 BOOST_UBLAS_INLINE
01576 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01577 typename self_type::
01578 #endif
01579 iterator2 begin () const {
01580 return (*this) ().find2 (1, index1 (), 0);
01581 }
01582 BOOST_UBLAS_INLINE
01583 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01584 typename self_type::
01585 #endif
01586 iterator2 end () const {
01587 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
01588 }
01589 BOOST_UBLAS_INLINE
01590 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01591 typename self_type::
01592 #endif
01593 reverse_iterator2 rbegin () const {
01594 return reverse_iterator2 (end ());
01595 }
01596 BOOST_UBLAS_INLINE
01597 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01598 typename self_type::
01599 #endif
01600 reverse_iterator2 rend () const {
01601 return reverse_iterator2 (begin ());
01602 }
01603 #endif
01604
01605
01606 BOOST_UBLAS_INLINE
01607 size_type index1 () const {
01608 return it1_.index1 ();
01609 }
01610 BOOST_UBLAS_INLINE
01611 size_type index2 () const {
01612 return it1_.index2 ();
01613 }
01614
01615
01616 BOOST_UBLAS_INLINE
01617 iterator1 &operator = (const iterator1 &it) {
01618 container_reference<self_type>::assign (&it ());
01619 it1_ = it.it1_;
01620 return *this;
01621 }
01622
01623
01624 BOOST_UBLAS_INLINE
01625 bool operator == (const iterator1 &it) const {
01626 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01627 return it1_ == it.it1_;
01628 }
01629 BOOST_UBLAS_INLINE
01630 bool operator < (const iterator1 &it) const {
01631 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01632 return it1_ < it.it1_;
01633 }
01634
01635 private:
01636 subiterator1_type it1_;
01637
01638 friend class const_iterator1;
01639 };
01640 #endif
01641
01642 BOOST_UBLAS_INLINE
01643 iterator1 begin1 () {
01644 return find1 (0, 0, 0);
01645 }
01646 BOOST_UBLAS_INLINE
01647 iterator1 end1 () {
01648 return find1 (0, size1 (), 0);
01649 }
01650
01651 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01652 class const_iterator2:
01653 public container_const_reference<banded_adaptor>,
01654 public random_access_iterator_base<packed_random_access_iterator_tag,
01655 const_iterator2, value_type> {
01656 public:
01657 typedef typename iterator_restrict_traits<typename const_subiterator2_type::iterator_category,
01658 packed_random_access_iterator_tag>::iterator_category iterator_category;
01659 typedef typename const_subiterator2_type::value_type value_type;
01660 typedef typename const_subiterator2_type::difference_type difference_type;
01661 typedef typename const_subiterator2_type::reference reference;
01662 typedef typename const_subiterator2_type::pointer pointer;
01663
01664 typedef const_iterator1 dual_iterator_type;
01665 typedef const_reverse_iterator1 dual_reverse_iterator_type;
01666
01667
01668 BOOST_UBLAS_INLINE
01669 const_iterator2 ():
01670 container_const_reference<self_type> (), it2_ () {}
01671 BOOST_UBLAS_INLINE
01672 const_iterator2 (const self_type &m, const const_subiterator2_type &it2):
01673 container_const_reference<self_type> (m), it2_ (it2) {}
01674 BOOST_UBLAS_INLINE
01675 const_iterator2 (const iterator2 &it):
01676 container_const_reference<self_type> (it ()), it2_ (it.it2_) {}
01677
01678
01679 BOOST_UBLAS_INLINE
01680 const_iterator2 &operator ++ () {
01681 ++ it2_;
01682 return *this;
01683 }
01684 BOOST_UBLAS_INLINE
01685 const_iterator2 &operator -- () {
01686 -- it2_;
01687 return *this;
01688 }
01689 BOOST_UBLAS_INLINE
01690 const_iterator2 &operator += (difference_type n) {
01691 it2_ += n;
01692 return *this;
01693 }
01694 BOOST_UBLAS_INLINE
01695 const_iterator2 &operator -= (difference_type n) {
01696 it2_ -= n;
01697 return *this;
01698 }
01699 BOOST_UBLAS_INLINE
01700 difference_type operator - (const const_iterator2 &it) const {
01701 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01702 return it2_ - it.it2_;
01703 }
01704
01705
01706 BOOST_UBLAS_INLINE
01707 const_reference operator * () const {
01708 size_type i = index1 ();
01709 size_type j = index2 ();
01710 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
01711 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
01712 #ifdef BOOST_UBLAS_OWN_BANDED
01713 size_type k = (std::max) (i, j);
01714 size_type l = (*this) ().lower () + j - i;
01715 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
01716 l < (*this) ().lower () + 1 + (*this) ().upper ())
01717 return *it2_;
01718 #else
01719 size_type k = j;
01720 size_type l = (*this) ().upper () + i - j;
01721 if (k < (*this) ().size2 () &&
01722 l < (*this) ().lower () + 1 + (*this) ().upper ())
01723 return *it2_;
01724 #endif
01725 return (*this) () (i, j);
01726 }
01727 BOOST_UBLAS_INLINE
01728 const_reference operator [] (difference_type n) const {
01729 return *(*this + n);
01730 }
01731
01732 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01733 BOOST_UBLAS_INLINE
01734 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01735 typename self_type::
01736 #endif
01737 const_iterator1 begin () const {
01738 return (*this) ().find1 (1, 0, index2 ());
01739 }
01740 BOOST_UBLAS_INLINE
01741 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01742 typename self_type::
01743 #endif
01744 const_iterator1 end () const {
01745 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
01746 }
01747 BOOST_UBLAS_INLINE
01748 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01749 typename self_type::
01750 #endif
01751 const_reverse_iterator1 rbegin () const {
01752 return const_reverse_iterator1 (end ());
01753 }
01754 BOOST_UBLAS_INLINE
01755 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01756 typename self_type::
01757 #endif
01758 const_reverse_iterator1 rend () const {
01759 return const_reverse_iterator1 (begin ());
01760 }
01761 #endif
01762
01763
01764 BOOST_UBLAS_INLINE
01765 size_type index1 () const {
01766 return it2_.index1 ();
01767 }
01768 BOOST_UBLAS_INLINE
01769 size_type index2 () const {
01770 return it2_.index2 ();
01771 }
01772
01773
01774 BOOST_UBLAS_INLINE
01775 const_iterator2 &operator = (const const_iterator2 &it) {
01776 container_const_reference<self_type>::assign (&it ());
01777 it2_ = it.it2_;
01778 return *this;
01779 }
01780
01781
01782 BOOST_UBLAS_INLINE
01783 bool operator == (const const_iterator2 &it) const {
01784 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01785 return it2_ == it.it2_;
01786 }
01787 BOOST_UBLAS_INLINE
01788 bool operator < (const const_iterator2 &it) const {
01789 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01790 return it2_ < it.it2_;
01791 }
01792
01793 private:
01794 const_subiterator2_type it2_;
01795 };
01796 #endif
01797
01798 BOOST_UBLAS_INLINE
01799 const_iterator2 begin2 () const {
01800 return find2 (0, 0, 0);
01801 }
01802 BOOST_UBLAS_INLINE
01803 const_iterator2 end2 () const {
01804 return find2 (0, 0, size2 ());
01805 }
01806
01807 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01808 class iterator2:
01809 public container_reference<banded_adaptor>,
01810 public random_access_iterator_base<typename iterator_restrict_traits<
01811 typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
01812 iterator2, value_type> {
01813 public:
01814 typedef typename subiterator2_type::value_type value_type;
01815 typedef typename subiterator2_type::difference_type difference_type;
01816 typedef typename subiterator2_type::reference reference;
01817 typedef typename subiterator2_type::pointer pointer;
01818
01819 typedef iterator1 dual_iterator_type;
01820 typedef reverse_iterator1 dual_reverse_iterator_type;
01821
01822
01823 BOOST_UBLAS_INLINE
01824 iterator2 ():
01825 container_reference<self_type> (), it2_ () {}
01826 BOOST_UBLAS_INLINE
01827 iterator2 (self_type &m, const subiterator2_type &it2):
01828 container_reference<self_type> (m), it2_ (it2) {}
01829
01830
01831 BOOST_UBLAS_INLINE
01832 iterator2 &operator ++ () {
01833 ++ it2_;
01834 return *this;
01835 }
01836 BOOST_UBLAS_INLINE
01837 iterator2 &operator -- () {
01838 -- it2_;
01839 return *this;
01840 }
01841 BOOST_UBLAS_INLINE
01842 iterator2 &operator += (difference_type n) {
01843 it2_ += n;
01844 return *this;
01845 }
01846 BOOST_UBLAS_INLINE
01847 iterator2 &operator -= (difference_type n) {
01848 it2_ -= n;
01849 return *this;
01850 }
01851 BOOST_UBLAS_INLINE
01852 difference_type operator - (const iterator2 &it) const {
01853 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01854 return it2_ - it.it2_;
01855 }
01856
01857
01858 BOOST_UBLAS_INLINE
01859 reference operator * () const {
01860 size_type i = index1 ();
01861 size_type j = index2 ();
01862 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
01863 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
01864 #ifdef BOOST_UBLAS_OWN_BANDED
01865 size_type k = (std::max) (i, j);
01866 size_type l = (*this) ().lower () + j - i;
01867 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
01868 l < (*this) ().lower () + 1 + (*this) ().upper ())
01869 return *it2_;
01870 #else
01871 size_type k = j;
01872 size_type l = (*this) ().upper () + i - j;
01873 if (k < (*this) ().size2 () &&
01874 l < (*this) ().lower () + 1 + (*this) ().upper ())
01875 return *it2_;
01876 #endif
01877 return (*this) () (i, j);
01878 }
01879 BOOST_UBLAS_INLINE
01880 reference operator [] (difference_type n) const {
01881 return *(*this + n);
01882 }
01883
01884 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01885 BOOST_UBLAS_INLINE
01886 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01887 typename self_type::
01888 #endif
01889 iterator1 begin () const {
01890 return (*this) ().find1 (1, 0, index2 ());
01891 }
01892 BOOST_UBLAS_INLINE
01893 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01894 typename self_type::
01895 #endif
01896 iterator1 end () const {
01897 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
01898 }
01899 BOOST_UBLAS_INLINE
01900 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01901 typename self_type::
01902 #endif
01903 reverse_iterator1 rbegin () const {
01904 return reverse_iterator1 (end ());
01905 }
01906 BOOST_UBLAS_INLINE
01907 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01908 typename self_type::
01909 #endif
01910 reverse_iterator1 rend () const {
01911 return reverse_iterator1 (begin ());
01912 }
01913 #endif
01914
01915
01916 BOOST_UBLAS_INLINE
01917 size_type index1 () const {
01918 return it2_.index1 ();
01919 }
01920 BOOST_UBLAS_INLINE
01921 size_type index2 () const {
01922 return it2_.index2 ();
01923 }
01924
01925
01926 BOOST_UBLAS_INLINE
01927 iterator2 &operator = (const iterator2 &it) {
01928 container_reference<self_type>::assign (&it ());
01929 it2_ = it.it2_;
01930 return *this;
01931 }
01932
01933
01934 BOOST_UBLAS_INLINE
01935 bool operator == (const iterator2 &it) const {
01936 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01937 return it2_ == it.it2_;
01938 }
01939 BOOST_UBLAS_INLINE
01940 bool operator < (const iterator2 &it) const {
01941 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01942 return it2_ < it.it2_;
01943 }
01944
01945 private:
01946 subiterator2_type it2_;
01947
01948 friend class const_iterator2;
01949 };
01950 #endif
01951
01952 BOOST_UBLAS_INLINE
01953 iterator2 begin2 () {
01954 return find2 (0, 0, 0);
01955 }
01956 BOOST_UBLAS_INLINE
01957 iterator2 end2 () {
01958 return find2 (0, 0, size2 ());
01959 }
01960
01961
01962
01963 BOOST_UBLAS_INLINE
01964 const_reverse_iterator1 rbegin1 () const {
01965 return const_reverse_iterator1 (end1 ());
01966 }
01967 BOOST_UBLAS_INLINE
01968 const_reverse_iterator1 rend1 () const {
01969 return const_reverse_iterator1 (begin1 ());
01970 }
01971
01972 BOOST_UBLAS_INLINE
01973 reverse_iterator1 rbegin1 () {
01974 return reverse_iterator1 (end1 ());
01975 }
01976 BOOST_UBLAS_INLINE
01977 reverse_iterator1 rend1 () {
01978 return reverse_iterator1 (begin1 ());
01979 }
01980
01981 BOOST_UBLAS_INLINE
01982 const_reverse_iterator2 rbegin2 () const {
01983 return const_reverse_iterator2 (end2 ());
01984 }
01985 BOOST_UBLAS_INLINE
01986 const_reverse_iterator2 rend2 () const {
01987 return const_reverse_iterator2 (begin2 ());
01988 }
01989
01990 BOOST_UBLAS_INLINE
01991 reverse_iterator2 rbegin2 () {
01992 return reverse_iterator2 (end2 ());
01993 }
01994 BOOST_UBLAS_INLINE
01995 reverse_iterator2 rend2 () {
01996 return reverse_iterator2 (begin2 ());
01997 }
01998
01999 private:
02000 matrix_closure_type data_;
02001 size_type lower_;
02002 size_type upper_;
02003 typedef const value_type const_value_type;
02004 static const_value_type zero_;
02005 };
02006
02007
02008 template <class M>
02009 struct vector_temporary_traits< banded_adaptor<M> >
02010 : vector_temporary_traits< M > {} ;
02011 template <class M>
02012 struct vector_temporary_traits< const banded_adaptor<M> >
02013 : vector_temporary_traits< M > {} ;
02014
02015 template <class M>
02016 struct matrix_temporary_traits< banded_adaptor<M> >
02017 : matrix_temporary_traits< M > {} ;
02018 template <class M>
02019 struct matrix_temporary_traits< const banded_adaptor<M> >
02020 : matrix_temporary_traits< M > {} ;
02021
02022
02023 template<class M>
02024 typename banded_adaptor<M>::const_value_type banded_adaptor<M>::zero_ = value_type();
02025
02038 template<class M>
02039 class diagonal_adaptor:
02040 public banded_adaptor<M> {
02041 public:
02042 typedef M matrix_type;
02043 typedef banded_adaptor<M> adaptor_type;
02044
02045
02046 BOOST_UBLAS_INLINE
02047 diagonal_adaptor ():
02048 adaptor_type () {}
02049 BOOST_UBLAS_INLINE
02050 diagonal_adaptor (matrix_type &data):
02051 adaptor_type (data) {}
02052 BOOST_UBLAS_INLINE
02053 ~diagonal_adaptor () {}
02054
02055
02056 BOOST_UBLAS_INLINE
02057 diagonal_adaptor &operator = (const diagonal_adaptor &m) {
02058 adaptor_type::operator = (m);
02059 return *this;
02060 }
02061 template<class AE>
02062 BOOST_UBLAS_INLINE
02063 diagonal_adaptor &operator = (const matrix_expression<AE> &ae) {
02064 adaptor_type::operator = (ae);
02065 return *this;
02066 }
02067 };
02068
02069 }}}
02070
02071 #endif