- Main Page
- Related Pages
- Classes
- Files

- File List

# banded.hpp

    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