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

Generated on Wed Oct 15 2014 00:37:22 for Jafar by doxygen 1.7.6.1
LAAS-CNRS