Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
serialize_matrix.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_MATRIX_
00018 #define _BOOST_UBLAS_MATRIX_
00019 
00020 #include "jmath/serialize_vector.hpp"
00021 #include <boost/numeric/ublas/matrix_expression.hpp>
00022 #include <boost/numeric/ublas/detail/matrix_assign.hpp>
00023 
00024 // Iterators based on ideas of Jeremy Siek
00025 
00026 namespace boost { namespace numeric { namespace ublas {
00027 
00028     namespace detail {
00029         using namespace boost::numeric::ublas;
00030 
00031         // Matrix resizing algorithm
00032         template <class L, class M>
00033         BOOST_UBLAS_INLINE
00034         void matrix_resize_preserve (M& m, M& temporary) {
00035             typedef L layout_type;
00036             typedef typename M::size_type size_type;
00037             const size_type msize1 (m.size1 ());        // original size
00038             const size_type msize2 (m.size2 ());
00039             const size_type size1 (temporary.size1 ());    // new size is specified by temporary
00040             const size_type size2 (temporary.size2 ());
00041             // Common elements to preserve
00042             const size_type size1_min = (std::min) (size1, msize1);
00043             const size_type size2_min = (std::min) (size2, msize2);
00044             // Order loop for i-major and j-minor sizes
00045             const size_type i_size = layout_type::size1 (size1_min, size2_min);
00046             const size_type j_size = layout_type::size2 (size1_min, size2_min);
00047             for (size_type i = 0; i != i_size; ++i) {    // indexing copy over major
00048                 for (size_type j = 0; j != j_size; ++j) {
00049                     const size_type element1 = layout_type::element1(i,i_size, j,j_size);
00050                     const size_type element2 = layout_type::element2(i,i_size, j,j_size);
00051                     temporary.data () [layout_type::element (element1, size1, element2, size2)] =
00052                             m.data() [layout_type::element (element1, msize1, element2, msize2)];
00053                 }
00054             }
00055             m.assign_temporary (temporary);
00056         }
00057     }
00058 
00059 
00060     // Array based matrix class
00061     template<class T, class L, class A>
00062     class matrix:
00063         public matrix_container<matrix<T, L, A> > {
00064 
00065         typedef T *pointer;
00066         typedef L layout_type;
00067         typedef matrix<T, L, A> self_type;
00068     public:
00069 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00070         using matrix_container<self_type>::operator ();
00071 #endif
00072         typedef typename A::size_type size_type;
00073         typedef typename A::difference_type difference_type;
00074         typedef T value_type;
00075         typedef const T &const_reference;
00076         typedef T &reference;
00077         typedef A array_type;
00078         typedef const matrix_reference<const self_type> const_closure_type;
00079         typedef matrix_reference<self_type> closure_type;
00080         typedef vector<T, A> vector_temporary_type;
00081         typedef self_type matrix_temporary_type;
00082         typedef dense_tag storage_category;
00083         // This could be better for performance,
00084         // typedef typename unknown_orientation_tag orientation_category;
00085         // but others depend on the orientation information...
00086         typedef typename L::orientation_category orientation_category;
00087 
00088         // Construction and destruction
00089         BOOST_UBLAS_INLINE
00090         matrix ():
00091             matrix_container<self_type> (),
00092             size1_ (0), size2_ (0), data_ () {}
00093         BOOST_UBLAS_INLINE
00094         matrix (size_type size1, size_type size2):
00095             matrix_container<self_type> (),
00096             size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2)) {
00097         }
00098         BOOST_UBLAS_INLINE
00099         matrix (size_type size1, size_type size2, const array_type &data):
00100             matrix_container<self_type> (),
00101             size1_ (size1), size2_ (size2), data_ (data) {}
00102         BOOST_UBLAS_INLINE
00103         matrix (const matrix &m):
00104             matrix_container<self_type> (),
00105             size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
00106         template<class AE>
00107         BOOST_UBLAS_INLINE
00108         matrix (const matrix_expression<AE> &ae):
00109             matrix_container<self_type> (),
00110             size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::storage_size (size1_, size2_)) {
00111             matrix_assign<scalar_assign> (*this, ae);
00112         }
00113 
00114         // Accessors
00115         BOOST_UBLAS_INLINE
00116         size_type size1 () const {
00117             return size1_;
00118         }
00119         BOOST_UBLAS_INLINE
00120         size_type size2 () const {
00121             return size2_;
00122         }
00123 
00124         // Storage accessors
00125         BOOST_UBLAS_INLINE
00126         const array_type &data () const {
00127             return data_;
00128         }
00129         BOOST_UBLAS_INLINE
00130         array_type &data () {
00131             return data_;
00132         }
00133 
00134         // Resizing
00135         BOOST_UBLAS_INLINE
00136         void resize (size_type size1, size_type size2, bool preserve = true) {
00137             if (preserve) {
00138                 self_type temporary (size1, size2);
00139                 detail::matrix_resize_preserve<layout_type> (*this, temporary);
00140             }
00141             else {
00142                 data ().resize (layout_type::storage_size (size1, size2));
00143                 size1_ = size1;
00144                 size2_ = size2;
00145             }
00146         }
00147 
00148         // Element access
00149         BOOST_UBLAS_INLINE
00150         const_reference operator () (size_type i, size_type j) const {
00151             return data () [layout_type::element (i, size1_, j, size2_)];
00152         }
00153         BOOST_UBLAS_INLINE
00154         reference at_element (size_type i, size_type j) {
00155             return data () [layout_type::element (i, size1_, j, size2_)];
00156         }
00157         BOOST_UBLAS_INLINE
00158         reference operator () (size_type i, size_type j) {
00159             return at_element (i, j);
00160         }
00161 
00162         // Element assignment
00163         BOOST_UBLAS_INLINE
00164         reference insert_element (size_type i, size_type j, const_reference t) {
00165             return (at_element (i, j) = t);
00166         }
00167         void erase_element (size_type i, size_type j) {
00168             at_element (i, j) = value_type/*zero*/();
00169         }
00170 
00171         // Zeroing
00172         BOOST_UBLAS_INLINE
00173         void clear () {
00174             std::fill (data ().begin (), data ().end (), value_type/*zero*/());
00175         }
00176 
00177         // Assignment
00178         BOOST_UBLAS_INLINE
00179         matrix &operator = (const matrix &m) {
00180             size1_ = m.size1_;
00181             size2_ = m.size2_;
00182             data () = m.data ();
00183             return *this;
00184         }
00185         template<class C>          // Container assignment without temporary
00186         BOOST_UBLAS_INLINE
00187         matrix &operator = (const matrix_container<C> &m) {
00188             resize (m ().size1 (), m ().size2 (), false);
00189             assign (m);
00190             return *this;
00191         }
00192         BOOST_UBLAS_INLINE
00193         matrix &assign_temporary (matrix &m) {
00194             swap (m);
00195             return *this;
00196         }
00197         template<class AE>
00198         BOOST_UBLAS_INLINE
00199         matrix &operator = (const matrix_expression<AE> &ae) {
00200             self_type temporary (ae);
00201             return assign_temporary (temporary);
00202         }
00203         template<class AE>
00204         BOOST_UBLAS_INLINE
00205         matrix &assign (const matrix_expression<AE> &ae) {
00206             matrix_assign<scalar_assign> (*this, ae);
00207             return *this;
00208         }
00209         template<class AE>
00210         BOOST_UBLAS_INLINE
00211         matrix& operator += (const matrix_expression<AE> &ae) {
00212             self_type temporary (*this + ae);
00213             return assign_temporary (temporary);
00214         }
00215         template<class C>          // Container assignment without temporary
00216         BOOST_UBLAS_INLINE
00217         matrix &operator += (const matrix_container<C> &m) {
00218             plus_assign (m);
00219             return *this;
00220         }
00221         template<class AE>
00222         BOOST_UBLAS_INLINE
00223         matrix &plus_assign (const matrix_expression<AE> &ae) {
00224             matrix_assign<scalar_plus_assign> (*this, ae);
00225             return *this;
00226         }
00227         template<class AE>
00228         BOOST_UBLAS_INLINE
00229         matrix& operator -= (const matrix_expression<AE> &ae) {
00230             self_type temporary (*this - ae);
00231             return assign_temporary (temporary);
00232         }
00233         template<class C>          // Container assignment without temporary
00234         BOOST_UBLAS_INLINE
00235         matrix &operator -= (const matrix_container<C> &m) {
00236             minus_assign (m);
00237             return *this;
00238         }
00239         template<class AE>
00240         BOOST_UBLAS_INLINE
00241         matrix &minus_assign (const matrix_expression<AE> &ae) {
00242             matrix_assign<scalar_minus_assign> (*this, ae);
00243             return *this;
00244         }
00245         template<class AT>
00246         BOOST_UBLAS_INLINE
00247         matrix& operator *= (const AT &at) {
00248             matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
00249             return *this;
00250         }
00251         template<class AT>
00252         BOOST_UBLAS_INLINE
00253         matrix& operator /= (const AT &at) {
00254             matrix_assign_scalar<scalar_divides_assign> (*this, at);
00255             return *this;
00256         }
00257 
00258         // Swapping
00259         BOOST_UBLAS_INLINE
00260         void swap (matrix &m) {
00261             if (this != &m) {
00262                 std::swap (size1_, m.size1_);
00263                 std::swap (size2_, m.size2_);
00264                 data ().swap (m.data ());
00265             }
00266         }
00267         BOOST_UBLAS_INLINE
00268         friend void swap (matrix &m1, matrix &m2) {
00269             m1.swap (m2);
00270         }
00271 
00272         // Iterator types
00273     private:
00274         // Use the storage array iterator
00275         typedef typename A::const_iterator const_subiterator_type;
00276         typedef typename A::iterator subiterator_type;
00277 
00278     public:
00279 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00280         typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
00281         typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
00282         typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
00283         typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
00284 #else
00285         class const_iterator1;
00286         class iterator1;
00287         class const_iterator2;
00288         class iterator2;
00289 #endif
00290         typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
00291         typedef reverse_iterator_base1<iterator1> reverse_iterator1;
00292         typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
00293         typedef reverse_iterator_base2<iterator2> reverse_iterator2;
00294 
00295         // Element lookup
00296         BOOST_UBLAS_INLINE
00297         const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
00298 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00299             return const_iterator1 (*this, i, j);
00300 #else
00301             return const_iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
00302 #endif
00303         }
00304         BOOST_UBLAS_INLINE
00305         iterator1 find1 (int /* rank */, size_type i, size_type j) {
00306 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00307             return iterator1 (*this, i, j);
00308 #else
00309             return iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
00310 #endif
00311         }
00312         BOOST_UBLAS_INLINE
00313         const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
00314 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00315             return const_iterator2 (*this, i, j);
00316 #else
00317             return const_iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
00318 #endif
00319         }
00320         BOOST_UBLAS_INLINE
00321         iterator2 find2 (int /* rank */, size_type i, size_type j) {
00322 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00323             return iterator2 (*this, i, j);
00324 #else
00325             return iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
00326 #endif
00327         }
00328 
00329 
00330 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00331         class const_iterator1:
00332             public container_const_reference<matrix>,
00333             public random_access_iterator_base<dense_random_access_iterator_tag,
00334                                                const_iterator1, value_type> {
00335         public:
00336             typedef typename matrix::value_type value_type;
00337             typedef typename matrix::difference_type difference_type;
00338             typedef typename matrix::const_reference reference;
00339             typedef const typename matrix::pointer pointer;
00340 
00341             typedef const_iterator2 dual_iterator_type;
00342             typedef const_reverse_iterator2 dual_reverse_iterator_type;
00343 
00344             // Construction and destruction
00345             BOOST_UBLAS_INLINE
00346             const_iterator1 ():
00347                 container_const_reference<self_type> (), it_ () {}
00348             BOOST_UBLAS_INLINE
00349             const_iterator1 (const self_type &m, const const_subiterator_type &it):
00350                 container_const_reference<self_type> (m), it_ (it) {}
00351             BOOST_UBLAS_INLINE
00352             const_iterator1 (const iterator1 &it):
00353                 container_const_reference<self_type> (it ()), it_ (it.it_) {}
00354 
00355             // Arithmetic
00356             BOOST_UBLAS_INLINE
00357             const_iterator1 &operator ++ () {
00358                 layout_type::increment1 (it_, (*this) ().size1 (), (*this) ().size2 ());
00359                 return *this;
00360             }
00361             BOOST_UBLAS_INLINE
00362             const_iterator1 &operator -- () {
00363                 layout_type::decrement1 (it_, (*this) ().size1 (), (*this) ().size2 ());
00364                 return *this;
00365             }
00366             BOOST_UBLAS_INLINE
00367             const_iterator1 &operator += (difference_type n) {
00368                 it_ += n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ());
00369                 return *this;
00370             }
00371             BOOST_UBLAS_INLINE
00372             const_iterator1 &operator -= (difference_type n) {
00373                 it_ -= n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ());
00374                 return *this;
00375             }
00376             BOOST_UBLAS_INLINE
00377             difference_type operator - (const const_iterator1 &it) const {
00378                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00379                 return layout_type::distance1 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
00380             }
00381 
00382             // Dereference
00383             BOOST_UBLAS_INLINE
00384             const_reference operator * () const {
00385                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
00386                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
00387                 return *it_;
00388             }
00389 
00390 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00391             BOOST_UBLAS_INLINE
00392 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00393             typename self_type::
00394 #endif
00395             const_iterator2 begin () const {
00396                 const self_type &m = (*this) ();
00397                 return m.find2 (1, index1 (), 0);
00398             }
00399             BOOST_UBLAS_INLINE
00400 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00401             typename self_type::
00402 #endif
00403             const_iterator2 end () const {
00404                 const self_type &m = (*this) ();
00405                 return m.find2 (1, index1 (), m.size2 ());
00406             }
00407             BOOST_UBLAS_INLINE
00408 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00409             typename self_type::
00410 #endif
00411             const_reverse_iterator2 rbegin () const {
00412                 return const_reverse_iterator2 (end ());
00413             }
00414             BOOST_UBLAS_INLINE
00415 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00416             typename self_type::
00417 #endif
00418             const_reverse_iterator2 rend () const {
00419                 return const_reverse_iterator2 (begin ());
00420             }
00421 #endif
00422 
00423             // Indices
00424             BOOST_UBLAS_INLINE
00425             size_type index1 () const {
00426                 const self_type &m = (*this) ();
00427                 return layout_type::index1 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
00428             }
00429             BOOST_UBLAS_INLINE
00430             size_type index2 () const {
00431                 const self_type &m = (*this) ();
00432                 return layout_type::index2 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
00433             }
00434 
00435             // Assignment
00436             BOOST_UBLAS_INLINE
00437             const_iterator1 &operator = (const const_iterator1 &it) {
00438                 container_const_reference<self_type>::assign (&it ());
00439                 it_ = it.it_;
00440                 return *this;
00441             }
00442 
00443             // Comparison
00444             BOOST_UBLAS_INLINE
00445             bool operator == (const const_iterator1 &it) const {
00446                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00447                 return it_ == it.it_;
00448             }
00449             BOOST_UBLAS_INLINE
00450             bool operator < (const const_iterator1 &it) const {
00451                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00452                 return it_ < it.it_;
00453             }
00454 
00455         private:
00456             const_subiterator_type it_;
00457 
00458             friend class iterator1;
00459         };
00460 #endif
00461 
00462         BOOST_UBLAS_INLINE
00463         const_iterator1 begin1 () const {
00464             return find1 (0, 0, 0);
00465         }
00466         BOOST_UBLAS_INLINE
00467         const_iterator1 end1 () const {
00468             return find1 (0, size1_, 0);
00469         }
00470 
00471 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00472         class iterator1:
00473             public container_reference<matrix>,
00474             public random_access_iterator_base<dense_random_access_iterator_tag,
00475                                                iterator1, value_type> {
00476         public:
00477             typedef typename matrix::value_type value_type;
00478             typedef typename matrix::difference_type difference_type;
00479             typedef typename matrix::reference reference;
00480             typedef typename matrix::pointer pointer;
00481 
00482             typedef iterator2 dual_iterator_type;
00483             typedef reverse_iterator2 dual_reverse_iterator_type;
00484 
00485             // Construction and destruction
00486             BOOST_UBLAS_INLINE
00487             iterator1 ():
00488                 container_reference<self_type> (), it_ () {}
00489             BOOST_UBLAS_INLINE
00490             iterator1 (self_type &m, const subiterator_type &it):
00491                 container_reference<self_type> (m), it_ (it) {}
00492 
00493             // Arithmetic
00494             BOOST_UBLAS_INLINE
00495             iterator1 &operator ++ () {
00496                 layout_type::increment1 (it_, (*this) ().size1 (), (*this) ().size2 ());
00497                 return *this;
00498             }
00499             BOOST_UBLAS_INLINE
00500             iterator1 &operator -- () {
00501                 layout_type::decrement1 (it_, (*this) ().size1 (), (*this) ().size2 ());
00502                 return *this;
00503             }
00504             BOOST_UBLAS_INLINE
00505             iterator1 &operator += (difference_type n) {
00506                 it_ += n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ());
00507                 return *this;
00508             }
00509             BOOST_UBLAS_INLINE
00510             iterator1 &operator -= (difference_type n) {
00511                 it_ -= n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ());
00512                 return *this;
00513             }
00514             BOOST_UBLAS_INLINE
00515             difference_type operator - (const iterator1 &it) const {
00516                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00517                 return layout_type::distance1 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
00518             }
00519 
00520             // Dereference
00521             BOOST_UBLAS_INLINE
00522             reference operator * () const {
00523                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
00524                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
00525                 return *it_;
00526             }
00527 
00528 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00529             BOOST_UBLAS_INLINE
00530 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00531             typename self_type::
00532 #endif
00533             iterator2 begin () const {
00534                 self_type &m = (*this) ();
00535                 return m.find2 (1, index1 (), 0);
00536             }
00537             BOOST_UBLAS_INLINE
00538 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00539             typename self_type::
00540 #endif
00541             iterator2 end () const {
00542                 self_type &m = (*this) ();
00543                 return m.find2 (1, index1 (), m.size2 ());
00544             }
00545             BOOST_UBLAS_INLINE
00546 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00547             typename self_type::
00548 #endif
00549             reverse_iterator2 rbegin () const {
00550                 return reverse_iterator2 (end ());
00551             }
00552             BOOST_UBLAS_INLINE
00553 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00554             typename self_type::
00555 #endif
00556             reverse_iterator2 rend () const {
00557                 return reverse_iterator2 (begin ());
00558             }
00559 #endif
00560 
00561             // Indices
00562             BOOST_UBLAS_INLINE
00563             size_type index1 () const {
00564                 self_type &m = (*this) ();
00565                 return layout_type::index1 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
00566             }
00567             BOOST_UBLAS_INLINE
00568             size_type index2 () const {
00569                 self_type &m = (*this) ();
00570                 return layout_type::index2 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
00571             }
00572 
00573             // Assignment
00574             BOOST_UBLAS_INLINE
00575             iterator1 &operator = (const iterator1 &it) {
00576                 container_reference<self_type>::assign (&it ());
00577                 it_ = it.it_;
00578                 return *this;
00579             }
00580 
00581             // Comparison
00582             BOOST_UBLAS_INLINE
00583             bool operator == (const iterator1 &it) const {
00584                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00585                 return it_ == it.it_;
00586             }
00587             BOOST_UBLAS_INLINE
00588             bool operator < (const iterator1 &it) const {
00589                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00590                 return it_ < it.it_;
00591             }
00592 
00593         private:
00594             subiterator_type it_;
00595 
00596             friend class const_iterator1;
00597         };
00598 #endif
00599 
00600         BOOST_UBLAS_INLINE
00601         iterator1 begin1 () {
00602             return find1 (0, 0, 0);
00603         }
00604         BOOST_UBLAS_INLINE
00605         iterator1 end1 () {
00606             return find1 (0, size1_, 0);
00607         }
00608 
00609 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00610         class const_iterator2:
00611             public container_const_reference<matrix>,
00612             public random_access_iterator_base<dense_random_access_iterator_tag,
00613                                                const_iterator2, value_type> {
00614         public:
00615             typedef typename matrix::value_type value_type;
00616             typedef typename matrix::difference_type difference_type;
00617             typedef typename matrix::const_reference reference;
00618             typedef const typename matrix::pointer pointer;
00619 
00620             typedef const_iterator1 dual_iterator_type;
00621             typedef const_reverse_iterator1 dual_reverse_iterator_type;
00622 
00623             // Construction and destruction
00624             BOOST_UBLAS_INLINE
00625             const_iterator2 ():
00626                 container_const_reference<self_type> (), it_ () {}
00627             BOOST_UBLAS_INLINE
00628             const_iterator2 (const self_type &m, const const_subiterator_type &it):
00629                 container_const_reference<self_type> (m), it_ (it) {}
00630             BOOST_UBLAS_INLINE
00631             const_iterator2 (const iterator2 &it):
00632                 container_const_reference<self_type> (it ()), it_ (it.it_) {}
00633 
00634             // Arithmetic
00635             BOOST_UBLAS_INLINE
00636             const_iterator2 &operator ++ () {
00637                 layout_type::increment2 (it_, (*this) ().size1 (), (*this) ().size2 ());
00638                 return *this;
00639             }
00640             BOOST_UBLAS_INLINE
00641             const_iterator2 &operator -- () {
00642                 layout_type::decrement2 (it_, (*this) ().size1 (), (*this) ().size2 ());
00643                 return *this;
00644             }
00645             BOOST_UBLAS_INLINE
00646             const_iterator2 &operator += (difference_type n) {
00647                 it_ += n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ());
00648                 return *this;
00649             }
00650             BOOST_UBLAS_INLINE
00651             const_iterator2 &operator -= (difference_type n) {
00652                 it_ -= n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ());
00653                 return *this;
00654             }
00655             BOOST_UBLAS_INLINE
00656             difference_type operator - (const const_iterator2 &it) const {
00657                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00658                 return layout_type::distance2 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
00659             }
00660 
00661             // Dereference
00662             BOOST_UBLAS_INLINE
00663             const_reference operator * () const {
00664                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
00665                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
00666                 return *it_;
00667             }
00668 
00669 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00670             BOOST_UBLAS_INLINE
00671 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00672             typename self_type::
00673 #endif
00674             const_iterator1 begin () const {
00675                 const self_type &m = (*this) ();
00676                 return m.find1 (1, 0, index2 ());
00677             }
00678             BOOST_UBLAS_INLINE
00679 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00680             typename self_type::
00681 #endif
00682             const_iterator1 end () const {
00683                 const self_type &m = (*this) ();
00684                 return m.find1 (1, m.size1 (), index2 ());
00685             }
00686             BOOST_UBLAS_INLINE
00687 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00688             typename self_type::
00689 #endif
00690             const_reverse_iterator1 rbegin () const {
00691                 return const_reverse_iterator1 (end ());
00692             }
00693             BOOST_UBLAS_INLINE
00694 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00695             typename self_type::
00696 #endif
00697             const_reverse_iterator1 rend () const {
00698                 return const_reverse_iterator1 (begin ());
00699             }
00700 #endif
00701 
00702             // Indices
00703             BOOST_UBLAS_INLINE
00704             size_type index1 () const {
00705                 const self_type &m = (*this) ();
00706                 return layout_type::index1 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
00707             }
00708             BOOST_UBLAS_INLINE
00709             size_type index2 () const {
00710                 const self_type &m = (*this) ();
00711                 return layout_type::index2 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
00712             }
00713 
00714             // Assignment
00715             BOOST_UBLAS_INLINE
00716             const_iterator2 &operator = (const const_iterator2 &it) {
00717                 container_const_reference<self_type>::assign (&it ());
00718                 it_ = it.it_;
00719                 return *this;
00720             }
00721 
00722             // Comparison
00723             BOOST_UBLAS_INLINE
00724             bool operator == (const const_iterator2 &it) const {
00725                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00726                 return it_ == it.it_;
00727             }
00728             BOOST_UBLAS_INLINE
00729             bool operator < (const const_iterator2 &it) const {
00730                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00731                 return it_ < it.it_;
00732             }
00733 
00734         private:
00735             const_subiterator_type it_;
00736 
00737             friend class iterator2;
00738         };
00739 #endif
00740 
00741         BOOST_UBLAS_INLINE
00742         const_iterator2 begin2 () const {
00743             return find2 (0, 0, 0);
00744         }
00745         BOOST_UBLAS_INLINE
00746         const_iterator2 end2 () const {
00747             return find2 (0, 0, size2_);
00748         }
00749 
00750 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00751         class iterator2:
00752             public container_reference<matrix>,
00753             public random_access_iterator_base<dense_random_access_iterator_tag,
00754                                                iterator2, value_type> {
00755         public:
00756             typedef typename matrix::value_type value_type;
00757             typedef typename matrix::difference_type difference_type;
00758             typedef typename matrix::reference reference;
00759             typedef typename matrix::pointer pointer;
00760 
00761             typedef iterator1 dual_iterator_type;
00762             typedef reverse_iterator1 dual_reverse_iterator_type;
00763 
00764             // Construction and destruction
00765             BOOST_UBLAS_INLINE
00766             iterator2 ():
00767                 container_reference<self_type> (), it_ () {}
00768             BOOST_UBLAS_INLINE
00769             iterator2 (self_type &m, const subiterator_type &it):
00770                 container_reference<self_type> (m), it_ (it) {}
00771 
00772             // Arithmetic
00773             BOOST_UBLAS_INLINE
00774             iterator2 &operator ++ () {
00775                 layout_type::increment2 (it_, (*this) ().size1 (), (*this) ().size2 ());
00776                 return *this;
00777             }
00778             BOOST_UBLAS_INLINE
00779             iterator2 &operator -- () {
00780                 layout_type::decrement2 (it_, (*this) ().size1 (), (*this) ().size2 ());
00781                 return *this;
00782             }
00783             BOOST_UBLAS_INLINE
00784             iterator2 &operator += (difference_type n) {
00785                 it_ += n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ());
00786                 return *this;
00787             }
00788             BOOST_UBLAS_INLINE
00789             iterator2 &operator -= (difference_type n) {
00790                 it_ -= n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ());
00791                 return *this;
00792             }
00793             BOOST_UBLAS_INLINE
00794             difference_type operator - (const iterator2 &it) const {
00795                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00796                 return layout_type::distance2 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
00797             }
00798 
00799             // Dereference
00800             BOOST_UBLAS_INLINE
00801             reference operator * () const {
00802                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
00803                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
00804                 return *it_;
00805             }
00806 
00807 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00808             BOOST_UBLAS_INLINE
00809 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00810             typename self_type::
00811 #endif
00812             iterator1 begin () const {
00813                 self_type &m = (*this) ();
00814                 return m.find1 (1, 0, index2 ());
00815             }
00816             BOOST_UBLAS_INLINE
00817 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00818             typename self_type::
00819 #endif
00820             iterator1 end () const {
00821                 self_type &m = (*this) ();
00822                 return m.find1 (1, m.size1 (), index2 ());
00823             }
00824             BOOST_UBLAS_INLINE
00825 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00826             typename self_type::
00827 #endif
00828             reverse_iterator1 rbegin () const {
00829                 return reverse_iterator1 (end ());
00830             }
00831             BOOST_UBLAS_INLINE
00832 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00833             typename self_type::
00834 #endif
00835             reverse_iterator1 rend () const {
00836                 return reverse_iterator1 (begin ());
00837             }
00838 #endif
00839 
00840             // Indices
00841             BOOST_UBLAS_INLINE
00842             size_type index1 () const {
00843                 self_type &m = (*this) ();
00844                 return layout_type::index1 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
00845             }
00846             BOOST_UBLAS_INLINE
00847             size_type index2 () const {
00848                 self_type &m = (*this) ();
00849                 return layout_type::index2 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
00850             }
00851 
00852             // Assignment
00853             BOOST_UBLAS_INLINE
00854             iterator2 &operator = (const iterator2 &it) {
00855                 container_reference<self_type>::assign (&it ());
00856                 it_ = it.it_;
00857                 return *this;
00858             }
00859 
00860             // Comparison
00861             BOOST_UBLAS_INLINE
00862             bool operator == (const iterator2 &it) const {
00863                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00864                 return it_ == it.it_;
00865             }
00866             BOOST_UBLAS_INLINE
00867             bool operator < (const iterator2 &it) const {
00868                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00869                 return it_ < it.it_;
00870             }
00871 
00872         private:
00873             subiterator_type it_;
00874 
00875             friend class const_iterator2;
00876         };
00877 #endif
00878 
00879         BOOST_UBLAS_INLINE
00880         iterator2 begin2 () {
00881             return find2 (0, 0, 0);
00882         }
00883         BOOST_UBLAS_INLINE
00884         iterator2 end2 () {
00885             return find2 (0, 0, size2_);
00886         }
00887 
00888         // Reverse iterators
00889 
00890         BOOST_UBLAS_INLINE
00891         const_reverse_iterator1 rbegin1 () const {
00892             return const_reverse_iterator1 (end1 ());
00893         }
00894         BOOST_UBLAS_INLINE
00895         const_reverse_iterator1 rend1 () const {
00896             return const_reverse_iterator1 (begin1 ());
00897         }
00898 
00899         BOOST_UBLAS_INLINE
00900         reverse_iterator1 rbegin1 () {
00901             return reverse_iterator1 (end1 ());
00902         }
00903         BOOST_UBLAS_INLINE
00904         reverse_iterator1 rend1 () {
00905             return reverse_iterator1 (begin1 ());
00906         }
00907 
00908         BOOST_UBLAS_INLINE
00909         const_reverse_iterator2 rbegin2 () const {
00910             return const_reverse_iterator2 (end2 ());
00911         }
00912         BOOST_UBLAS_INLINE
00913         const_reverse_iterator2 rend2 () const {
00914             return const_reverse_iterator2 (begin2 ());
00915         }
00916 
00917         BOOST_UBLAS_INLINE
00918         reverse_iterator2 rbegin2 () {
00919             return reverse_iterator2 (end2 ());
00920         }
00921         BOOST_UBLAS_INLINE
00922         reverse_iterator2 rend2 () {
00923             return reverse_iterator2 (begin2 ());
00924         }
00925 
00926         // Serialization
00927         template<class Archive>
00928         void serialize(Archive & ar, const unsigned int version){
00929           ar & BOOST_SERIALIZATION_NVP(size1_);
00930           ar & BOOST_SERIALIZATION_NVP(size2_);
00931           ar & BOOST_SERIALIZATION_NVP(data_);
00932         }
00933 
00934     private:
00935         size_type size1_;
00936         size_type size2_;
00937         array_type data_;
00938     };
00939 
00940 
00941     // Bounded matrix class
00942     template<class T, std::size_t M, std::size_t N, class L>
00943     class bounded_matrix:
00944         public matrix<T, L, bounded_array<T, M * N> > {
00945 
00946         typedef matrix<T, L, bounded_array<T, M * N> > matrix_type;
00947     public:
00948         typedef typename matrix_type::size_type size_type;
00949         static const size_type max_size1 = M;
00950         static const size_type max_size2 = N;
00951 
00952         // Construction and destruction
00953         BOOST_UBLAS_INLINE
00954         bounded_matrix ():
00955             matrix_type (M, N) {}
00956         BOOST_UBLAS_INLINE
00957         bounded_matrix (size_type size1, size_type size2):
00958             matrix_type (size1, size2) {}
00959         BOOST_UBLAS_INLINE
00960         bounded_matrix (const bounded_matrix &m):
00961             matrix_type (m) {}
00962         template<class A2>              // Allow matrix<T, L, bounded_array<M,N> > construction
00963         BOOST_UBLAS_INLINE
00964         bounded_matrix (const matrix<T, L, A2> &m):
00965             matrix_type (m) {}
00966         template<class AE>
00967         BOOST_UBLAS_INLINE
00968         bounded_matrix (const matrix_expression<AE> &ae):
00969             matrix_type (ae) {}
00970         BOOST_UBLAS_INLINE
00971         ~bounded_matrix () {}
00972 
00973         // Assignment
00974         BOOST_UBLAS_INLINE
00975         bounded_matrix &operator = (const bounded_matrix &m) {
00976             matrix_type::operator = (m);
00977             return *this;
00978         }
00979         template<class L2, class A2>        // Generic matrix assignment
00980         BOOST_UBLAS_INLINE
00981         bounded_matrix &operator = (const matrix<T, L2, A2> &m) {
00982             matrix_type::operator = (m);
00983             return *this;
00984         }
00985         template<class C>          // Container assignment without temporary
00986         BOOST_UBLAS_INLINE
00987         bounded_matrix &operator = (const matrix_container<C> &m) {
00988             matrix_type::operator = (m);
00989             return *this;
00990         }
00991         template<class AE>
00992         BOOST_UBLAS_INLINE
00993         bounded_matrix &operator = (const matrix_expression<AE> &ae) {
00994             matrix_type::operator = (ae);
00995             return *this;
00996         }
00997     };
00998 
00999 
01000     // Array based matrix class
01001     template<class T, class L, class A>
01002     class vector_of_vector:
01003         public matrix_container<vector_of_vector<T, L, A> > {
01004 
01005         typedef T *pointer;
01006         typedef L layout_type;
01007         typedef vector_of_vector<T, L, A> self_type;
01008     public:
01009 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
01010         using matrix_container<self_type>::operator ();
01011 #endif
01012         typedef typename A::size_type size_type;
01013         typedef typename A::difference_type difference_type;
01014         typedef T value_type;
01015         typedef const T &const_reference;
01016         typedef T &reference;
01017         typedef A array_type;
01018         typedef const matrix_reference<const self_type> const_closure_type;
01019         typedef matrix_reference<self_type> closure_type;
01020         typedef vector<T, typename A::value_type> vector_temporary_type;
01021         typedef self_type matrix_temporary_type;
01022         typedef dense_tag storage_category;
01023         // This could be better for performance,
01024         // typedef typename unknown_orientation_tag orientation_category;
01025         // but others depend on the orientation information...
01026         typedef typename L::orientation_category orientation_category;
01027 
01028         // Construction and destruction
01029         BOOST_UBLAS_INLINE
01030         vector_of_vector ():
01031             matrix_container<self_type> (),
01032             size1_ (0), size2_ (0), data_ (1) {}
01033         BOOST_UBLAS_INLINE
01034         vector_of_vector (size_type size1, size_type size2):
01035             matrix_container<self_type> (),
01036             size1_ (size1), size2_ (size2), data_ (1) {
01037             resize (size1, size2, true);
01038         }
01039         BOOST_UBLAS_INLINE
01040         vector_of_vector (const vector_of_vector &m):
01041             matrix_container<self_type> (),
01042             size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
01043         template<class AE>
01044         BOOST_UBLAS_INLINE
01045         vector_of_vector (const matrix_expression<AE> &ae):
01046             matrix_container<self_type> (),
01047             size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size1 (size1_, size2_) + 1) {
01048             for (size_type k = 0; k < layout_type::size1 (size1_, size2_); ++ k)
01049                 data ()[k].resize (layout_type::size2 (size1_, size2_));
01050             matrix_assign<scalar_assign> (*this, ae);
01051         }
01052 
01053         // Accessors
01054         BOOST_UBLAS_INLINE
01055         size_type size1 () const {
01056             return size1_;
01057         }
01058         BOOST_UBLAS_INLINE
01059         size_type size2 () const { 
01060             return size2_;
01061         }
01062 
01063         // Storage accessors
01064         BOOST_UBLAS_INLINE
01065         const array_type &data () const {
01066             return data_;
01067         }
01068         BOOST_UBLAS_INLINE
01069         array_type &data () {
01070             return data_;
01071         }
01072 
01073         // Resizing
01074         BOOST_UBLAS_INLINE
01075         void resize (size_type size1, size_type size2, bool preserve = true) {
01076             size1_ = size1;
01077             size2_ = size2;
01078             if (preserve)
01079                 data ().resize (layout_type::size1 (size1, size2) + 1, typename array_type::value_type ());
01080             else
01081                 data ().resize (layout_type::size1 (size1, size2) + 1);
01082             for (size_type k = 0; k < layout_type::size1 (size1, size2); ++ k) {
01083                 if (preserve)
01084                     data () [k].resize (layout_type::size2 (size1, size2), value_type ());
01085                 else
01086                     data () [k].resize (layout_type::size2 (size1, size2));
01087             }
01088         }
01089 
01090         // Element access
01091         BOOST_UBLAS_INLINE
01092         const_reference operator () (size_type i, size_type j) const {
01093             return data () [layout_type::element1 (i, size1_, j, size2_)] [layout_type::element2 (i, size1_, j, size2_)]; 
01094         }
01095         BOOST_UBLAS_INLINE
01096         reference at_element (size_type i, size_type j) {
01097             return data () [layout_type::element1 (i, size1_, j, size2_)] [layout_type::element2 (i, size1_, j, size2_)]; 
01098         }
01099         BOOST_UBLAS_INLINE
01100         reference operator () (size_type i, size_type j) {
01101             return at_element (i, j); 
01102         }
01103 
01104         // Element assignment
01105         BOOST_UBLAS_INLINE
01106         reference insert_element (size_type i, size_type j, const_reference t) {
01107             return (at_element (i, j) = t); 
01108         }
01109         BOOST_UBLAS_INLINE
01110         void erase_element (size_type i, size_type j) {
01111             at_element (i, j) = value_type/*zero*/(); 
01112         }
01113         
01114         // Zeroing
01115         BOOST_UBLAS_INLINE
01116         void clear () {
01117             for (size_type k = 0; k < layout_type::size1 (size1_, size2_); ++ k)
01118                 std::fill (data () [k].begin (), data () [k].end (), value_type/*zero*/());
01119         }
01120 
01121         // Assignment
01122         BOOST_UBLAS_INLINE
01123         vector_of_vector &operator = (const vector_of_vector &m) {
01124             size1_ = m.size1_;
01125             size2_ = m.size2_;
01126             data () = m.data ();
01127             return *this;
01128         }
01129         BOOST_UBLAS_INLINE
01130         vector_of_vector &assign_temporary (vector_of_vector &m) { 
01131             swap (m);
01132             return *this;
01133         }
01134         template<class AE>
01135         BOOST_UBLAS_INLINE
01136         vector_of_vector &operator = (const matrix_expression<AE> &ae) { 
01137             self_type temporary (ae);
01138             return assign_temporary (temporary);
01139         }
01140         template<class C>          // Container assignment without temporary
01141         BOOST_UBLAS_INLINE
01142         vector_of_vector &operator = (const matrix_container<C> &m) {
01143             resize (m ().size1 (), m ().size2 (), false);
01144             assign (m);
01145             return *this;
01146         }
01147         template<class AE>
01148         BOOST_UBLAS_INLINE
01149         vector_of_vector &assign (const matrix_expression<AE> &ae) { 
01150             matrix_assign<scalar_assign> (*this, ae); 
01151             return *this;
01152         }
01153         template<class AE>
01154         BOOST_UBLAS_INLINE
01155         vector_of_vector& operator += (const matrix_expression<AE> &ae) {
01156             self_type temporary (*this + ae);
01157             return assign_temporary (temporary);
01158         }
01159         template<class C>          // Container assignment without temporary
01160         BOOST_UBLAS_INLINE
01161         vector_of_vector &operator += (const matrix_container<C> &m) {
01162             plus_assign (m);
01163             return *this;
01164         }
01165         template<class AE>
01166         BOOST_UBLAS_INLINE
01167         vector_of_vector &plus_assign (const matrix_expression<AE> &ae) { 
01168             matrix_assign<scalar_plus_assign> (*this, ae); 
01169             return *this;
01170         }
01171         template<class AE>
01172         BOOST_UBLAS_INLINE
01173         vector_of_vector& operator -= (const matrix_expression<AE> &ae) {
01174             self_type temporary (*this - ae);
01175             return assign_temporary (temporary);
01176         }
01177         template<class C>          // Container assignment without temporary
01178         BOOST_UBLAS_INLINE
01179         vector_of_vector &operator -= (const matrix_container<C> &m) {
01180             minus_assign (m);
01181             return *this;
01182         }
01183         template<class AE>
01184         BOOST_UBLAS_INLINE
01185         vector_of_vector &minus_assign (const matrix_expression<AE> &ae) {
01186             matrix_assign<scalar_minus_assign> (*this, ae); 
01187             return *this;
01188         }
01189         template<class AT>
01190         BOOST_UBLAS_INLINE
01191         vector_of_vector& operator *= (const AT &at) {
01192             matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
01193             return *this;
01194         }
01195         template<class AT>
01196         BOOST_UBLAS_INLINE
01197         vector_of_vector& operator /= (const AT &at) {
01198             matrix_assign_scalar<scalar_divides_assign> (*this, at);
01199             return *this;
01200         }
01201 
01202         // Swapping
01203         BOOST_UBLAS_INLINE
01204         void swap (vector_of_vector &m) {
01205             if (this != &m) {
01206                 std::swap (size1_, m.size1_);
01207                 std::swap (size2_, m.size2_);
01208                 data ().swap (m.data ());
01209             }
01210         }
01211         BOOST_UBLAS_INLINE
01212         friend void swap (vector_of_vector &m1, vector_of_vector &m2) {
01213             m1.swap (m2);
01214         }
01215 
01216         // Iterator types
01217     private:
01218         // Use the vector iterator
01219         typedef typename A::value_type::const_iterator const_subiterator_type;
01220         typedef typename A::value_type::iterator subiterator_type;
01221     public:
01222 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01223         typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
01224         typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
01225         typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
01226         typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
01227 #else
01228         class const_iterator1;
01229         class iterator1;
01230         class const_iterator2;
01231         class iterator2;
01232 #endif
01233         typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
01234         typedef reverse_iterator_base1<iterator1> reverse_iterator1;
01235         typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
01236         typedef reverse_iterator_base2<iterator2> reverse_iterator2;
01237 
01238         // Element lookup
01239         BOOST_UBLAS_INLINE
01240         const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
01241 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01242             return const_iterator1 (*this, i, j);
01243 #else
01244             return const_iterator1 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin ()  + layout_type::address2 (i, size1_, j, size2_));
01245 #endif
01246         }
01247         BOOST_UBLAS_INLINE
01248         iterator1 find1 (int /*rank*/, size_type i, size_type j) {
01249 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01250             return iterator1 (*this, i, j);
01251 #else
01252             return iterator1 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin ()  + layout_type::address2 (i, size1_, j, size2_));
01253 #endif
01254         }
01255         BOOST_UBLAS_INLINE
01256         const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
01257 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01258             return const_iterator2 (*this, i, j);
01259 #else
01260             return const_iterator2 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin ()  + layout_type::address2 (i, size1_, j, size2_));
01261 #endif
01262         }
01263         BOOST_UBLAS_INLINE
01264         iterator2 find2 (int /*rank*/, size_type i, size_type j) {
01265 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01266             return iterator2 (*this, i, j);
01267 #else
01268             return iterator2 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin () + layout_type::address2 (i, size1_, j, size2_));
01269 #endif
01270         }
01271 
01272 
01273 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01274         class const_iterator1:
01275             public container_const_reference<vector_of_vector>,
01276             public random_access_iterator_base<dense_random_access_iterator_tag,
01277                                                const_iterator1, value_type> {
01278         public:
01279             typedef typename vector_of_vector::value_type value_type;
01280             typedef typename vector_of_vector::difference_type difference_type;
01281             typedef typename vector_of_vector::const_reference reference;
01282             typedef const typename vector_of_vector::pointer pointer;
01283 
01284             typedef const_iterator2 dual_iterator_type;
01285             typedef const_reverse_iterator2 dual_reverse_iterator_type;
01286 
01287             // Construction and destruction
01288             BOOST_UBLAS_INLINE
01289             const_iterator1 ():
01290                 container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
01291             BOOST_UBLAS_INLINE
01292             const_iterator1 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
01293                 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
01294             BOOST_UBLAS_INLINE
01295             const_iterator1 (const iterator1 &it):
01296                 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
01297 
01298             // Arithmetic
01299             BOOST_UBLAS_INLINE
01300             const_iterator1 &operator ++ () {
01301                 ++ i_;
01302                 const self_type &m = (*this) ();
01303                 if (layout_type::fast1 ())
01304                     ++ it_;
01305                 else 
01306                     it_ = m.find1 (1, i_, j_).it_;
01307                 return *this;
01308             }
01309             BOOST_UBLAS_INLINE
01310             const_iterator1 &operator -- () {
01311                 -- i_;
01312                 const self_type &m = (*this) ();
01313                 if (layout_type::fast1 ())
01314                     -- it_;
01315                 else
01316                     it_ = m.find1 (1, i_, j_).it_;
01317                 return *this;
01318             }
01319             BOOST_UBLAS_INLINE
01320             const_iterator1 &operator += (difference_type n) {
01321                 i_ += n;
01322                 const self_type &m = (*this) ();
01323                 it_ = m.find1 (1, i_, j_).it_;
01324                 return *this;
01325             }
01326             BOOST_UBLAS_INLINE
01327             const_iterator1 &operator -= (difference_type n) {
01328                 i_ -= n;
01329                 const self_type &m = (*this) ();
01330                 it_ = m.find1 (1, i_, j_).it_;
01331                 return *this;
01332             }
01333             BOOST_UBLAS_INLINE
01334             difference_type operator - (const const_iterator1 &it) const {
01335                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01336                 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01337                 return index1 () - it.index1 ();
01338             }
01339 
01340             // Dereference
01341             BOOST_UBLAS_INLINE
01342             const_reference operator * () const {
01343                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
01344                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
01345                 return *it_;
01346             }
01347 
01348 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01349             BOOST_UBLAS_INLINE
01350 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01351             typename self_type::
01352 #endif
01353             const_iterator2 begin () const {
01354                 const self_type &m = (*this) ();
01355                 return m.find2 (1, index1 (), 0);
01356             }
01357             BOOST_UBLAS_INLINE
01358 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01359             typename self_type::
01360 #endif
01361             const_iterator2 end () const {
01362                 const self_type &m = (*this) ();
01363                 return m.find2 (1, index1 (), m.size2 ());
01364             }
01365             BOOST_UBLAS_INLINE
01366 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01367             typename self_type::
01368 #endif
01369             const_reverse_iterator2 rbegin () const {
01370                 return const_reverse_iterator2 (end ());
01371             }
01372             BOOST_UBLAS_INLINE
01373 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01374             typename self_type::
01375 #endif
01376             const_reverse_iterator2 rend () const {
01377                 return const_reverse_iterator2 (begin ());
01378             }
01379 #endif
01380 
01381             // Indices
01382             BOOST_UBLAS_INLINE
01383             size_type index1 () const {
01384                 return i_;
01385             }
01386             BOOST_UBLAS_INLINE
01387             size_type index2 () const {
01388                 return j_;
01389             }
01390 
01391             // Assignment
01392             BOOST_UBLAS_INLINE
01393             const_iterator1 &operator = (const const_iterator1 &it) {
01394                 container_const_reference<self_type>::assign (&it ());
01395                 it_ = it.it_;
01396                 return *this;
01397             }
01398 
01399             // Comparison
01400             BOOST_UBLAS_INLINE
01401             bool operator == (const const_iterator1 &it) const {
01402                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01403                 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01404                 return it_ == it.it_;
01405             }
01406             BOOST_UBLAS_INLINE
01407             bool operator < (const const_iterator1 &it) const {
01408                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01409                 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01410                 return it_ < it.it_;
01411             }
01412 
01413         private:
01414             size_type i_;
01415             size_type j_;
01416             const_subiterator_type it_;
01417 
01418             friend class iterator1;
01419         };
01420 #endif
01421 
01422         BOOST_UBLAS_INLINE
01423         const_iterator1 begin1 () const {
01424             return find1 (0, 0, 0);
01425         }
01426         BOOST_UBLAS_INLINE
01427         const_iterator1 end1 () const {
01428             return find1 (0, size1_, 0);
01429         }
01430 
01431 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01432         class iterator1:
01433             public container_reference<vector_of_vector>,
01434             public random_access_iterator_base<dense_random_access_iterator_tag,
01435                                                iterator1, value_type> {
01436         public:
01437             typedef typename vector_of_vector::value_type value_type;
01438             typedef typename vector_of_vector::difference_type difference_type;
01439             typedef typename vector_of_vector::reference reference;
01440             typedef typename vector_of_vector::pointer pointer;
01441 
01442             typedef iterator2 dual_iterator_type;
01443             typedef reverse_iterator2 dual_reverse_iterator_type;
01444 
01445             // Construction and destruction
01446             BOOST_UBLAS_INLINE
01447             iterator1 ():
01448                 container_reference<self_type> (), i_ (), j_ (), it_ () {}
01449             BOOST_UBLAS_INLINE
01450             iterator1 (self_type &m, size_type i, size_type j, const subiterator_type &it):
01451                 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
01452 
01453             // Arithmetic
01454             BOOST_UBLAS_INLINE
01455             iterator1 &operator ++ () {
01456                 ++ i_;
01457                 self_type &m = (*this) ();
01458                 if (layout_type::fast1 ())
01459                     ++ it_;
01460                 else
01461                     it_ = m.find1 (1, i_, j_).it_;
01462                 return *this;
01463             }
01464             BOOST_UBLAS_INLINE
01465             iterator1 &operator -- () {
01466                 -- i_;
01467                 self_type &m = (*this) ();
01468                 if (layout_type::fast1 ())
01469                     -- it_;
01470                 else
01471                     it_ = m.find1 (1, i_, j_).it_;
01472                 return *this;
01473             }
01474             BOOST_UBLAS_INLINE
01475             iterator1 &operator += (difference_type n) {
01476                 i_ += n;
01477                 self_type &m = (*this) ();
01478                 it_ = m.find1 (1, i_, j_).it_;
01479                 return *this;
01480             }
01481             BOOST_UBLAS_INLINE
01482             iterator1 &operator -= (difference_type n) {
01483                 i_ -= n;
01484                 self_type &m = (*this) ();
01485                 it_ = m.find1 (1, i_, j_).it_;
01486                 return *this;
01487             }
01488             BOOST_UBLAS_INLINE
01489             difference_type operator - (const iterator1 &it) const {
01490                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01491                 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01492                 return index1 () - it.index1 ();
01493             }
01494 
01495             // Dereference
01496             BOOST_UBLAS_INLINE
01497             reference operator * () const {
01498                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
01499                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
01500                 return *it_;
01501             }
01502 
01503 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01504             BOOST_UBLAS_INLINE
01505 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01506             typename self_type::
01507 #endif
01508             iterator2 begin () const {
01509                 self_type &m = (*this) ();
01510                 return m.find2 (1, index1 (), 0);
01511             }
01512             BOOST_UBLAS_INLINE
01513 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01514             typename self_type::
01515 #endif
01516             iterator2 end () const {
01517                 self_type &m = (*this) ();
01518                 return m.find2 (1, index1 (), m.size2 ());
01519             }
01520             BOOST_UBLAS_INLINE
01521 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01522             typename self_type::
01523 #endif
01524             reverse_iterator2 rbegin () const {
01525                 return reverse_iterator2 (end ());
01526             }
01527             BOOST_UBLAS_INLINE
01528 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01529             typename self_type::
01530 #endif
01531             reverse_iterator2 rend () const {
01532                 return reverse_iterator2 (begin ());
01533             }
01534 #endif
01535 
01536             // Indices
01537             BOOST_UBLAS_INLINE
01538             size_type index1 () const {
01539                 return i_;
01540             }
01541             BOOST_UBLAS_INLINE
01542             size_type index2 () const {
01543                 return j_;
01544             }
01545 
01546             // Assignment
01547             BOOST_UBLAS_INLINE
01548             iterator1 &operator = (const iterator1 &it) {
01549                 container_reference<self_type>::assign (&it ());
01550                 it_ = it.it_;
01551                 return *this;
01552             }
01553 
01554             // Comparison
01555             BOOST_UBLAS_INLINE
01556             bool operator == (const iterator1 &it) const {
01557                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01558                 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01559                 return it_ == it.it_;
01560             }
01561             BOOST_UBLAS_INLINE
01562             bool operator < (const iterator1 &it) const {
01563                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01564                 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01565                 return it_ < it.it_;
01566             }
01567 
01568         private:
01569             size_type i_;
01570             size_type j_;
01571             subiterator_type it_;
01572 
01573             friend class const_iterator1;
01574         };
01575 #endif
01576 
01577         BOOST_UBLAS_INLINE
01578         iterator1 begin1 () {
01579             return find1 (0, 0, 0);
01580         }
01581         BOOST_UBLAS_INLINE
01582         iterator1 end1 () {
01583             return find1 (0, size1_, 0);
01584         }
01585 
01586 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01587         class const_iterator2:
01588             public container_const_reference<vector_of_vector>,
01589             public random_access_iterator_base<dense_random_access_iterator_tag,
01590                                                const_iterator2, value_type> {
01591         public:
01592             typedef typename vector_of_vector::value_type value_type;
01593             typedef typename vector_of_vector::difference_type difference_type;
01594             typedef typename vector_of_vector::const_reference reference;
01595             typedef const typename vector_of_vector::pointer pointer;
01596 
01597             typedef const_iterator1 dual_iterator_type;
01598             typedef const_reverse_iterator1 dual_reverse_iterator_type;
01599 
01600             // Construction and destruction
01601             BOOST_UBLAS_INLINE
01602             const_iterator2 ():
01603                 container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
01604             BOOST_UBLAS_INLINE
01605             const_iterator2 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
01606                 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
01607             BOOST_UBLAS_INLINE
01608             const_iterator2 (const iterator2 &it):
01609                 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
01610 
01611             // Arithmetic
01612             BOOST_UBLAS_INLINE
01613             const_iterator2 &operator ++ () {
01614                 ++ j_;
01615                 const self_type &m = (*this) ();
01616                 if (layout_type::fast2 ())
01617                     ++ it_;
01618                 else
01619                     it_ = m.find2 (1, i_, j_).it_;
01620                 return *this;
01621             }
01622             BOOST_UBLAS_INLINE
01623             const_iterator2 &operator -- () {
01624                 -- j_;
01625                 const self_type &m = (*this) ();
01626                 if (layout_type::fast2 ())
01627                     -- it_;
01628                 else
01629                     it_ = m.find2 (1, i_, j_).it_;
01630                 return *this;
01631             }
01632             BOOST_UBLAS_INLINE
01633             const_iterator2 &operator += (difference_type n) {
01634                 j_ += n;
01635                 const self_type &m = (*this) ();
01636                 it_ = m.find2 (1, i_, j_).it_;
01637                 return *this;
01638             }
01639             BOOST_UBLAS_INLINE
01640             const_iterator2 &operator -= (difference_type n) {
01641                 j_ -= n;
01642                 const self_type &m = (*this) ();
01643                 it_ = m.find2 (1, i_, j_).it_;
01644                 return *this;
01645             }
01646             BOOST_UBLAS_INLINE
01647             difference_type operator - (const const_iterator2 &it) const {
01648                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01649                 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
01650                 return index2 () - it.index2 ();
01651             }
01652 
01653             // Dereference
01654             BOOST_UBLAS_INLINE
01655             const_reference operator * () const {
01656                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
01657                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
01658                 return *it_;
01659             }
01660 
01661 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01662             BOOST_UBLAS_INLINE
01663 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01664             typename self_type::
01665 #endif
01666             const_iterator1 begin () const {
01667                 const self_type &m = (*this) ();
01668                 return m.find1 (1, 0, index2 ());
01669             }
01670             BOOST_UBLAS_INLINE
01671 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01672             typename self_type::
01673 #endif
01674             const_iterator1 end () const {
01675                 const self_type &m = (*this) ();
01676                 return m.find1 (1, m.size1 (), index2 ());
01677             }
01678             BOOST_UBLAS_INLINE
01679 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01680             typename self_type::
01681 #endif
01682             const_reverse_iterator1 rbegin () const {
01683                 return const_reverse_iterator1 (end ());
01684             }
01685             BOOST_UBLAS_INLINE
01686 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01687             typename self_type::
01688 #endif
01689             const_reverse_iterator1 rend () const {
01690                 return const_reverse_iterator1 (begin ());
01691             }
01692 #endif
01693 
01694             // Indices
01695             BOOST_UBLAS_INLINE
01696             size_type index1 () const {
01697                 return i_;
01698             }
01699             BOOST_UBLAS_INLINE
01700             size_type index2 () const {
01701                 return j_;
01702             }
01703 
01704             // Assignment
01705             BOOST_UBLAS_INLINE
01706             const_iterator2 &operator = (const const_iterator2 &it) {
01707                 container_const_reference<self_type>::assign (&it ());
01708                 it_ = it.it_;
01709                 return *this;
01710             }
01711 
01712             // Comparison
01713             BOOST_UBLAS_INLINE
01714             bool operator == (const const_iterator2 &it) const {
01715                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01716                 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
01717                 return it_ == it.it_;
01718             }
01719             BOOST_UBLAS_INLINE
01720             bool operator < (const const_iterator2 &it) const {
01721                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01722                 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
01723                 return it_ < it.it_;
01724             }
01725 
01726         private:
01727             size_type i_;
01728             size_type j_;
01729             const_subiterator_type it_;
01730 
01731             friend class iterator2;
01732         };
01733 #endif
01734 
01735         BOOST_UBLAS_INLINE
01736         const_iterator2 begin2 () const {
01737             return find2 (0, 0, 0);
01738         }
01739         BOOST_UBLAS_INLINE
01740         const_iterator2 end2 () const {
01741             return find2 (0, 0, size2_);
01742         }
01743 
01744 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01745         class iterator2:
01746             public container_reference<vector_of_vector>,
01747             public random_access_iterator_base<dense_random_access_iterator_tag,
01748                                                iterator2, value_type> {
01749         public:
01750             typedef typename vector_of_vector::value_type value_type;
01751             typedef typename vector_of_vector::difference_type difference_type;
01752             typedef typename vector_of_vector::reference reference;
01753             typedef typename vector_of_vector::pointer pointer;
01754 
01755             typedef iterator1 dual_iterator_type;
01756             typedef reverse_iterator1 dual_reverse_iterator_type;
01757 
01758             // Construction and destruction
01759             BOOST_UBLAS_INLINE
01760             iterator2 ():
01761                 container_reference<self_type> (), i_ (), j_ (), it_ () {}
01762             BOOST_UBLAS_INLINE
01763             iterator2 (self_type &m, size_type i, size_type j, const subiterator_type &it):
01764                 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
01765 
01766             // Arithmetic
01767             BOOST_UBLAS_INLINE
01768             iterator2 &operator ++ () {
01769                 ++ j_;
01770                 self_type &m = (*this) ();
01771                 if (layout_type::fast2 ())
01772                     ++ it_;
01773                 else
01774                     it_ = m.find2 (1, i_, j_).it_;
01775                 return *this;
01776             }
01777             BOOST_UBLAS_INLINE
01778             iterator2 &operator -- () {
01779                 -- j_;
01780                 self_type &m = (*this) ();
01781                 if (layout_type::fast2 ())
01782                     -- it_;
01783                 else
01784                     it_ = m.find2 (1, i_, j_).it_;
01785                 return *this;
01786             }
01787             BOOST_UBLAS_INLINE
01788             iterator2 &operator += (difference_type n) {
01789                 j_ += n;
01790                 self_type &m = (*this) ();
01791                 it_ = m.find2 (1, i_, j_).it_;
01792                 return *this;
01793             }
01794             BOOST_UBLAS_INLINE
01795             iterator2 &operator -= (difference_type n) {
01796                 j_ -= n;
01797                 self_type &m = (*this) ();
01798                 it_ = m.find2 (1, i_, j_).it_;
01799                 return *this;
01800             }
01801             BOOST_UBLAS_INLINE
01802             difference_type operator - (const iterator2 &it) const {
01803                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01804                 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
01805                 return index2 () - it.index2 ();
01806             }
01807 
01808             // Dereference
01809             BOOST_UBLAS_INLINE
01810             reference operator * () const {
01811                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
01812                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
01813                 return *it_;
01814             }
01815 
01816 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01817             BOOST_UBLAS_INLINE
01818 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01819             typename self_type::
01820 #endif
01821             iterator1 begin () const {
01822                 self_type &m = (*this) ();
01823                 return m.find1 (1, 0, index2 ());
01824             }
01825             BOOST_UBLAS_INLINE
01826 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01827             typename self_type::
01828 #endif
01829             iterator1 end () const {
01830                 self_type &m = (*this) ();
01831                 return m.find1 (1, m.size1 (), index2 ());
01832             }
01833             BOOST_UBLAS_INLINE
01834 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01835             typename self_type::
01836 #endif
01837             reverse_iterator1 rbegin () const {
01838                 return reverse_iterator1 (end ());
01839             }
01840             BOOST_UBLAS_INLINE
01841 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01842             typename self_type::
01843 #endif
01844             reverse_iterator1 rend () const {
01845                 return reverse_iterator1 (begin ());
01846             }
01847 #endif
01848 
01849             // Indices
01850             BOOST_UBLAS_INLINE
01851             size_type index1 () const {
01852                 return i_;
01853             }
01854             BOOST_UBLAS_INLINE
01855             size_type index2 () const {
01856                 return j_;
01857             }
01858 
01859             // Assignment
01860             BOOST_UBLAS_INLINE
01861             iterator2 &operator = (const iterator2 &it) {
01862                 container_reference<self_type>::assign (&it ());
01863                 it_ = it.it_;
01864                 return *this;
01865             }
01866 
01867             // Comparison
01868             BOOST_UBLAS_INLINE
01869             bool operator == (const iterator2 &it) const {
01870                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01871                 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
01872                 return it_ == it.it_;
01873             }
01874             BOOST_UBLAS_INLINE
01875             bool operator < (const iterator2 &it) const {
01876                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01877                 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
01878                 return it_ < it.it_;
01879             }
01880 
01881         private:
01882             size_type i_;
01883             size_type j_;
01884             subiterator_type it_;
01885 
01886             friend class const_iterator2;
01887         };
01888 #endif
01889 
01890         BOOST_UBLAS_INLINE
01891         iterator2 begin2 () {
01892             return find2 (0, 0, 0);
01893         }
01894         BOOST_UBLAS_INLINE
01895         iterator2 end2 () {
01896             return find2 (0, 0, size2_);
01897         }
01898 
01899         // Reverse iterators
01900 
01901         BOOST_UBLAS_INLINE
01902         const_reverse_iterator1 rbegin1 () const {
01903             return const_reverse_iterator1 (end1 ());
01904         }
01905         BOOST_UBLAS_INLINE
01906         const_reverse_iterator1 rend1 () const {
01907             return const_reverse_iterator1 (begin1 ());
01908         }
01909 
01910         BOOST_UBLAS_INLINE
01911         reverse_iterator1 rbegin1 () {
01912             return reverse_iterator1 (end1 ());
01913         }
01914         BOOST_UBLAS_INLINE
01915         reverse_iterator1 rend1 () {
01916             return reverse_iterator1 (begin1 ());
01917         }
01918 
01919         BOOST_UBLAS_INLINE
01920         const_reverse_iterator2 rbegin2 () const {
01921             return const_reverse_iterator2 (end2 ());
01922         }
01923         BOOST_UBLAS_INLINE
01924         const_reverse_iterator2 rend2 () const {
01925             return const_reverse_iterator2 (begin2 ());
01926         }
01927 
01928         BOOST_UBLAS_INLINE
01929         reverse_iterator2 rbegin2 () {
01930             return reverse_iterator2 (end2 ());
01931         }
01932         BOOST_UBLAS_INLINE
01933         reverse_iterator2 rend2 () {
01934             return reverse_iterator2 (begin2 ());
01935         }
01936 
01937         // Serialization
01938         template<class Archive>
01939         void serialize(Archive & ar, const unsigned int version){
01940           ar & BOOST_SERIALIZATION_NVP(size1_); 
01941           ar & BOOST_SERIALIZATION_NVP(size2_);
01942           ar & BOOST_SERIALIZATION_NVP(data_);
01943         }
01944 
01945     private:
01946         size_type size1_;
01947         size_type size2_;
01948         array_type data_;
01949     };
01950 
01951 
01952     // Zero matrix class
01953     template<class T>
01954     class zero_matrix:
01955         public matrix_container<zero_matrix<T> > {
01956 
01957         typedef const T *const_pointer;
01958         typedef zero_matrix<T> self_type;
01959     public:
01960 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
01961         using matrix_container<self_type>::operator ();
01962 #endif
01963         typedef std::size_t size_type;
01964         typedef std::ptrdiff_t difference_type;
01965         typedef T value_type;
01966         typedef const T &const_reference;
01967         typedef T &reference;
01968         typedef const matrix_reference<const self_type> const_closure_type;
01969         typedef matrix_reference<self_type> closure_type;
01970         typedef sparse_tag storage_category;
01971         typedef unknown_orientation_tag orientation_category;
01972 
01973         // Construction and destruction
01974         BOOST_UBLAS_INLINE
01975         zero_matrix ():
01976             matrix_container<self_type> (),
01977             size1_ (0), size2_ (0) {}
01978         BOOST_UBLAS_INLINE
01979         zero_matrix (size_type size):
01980             matrix_container<self_type> (),
01981             size1_ (size), size2_ (size) {}
01982         BOOST_UBLAS_INLINE
01983         zero_matrix (size_type size1, size_type size2):
01984             matrix_container<self_type> (),
01985             size1_ (size1), size2_ (size2) {}
01986         BOOST_UBLAS_INLINE
01987         zero_matrix (const zero_matrix &m):
01988             matrix_container<self_type> (),
01989             size1_ (m.size1_), size2_ (m.size2_) {}
01990 
01991         // Accessors
01992         BOOST_UBLAS_INLINE
01993         size_type size1 () const {
01994             return size1_;
01995         }
01996         BOOST_UBLAS_INLINE
01997         size_type size2 () const {
01998             return size2_;
01999         }
02000 
02001         // Resizing
02002         BOOST_UBLAS_INLINE
02003         void resize (size_type size, bool preserve = true) {
02004             size1_ = size;
02005             size2_ = size;
02006         }
02007         BOOST_UBLAS_INLINE
02008         void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
02009             size1_ = size1;
02010             size2_ = size2;
02011         }
02012 
02013         // Element access
02014         BOOST_UBLAS_INLINE
02015         const_reference operator () (size_type /* i */, size_type /* j */) const {
02016             return zero_;
02017         }
02018 
02019         // Assignment
02020         BOOST_UBLAS_INLINE
02021         zero_matrix &operator = (const zero_matrix &m) {
02022             size1_ = m.size1_;
02023             size2_ = m.size2_;
02024             return *this;
02025         }
02026         BOOST_UBLAS_INLINE
02027         zero_matrix &assign_temporary (zero_matrix &m) {
02028             swap (m);
02029             return *this;
02030         }
02031 
02032         // Swapping
02033         BOOST_UBLAS_INLINE
02034         void swap (zero_matrix &m) {
02035             if (this != &m) {
02036                 std::swap (size1_, m.size1_);
02037                 std::swap (size2_, m.size2_);
02038             }
02039         }
02040         BOOST_UBLAS_INLINE
02041         friend void swap (zero_matrix &m1, zero_matrix &m2) {
02042             m1.swap (m2);
02043         }
02044 
02045         // Iterator types
02046     public:
02047         class const_iterator1;
02048         class const_iterator2;
02049         typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
02050         typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
02051 
02052         // Element lookup
02053         BOOST_UBLAS_INLINE
02054         const_iterator1 find1 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
02055             return const_iterator1 (*this);
02056         }
02057         BOOST_UBLAS_INLINE
02058         const_iterator2 find2 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
02059             return const_iterator2 (*this);
02060         }
02061 
02062         class const_iterator1:
02063             public container_const_reference<zero_matrix>,
02064             public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
02065                                                const_iterator1, value_type> {
02066         public:
02067             typedef typename zero_matrix::value_type value_type;
02068             typedef typename zero_matrix::difference_type difference_type;
02069             typedef typename zero_matrix::const_reference reference;
02070             typedef typename zero_matrix::const_pointer pointer;
02071 
02072             typedef const_iterator2 dual_iterator_type;
02073             typedef const_reverse_iterator2 dual_reverse_iterator_type;
02074 
02075             // Construction and destruction
02076             BOOST_UBLAS_INLINE
02077             const_iterator1 ():
02078                 container_const_reference<self_type> () {}
02079             BOOST_UBLAS_INLINE
02080             const_iterator1 (const self_type &m):
02081                 container_const_reference<self_type> (m) {}
02082 
02083             // Arithmetic
02084             BOOST_UBLAS_INLINE
02085             const_iterator1 &operator ++ () {
02086                 BOOST_UBLAS_CHECK (false, bad_index ());
02087                 return *this;
02088             }
02089             BOOST_UBLAS_INLINE
02090             const_iterator1 &operator -- () {
02091                 BOOST_UBLAS_CHECK (false, bad_index ());
02092                 return *this;
02093             }
02094 
02095             // Dereference
02096             BOOST_UBLAS_INLINE
02097             const_reference operator * () const {
02098                 BOOST_UBLAS_CHECK (false, bad_index ());
02099                 return zero_;   // arbitary return value
02100             }
02101 
02102 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
02103             BOOST_UBLAS_INLINE
02104 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02105             typename self_type::
02106 #endif
02107             const_iterator2 begin () const {
02108                 return const_iterator2 ((*this) ());
02109             }
02110             BOOST_UBLAS_INLINE
02111 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02112             typename self_type::
02113 #endif
02114             const_iterator2 end () const {
02115                 return const_iterator2 ((*this) ());
02116             }
02117             BOOST_UBLAS_INLINE
02118 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02119             typename self_type::
02120 #endif
02121             const_reverse_iterator2 rbegin () const {
02122                 return const_reverse_iterator2 (end ());
02123             }
02124             BOOST_UBLAS_INLINE
02125 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02126             typename self_type::
02127 #endif
02128             const_reverse_iterator2 rend () const {
02129                 return const_reverse_iterator2 (begin ());
02130             }
02131 #endif
02132 
02133             // Indices
02134             BOOST_UBLAS_INLINE
02135             size_type index1 () const {
02136                 BOOST_UBLAS_CHECK (false, bad_index ());
02137                 return 0;   // arbitary return value
02138             }
02139             BOOST_UBLAS_INLINE
02140             size_type index2 () const {
02141                 BOOST_UBLAS_CHECK (false, bad_index ());
02142                 return 0;   // arbitary return value
02143             }
02144 
02145             // Assignment
02146             BOOST_UBLAS_INLINE
02147             const_iterator1 &operator = (const const_iterator1 &it) {
02148                 container_const_reference<self_type>::assign (&it ());
02149                 return *this;
02150             }
02151 
02152             // Comparison
02153             BOOST_UBLAS_INLINE
02154             bool operator == (const const_iterator1 &it) const {
02155                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02156                 return true;
02157             }
02158         };
02159 
02160         typedef const_iterator1 iterator1;
02161 
02162         BOOST_UBLAS_INLINE
02163         const_iterator1 begin1 () const {
02164             return const_iterator1 (*this);
02165         }
02166         BOOST_UBLAS_INLINE
02167         const_iterator1 end1 () const {
02168             return const_iterator1 (*this);
02169         }
02170 
02171         class const_iterator2:
02172             public container_const_reference<zero_matrix>,
02173             public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
02174                                                const_iterator2, value_type> {
02175         public:
02176             typedef typename zero_matrix::value_type value_type;
02177             typedef typename zero_matrix::difference_type difference_type;
02178             typedef typename zero_matrix::const_reference reference;
02179             typedef typename zero_matrix::const_pointer pointer;
02180 
02181             typedef const_iterator1 dual_iterator_type;
02182             typedef const_reverse_iterator1 dual_reverse_iterator_type;
02183 
02184             // Construction and destruction
02185             BOOST_UBLAS_INLINE
02186             const_iterator2 ():
02187                 container_const_reference<self_type> () {}
02188             BOOST_UBLAS_INLINE
02189             const_iterator2 (const self_type &m):
02190                 container_const_reference<self_type> (m) {}
02191 
02192             // Arithmetic
02193             BOOST_UBLAS_INLINE
02194             const_iterator2 &operator ++ () {
02195                 BOOST_UBLAS_CHECK (false, bad_index ());
02196                 return *this;
02197             }
02198             BOOST_UBLAS_INLINE
02199             const_iterator2 &operator -- () {
02200                 BOOST_UBLAS_CHECK (false, bad_index ());
02201                 return *this;
02202             }
02203 
02204             // Dereference
02205             BOOST_UBLAS_INLINE
02206             const_reference operator * () const {
02207                 BOOST_UBLAS_CHECK (false, bad_index ());
02208                 return zero_;   // arbitary return value
02209             }
02210 
02211 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
02212             BOOST_UBLAS_INLINE
02213 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02214             typename self_type::
02215 #endif
02216             const_iterator1 begin () const {
02217                 return const_iterator1 ((*this) ());
02218             }
02219             BOOST_UBLAS_INLINE
02220 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02221             typename self_type::
02222 #endif
02223             const_iterator1 end () const {
02224                 return const_iterator1 ((*this) ());
02225             }
02226             BOOST_UBLAS_INLINE
02227 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02228             typename self_type::
02229 #endif
02230             const_reverse_iterator1 rbegin () const {
02231                 return const_reverse_iterator1 (end ());
02232             }
02233             BOOST_UBLAS_INLINE
02234 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02235             typename self_type::
02236 #endif
02237             const_reverse_iterator1 rend () const {
02238                 return const_reverse_iterator1 (begin ());
02239             }
02240 #endif
02241 
02242             // Indices
02243             BOOST_UBLAS_INLINE
02244             size_type index1 () const {
02245                 BOOST_UBLAS_CHECK (false, bad_index ());
02246                 return 0;   // arbitary return value
02247             }
02248             BOOST_UBLAS_INLINE
02249             size_type index2 () const {
02250                 BOOST_UBLAS_CHECK (false, bad_index ());
02251                 return 0;   // arbitary return value
02252             }
02253 
02254             // Assignment
02255             BOOST_UBLAS_INLINE
02256             const_iterator2 &operator = (const const_iterator2 &it) {
02257                 container_const_reference<self_type>::assign (&it ());
02258                 return *this;
02259             }
02260 
02261             // Comparison
02262             BOOST_UBLAS_INLINE
02263             bool operator == (const const_iterator2 &it) const {
02264                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02265                 return true;
02266             }
02267         };
02268 
02269         typedef const_iterator2 iterator2;
02270 
02271         BOOST_UBLAS_INLINE
02272         const_iterator2 begin2 () const {
02273             return find2 (0, 0, 0);
02274         }
02275         BOOST_UBLAS_INLINE
02276         const_iterator2 end2 () const {
02277             return find2 (0, 0, size2_);
02278         }
02279 
02280         // Reverse iterators
02281 
02282         BOOST_UBLAS_INLINE
02283         const_reverse_iterator1 rbegin1 () const {
02284             return const_reverse_iterator1 (end1 ());
02285         }
02286         BOOST_UBLAS_INLINE
02287         const_reverse_iterator1 rend1 () const {
02288             return const_reverse_iterator1 (begin1 ());
02289         }
02290 
02291         BOOST_UBLAS_INLINE
02292         const_reverse_iterator2 rbegin2 () const {
02293             return const_reverse_iterator2 (end2 ());
02294         }
02295         BOOST_UBLAS_INLINE
02296         const_reverse_iterator2 rend2 () const {
02297             return const_reverse_iterator2 (begin2 ());
02298         }
02299 
02300     private:
02301         size_type size1_;
02302         size_type size2_;
02303         static const value_type zero_;
02304     };
02305 
02306     template<class T>
02307     const typename zero_matrix<T>::value_type zero_matrix<T>::zero_ (0);
02308 
02309 
02310     // Identity matrix class
02311     template<class T>
02312     class identity_matrix:
02313         public matrix_container<identity_matrix<T> > {
02314 
02315         typedef const T *const_pointer;
02316         typedef identity_matrix<T> self_type;
02317     public:
02318 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
02319         using matrix_container<self_type>::operator ();
02320 #endif
02321         typedef std::size_t size_type;
02322         typedef std::ptrdiff_t difference_type;
02323         typedef T value_type;
02324         typedef const T &const_reference;
02325         typedef T &reference;
02326         typedef const matrix_reference<const self_type> const_closure_type;
02327         typedef matrix_reference<self_type> closure_type;
02328         typedef sparse_tag storage_category;
02329         typedef unknown_orientation_tag orientation_category;
02330 
02331         // Construction and destruction
02332         BOOST_UBLAS_INLINE
02333         identity_matrix ():
02334             matrix_container<self_type> (),
02335             size1_ (0), size2_ (0), size_common_ (0) {}
02336         BOOST_UBLAS_INLINE
02337         identity_matrix (size_type size):
02338             matrix_container<self_type> (),
02339             size1_ (size), size2_ (size), size_common_ ((std::min) (size1_, size2_)) {}
02340         BOOST_UBLAS_INLINE
02341         identity_matrix (size_type size1, size_type size2):
02342             matrix_container<self_type> (),
02343             size1_ (size1), size2_ (size2), size_common_ ((std::min) (size1_, size2_)) {}
02344         BOOST_UBLAS_INLINE
02345         identity_matrix (const identity_matrix &m):
02346             matrix_container<self_type> (),
02347             size1_ (m.size1_), size2_ (m.size2_), size_common_ ((std::min) (size1_, size2_)) {}
02348 
02349         // Accessors
02350         BOOST_UBLAS_INLINE
02351         size_type size1 () const {
02352             return size1_;
02353         }
02354         BOOST_UBLAS_INLINE
02355         size_type size2 () const {
02356             return size2_;
02357         }
02358 
02359         // Resizing
02360         BOOST_UBLAS_INLINE
02361         void resize (size_type size, bool preserve = true) {
02362             size1_ = size;
02363             size2_ = size;
02364         }
02365         BOOST_UBLAS_INLINE
02366         void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
02367             size1_ = size1;
02368             size2_ = size2;
02369         }
02370 
02371         // Element access
02372         BOOST_UBLAS_INLINE
02373         const_reference operator () (size_type i, size_type j) const {
02374             if (i == j)
02375                 return one_;
02376             else
02377                 return zero_;
02378         }
02379 
02380         // Assignment
02381         BOOST_UBLAS_INLINE
02382         identity_matrix &operator = (const identity_matrix &m) {
02383             size1_ = m.size1_;
02384             size2_ = m.size2_;
02385             return *this;
02386         }
02387         BOOST_UBLAS_INLINE
02388         identity_matrix &assign_temporary (identity_matrix &m) { 
02389             swap (m);
02390             return *this;
02391         }
02392 
02393         // Swapping
02394         BOOST_UBLAS_INLINE
02395         void swap (identity_matrix &m) {
02396             if (this != &m) {
02397                 std::swap (size1_, m.size1_);
02398                 std::swap (size2_, m.size2_);
02399             }
02400         }
02401         BOOST_UBLAS_INLINE
02402         friend void swap (identity_matrix &m1, identity_matrix &m2) {
02403             m1.swap (m2);
02404         }
02405 
02406         // Iterator types
02407     private:
02408         // Use an index
02409         typedef size_type const_subiterator_type;
02410 
02411     public:
02412         class const_iterator1;
02413         class const_iterator2;
02414         typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
02415         typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
02416 
02417         // Element lookup
02418         BOOST_UBLAS_INLINE
02419         const_iterator1 find1 (int rank, size_type i, size_type j) const {
02420             if (rank == 1) {
02421                 i = (std::max) (i, j);
02422                 i = (std::min) (i, j + 1);
02423             }
02424             return const_iterator1 (*this, i);
02425         }
02426         BOOST_UBLAS_INLINE
02427         const_iterator2 find2 (int rank, size_type i, size_type j) const {
02428             if (rank == 1) {
02429                 j = (std::max) (j, i);
02430                 j = (std::min) (j, i + 1);
02431             }
02432             return const_iterator2 (*this, j);
02433         }
02434 
02435 
02436         class const_iterator1:
02437             public container_const_reference<identity_matrix>,
02438             public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
02439                                                const_iterator1, value_type> {
02440         public:
02441             typedef typename identity_matrix::value_type value_type;
02442             typedef typename identity_matrix::difference_type difference_type;
02443             typedef typename identity_matrix::const_reference reference;
02444             typedef typename identity_matrix::const_pointer pointer;
02445 
02446             typedef const_iterator2 dual_iterator_type;
02447             typedef const_reverse_iterator2 dual_reverse_iterator_type;
02448 
02449             // Construction and destruction
02450             BOOST_UBLAS_INLINE
02451             const_iterator1 ():
02452                 container_const_reference<self_type> (), it_ () {}
02453             BOOST_UBLAS_INLINE
02454             const_iterator1 (const self_type &m, const const_subiterator_type &it):
02455                 container_const_reference<self_type> (m), it_ (it) {}
02456 
02457             // Arithmetic
02458             BOOST_UBLAS_INLINE
02459             const_iterator1 &operator ++ () {
02460                 BOOST_UBLAS_CHECK (it_ < (*this) ().size1 (), bad_index ());
02461                 ++it_;
02462                 return *this;
02463             }
02464             BOOST_UBLAS_INLINE
02465             const_iterator1 &operator -- () {
02466                 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
02467                 --it_;
02468                 return *this;
02469             }
02470 
02471             // Dereference
02472             BOOST_UBLAS_INLINE
02473             const_reference operator * () const {
02474                 return one_;
02475             }
02476 
02477 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
02478             BOOST_UBLAS_INLINE
02479 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02480             typename self_type::
02481 #endif
02482             const_iterator2 begin () const {
02483                 return const_iterator2 ((*this) (), it_); 
02484             }
02485             BOOST_UBLAS_INLINE
02486 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02487             typename self_type::
02488 #endif
02489             const_iterator2 end () const {
02490                 return const_iterator2 ((*this) (), it_ + 1); 
02491             }
02492             BOOST_UBLAS_INLINE
02493 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02494             typename self_type::
02495 #endif
02496             const_reverse_iterator2 rbegin () const {
02497                 return const_reverse_iterator2 (end ());
02498             }
02499             BOOST_UBLAS_INLINE
02500 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02501             typename self_type::
02502 #endif
02503             const_reverse_iterator2 rend () const {
02504                 return const_reverse_iterator2 (begin ());
02505             }
02506 #endif
02507 
02508             // Indices
02509             BOOST_UBLAS_INLINE
02510             size_type index1 () const {
02511                 return it_;
02512             }
02513             BOOST_UBLAS_INLINE
02514             size_type index2 () const {
02515                 return it_;
02516             }
02517 
02518             // Assignment
02519             BOOST_UBLAS_INLINE
02520             const_iterator1 &operator = (const const_iterator1 &it) {
02521                 container_const_reference<self_type>::assign (&it ());
02522                 it_ = it.it_;
02523                 return *this;
02524             }
02525 
02526             // Comparison
02527             BOOST_UBLAS_INLINE
02528             bool operator == (const const_iterator1 &it) const {
02529                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02530                 return it_ == it.it_;
02531             }
02532 
02533         private:
02534             const_subiterator_type it_;
02535         };
02536 
02537         typedef const_iterator1 iterator1;
02538 
02539         BOOST_UBLAS_INLINE
02540         const_iterator1 begin1 () const {
02541             return const_iterator1 (*this, 0);
02542         }
02543         BOOST_UBLAS_INLINE
02544         const_iterator1 end1 () const {
02545             return const_iterator1 (*this, size_common_);
02546         }
02547 
02548         class const_iterator2:
02549             public container_const_reference<identity_matrix>,
02550             public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
02551                                                const_iterator2, value_type> {
02552         public:
02553             typedef typename identity_matrix::value_type value_type;
02554             typedef typename identity_matrix::difference_type difference_type;
02555             typedef typename identity_matrix::const_reference reference;
02556             typedef typename identity_matrix::const_pointer pointer;
02557 
02558             typedef const_iterator1 dual_iterator_type;
02559             typedef const_reverse_iterator1 dual_reverse_iterator_type;
02560 
02561             // Construction and destruction
02562             BOOST_UBLAS_INLINE
02563             const_iterator2 ():
02564                 container_const_reference<self_type> (), it_ () {}
02565             BOOST_UBLAS_INLINE
02566             const_iterator2 (const self_type &m, const const_subiterator_type &it):
02567                 container_const_reference<self_type> (m), it_ (it) {}
02568 
02569             // Arithmetic
02570             BOOST_UBLAS_INLINE
02571             const_iterator2 &operator ++ () {
02572                 BOOST_UBLAS_CHECK (it_ < (*this) ().size_common_, bad_index ());
02573                 ++it_;
02574                 return *this;
02575             }
02576             BOOST_UBLAS_INLINE
02577             const_iterator2 &operator -- () {
02578                 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
02579                 --it_;
02580                 return *this;
02581             }
02582 
02583             // Dereference
02584             BOOST_UBLAS_INLINE
02585             const_reference operator * () const {
02586                 return one_;
02587             }
02588 
02589 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
02590             BOOST_UBLAS_INLINE
02591 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02592             typename self_type::
02593 #endif
02594             const_iterator1 begin () const {
02595                 return const_iterator1 ((*this) (), it_); 
02596             }
02597             BOOST_UBLAS_INLINE
02598 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02599             typename self_type::
02600 #endif
02601             const_iterator1 end () const {
02602                 return const_iterator1 ((*this) (), it_ + 1); 
02603             }
02604             BOOST_UBLAS_INLINE
02605 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02606             typename self_type::
02607 #endif
02608             const_reverse_iterator1 rbegin () const {
02609                 return const_reverse_iterator1 (end ());
02610             }
02611             BOOST_UBLAS_INLINE
02612 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02613             typename self_type::
02614 #endif
02615             const_reverse_iterator1 rend () const {
02616                 return const_reverse_iterator1 (begin ());
02617             }
02618 #endif
02619 
02620             // Indices
02621             BOOST_UBLAS_INLINE
02622             size_type index1 () const {
02623                 return it_;
02624             }
02625             BOOST_UBLAS_INLINE
02626             size_type index2 () const {
02627                 return it_;
02628             }
02629 
02630             // Assignment
02631             BOOST_UBLAS_INLINE
02632             const_iterator2 &operator = (const const_iterator2 &it) {
02633                 container_const_reference<self_type>::assign (&it ());
02634                 it_ = it.it_;
02635                 return *this;
02636             }
02637 
02638             // Comparison
02639             BOOST_UBLAS_INLINE
02640             bool operator == (const const_iterator2 &it) const {
02641                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02642                 return it_ == it.it_;
02643             }
02644 
02645         private:
02646             const_subiterator_type it_;
02647         };
02648 
02649         typedef const_iterator2 iterator2;
02650 
02651         BOOST_UBLAS_INLINE
02652         const_iterator2 begin2 () const {
02653             return const_iterator2 (*this, 0);
02654         }
02655         BOOST_UBLAS_INLINE
02656         const_iterator2 end2 () const {
02657             return const_iterator2 (*this, size_common_);
02658         }
02659 
02660         // Reverse iterators
02661 
02662         BOOST_UBLAS_INLINE
02663         const_reverse_iterator1 rbegin1 () const {
02664             return const_reverse_iterator1 (end1 ());
02665         }
02666         BOOST_UBLAS_INLINE
02667         const_reverse_iterator1 rend1 () const {
02668             return const_reverse_iterator1 (begin1 ());
02669         }
02670 
02671         BOOST_UBLAS_INLINE
02672         const_reverse_iterator2 rbegin2 () const {
02673             return const_reverse_iterator2 (end2 ());
02674         }
02675         BOOST_UBLAS_INLINE
02676         const_reverse_iterator2 rend2 () const {
02677             return const_reverse_iterator2 (begin2 ());
02678         }
02679 
02680     private:
02681         size_type size1_;
02682         size_type size2_;
02683         size_type size_common_;
02684         static const value_type zero_;
02685         static const value_type one_;
02686     };
02687 
02688     template<class T>
02689     const typename identity_matrix<T>::value_type identity_matrix<T>::zero_ (0);
02690     template<class T>
02691     const typename identity_matrix<T>::value_type identity_matrix<T>::one_ (1);
02692 
02693 
02694     // Scalar matrix class
02695     template<class T>
02696     class scalar_matrix:
02697         public matrix_container<scalar_matrix<T> > {
02698 
02699         typedef const T *const_pointer;
02700         typedef scalar_matrix<T> self_type;
02701     public:
02702 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
02703         using matrix_container<self_type>::operator ();
02704 #endif
02705         typedef std::size_t size_type;
02706         typedef std::ptrdiff_t difference_type;
02707         typedef T value_type;
02708         typedef const T &const_reference;
02709         typedef T &reference;
02710         typedef const matrix_reference<const self_type> const_closure_type;
02711         typedef dense_tag storage_category;
02712         typedef unknown_orientation_tag orientation_category;
02713 
02714         // Construction and destruction
02715         BOOST_UBLAS_INLINE
02716         scalar_matrix ():
02717             matrix_container<self_type> (),
02718             size1_ (0), size2_ (0), value_ () {}
02719         BOOST_UBLAS_INLINE
02720         scalar_matrix (size_type size1, size_type size2, const value_type &value = value_type(1)):
02721             matrix_container<self_type> (),
02722             size1_ (size1), size2_ (size2), value_ (value) {}
02723         BOOST_UBLAS_INLINE
02724         scalar_matrix (const scalar_matrix &m):
02725             matrix_container<self_type> (),
02726             size1_ (m.size1_), size2_ (m.size2_), value_ (m.value_) {}
02727 
02728         // Accessors
02729         BOOST_UBLAS_INLINE
02730         size_type size1 () const {
02731             return size1_;
02732         }
02733         BOOST_UBLAS_INLINE
02734         size_type size2 () const {
02735             return size2_;
02736         }
02737 
02738         // Resizing
02739         BOOST_UBLAS_INLINE
02740         void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
02741             size1_ = size1;
02742             size2_ = size2;
02743         }
02744 
02745         // Element access
02746         BOOST_UBLAS_INLINE
02747         const_reference operator () (size_type /*i*/, size_type /*j*/) const {
02748             return value_; 
02749         }
02750 
02751         // Assignment
02752         BOOST_UBLAS_INLINE
02753         scalar_matrix &operator = (const scalar_matrix &m) {
02754             size1_ = m.size1_;
02755             size2_ = m.size2_;
02756             value_ = m.value_;
02757             return *this;
02758         }
02759         BOOST_UBLAS_INLINE
02760         scalar_matrix &assign_temporary (scalar_matrix &m) { 
02761             swap (m);
02762             return *this;
02763         }
02764 
02765         // Swapping
02766         BOOST_UBLAS_INLINE
02767         void swap (scalar_matrix &m) {
02768             if (this != &m) {
02769                 std::swap (size1_, m.size1_);
02770                 std::swap (size2_, m.size2_);
02771                 std::swap (value_, m.value_);
02772             }
02773         }
02774         BOOST_UBLAS_INLINE
02775         friend void swap (scalar_matrix &m1, scalar_matrix &m2) {
02776             m1.swap (m2);
02777         }
02778 
02779         // Iterator types
02780     private:
02781         // Use an index
02782         typedef size_type const_subiterator_type;
02783 
02784     public:
02785 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
02786         typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
02787         typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
02788         typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
02789         typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
02790 #else
02791         class const_iterator1;
02792         class const_iterator2;
02793 #endif
02794         typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
02795         typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
02796 
02797         // Element lookup
02798         BOOST_UBLAS_INLINE
02799         const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
02800             return const_iterator1 (*this, i, j);
02801         }
02802         BOOST_UBLAS_INLINE
02803         const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
02804             return const_iterator2 (*this, i, j);
02805         }   
02806 
02807 
02808 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
02809         class const_iterator1:
02810             public container_const_reference<scalar_matrix>,
02811             public random_access_iterator_base<dense_random_access_iterator_tag,
02812                                                const_iterator1, value_type> {
02813         public:
02814             typedef typename scalar_matrix::value_type value_type;
02815             typedef typename scalar_matrix::difference_type difference_type;
02816             typedef typename scalar_matrix::const_reference reference;
02817             typedef typename scalar_matrix::const_pointer pointer;
02818 
02819             typedef const_iterator2 dual_iterator_type;
02820             typedef const_reverse_iterator2 dual_reverse_iterator_type;
02821 
02822             // Construction and destruction
02823             BOOST_UBLAS_INLINE
02824             const_iterator1 ():
02825                 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
02826             BOOST_UBLAS_INLINE
02827             const_iterator1 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
02828                 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
02829 
02830             // Arithmetic
02831             BOOST_UBLAS_INLINE
02832             const_iterator1 &operator ++ () {
02833                 ++ it1_;
02834                 return *this;
02835             }
02836             BOOST_UBLAS_INLINE
02837             const_iterator1 &operator -- () {
02838                 -- it1_;
02839                 return *this;
02840             }
02841             BOOST_UBLAS_INLINE
02842             const_iterator1 &operator += (difference_type n) {
02843                 it1_ += n;
02844                 return *this;
02845             }
02846             BOOST_UBLAS_INLINE
02847             const_iterator1 &operator -= (difference_type n) {
02848                 it1_ -= n;
02849                 return *this;
02850             }
02851             BOOST_UBLAS_INLINE
02852             difference_type operator - (const const_iterator1 &it) const {
02853                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02854                 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
02855                 return it1_ - it.it1_;
02856             }
02857 
02858             // Dereference
02859             BOOST_UBLAS_INLINE
02860             const_reference operator * () const {
02861                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
02862                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
02863                 return (*this) () (index1 (), index2 ());
02864             }
02865 
02866 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
02867             BOOST_UBLAS_INLINE
02868 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02869             typename self_type::
02870 #endif
02871             const_iterator2 begin () const {
02872                 const scalar_matrix &m = (*this) ();
02873                 return m.find2 (1, index1 (), 0);
02874             }
02875             BOOST_UBLAS_INLINE
02876 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02877             typename self_type::
02878 #endif
02879             const_iterator2 end () const {
02880                 const scalar_matrix &m = (*this) ();
02881                 return m.find2 (1, index1 (), m.size2 ());
02882             }
02883             BOOST_UBLAS_INLINE
02884 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02885             typename self_type::
02886 #endif
02887             const_reverse_iterator2 rbegin () const {
02888                 return const_reverse_iterator2 (end ());
02889             }
02890             BOOST_UBLAS_INLINE
02891 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02892             typename self_type::
02893 #endif
02894             const_reverse_iterator2 rend () const {
02895                 return const_reverse_iterator2 (begin ());
02896             }
02897 #endif
02898 
02899             // Indices
02900             BOOST_UBLAS_INLINE
02901             size_type index1 () const {
02902                 return it1_;
02903             }
02904             BOOST_UBLAS_INLINE
02905             size_type index2 () const {
02906                 return it2_;
02907             }
02908 
02909             // Assignment
02910             BOOST_UBLAS_INLINE
02911             const_iterator1 &operator = (const const_iterator1 &it) {
02912                 container_const_reference<scalar_matrix>::assign (&it ());
02913                 it1_ = it.it1_;
02914                 it2_ = it.it2_;
02915                 return *this;
02916             }
02917 
02918             // Comparison
02919             BOOST_UBLAS_INLINE
02920             bool operator == (const const_iterator1 &it) const {
02921                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02922                 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
02923                 return it1_ == it.it1_;
02924             }
02925             BOOST_UBLAS_INLINE
02926             bool operator < (const const_iterator1 &it) const {
02927                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02928                 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
02929                 return it1_ < it.it1_;
02930             }
02931 
02932         private:
02933             const_subiterator_type it1_;
02934             const_subiterator_type it2_;
02935         };
02936 
02937         typedef const_iterator1 iterator1;
02938 #endif
02939 
02940         BOOST_UBLAS_INLINE
02941         const_iterator1 begin1 () const {
02942             return find1 (0, 0, 0);
02943         }
02944         BOOST_UBLAS_INLINE
02945         const_iterator1 end1 () const {
02946             return find1 (0, size1_, 0);
02947         }
02948 
02949 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
02950         class const_iterator2:
02951             public container_const_reference<scalar_matrix>,
02952             public random_access_iterator_base<dense_random_access_iterator_tag,
02953                                                const_iterator2, value_type> {
02954         public:
02955             typedef typename scalar_matrix::value_type value_type;
02956             typedef typename scalar_matrix::difference_type difference_type;
02957             typedef typename scalar_matrix::const_reference reference;
02958             typedef typename scalar_matrix::const_pointer pointer;
02959 
02960             typedef const_iterator1 dual_iterator_type;
02961             typedef const_reverse_iterator1 dual_reverse_iterator_type;
02962 
02963             // Construction and destruction
02964             BOOST_UBLAS_INLINE
02965             const_iterator2 ():
02966                 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
02967             BOOST_UBLAS_INLINE
02968             const_iterator2 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
02969                 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
02970 
02971             // Arithmetic
02972             BOOST_UBLAS_INLINE
02973             const_iterator2 &operator ++ () {
02974                 ++ it2_;
02975                 return *this;
02976             }
02977             BOOST_UBLAS_INLINE
02978             const_iterator2 &operator -- () {
02979                 -- it2_;
02980                 return *this;
02981             }
02982             BOOST_UBLAS_INLINE
02983             const_iterator2 &operator += (difference_type n) {
02984                 it2_ += n;
02985                 return *this;
02986             }
02987             BOOST_UBLAS_INLINE
02988             const_iterator2 &operator -= (difference_type n) {
02989                 it2_ -= n;
02990                 return *this;
02991             }
02992             BOOST_UBLAS_INLINE
02993             difference_type operator - (const const_iterator2 &it) const {
02994                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02995                 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
02996                 return it2_ - it.it2_;
02997             }
02998 
02999             // Dereference
03000             BOOST_UBLAS_INLINE
03001             const_reference operator * () const {
03002                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
03003                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
03004                 return (*this) () (index1 (), index2 ());
03005             }
03006 
03007 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
03008             BOOST_UBLAS_INLINE
03009 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03010             typename self_type::
03011 #endif
03012             const_iterator1 begin () const {
03013                 const scalar_matrix &m = (*this) ();
03014                 return m.find1 (1, 0, index2 ());
03015             }
03016             BOOST_UBLAS_INLINE
03017 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03018             typename self_type::
03019 #endif
03020             const_iterator1 end () const {
03021                 const scalar_matrix &m = (*this) ();
03022                 return m.find1 (1, m.size1 (), index2 ());
03023             }
03024             BOOST_UBLAS_INLINE
03025 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03026             typename self_type::
03027 #endif
03028             const_reverse_iterator1 rbegin () const {
03029                 return const_reverse_iterator1 (end ());
03030             }
03031             BOOST_UBLAS_INLINE
03032 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03033             typename self_type::
03034 #endif
03035             const_reverse_iterator1 rend () const {
03036                 return const_reverse_iterator1 (begin ());
03037             }
03038 #endif
03039 
03040             // Indices
03041             BOOST_UBLAS_INLINE
03042             size_type index1 () const {
03043                 return it1_;
03044             }
03045             BOOST_UBLAS_INLINE
03046             size_type index2 () const {
03047                 return it2_;
03048             }
03049 
03050             // Assignment
03051             BOOST_UBLAS_INLINE
03052             const_iterator2 &operator = (const const_iterator2 &it) {
03053                 container_const_reference<scalar_matrix>::assign (&it ());
03054                 it1_ = it.it1_;
03055                 it2_ = it.it2_;
03056                 return *this;
03057             }
03058 
03059             // Comparison
03060             BOOST_UBLAS_INLINE
03061             bool operator == (const const_iterator2 &it) const {
03062                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03063                 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
03064                 return it2_ == it.it2_;
03065             }
03066             BOOST_UBLAS_INLINE
03067             bool operator < (const const_iterator2 &it) const {
03068                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03069                 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
03070                 return it2_ < it.it2_;
03071             }
03072 
03073         private:
03074             const_subiterator_type it1_;
03075             const_subiterator_type it2_;
03076         };
03077 
03078         typedef const_iterator2 iterator2;
03079 #endif
03080 
03081         BOOST_UBLAS_INLINE
03082         const_iterator2 begin2 () const {
03083             return find2 (0, 0, 0);
03084         }
03085         BOOST_UBLAS_INLINE
03086         const_iterator2 end2 () const {
03087             return find2 (0, 0, size2_);
03088         }
03089 
03090         // Reverse iterators
03091 
03092         BOOST_UBLAS_INLINE
03093         const_reverse_iterator1 rbegin1 () const {
03094             return const_reverse_iterator1 (end1 ());
03095         }
03096         BOOST_UBLAS_INLINE
03097         const_reverse_iterator1 rend1 () const {
03098             return const_reverse_iterator1 (begin1 ());
03099         }
03100 
03101         BOOST_UBLAS_INLINE
03102         const_reverse_iterator2 rbegin2 () const {
03103             return const_reverse_iterator2 (end2 ());
03104         }
03105         BOOST_UBLAS_INLINE
03106         const_reverse_iterator2 rend2 () const {
03107             return const_reverse_iterator2 (begin2 ());
03108         }
03109 
03110     private:
03111         size_type size1_;
03112         size_type size2_;
03113         value_type value_;
03114     };
03115 
03116 
03117     // Array based matrix class
03118     template<class T, std::size_t N, std::size_t M>
03119     class c_matrix:
03120         public matrix_container<c_matrix<T, N, M> > {
03121 
03122         typedef c_matrix<T, N, M> self_type;
03123     public:
03124 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
03125         using matrix_container<self_type>::operator ();
03126 #endif
03127         typedef std::size_t size_type;
03128         typedef std::ptrdiff_t difference_type;
03129         typedef T value_type;
03130         typedef const T &const_reference;
03131         typedef T &reference;
03132         typedef const T *const_pointer;
03133         typedef T *pointer;
03134         typedef const matrix_reference<const self_type> const_closure_type;
03135         typedef matrix_reference<self_type> closure_type;
03136         typedef c_vector<T, N * M> vector_temporary_type;     // vector able to store all elements of c_matrix
03137         typedef self_type matrix_temporary_type;
03138         typedef dense_tag storage_category;
03139         // This could be better for performance,
03140         // typedef typename unknown_orientation_tag orientation_category;
03141         // but others depend on the orientation information...
03142         typedef row_major_tag orientation_category;
03143 
03144         // Construction and destruction
03145         BOOST_UBLAS_INLINE
03146         c_matrix ():
03147             size1_ (N), size2_ (M) /* , data_ () */ {
03148         }
03149         BOOST_UBLAS_INLINE
03150         c_matrix (size_type size1, size_type size2):
03151             size1_ (size1), size2_ (size2) /* , data_ () */ {
03152             if (size1_ > N || size2_ > M)
03153                 bad_size ().raise ();
03154         }
03155         BOOST_UBLAS_INLINE
03156         c_matrix (const c_matrix &m):
03157             size1_ (m.size1_), size2_ (m.size2_) /* , data_ () */ {
03158             if (size1_ > N || size2_ > M)
03159                 bad_size ().raise ();
03160             *this = m;
03161         }
03162         template<class AE>
03163         BOOST_UBLAS_INLINE
03164         c_matrix (const matrix_expression<AE> &ae):
03165             size1_ (ae ().size1 ()), size2_ (ae ().size2 ()) /* , data_ () */ {
03166             if (size1_ > N || size2_ > M)
03167                 bad_size ().raise ();
03168             matrix_assign<scalar_assign> (*this, ae);
03169         }
03170 
03171         // Accessors
03172         BOOST_UBLAS_INLINE
03173         size_type size1 () const {
03174             return size1_;
03175         }
03176         BOOST_UBLAS_INLINE
03177         size_type size2 () const {
03178             return size2_;
03179         }
03180         BOOST_UBLAS_INLINE
03181         const_pointer data () const {
03182             return reinterpret_cast<const_pointer> (data_);
03183         }
03184         BOOST_UBLAS_INLINE
03185         pointer data () {
03186             return reinterpret_cast<pointer> (data_);
03187         }
03188 
03189         // Resizing
03190         BOOST_UBLAS_INLINE
03191         void resize (size_type size1, size_type size2, bool preserve = true) {
03192             if (size1 > N || size2 > M)
03193                 bad_size ().raise ();
03194             if (preserve) {
03195                 self_type temporary (size1, size2);
03196                 // Common elements to preserve
03197                 const size_type size1_min = (std::min) (size1, size1_);
03198                 const size_type size2_min = (std::min) (size2, size2_);
03199                 for (size_type i = 0; i != size1_min; ++i) {    // indexing copy over major
03200                     for (size_type j = 0; j != size2_min; ++j) {
03201                         temporary.data_[i][j] = data_[i][j];
03202                     }
03203                 }
03204                 assign_temporary (temporary);
03205             }
03206             else {
03207                 size1_ = size1;
03208                 size2_ = size2;
03209             }
03210         }
03211 
03212         // Element access
03213         BOOST_UBLAS_INLINE
03214         const_reference operator () (size_type i, size_type j) const {
03215             BOOST_UBLAS_CHECK (i < size1_, bad_index ());
03216             BOOST_UBLAS_CHECK (j < size2_, bad_index ());
03217             return data_ [i] [j];
03218         }
03219         BOOST_UBLAS_INLINE
03220         reference at_element (size_type i, size_type j) {
03221             BOOST_UBLAS_CHECK (i < size1_, bad_index ());
03222             BOOST_UBLAS_CHECK (j < size2_, bad_index ());
03223             return data_ [i] [j];
03224         }
03225         BOOST_UBLAS_INLINE
03226         reference operator () (size_type i, size_type j) {
03227             return at_element (i, j);
03228         }
03229 
03230         // Element assignment
03231         BOOST_UBLAS_INLINE
03232         reference insert_element (size_type i, size_type j, const_reference t) {
03233             return (at_element (i, j) = t);
03234         }
03235         
03236         // Zeroing
03237         BOOST_UBLAS_INLINE
03238         void clear () {
03239             for (size_type i = 0; i < size1_; ++ i)
03240                 std::fill (data_ [i], data_ [i] + size2_, value_type/*zero*/());
03241         }
03242 
03243         // Assignment
03244         BOOST_UBLAS_INLINE
03245         c_matrix &operator = (const c_matrix &m) {
03246             size1_ = m.size1_;
03247             size2_ = m.size2_;
03248             for (size_type i = 0; i < m.size1_; ++ i)
03249                 std::copy (m.data_ [i], m.data_ [i] + m.size2_, data_ [i]);
03250             return *this;
03251         }
03252         template<class C>          // Container assignment without temporary
03253         BOOST_UBLAS_INLINE
03254         c_matrix &operator = (const matrix_container<C> &m) {
03255             resize (m ().size1 (), m ().size2 (), false);
03256             assign (m);
03257             return *this;
03258         }
03259         BOOST_UBLAS_INLINE
03260         c_matrix &assign_temporary (c_matrix &m) {
03261             swap (m);
03262             return *this;
03263         }
03264         template<class AE>
03265         BOOST_UBLAS_INLINE
03266         c_matrix &operator = (const matrix_expression<AE> &ae) { 
03267             self_type temporary (ae);
03268             return assign_temporary (temporary);
03269         }
03270         template<class AE>
03271         BOOST_UBLAS_INLINE
03272         c_matrix &assign (const matrix_expression<AE> &ae) { 
03273             matrix_assign<scalar_assign> (*this, ae); 
03274             return *this;
03275         }
03276         template<class AE>
03277         BOOST_UBLAS_INLINE
03278         c_matrix& operator += (const matrix_expression<AE> &ae) {
03279             self_type temporary (*this + ae);
03280             return assign_temporary (temporary);
03281         }
03282         template<class C>          // Container assignment without temporary
03283         BOOST_UBLAS_INLINE
03284         c_matrix &operator += (const matrix_container<C> &m) {
03285             plus_assign (m);
03286             return *this;
03287         }
03288         template<class AE>
03289         BOOST_UBLAS_INLINE
03290         c_matrix &plus_assign (const matrix_expression<AE> &ae) { 
03291             matrix_assign<scalar_plus_assign> (*this, ae); 
03292             return *this;
03293         }
03294         template<class AE>
03295         BOOST_UBLAS_INLINE
03296         c_matrix& operator -= (const matrix_expression<AE> &ae) {
03297             self_type temporary (*this - ae);
03298             return assign_temporary (temporary);
03299         }
03300         template<class C>          // Container assignment without temporary
03301         BOOST_UBLAS_INLINE
03302         c_matrix &operator -= (const matrix_container<C> &m) {
03303             minus_assign (m);
03304             return *this;
03305         }
03306         template<class AE>
03307         BOOST_UBLAS_INLINE
03308         c_matrix &minus_assign (const matrix_expression<AE> &ae) { 
03309             matrix_assign<scalar_minus_assign> (*this, ae); 
03310             return *this;
03311         }
03312         template<class AT>
03313         BOOST_UBLAS_INLINE
03314         c_matrix& operator *= (const AT &at) {
03315             matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
03316             return *this;
03317         }
03318         template<class AT>
03319         BOOST_UBLAS_INLINE
03320         c_matrix& operator /= (const AT &at) {
03321             matrix_assign_scalar<scalar_divides_assign> (*this, at);
03322             return *this;
03323         }
03324 
03325         // Swapping
03326         BOOST_UBLAS_INLINE
03327         void swap (c_matrix &m) {
03328             if (this != &m) {
03329                 BOOST_UBLAS_CHECK (size1_ == m.size1_, bad_size ());
03330                 BOOST_UBLAS_CHECK (size2_ == m.size2_, bad_size ());
03331                 std::swap (size1_, m.size1_);
03332                 std::swap (size2_, m.size2_);
03333                 for (size_type i = 0; i < size1_; ++ i)
03334                     std::swap_ranges (data_ [i], data_ [i] + size2_, m.data_ [i]);
03335             }
03336         }
03337         BOOST_UBLAS_INLINE
03338         friend void swap (c_matrix &m1, c_matrix &m2) {
03339             m1.swap (m2);
03340         }
03341 
03342         // Iterator types
03343     private:
03344         // Use pointers for iterator
03345         typedef const_pointer const_subiterator_type;
03346         typedef pointer subiterator_type;
03347 
03348     public:
03349 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
03350         typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
03351         typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
03352         typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
03353         typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
03354 #else
03355         class const_iterator1;
03356         class iterator1;
03357         class const_iterator2;
03358         class iterator2;
03359 #endif
03360         typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
03361         typedef reverse_iterator_base1<iterator1> reverse_iterator1;
03362         typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
03363         typedef reverse_iterator_base2<iterator2> reverse_iterator2;
03364 
03365         // Element lookup
03366         BOOST_UBLAS_INLINE
03367         const_iterator1 find1 (int rank, size_type i, size_type j) const {
03368 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
03369             return const_iterator1 (*this, i, j);
03370 #else
03371             return const_iterator1 (*this, &data_ [i] [j]);
03372 #endif
03373         }
03374         BOOST_UBLAS_INLINE
03375         iterator1 find1 (int rank, size_type i, size_type j) {
03376 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
03377             return iterator1 (*this, i, j);
03378 #else
03379             return iterator1 (*this, &data_ [i] [j]);
03380 #endif
03381         }
03382         BOOST_UBLAS_INLINE
03383         const_iterator2 find2 (int rank, size_type i, size_type j) const {
03384 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
03385             return const_iterator2 (*this, i, j);
03386 #else
03387             return const_iterator2 (*this, &data_ [i] [j]);
03388 #endif
03389         }
03390         BOOST_UBLAS_INLINE
03391         iterator2 find2 (int rank, size_type i, size_type j) {
03392 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
03393             return iterator2 (*this, i, j);
03394 #else
03395             return iterator2 (*this, &data_ [i] [j]);
03396 #endif
03397         }
03398 
03399 
03400 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
03401         class const_iterator1:
03402             public container_const_reference<c_matrix>,
03403             public random_access_iterator_base<dense_random_access_iterator_tag,
03404                                                const_iterator1, value_type> {
03405         public:
03406             typedef typename c_matrix::difference_type difference_type;
03407             typedef typename c_matrix::value_type value_type;
03408             typedef typename c_matrix::const_reference reference;
03409             typedef typename c_matrix::const_pointer pointer;
03410 
03411             typedef const_iterator2 dual_iterator_type;
03412             typedef const_reverse_iterator2 dual_reverse_iterator_type;
03413 
03414             // Construction and destruction
03415             BOOST_UBLAS_INLINE
03416             const_iterator1 ():
03417                 container_const_reference<self_type> (), it_ () {}
03418             BOOST_UBLAS_INLINE
03419             const_iterator1 (const self_type &m, const const_subiterator_type &it):
03420                 container_const_reference<self_type> (m), it_ (it) {}
03421             BOOST_UBLAS_INLINE
03422             const_iterator1 (const iterator1 &it):
03423                 container_const_reference<self_type> (it ()), it_ (it.it_) {}
03424 
03425             // Arithmetic
03426             BOOST_UBLAS_INLINE
03427             const_iterator1 &operator ++ () {
03428                 it_ += M;
03429                 return *this;
03430             }
03431             BOOST_UBLAS_INLINE
03432             const_iterator1 &operator -- () {
03433                 it_ -= M;
03434                 return *this;
03435             }
03436             BOOST_UBLAS_INLINE
03437             const_iterator1 &operator += (difference_type n) {
03438                 it_ += n * M;
03439                 return *this;
03440             }
03441             BOOST_UBLAS_INLINE
03442             const_iterator1 &operator -= (difference_type n) {
03443                 it_ -= n * M;
03444                 return *this;
03445             }
03446             BOOST_UBLAS_INLINE
03447             difference_type operator - (const const_iterator1 &it) const {
03448                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03449                 return (it_ - it.it_) / M;
03450             }
03451 
03452             // Dereference
03453             BOOST_UBLAS_INLINE
03454             const_reference operator * () const {
03455                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
03456                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
03457                 return *it_;
03458             }
03459 
03460 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
03461             BOOST_UBLAS_INLINE
03462 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03463             typename self_type::
03464 #endif
03465             const_iterator2 begin () const {
03466                 const self_type &m = (*this) ();
03467                 return m.find2 (1, index1 (), 0);
03468             }
03469             BOOST_UBLAS_INLINE
03470 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03471             typename self_type::
03472 #endif
03473             const_iterator2 end () const {
03474                 const self_type &m = (*this) ();
03475                 return m.find2 (1, index1 (), m.size2 ());
03476             }
03477             BOOST_UBLAS_INLINE
03478 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03479             typename self_type::
03480 #endif
03481             const_reverse_iterator2 rbegin () const {
03482                 return const_reverse_iterator2 (end ());
03483             }
03484             BOOST_UBLAS_INLINE
03485 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03486             typename self_type::
03487 #endif
03488             const_reverse_iterator2 rend () const {
03489                 return const_reverse_iterator2 (begin ());
03490             }
03491 #endif
03492 
03493             // Indices
03494             BOOST_UBLAS_INLINE
03495             size_type index1 () const {
03496                 const self_type &m = (*this) ();
03497                 return (it_ - m.begin1 ().it_) / M;
03498             }
03499             BOOST_UBLAS_INLINE
03500             size_type index2 () const {
03501                 const self_type &m = (*this) ();
03502                 return (it_ - m.begin1 ().it_) % M;
03503             }
03504 
03505             // Assignment
03506             BOOST_UBLAS_INLINE
03507             const_iterator1 &operator = (const const_iterator1 &it) {
03508                 container_const_reference<self_type>::assign (&it ());
03509                 it_ = it.it_;
03510                 return *this;
03511             }
03512 
03513             // Comparison
03514             BOOST_UBLAS_INLINE
03515             bool operator == (const const_iterator1 &it) const {
03516                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03517                 return it_ == it.it_;
03518             }
03519             BOOST_UBLAS_INLINE
03520             bool operator < (const const_iterator1 &it) const {
03521                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03522                 return it_ < it.it_;
03523             }
03524 
03525         private:
03526             const_subiterator_type it_;
03527 
03528             friend class iterator1;
03529         };
03530 #endif
03531 
03532         BOOST_UBLAS_INLINE
03533         const_iterator1 begin1 () const {
03534             return find1 (0, 0, 0);
03535         }
03536         BOOST_UBLAS_INLINE
03537         const_iterator1 end1 () const {
03538             return find1 (0, size1_, 0);
03539         }
03540 
03541 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
03542         class iterator1:
03543             public container_reference<c_matrix>,
03544             public random_access_iterator_base<dense_random_access_iterator_tag,
03545                                                iterator1, value_type> {
03546         public:
03547 
03548             typedef typename c_matrix::difference_type difference_type;
03549             typedef typename c_matrix::value_type value_type;
03550             typedef typename c_matrix::reference reference;
03551             typedef typename c_matrix::pointer pointer;
03552 
03553             typedef iterator2 dual_iterator_type;
03554             typedef reverse_iterator2 dual_reverse_iterator_type;
03555 
03556             // Construction and destruction
03557             BOOST_UBLAS_INLINE
03558             iterator1 ():
03559                 container_reference<self_type> (), it_ () {}
03560             BOOST_UBLAS_INLINE
03561             iterator1 (self_type &m, const subiterator_type &it):
03562                 container_reference<self_type> (m), it_ (it) {}
03563 
03564             // Arithmetic
03565             BOOST_UBLAS_INLINE
03566             iterator1 &operator ++ () {
03567                 it_ += M;
03568                 return *this;
03569             }
03570             BOOST_UBLAS_INLINE
03571             iterator1 &operator -- () {
03572                 it_ -= M;
03573                 return *this;
03574             }
03575             BOOST_UBLAS_INLINE
03576             iterator1 &operator += (difference_type n) {
03577                 it_ += n * M;
03578                 return *this;
03579             }
03580             BOOST_UBLAS_INLINE
03581             iterator1 &operator -= (difference_type n) {
03582                 it_ -= n * M;
03583                 return *this;
03584             }
03585             BOOST_UBLAS_INLINE
03586             difference_type operator - (const iterator1 &it) const {
03587                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03588                 return (it_ - it.it_) / M;
03589             }
03590 
03591             // Dereference
03592             BOOST_UBLAS_INLINE
03593             reference operator * () const {
03594                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
03595                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
03596                 return *it_;
03597             }
03598 
03599 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
03600             BOOST_UBLAS_INLINE
03601 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03602             typename self_type::
03603 #endif
03604             iterator2 begin () const {
03605                 self_type &m = (*this) ();
03606                 return m.find2 (1, index1 (), 0);
03607             }
03608             BOOST_UBLAS_INLINE
03609 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03610             typename self_type::
03611 #endif
03612             iterator2 end () const {
03613                 self_type &m = (*this) ();
03614                 return m.find2 (1, index1 (), m.size2 ());
03615             }
03616             BOOST_UBLAS_INLINE
03617 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03618             typename self_type::
03619 #endif
03620             reverse_iterator2 rbegin () const {
03621                 return reverse_iterator2 (end ());
03622             }
03623             BOOST_UBLAS_INLINE
03624 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03625             typename self_type::
03626 #endif
03627             reverse_iterator2 rend () const {
03628                 return reverse_iterator2 (begin ());
03629             }
03630 #endif
03631 
03632             // Indices
03633             BOOST_UBLAS_INLINE
03634             size_type index1 () const {
03635                 const self_type &m = (*this) ();
03636                 return (it_ - m.begin1 ().it_) / M;
03637             }
03638             BOOST_UBLAS_INLINE
03639             size_type index2 () const {
03640                 const self_type &m = (*this) ();
03641                 return (it_ - m.begin1 ().it_) % M;
03642             }
03643 
03644             // Assignment
03645             BOOST_UBLAS_INLINE
03646             iterator1 &operator = (const iterator1 &it) {
03647                 container_reference<self_type>::assign (&it ());
03648                 it_ = it.it_;
03649                 return *this;
03650             }
03651 
03652             // Comparison
03653             BOOST_UBLAS_INLINE
03654             bool operator == (const iterator1 &it) const {
03655                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03656                 return it_ == it.it_;
03657             }
03658             BOOST_UBLAS_INLINE
03659             bool operator < (const iterator1 &it) const {
03660                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03661                 return it_ < it.it_;
03662             }
03663 
03664         private:
03665             subiterator_type it_;
03666 
03667             friend class const_iterator1;
03668         };
03669 #endif
03670 
03671         BOOST_UBLAS_INLINE
03672         iterator1 begin1 () {
03673             return find1 (0, 0, 0);
03674         }
03675         BOOST_UBLAS_INLINE
03676         iterator1 end1 () {
03677             return find1 (0, size1_, 0);
03678         }
03679 
03680 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
03681         class const_iterator2:
03682             public container_const_reference<c_matrix>,
03683             public random_access_iterator_base<dense_random_access_iterator_tag,
03684                                                const_iterator2, value_type> {
03685         public:
03686             typedef typename c_matrix::difference_type difference_type;
03687             typedef typename c_matrix::value_type value_type;
03688             typedef typename c_matrix::const_reference reference;
03689             typedef typename c_matrix::const_reference pointer;
03690 
03691             typedef const_iterator1 dual_iterator_type;
03692             typedef const_reverse_iterator1 dual_reverse_iterator_type;
03693 
03694             // Construction and destruction
03695             BOOST_UBLAS_INLINE
03696             const_iterator2 ():
03697                 container_const_reference<self_type> (), it_ () {}
03698             BOOST_UBLAS_INLINE
03699             const_iterator2 (const self_type &m, const const_subiterator_type &it):
03700                 container_const_reference<self_type> (m), it_ (it) {}
03701             BOOST_UBLAS_INLINE
03702             const_iterator2 (const iterator2 &it):
03703                 container_const_reference<self_type> (it ()), it_ (it.it_) {}
03704 
03705             // Arithmetic
03706             BOOST_UBLAS_INLINE
03707             const_iterator2 &operator ++ () {
03708                 ++ it_;
03709                 return *this;
03710             }
03711             BOOST_UBLAS_INLINE
03712             const_iterator2 &operator -- () {
03713                 -- it_;
03714                 return *this;
03715             }
03716             BOOST_UBLAS_INLINE
03717             const_iterator2 &operator += (difference_type n) {
03718                 it_ += n;
03719                 return *this;
03720             }
03721             BOOST_UBLAS_INLINE
03722             const_iterator2 &operator -= (difference_type n) {
03723                 it_ -= n;
03724                 return *this;
03725             }
03726             BOOST_UBLAS_INLINE
03727             difference_type operator - (const const_iterator2 &it) const {
03728                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03729                 return it_ - it.it_;
03730             }
03731 
03732             // Dereference
03733             BOOST_UBLAS_INLINE
03734             const_reference operator * () const {
03735                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
03736                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
03737                 return *it_;
03738             }
03739 
03740 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
03741             BOOST_UBLAS_INLINE
03742 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03743             typename self_type::
03744 #endif
03745             const_iterator1 begin () const {
03746                 const self_type &m = (*this) ();
03747                 return m.find1 (1, 0, index2 ());
03748             }
03749             BOOST_UBLAS_INLINE
03750 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03751             typename self_type::
03752 #endif
03753             const_iterator1 end () const {
03754                 const self_type &m = (*this) ();
03755                 return m.find1 (1, m.size1 (), index2 ());
03756             }
03757             BOOST_UBLAS_INLINE
03758 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03759             typename self_type::
03760 #endif
03761             const_reverse_iterator1 rbegin () const {
03762                 return const_reverse_iterator1 (end ());
03763             }
03764             BOOST_UBLAS_INLINE
03765 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03766             typename self_type::
03767 #endif
03768             const_reverse_iterator1 rend () const {
03769                 return const_reverse_iterator1 (begin ());
03770             }
03771 #endif
03772 
03773             // Indices
03774             BOOST_UBLAS_INLINE
03775             size_type index1 () const {
03776                 const self_type &m = (*this) ();
03777                 return (it_ - m.begin2 ().it_) / M;
03778             }
03779             BOOST_UBLAS_INLINE
03780             size_type index2 () const {
03781                 const self_type &m = (*this) ();
03782                 return (it_ - m.begin2 ().it_) % M;
03783             }
03784 
03785             // Assignment
03786             BOOST_UBLAS_INLINE
03787             const_iterator2 &operator = (const const_iterator2 &it) {
03788                 container_const_reference<self_type>::assign (&it ());
03789                 it_ = it.it_;
03790                 return *this;
03791             }
03792 
03793             // Comparison
03794             BOOST_UBLAS_INLINE
03795             bool operator == (const const_iterator2 &it) const {
03796                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03797                 return it_ == it.it_;
03798             }
03799             BOOST_UBLAS_INLINE
03800             bool operator < (const const_iterator2 &it) const {
03801                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03802                 return it_ < it.it_;
03803             }
03804 
03805         private:
03806             const_subiterator_type it_;
03807 
03808             friend class iterator2;
03809         };
03810 #endif
03811 
03812         BOOST_UBLAS_INLINE
03813         const_iterator2 begin2 () const {
03814             return find2 (0, 0, 0);
03815         }
03816         BOOST_UBLAS_INLINE
03817         const_iterator2 end2 () const {
03818             return find2 (0, 0, size2_);
03819         }
03820 
03821 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
03822         class iterator2:
03823             public container_reference<c_matrix>,
03824             public random_access_iterator_base<dense_random_access_iterator_tag,
03825                                                iterator2, value_type> {
03826         public:
03827             typedef typename c_matrix::difference_type difference_type;
03828             typedef typename c_matrix::value_type value_type;
03829             typedef typename c_matrix::reference reference;
03830             typedef typename c_matrix::pointer pointer;
03831 
03832             typedef iterator1 dual_iterator_type;
03833             typedef reverse_iterator1 dual_reverse_iterator_type;
03834 
03835             // Construction and destruction
03836             BOOST_UBLAS_INLINE
03837             iterator2 ():
03838                 container_reference<self_type> (), it_ () {}
03839             BOOST_UBLAS_INLINE
03840             iterator2 (self_type &m, const subiterator_type &it):
03841                 container_reference<self_type> (m), it_ (it) {}
03842 
03843             // Arithmetic
03844             BOOST_UBLAS_INLINE
03845             iterator2 &operator ++ () {
03846                 ++ it_;
03847                 return *this;
03848             }
03849             BOOST_UBLAS_INLINE
03850             iterator2 &operator -- () {
03851                 -- it_;
03852                 return *this;
03853             }
03854             BOOST_UBLAS_INLINE
03855             iterator2 &operator += (difference_type n) {
03856                 it_ += n;
03857                 return *this;
03858             }
03859             BOOST_UBLAS_INLINE
03860             iterator2 &operator -= (difference_type n) {
03861                 it_ -= n;
03862                 return *this;
03863             }
03864             BOOST_UBLAS_INLINE
03865             difference_type operator - (const iterator2 &it) const {
03866                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03867                 return it_ - it.it_;
03868             }
03869 
03870             // Dereference
03871             BOOST_UBLAS_INLINE
03872             reference operator * () const {
03873                 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
03874                 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
03875                 return *it_;
03876             }
03877 
03878 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
03879             BOOST_UBLAS_INLINE
03880 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03881             typename self_type::
03882 #endif
03883             iterator1 begin () const {
03884                 self_type &m = (*this) ();
03885                 return m.find1 (1, 0, index2 ());
03886             }
03887             BOOST_UBLAS_INLINE
03888 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03889             typename self_type::
03890 #endif
03891             iterator1 end () const {
03892                 self_type &m = (*this) ();
03893                 return m.find1 (1, m.size1 (), index2 ());
03894             }
03895             BOOST_UBLAS_INLINE
03896 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03897             typename self_type::
03898 #endif
03899             reverse_iterator1 rbegin () const {
03900                 return reverse_iterator1 (end ());
03901             }
03902             BOOST_UBLAS_INLINE
03903 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03904             typename self_type::
03905 #endif
03906             reverse_iterator1 rend () const {
03907                 return reverse_iterator1 (begin ());
03908             }
03909 #endif
03910 
03911             // Indices
03912             BOOST_UBLAS_INLINE
03913             size_type index1 () const {
03914                 const self_type &m = (*this) ();
03915                 return (it_ - m.begin2 ().it_) / M;
03916             }
03917             BOOST_UBLAS_INLINE
03918             size_type index2 () const {
03919                 const self_type &m = (*this) ();
03920                 return (it_ - m.begin2 ().it_) % M;
03921             }
03922 
03923             // Assignment
03924             BOOST_UBLAS_INLINE
03925             iterator2 &operator = (const iterator2 &it) {
03926                 container_reference<self_type>::assign (&it ());
03927                 it_ = it.it_;
03928                 return *this;
03929             }
03930 
03931             // Comparison
03932             BOOST_UBLAS_INLINE
03933             bool operator == (const iterator2 &it) const {
03934                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03935                 return it_ == it.it_;
03936             }
03937             BOOST_UBLAS_INLINE
03938             bool operator < (const iterator2 &it) const {
03939                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03940                 return it_ < it.it_;
03941             }
03942 
03943         private:
03944             subiterator_type it_;
03945 
03946             friend class const_iterator2;
03947         };
03948 #endif
03949 
03950         BOOST_UBLAS_INLINE
03951         iterator2 begin2 () {
03952             return find2 (0, 0, 0);
03953         }
03954         BOOST_UBLAS_INLINE
03955         iterator2 end2 () {
03956             return find2 (0, 0, size2_);
03957         }
03958 
03959         // Reverse iterators
03960 
03961         BOOST_UBLAS_INLINE
03962         const_reverse_iterator1 rbegin1 () const {
03963             return const_reverse_iterator1 (end1 ());
03964         }
03965         BOOST_UBLAS_INLINE
03966         const_reverse_iterator1 rend1 () const {
03967             return const_reverse_iterator1 (begin1 ());
03968         }
03969 
03970         BOOST_UBLAS_INLINE
03971         reverse_iterator1 rbegin1 () {
03972             return reverse_iterator1 (end1 ());
03973         }
03974         BOOST_UBLAS_INLINE
03975         reverse_iterator1 rend1 () {
03976             return reverse_iterator1 (begin1 ());
03977         }
03978 
03979         BOOST_UBLAS_INLINE
03980         const_reverse_iterator2 rbegin2 () const {
03981             return const_reverse_iterator2 (end2 ());
03982         }
03983         BOOST_UBLAS_INLINE
03984         const_reverse_iterator2 rend2 () const {
03985             return const_reverse_iterator2 (begin2 ());
03986         }
03987 
03988         BOOST_UBLAS_INLINE
03989         reverse_iterator2 rbegin2 () {
03990             return reverse_iterator2 (end2 ());
03991         }
03992         BOOST_UBLAS_INLINE
03993         reverse_iterator2 rend2 () {
03994             return reverse_iterator2 (begin2 ());
03995         }
03996 
03997         // Serialization
03998         template<class Archive>
03999         void serialize(Archive & ar, const unsigned int /* file_version */){
04000           ar & BOOST_SERIALIZATION_NVP(size1_);
04001           ar & BOOST_SERIALIZATION_NVP(size2_);
04002           for (size_type i=0; i<N; ++i) ar & BOOST_SERIALIZATION_NVP(data_[i]);
04003         }
04004 
04005     private:
04006         size_type size1_;
04007         size_type size2_;
04008         value_type data_ [N] [M];
04009     };
04010 
04011 }}}
04012 
04013 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

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