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