Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms

banded.hpp

Go to the documentation of this file.
00001 //
00002 //  Copyright (c) 2000-2002
00003 //  Joerg Walter, Mathias Koch
00004 //
00005 //  Distributed under the Boost Software License, Version 1.0. (See
00006 //  accompanying file LICENSE_1_0.txt or copy at
00007 //  http://www.boost.org/LICENSE_1_0.txt)
00008 //
00009 //  The authors gratefully acknowledge the support of
00010 //  GeNeSys mbH & Co. KG in producing this work.
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 // Iterators based on ideas of Jeremy Siek
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;  // general sub-matrix
00056         typedef packed_tag storage_category;
00057         typedef typename L::orientation_category orientation_category;
00058 
00059         // Construction and destruction
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         // Accessors
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         // Storage accessors
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         // Resizing
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         // Element access
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                 // NEVER reached
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                 // NEVER reached
00203             }
00204             return data () [layout_type::element (k, size2_,
00205                                                        l, lower_ + 1 + upper_)];
00206 #endif
00207         }
00208 
00209         // Element assignment
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/*zero*/();
00217         }
00218 
00219         // Zeroing
00220         BOOST_UBLAS_INLINE
00221         void clear () {
00222             std::fill (data ().begin (), data ().end (), value_type/*zero*/());
00223         }
00224 
00225         // Assignment
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         // Swapping
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         // Iterator types
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         // Element lookup
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         // Iterators simply are indices.
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             // Construction and destruction
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             // Arithmetic
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             // Dereference
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             // Indices
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             // Assignment
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             // Comparison
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             // Construction and destruction
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             // Arithmetic
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             // Dereference
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             // Indices
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             // Assignment
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             // Comparison
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             // Construction and destruction
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             // Arithmetic
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             // Dereference
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             // Indices
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             // Assignment
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             // Comparison
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             // Construction and destruction
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             // Arithmetic
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             // Dereference
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             // Indices
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             // Assignment
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             // Comparison
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         // Reverse iterators
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/*zero*/();
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         // Construction and destruction
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         // Assignment
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         // Replaced by _temporary_traits to avoid type requirements on M
01077         //typedef typename M::vector_temporary_type vector_temporary_type;
01078         //typedef typename M::matrix_temporary_type matrix_temporary_type;
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         // Construction and destruction
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         // Accessors
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         // Storage accessors
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         // Element access
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         // Assignment
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         // Closure comparison
01250         BOOST_UBLAS_INLINE
01251         bool same_closure (const banded_adaptor &ba) const {
01252             return (*this).data ().same_closure (ba.data ());
01253         }
01254 
01255         // Swapping
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         // Iterator types
01270     private:
01271         // Use the matrix iterator
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         // Element lookup
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         // Iterators simply are indices.
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             // Construction and destruction
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             // Arithmetic
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             // Dereference
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             // Indices
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             // Assignment
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             // Comparison
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             // Construction and destruction
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             // Arithmetic
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             // Dereference
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             // Indices
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             // Assignment
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             // Comparison
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             // Construction and destruction
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             // Arithmetic
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             // Dereference
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             // Indices
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             // Assignment
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             // Comparison
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             // Construction and destruction
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             // Arithmetic
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             // Dereference
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             // Indices
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             // Assignment
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             // Comparison
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         // Reverse iterators
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     // Specialization for temporary_traits
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/*zero*/();
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         // Construction and destruction
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         // Assignment
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