New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
banded.hpp in vendors/XIOS/current/extern/boost/include/boost/numeric/ublas – NEMO

source: vendors/XIOS/current/extern/boost/include/boost/numeric/ublas/banded.hpp @ 3428

Last change on this file since 3428 was 3428, checked in by rblod, 12 years ago

importing initial XIOS vendor drop

File size: 74.5 KB
Line 
1//
2//  Copyright (c) 2000-2002
3//  Joerg Walter, Mathias Koch
4//
5//  Distributed under the Boost Software License, Version 1.0. (See
6//  accompanying file LICENSE_1_0.txt or copy at
7//  http://www.boost.org/LICENSE_1_0.txt)
8//
9//  The authors gratefully acknowledge the support of
10//  GeNeSys mbH & Co. KG in producing this work.
11//
12
13#ifndef _BOOST_UBLAS_BANDED_
14#define _BOOST_UBLAS_BANDED_
15
16#include <boost/numeric/ublas/matrix.hpp>
17#include <boost/numeric/ublas/detail/temporary.hpp>
18
19// Iterators based on ideas of Jeremy Siek
20
21namespace boost { namespace numeric { namespace ublas {
22
23    /** \brief A banded matrix of values of type \c T.
24     *
25     * For a \f$(mxn)\f$-dimensional banded matrix with \f$l\f$ lower and \f$u\f$ upper diagonals and
26     * \f$0 \leq i < m\f$ and \f$0 \leq j < n\f$, if \f$i>j+l\f$ or \f$i<j-u\f$ then \f$b_{i,j}=0\f$.
27     * The default storage for banded matrices is packed. Orientation and storage can also be specified.
28     * Default is \c row_major and and unbounded_array. It is \b not required by the storage to initialize
29     * elements of the matrix.
30     *
31     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
32     * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
33     * \tparam A the type of Storage array. Default is \c unbounded_array
34     */
35    template<class T, class L, class A>
36    class banded_matrix:
37        public matrix_container<banded_matrix<T, L, A> > {
38
39        typedef T *pointer;
40        typedef L layout_type;
41        typedef banded_matrix<T, L, A> self_type;
42    public:
43#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
44        using matrix_container<self_type>::operator ();
45#endif
46        typedef typename A::size_type size_type;
47        typedef typename A::difference_type difference_type;
48        typedef T value_type;
49        typedef const T &const_reference;
50        typedef T &reference;
51        typedef A array_type;
52        typedef const matrix_reference<const self_type> const_closure_type;
53        typedef matrix_reference<self_type> closure_type;
54        typedef vector<T, A> vector_temporary_type;
55        typedef matrix<T, L, A> matrix_temporary_type;  // general sub-matrix
56        typedef packed_tag storage_category;
57        typedef typename L::orientation_category orientation_category;
58
59        // Construction and destruction
60        BOOST_UBLAS_INLINE
61        banded_matrix ():
62            matrix_container<self_type> (),
63            size1_ (0), size2_ (0),
64            lower_ (0), upper_ (0), data_ (0) {}
65        BOOST_UBLAS_INLINE
66        banded_matrix (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0):
67            matrix_container<self_type> (),
68            size1_ (size1), size2_ (size2),
69            lower_ (lower), upper_ (upper), data_ ((std::max) (size1, size2) * (lower + 1 + upper)) {
70        }
71        BOOST_UBLAS_INLINE
72        banded_matrix (size_type size1, size_type size2, size_type lower, size_type upper, const array_type &data):
73            matrix_container<self_type> (),
74            size1_ (size1), size2_ (size2),
75            lower_ (lower), upper_ (upper), data_ (data) {}
76        BOOST_UBLAS_INLINE
77        banded_matrix (const banded_matrix &m):
78            matrix_container<self_type> (),
79            size1_ (m.size1_), size2_ (m.size2_),
80            lower_ (m.lower_), upper_ (m.upper_), data_ (m.data_) {}
81        template<class AE>
82        BOOST_UBLAS_INLINE
83        banded_matrix (const matrix_expression<AE> &ae, size_type lower = 0, size_type upper = 0):
84            matrix_container<self_type> (),
85            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()),
86            lower_ (lower), upper_ (upper),
87            data_ ((std::max) (size1_, size2_) * (lower_ + 1 + upper_)) {
88            matrix_assign<scalar_assign> (*this, ae);
89        }
90
91        // Accessors
92        BOOST_UBLAS_INLINE
93        size_type size1 () const {
94            return size1_;
95        }
96        BOOST_UBLAS_INLINE
97        size_type size2 () const {
98            return size2_;
99        }
100        BOOST_UBLAS_INLINE
101        size_type lower () const {
102            return lower_;
103        }
104        BOOST_UBLAS_INLINE
105        size_type upper () const {
106            return upper_;
107        }
108
109        // Storage accessors
110        BOOST_UBLAS_INLINE
111        const array_type &data () const {
112            return data_;
113        }
114        BOOST_UBLAS_INLINE
115        array_type &data () {
116            return data_;
117        }
118
119        // Resizing
120        BOOST_UBLAS_INLINE
121        void resize (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0, bool preserve = true) {
122            if (preserve) {
123                self_type temporary (size1, size2, lower, upper);
124                detail::matrix_resize_preserve<layout_type> (*this, temporary);
125            }
126            else {
127                data ().resize ((std::max) (size1, size2) * (lower + 1 + upper));
128                size1_ = size1;
129                size2_ = size2;
130                lower_ = lower;
131                upper_ = upper;
132            }
133        }
134
135        BOOST_UBLAS_INLINE
136        void resize_packed_preserve (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0) {
137            size1_ = size1;
138            size2_ = size2;
139            lower_ = lower;
140            upper_ = upper;
141            data ().resize ((std::max) (size1, size2) * (lower + 1 + upper), value_type ());
142        }
143
144        // Element access
145        BOOST_UBLAS_INLINE
146        const_reference operator () (size_type i, size_type j) const {
147            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
148            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
149#ifdef BOOST_UBLAS_OWN_BANDED
150            const size_type k = (std::max) (i, j);
151            const size_type l = lower_ + j - i;
152            if (k < (std::max) (size1_, size2_) &&
153                l < lower_ + 1 + upper_)
154                return data () [layout_type::element (k, (std::max) (size1_, size2_),
155                                                       l, lower_ + 1 + upper_)];
156#else
157            const size_type k = j;
158            const size_type l = upper_ + i - j;
159            if (k < size2_ &&
160                l < lower_ + 1 + upper_)
161                return data () [layout_type::element (k, size2_,
162                                                       l, lower_ + 1 + upper_)];
163#endif
164            return zero_;
165        }
166        BOOST_UBLAS_INLINE
167        reference at_element (size_type i, size_type j) {
168            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
169            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
170#ifdef BOOST_UBLAS_OWN_BANDED
171            const size_type k = (std::max) (i, j);
172            const size_type l = lower_ + j - i;
173            return data () [layout_type::element (k, (std::max) (size1_, size2_),
174                                                   l, lower_ + 1 + upper_)];
175#else
176            const size_type k = j;
177            const size_type l = upper_ + i - j;
178            return data () [layout_type::element (k, size2_,
179                                                   l, lower_ + 1 + upper_)];
180#endif
181        }
182        BOOST_UBLAS_INLINE
183        reference operator () (size_type i, size_type j) {
184            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
185            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
186#ifdef BOOST_UBLAS_OWN_BANDED
187            const size_type k = (std::max) (i, j);
188            const size_type l = lower_ + j - i;
189            if (! (k < (std::max) (size1_, size2_) &&
190                  l < lower_ + 1 + upper_) ) {
191                bad_index ().raise ();
192                // NEVER reached
193            }
194            return data () [layout_type::element (k, (std::max) (size1_, size2_),
195                                                       l, lower_ + 1 + upper_)];
196#else
197            const size_type k = j;
198            const size_type l = upper_ + i - j;
199            if (! (k < size2_ &&
200                   l < lower_ + 1 + upper_) ) {
201                bad_index ().raise ();
202                // NEVER reached
203            }
204            return data () [layout_type::element (k, size2_,
205                                                       l, lower_ + 1 + upper_)];
206#endif
207        }
208
209        // Element assignment
210        BOOST_UBLAS_INLINE
211        reference insert_element (size_type i, size_type j, const_reference t) {
212            return (operator () (i, j) = t);
213        }
214        BOOST_UBLAS_INLINE
215        void erase_element (size_type i, size_type j) {
216            operator () (i, j) = value_type/*zero*/();
217        }
218
219        // Zeroing
220        BOOST_UBLAS_INLINE
221        void clear () {
222            std::fill (data ().begin (), data ().end (), value_type/*zero*/());
223        }
224
225        // Assignment
226        BOOST_UBLAS_INLINE
227        banded_matrix &operator = (const banded_matrix &m) {
228            size1_ = m.size1_;
229            size2_ = m.size2_;
230            lower_ = m.lower_;
231            upper_ = m.upper_;
232            data () = m.data ();
233            return *this;
234        }
235        BOOST_UBLAS_INLINE
236        banded_matrix &assign_temporary (banded_matrix &m) {
237            swap (m);
238            return *this;
239        }
240        template<class AE>
241        BOOST_UBLAS_INLINE
242        banded_matrix &operator = (const matrix_expression<AE> &ae) {
243            self_type temporary (ae, lower_, upper_);
244            return assign_temporary (temporary);
245        }
246        template<class AE>
247        BOOST_UBLAS_INLINE
248        banded_matrix &assign (const matrix_expression<AE> &ae) {
249            matrix_assign<scalar_assign> (*this, ae);
250            return *this;
251        }
252        template<class AE>
253        BOOST_UBLAS_INLINE
254        banded_matrix& operator += (const matrix_expression<AE> &ae) {
255            self_type temporary (*this + ae, lower_, upper_);
256            return assign_temporary (temporary);
257        }
258        template<class AE>
259        BOOST_UBLAS_INLINE
260        banded_matrix &plus_assign (const matrix_expression<AE> &ae) {
261            matrix_assign<scalar_plus_assign> (*this, ae);
262            return *this;
263        }
264        template<class AE>
265        BOOST_UBLAS_INLINE
266        banded_matrix& operator -= (const matrix_expression<AE> &ae) {
267            self_type temporary (*this - ae, lower_, upper_);
268            return assign_temporary (temporary);
269        }
270        template<class AE>
271        BOOST_UBLAS_INLINE
272        banded_matrix &minus_assign (const matrix_expression<AE> &ae) {
273            matrix_assign<scalar_minus_assign> (*this, ae);
274            return *this;
275        }
276        template<class AT>
277        BOOST_UBLAS_INLINE
278        banded_matrix& operator *= (const AT &at) {
279            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
280            return *this;
281        }
282        template<class AT>
283        BOOST_UBLAS_INLINE
284        banded_matrix& operator /= (const AT &at) {
285            matrix_assign_scalar<scalar_divides_assign> (*this, at);
286            return *this;
287        }
288
289        // Swapping
290        BOOST_UBLAS_INLINE
291        void swap (banded_matrix &m) {
292            if (this != &m) {
293                std::swap (size1_, m.size1_);
294                std::swap (size2_, m.size2_);
295                std::swap (lower_, m.lower_);
296                std::swap (upper_, m.upper_);
297                data ().swap (m.data ());
298            }
299        }
300        BOOST_UBLAS_INLINE
301        friend void swap (banded_matrix &m1, banded_matrix &m2) {
302            m1.swap (m2);
303        }
304
305        // Iterator types
306#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
307        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
308        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
309        typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
310        typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
311#else
312        class const_iterator1;
313        class iterator1;
314        class const_iterator2;
315        class iterator2;
316#endif
317        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
318        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
319        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
320        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
321
322        // Element lookup
323        BOOST_UBLAS_INLINE
324        const_iterator1 find1 (int rank, size_type i, size_type j) const {
325            if (rank == 1) {
326                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
327                i = (std::max) (i, lower_i);
328                size_type upper_i = (std::min) (j + 1 + lower_, size1_);
329                i = (std::min) (i, upper_i);
330            }
331            return const_iterator1 (*this, i, j);
332        }
333        BOOST_UBLAS_INLINE
334        iterator1 find1 (int rank, size_type i, size_type j) {
335            if (rank == 1) {
336                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
337                i = (std::max) (i, lower_i);
338                size_type upper_i = (std::min) (j + 1 + lower_, size1_);
339                i = (std::min) (i, upper_i);
340            }
341            return iterator1 (*this, i, j);
342        }
343        BOOST_UBLAS_INLINE
344        const_iterator2 find2 (int rank, size_type i, size_type j) const {
345            if (rank == 1) {
346                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
347                j = (std::max) (j, lower_j);
348                size_type upper_j = (std::min) (i + 1 + upper_, size2_);
349                j = (std::min) (j, upper_j);
350            }
351            return const_iterator2 (*this, i, j);
352        }
353        BOOST_UBLAS_INLINE
354        iterator2 find2 (int rank, size_type i, size_type j) {
355            if (rank == 1) {
356                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
357                j = (std::max) (j, lower_j);
358                size_type upper_j = (std::min) (i + 1 + upper_, size2_);
359                j = (std::min) (j, upper_j);
360            }
361            return iterator2 (*this, i, j);
362        }
363
364        // Iterators simply are indices.
365
366#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
367        class const_iterator1:
368            public container_const_reference<banded_matrix>,
369            public random_access_iterator_base<packed_random_access_iterator_tag,
370                                               const_iterator1, value_type> {
371        public:
372            typedef typename banded_matrix::value_type value_type;
373            typedef typename banded_matrix::difference_type difference_type;
374            typedef typename banded_matrix::const_reference reference;
375            typedef const typename banded_matrix::pointer pointer;
376
377            typedef const_iterator2 dual_iterator_type;
378            typedef const_reverse_iterator2 dual_reverse_iterator_type;
379
380            // Construction and destruction
381            BOOST_UBLAS_INLINE
382            const_iterator1 ():
383                container_const_reference<self_type> (), it1_ (), it2_ () {}
384            BOOST_UBLAS_INLINE
385            const_iterator1 (const self_type &m, size_type it1, size_type it2):
386                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
387            BOOST_UBLAS_INLINE
388            const_iterator1 (const iterator1 &it):
389                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
390
391            // Arithmetic
392            BOOST_UBLAS_INLINE
393            const_iterator1 &operator ++ () {
394                ++ it1_;
395                return *this;
396            }
397            BOOST_UBLAS_INLINE
398            const_iterator1 &operator -- () {
399                -- it1_;
400                return *this;
401            }
402            BOOST_UBLAS_INLINE
403            const_iterator1 &operator += (difference_type n) {
404                it1_ += n;
405                return *this;
406            }
407            BOOST_UBLAS_INLINE
408            const_iterator1 &operator -= (difference_type n) {
409                it1_ -= n;
410                return *this;
411            }
412            BOOST_UBLAS_INLINE
413            difference_type operator - (const const_iterator1 &it) const {
414                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
415                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
416                return it1_ - it.it1_;
417            }
418
419            // Dereference
420            BOOST_UBLAS_INLINE
421            const_reference operator * () const {
422                return (*this) () (it1_, it2_);
423            }
424            BOOST_UBLAS_INLINE
425            const_reference operator [] (difference_type n) const {
426                return *(*this + n);
427            }
428
429#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
430            BOOST_UBLAS_INLINE
431#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
432            typename self_type::
433#endif
434            const_iterator2 begin () const {
435                return (*this) ().find2 (1, it1_, 0);
436            }
437            BOOST_UBLAS_INLINE
438#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
439            typename self_type::
440#endif
441            const_iterator2 end () const {
442                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
443            }
444            BOOST_UBLAS_INLINE
445#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
446            typename self_type::
447#endif
448            const_reverse_iterator2 rbegin () const {
449                return const_reverse_iterator2 (end ());
450            }
451            BOOST_UBLAS_INLINE
452#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
453            typename self_type::
454#endif
455            const_reverse_iterator2 rend () const {
456                return const_reverse_iterator2 (begin ());
457            }
458#endif
459
460            // Indices
461            BOOST_UBLAS_INLINE
462            size_type index1 () const {
463                return it1_;
464            }
465            BOOST_UBLAS_INLINE
466            size_type index2 () const {
467                return it2_;
468            }
469
470            // Assignment
471            BOOST_UBLAS_INLINE
472            const_iterator1 &operator = (const const_iterator1 &it) {
473                container_const_reference<self_type>::assign (&it ());
474                it1_ = it.it1_;
475                it2_ = it.it2_;
476                return *this;
477            }
478
479            // Comparison
480            BOOST_UBLAS_INLINE
481            bool operator == (const const_iterator1 &it) const {
482                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
483                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
484                return it1_ == it.it1_;
485            }
486            BOOST_UBLAS_INLINE
487            bool operator < (const const_iterator1 &it) const {
488                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
489                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
490                return it1_ < it.it1_;
491            }
492
493        private:
494            size_type it1_;
495            size_type it2_;
496        };
497#endif
498
499        BOOST_UBLAS_INLINE
500        const_iterator1 begin1 () const {
501            return find1 (0, 0, 0);
502        }
503        BOOST_UBLAS_INLINE
504        const_iterator1 end1 () const {
505            return find1 (0, size1_, 0);
506        }
507
508#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
509        class iterator1:
510            public container_reference<banded_matrix>,
511            public random_access_iterator_base<packed_random_access_iterator_tag,
512                                               iterator1, value_type> {
513        public:
514            typedef typename banded_matrix::value_type value_type;
515            typedef typename banded_matrix::difference_type difference_type;
516            typedef typename banded_matrix::reference reference;
517            typedef typename banded_matrix::pointer pointer;
518
519            typedef iterator2 dual_iterator_type;
520            typedef reverse_iterator2 dual_reverse_iterator_type;
521
522            // Construction and destruction
523            BOOST_UBLAS_INLINE
524            iterator1 ():
525                container_reference<self_type> (), it1_ (), it2_ () {}
526            BOOST_UBLAS_INLINE
527            iterator1 (self_type &m, size_type it1, size_type it2):
528                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
529
530            // Arithmetic
531            BOOST_UBLAS_INLINE
532            iterator1 &operator ++ () {
533                ++ it1_;
534                return *this;
535            }
536            BOOST_UBLAS_INLINE
537            iterator1 &operator -- () {
538                -- it1_;
539                return *this;
540            }
541            BOOST_UBLAS_INLINE
542            iterator1 &operator += (difference_type n) {
543                it1_ += n;
544                return *this;
545            }
546            BOOST_UBLAS_INLINE
547            iterator1 &operator -= (difference_type n) {
548                it1_ -= n;
549                return *this;
550            }
551            BOOST_UBLAS_INLINE
552            difference_type operator - (const iterator1 &it) const {
553                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
554                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
555                return it1_ - it.it1_;
556            }
557
558            // Dereference
559            BOOST_UBLAS_INLINE
560            reference operator * () const {
561                return (*this) ().at_element (it1_, it2_);
562            }
563            BOOST_UBLAS_INLINE
564            reference operator [] (difference_type n) const {
565                return *(*this + n);
566            }
567
568#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
569            BOOST_UBLAS_INLINE
570#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
571            typename self_type::
572#endif
573            iterator2 begin () const {
574                return (*this) ().find2 (1, it1_, 0);
575            }
576            BOOST_UBLAS_INLINE
577#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
578            typename self_type::
579#endif
580            iterator2 end () const {
581                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
582            }
583            BOOST_UBLAS_INLINE
584#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
585            typename self_type::
586#endif
587            reverse_iterator2 rbegin () const {
588                return reverse_iterator2 (end ());
589            }
590            BOOST_UBLAS_INLINE
591#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
592            typename self_type::
593#endif
594            reverse_iterator2 rend () const {
595                return reverse_iterator2 (begin ());
596            }
597#endif
598
599            // Indices
600            BOOST_UBLAS_INLINE
601            size_type index1 () const {
602                return it1_;
603            }
604            BOOST_UBLAS_INLINE
605            size_type index2 () const {
606                return it2_;
607            }
608
609            // Assignment
610            BOOST_UBLAS_INLINE
611            iterator1 &operator = (const iterator1 &it) {
612                container_reference<self_type>::assign (&it ());
613                it1_ = it.it1_;
614                it2_ = it.it2_;
615                return *this;
616            }
617
618            // Comparison
619            BOOST_UBLAS_INLINE
620            bool operator == (const iterator1 &it) const {
621                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
622                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
623                return it1_ == it.it1_;
624            }
625            BOOST_UBLAS_INLINE
626            bool operator < (const iterator1 &it) const {
627                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
628                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
629                return it1_ < it.it1_;
630            }
631
632        private:
633            size_type it1_;
634            size_type it2_;
635
636            friend class const_iterator1;
637        };
638#endif
639
640        BOOST_UBLAS_INLINE
641        iterator1 begin1 () {
642            return find1 (0, 0, 0);
643        }
644        BOOST_UBLAS_INLINE
645        iterator1 end1 () {
646            return find1 (0, size1_, 0);
647        }
648
649#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
650        class const_iterator2:
651            public container_const_reference<banded_matrix>,
652            public random_access_iterator_base<packed_random_access_iterator_tag,
653                                               const_iterator2, value_type> {
654        public:
655            typedef typename banded_matrix::value_type value_type;
656            typedef typename banded_matrix::difference_type difference_type;
657            typedef typename banded_matrix::const_reference reference;
658            typedef const typename banded_matrix::pointer pointer;
659
660            typedef const_iterator1 dual_iterator_type;
661            typedef const_reverse_iterator1 dual_reverse_iterator_type;
662
663            // Construction and destruction
664            BOOST_UBLAS_INLINE
665            const_iterator2 ():
666                container_const_reference<self_type> (), it1_ (), it2_ () {}
667            BOOST_UBLAS_INLINE
668            const_iterator2 (const self_type &m, size_type it1, size_type it2):
669                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
670            BOOST_UBLAS_INLINE
671            const_iterator2 (const iterator2 &it):
672                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
673
674            // Arithmetic
675            BOOST_UBLAS_INLINE
676            const_iterator2 &operator ++ () {
677                ++ it2_;
678                return *this;
679            }
680            BOOST_UBLAS_INLINE
681            const_iterator2 &operator -- () {
682                -- it2_;
683                return *this;
684            }
685            BOOST_UBLAS_INLINE
686            const_iterator2 &operator += (difference_type n) {
687                it2_ += n;
688                return *this;
689            }
690            BOOST_UBLAS_INLINE
691            const_iterator2 &operator -= (difference_type n) {
692                it2_ -= n;
693                return *this;
694            }
695            BOOST_UBLAS_INLINE
696            difference_type operator - (const const_iterator2 &it) const {
697                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
698                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
699                return it2_ - it.it2_;
700            }
701
702            // Dereference
703            BOOST_UBLAS_INLINE
704            const_reference operator * () const {
705                return (*this) () (it1_, it2_);
706            }
707            BOOST_UBLAS_INLINE
708            const_reference operator [] (difference_type n) const {
709                return *(*this + n);
710            }
711
712#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
713            BOOST_UBLAS_INLINE
714#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
715            typename self_type::
716#endif
717            const_iterator1 begin () const {
718                return (*this) ().find1 (1, 0, it2_);
719            }
720            BOOST_UBLAS_INLINE
721#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
722            typename self_type::
723#endif
724            const_iterator1 end () const {
725                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
726            }
727            BOOST_UBLAS_INLINE
728#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
729            typename self_type::
730#endif
731            const_reverse_iterator1 rbegin () const {
732                return const_reverse_iterator1 (end ());
733            }
734            BOOST_UBLAS_INLINE
735#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
736            typename self_type::
737#endif
738            const_reverse_iterator1 rend () const {
739                return const_reverse_iterator1 (begin ());
740            }
741#endif
742
743            // Indices
744            BOOST_UBLAS_INLINE
745            size_type index1 () const {
746                return it1_;
747            }
748            BOOST_UBLAS_INLINE
749            size_type index2 () const {
750                return it2_;
751            }
752
753            // Assignment
754            BOOST_UBLAS_INLINE
755            const_iterator2 &operator = (const const_iterator2 &it) {
756                container_const_reference<self_type>::assign (&it ());
757                it1_ = it.it1_;
758                it2_ = it.it2_;
759                return *this;
760            }
761
762            // Comparison
763            BOOST_UBLAS_INLINE
764            bool operator == (const const_iterator2 &it) const {
765                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
766                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
767                return it2_ == it.it2_;
768            }
769            BOOST_UBLAS_INLINE
770            bool operator < (const const_iterator2 &it) const {
771                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
772                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
773                return it2_ < it.it2_;
774            }
775
776        private:
777            size_type it1_;
778            size_type it2_;
779        };
780#endif
781
782        BOOST_UBLAS_INLINE
783        const_iterator2 begin2 () const {
784            return find2 (0, 0, 0);
785        }
786        BOOST_UBLAS_INLINE
787        const_iterator2 end2 () const {
788            return find2 (0, 0, size2_);
789        }
790
791#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
792        class iterator2:
793            public container_reference<banded_matrix>,
794            public random_access_iterator_base<packed_random_access_iterator_tag,
795                                               iterator2, value_type> {
796        public:
797            typedef typename banded_matrix::value_type value_type;
798            typedef typename banded_matrix::difference_type difference_type;
799            typedef typename banded_matrix::reference reference;
800            typedef typename banded_matrix::pointer pointer;
801
802            typedef iterator1 dual_iterator_type;
803            typedef reverse_iterator1 dual_reverse_iterator_type;
804
805            // Construction and destruction
806            BOOST_UBLAS_INLINE
807            iterator2 ():
808                container_reference<self_type> (), it1_ (), it2_ () {}
809            BOOST_UBLAS_INLINE
810            iterator2 (self_type &m, size_type it1, size_type it2):
811                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
812
813            // Arithmetic
814            BOOST_UBLAS_INLINE
815            iterator2 &operator ++ () {
816                ++ it2_;
817                return *this;
818            }
819            BOOST_UBLAS_INLINE
820            iterator2 &operator -- () {
821                -- it2_;
822                return *this;
823            }
824            BOOST_UBLAS_INLINE
825            iterator2 &operator += (difference_type n) {
826                it2_ += n;
827                return *this;
828            }
829            BOOST_UBLAS_INLINE
830            iterator2 &operator -= (difference_type n) {
831                it2_ -= n;
832                return *this;
833            }
834            BOOST_UBLAS_INLINE
835            difference_type operator - (const iterator2 &it) const {
836                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
837                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
838                return it2_ - it.it2_;
839            }
840
841            // Dereference
842            BOOST_UBLAS_INLINE
843            reference operator * () const {
844                return (*this) ().at_element (it1_, it2_);
845            }
846            BOOST_UBLAS_INLINE
847            reference operator [] (difference_type n) const {
848                return *(*this + n);
849            }
850
851#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
852            BOOST_UBLAS_INLINE
853#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
854            typename self_type::
855#endif
856            iterator1 begin () const {
857                return (*this) ().find1 (1, 0, it2_);
858            }
859            BOOST_UBLAS_INLINE
860#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
861            typename self_type::
862#endif
863            iterator1 end () const {
864                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
865            }
866            BOOST_UBLAS_INLINE
867#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
868            typename self_type::
869#endif
870            reverse_iterator1 rbegin () const {
871                return reverse_iterator1 (end ());
872            }
873            BOOST_UBLAS_INLINE
874#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
875            typename self_type::
876#endif
877            reverse_iterator1 rend () const {
878                return reverse_iterator1 (begin ());
879            }
880#endif
881
882            // Indices
883            BOOST_UBLAS_INLINE
884            size_type index1 () const {
885                return it1_;
886            }
887            BOOST_UBLAS_INLINE
888            size_type index2 () const {
889                return it2_;
890            }
891
892            // Assignment
893            BOOST_UBLAS_INLINE
894            iterator2 &operator = (const iterator2 &it) {
895                container_reference<self_type>::assign (&it ());
896                it1_ = it.it1_;
897                it2_ = it.it2_;
898                return *this;
899            }
900
901            // Comparison
902            BOOST_UBLAS_INLINE
903            bool operator == (const iterator2 &it) const {
904                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
905                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
906                return it2_ == it.it2_;
907            }
908            BOOST_UBLAS_INLINE
909            bool operator < (const iterator2 &it) const {
910                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
911                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
912                return it2_ < it.it2_;
913            }
914
915        private:
916            size_type it1_;
917            size_type it2_;
918
919            friend class const_iterator2;
920        };
921#endif
922
923        BOOST_UBLAS_INLINE
924        iterator2 begin2 () {
925            return find2 (0, 0, 0);
926        }
927        BOOST_UBLAS_INLINE
928        iterator2 end2 () {
929            return find2 (0, 0, size2_);
930        }
931
932        // Reverse iterators
933
934        BOOST_UBLAS_INLINE
935        const_reverse_iterator1 rbegin1 () const {
936            return const_reverse_iterator1 (end1 ());
937        }
938        BOOST_UBLAS_INLINE
939        const_reverse_iterator1 rend1 () const {
940            return const_reverse_iterator1 (begin1 ());
941        }
942
943        BOOST_UBLAS_INLINE
944        reverse_iterator1 rbegin1 () {
945            return reverse_iterator1 (end1 ());
946        }
947        BOOST_UBLAS_INLINE
948        reverse_iterator1 rend1 () {
949            return reverse_iterator1 (begin1 ());
950        }
951
952        BOOST_UBLAS_INLINE
953        const_reverse_iterator2 rbegin2 () const {
954            return const_reverse_iterator2 (end2 ());
955        }
956        BOOST_UBLAS_INLINE
957        const_reverse_iterator2 rend2 () const {
958            return const_reverse_iterator2 (begin2 ());
959        }
960
961        BOOST_UBLAS_INLINE
962        reverse_iterator2 rbegin2 () {
963            return reverse_iterator2 (end2 ());
964        }
965        BOOST_UBLAS_INLINE
966        reverse_iterator2 rend2 () {
967            return reverse_iterator2 (begin2 ());
968        }
969
970    private:
971        size_type size1_;
972        size_type size2_;
973        size_type lower_;
974        size_type upper_;
975        array_type data_;
976        typedef const value_type const_value_type;
977        static const_value_type zero_;
978    };
979
980    template<class T, class L, class A>
981    typename banded_matrix<T, L, A>::const_value_type banded_matrix<T, L, A>::zero_ = value_type/*zero*/();
982
983
984    /** \brief A diagonal matrix of values of type \c T, which is a specialization of a banded matrix
985     *
986     * For a \f$(m\times m)\f$-dimensional diagonal matrix, \f$0 \leq i < m\f$ and \f$0 \leq j < m\f$,
987     * if \f$i\neq j\f$ then \f$b_{i,j}=0\f$. The default storage for diagonal matrices is packed.
988     * Orientation and storage can also be specified. Default is \c row major \c unbounded_array.
989     *
990     * As a specialization of a banded matrix, the constructor of the diagonal matrix creates
991     * a banded matrix with 0 upper and lower diagonals around the main diagonal and the matrix is
992     * obviously a square matrix. Operations are optimized based on these 2 assumptions. It is
993     * \b not required by the storage to initialize elements of the matrix. 
994     *
995     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
996     * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
997     * \tparam A the type of Storage array. Default is \c unbounded_array
998     */
999    template<class T, class L, class A>
1000    class diagonal_matrix:
1001        public banded_matrix<T, L, A> {
1002    public:
1003        typedef typename A::size_type size_type;
1004        typedef banded_matrix<T, L, A> matrix_type;
1005        typedef A array_type;
1006
1007        // Construction and destruction
1008        BOOST_UBLAS_INLINE
1009        diagonal_matrix ():
1010            matrix_type () {}
1011        BOOST_UBLAS_INLINE
1012        diagonal_matrix (size_type size):
1013            matrix_type (size, size) {}
1014        BOOST_UBLAS_INLINE
1015        diagonal_matrix (size_type size, const array_type& data):
1016            matrix_type (size, size, 0, 0, data) {}
1017        BOOST_UBLAS_INLINE
1018        diagonal_matrix (size_type size1, size_type size2):
1019            matrix_type (size1, size2) {}
1020        template<class AE>
1021        BOOST_UBLAS_INLINE
1022        diagonal_matrix (const matrix_expression<AE> &ae):
1023            matrix_type (ae) {}
1024        BOOST_UBLAS_INLINE
1025        ~diagonal_matrix () {}
1026
1027        // Assignment
1028        BOOST_UBLAS_INLINE
1029        diagonal_matrix &operator = (const diagonal_matrix &m) {
1030            matrix_type::operator = (m);
1031            return *this;
1032        }
1033        template<class AE>
1034        BOOST_UBLAS_INLINE
1035        diagonal_matrix &operator = (const matrix_expression<AE> &ae) {
1036            matrix_type::operator = (ae);
1037            return *this;
1038        }
1039    };
1040
1041    /** \brief A banded matrix adaptator: convert a any matrix into a banded matrix expression
1042     *
1043     * For a \f$(m\times n)\f$-dimensional matrix, the \c banded_adaptor will provide a banded matrix
1044     * with \f$l\f$ lower and \f$u\f$ upper diagonals and \f$0 \leq i < m\f$ and \f$0 \leq j < n\f$,
1045     * if \f$i>j+l\f$ or \f$i<j-u\f$ then \f$b_{i,j}=0\f$.
1046     *
1047     * Storage and location are based on those of the underlying matrix. This is important because
1048     * a \c banded_adaptor does not copy the matrix data to a new place. Therefore, modifying values
1049     * in a \c banded_adaptor matrix will also modify the underlying matrix too.
1050     *
1051     * \tparam M the type of matrix used to generate a banded matrix
1052     */
1053    template<class M>
1054    class banded_adaptor:
1055        public matrix_expression<banded_adaptor<M> > {
1056
1057        typedef banded_adaptor<M> self_type;
1058    public:
1059#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1060        using matrix_expression<self_type>::operator ();
1061#endif
1062        typedef const M const_matrix_type;
1063        typedef M matrix_type;
1064        typedef typename M::size_type size_type;
1065        typedef typename M::difference_type difference_type;
1066        typedef typename M::value_type value_type;
1067        typedef typename M::const_reference const_reference;
1068        typedef typename boost::mpl::if_<boost::is_const<M>,
1069                                          typename M::const_reference,
1070                                          typename M::reference>::type reference;
1071        typedef typename boost::mpl::if_<boost::is_const<M>,
1072                                          typename M::const_closure_type,
1073                                          typename M::closure_type>::type matrix_closure_type;
1074        typedef const self_type const_closure_type;
1075        typedef self_type closure_type;
1076        // Replaced by _temporary_traits to avoid type requirements on M
1077        //typedef typename M::vector_temporary_type vector_temporary_type;
1078        //typedef typename M::matrix_temporary_type matrix_temporary_type;
1079        typedef typename storage_restrict_traits<typename M::storage_category,
1080                                                 packed_proxy_tag>::storage_category storage_category;
1081        typedef typename M::orientation_category orientation_category;
1082
1083        // Construction and destruction
1084        BOOST_UBLAS_INLINE
1085        banded_adaptor (matrix_type &data, size_type lower = 0, size_type upper = 0):
1086            matrix_expression<self_type> (),
1087            data_ (data), lower_ (lower), upper_ (upper) {}
1088        BOOST_UBLAS_INLINE
1089        banded_adaptor (const banded_adaptor &m):
1090            matrix_expression<self_type> (),
1091            data_ (m.data_), lower_ (m.lower_), upper_ (m.upper_) {}
1092
1093        // Accessors
1094        BOOST_UBLAS_INLINE
1095        size_type size1 () const {
1096            return data_.size1 ();
1097        }
1098        BOOST_UBLAS_INLINE
1099        size_type size2 () const {
1100            return data_.size2 ();
1101        }
1102        BOOST_UBLAS_INLINE
1103        size_type lower () const {
1104            return lower_;
1105        }
1106        BOOST_UBLAS_INLINE
1107        size_type upper () const {
1108            return upper_;
1109        }
1110
1111        // Storage accessors
1112        BOOST_UBLAS_INLINE
1113        const matrix_closure_type &data () const {
1114            return data_;
1115        }
1116        BOOST_UBLAS_INLINE
1117        matrix_closure_type &data () {
1118            return data_;
1119        }
1120
1121        // Element access
1122#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
1123        BOOST_UBLAS_INLINE
1124        const_reference operator () (size_type i, size_type j) const {
1125            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1126            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1127#ifdef BOOST_UBLAS_OWN_BANDED
1128            size_type k = (std::max) (i, j);
1129            size_type l = lower_ + j - i;
1130            if (k < (std::max) (size1 (), size2 ()) &&
1131                l < lower_ + 1 + upper_)
1132                return data () (i, j);
1133#else
1134            size_type k = j;
1135            size_type l = upper_ + i - j;
1136            if (k < size2 () &&
1137                l < lower_ + 1 + upper_)
1138                return data () (i, j);
1139#endif
1140            return zero_;
1141        }
1142        BOOST_UBLAS_INLINE
1143        reference operator () (size_type i, size_type j) {
1144            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1145            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1146#ifdef BOOST_UBLAS_OWN_BANDED
1147            size_type k = (std::max) (i, j);
1148            size_type l = lower_ + j - i;
1149            if (k < (std::max) (size1 (), size2 ()) &&
1150                l < lower_ + 1 + upper_)
1151                return data () (i, j);
1152#else
1153            size_type k = j;
1154            size_type l = upper_ + i - j;
1155            if (k < size2 () &&
1156                l < lower_ + 1 + upper_)
1157                return data () (i, j);
1158#endif
1159#ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
1160            bad_index ().raise ();
1161#endif
1162            return const_cast<reference>(zero_);
1163        }
1164#else
1165        BOOST_UBLAS_INLINE
1166        reference operator () (size_type i, size_type j) const {
1167            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1168            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1169#ifdef BOOST_UBLAS_OWN_BANDED
1170            size_type k = (std::max) (i, j);
1171            size_type l = lower_ + j - i;
1172            if (k < (std::max) (size1 (), size2 ()) &&
1173                l < lower_ + 1 + upper_)
1174                return data () (i, j);
1175#else
1176            size_type k = j;
1177            size_type l = upper_ + i - j;
1178            if (k < size2 () &&
1179                l < lower_ + 1 + upper_)
1180                return data () (i, j);
1181#endif
1182#ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
1183            bad_index ().raise ();
1184#endif
1185            return const_cast<reference>(zero_);
1186        }
1187#endif
1188
1189        // Assignment
1190        BOOST_UBLAS_INLINE
1191        banded_adaptor &operator = (const banded_adaptor &m) {
1192            matrix_assign<scalar_assign> (*this, m);
1193            return *this;
1194        }
1195        BOOST_UBLAS_INLINE
1196        banded_adaptor &assign_temporary (banded_adaptor &m) {
1197            *this = m;
1198            return *this;
1199        }
1200        template<class AE>
1201        BOOST_UBLAS_INLINE
1202        banded_adaptor &operator = (const matrix_expression<AE> &ae) {
1203            matrix_assign<scalar_assign> (*this, matrix<value_type> (ae));
1204            return *this;
1205        }
1206        template<class AE>
1207        BOOST_UBLAS_INLINE
1208        banded_adaptor &assign (const matrix_expression<AE> &ae) {
1209            matrix_assign<scalar_assign> (*this, ae);
1210            return *this;
1211        }
1212        template<class AE>
1213        BOOST_UBLAS_INLINE
1214        banded_adaptor& operator += (const matrix_expression<AE> &ae) {
1215            matrix_assign<scalar_assign> (*this, matrix<value_type> (*this + ae));
1216            return *this;
1217        }
1218        template<class AE>
1219        BOOST_UBLAS_INLINE
1220        banded_adaptor &plus_assign (const matrix_expression<AE> &ae) {
1221            matrix_assign<scalar_plus_assign> (*this, ae);
1222            return *this;
1223        }
1224        template<class AE>
1225        BOOST_UBLAS_INLINE
1226        banded_adaptor& operator -= (const matrix_expression<AE> &ae) {
1227            matrix_assign<scalar_assign> (*this, matrix<value_type> (*this - ae));
1228            return *this;
1229        }
1230        template<class AE>
1231        BOOST_UBLAS_INLINE
1232        banded_adaptor &minus_assign (const matrix_expression<AE> &ae) {
1233            matrix_assign<scalar_minus_assign> (*this, ae);
1234            return *this;
1235        }
1236        template<class AT>
1237        BOOST_UBLAS_INLINE
1238        banded_adaptor& operator *= (const AT &at) {
1239            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
1240            return *this;
1241        }
1242        template<class AT>
1243        BOOST_UBLAS_INLINE
1244        banded_adaptor& operator /= (const AT &at) {
1245            matrix_assign_scalar<scalar_divides_assign> (*this, at);
1246            return *this;
1247        }
1248
1249        // Closure comparison
1250        BOOST_UBLAS_INLINE
1251        bool same_closure (const banded_adaptor &ba) const {
1252            return (*this).data ().same_closure (ba.data ());
1253        }
1254
1255        // Swapping
1256        BOOST_UBLAS_INLINE
1257        void swap (banded_adaptor &m) {
1258            if (this != &m) {
1259                BOOST_UBLAS_CHECK (lower_ == m.lower_, bad_size ());
1260                BOOST_UBLAS_CHECK (upper_ == m.upper_, bad_size ());
1261                matrix_swap<scalar_swap> (*this, m);
1262            }
1263        }
1264        BOOST_UBLAS_INLINE
1265        friend void swap (banded_adaptor &m1, banded_adaptor &m2) {
1266            m1.swap (m2);
1267        }
1268
1269        // Iterator types
1270    private:
1271        // Use the matrix iterator
1272        typedef typename M::const_iterator1 const_subiterator1_type;
1273        typedef typename boost::mpl::if_<boost::is_const<M>,
1274                                          typename M::const_iterator1,
1275                                          typename M::iterator1>::type subiterator1_type;
1276        typedef typename M::const_iterator2 const_subiterator2_type;
1277        typedef typename boost::mpl::if_<boost::is_const<M>,
1278                                          typename M::const_iterator2,
1279                                          typename M::iterator2>::type subiterator2_type;
1280
1281    public:
1282#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1283        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
1284        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
1285        typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
1286        typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
1287#else
1288        class const_iterator1;
1289        class iterator1;
1290        class const_iterator2;
1291        class iterator2;
1292#endif
1293        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
1294        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
1295        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
1296        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
1297
1298        // Element lookup
1299        BOOST_UBLAS_INLINE
1300        const_iterator1 find1 (int rank, size_type i, size_type j) const {
1301            if (rank == 1) {
1302                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
1303                i = (std::max) (i, lower_i);
1304                size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
1305                i = (std::min) (i, upper_i);
1306            }
1307            return const_iterator1 (*this, data ().find1 (rank, i, j));
1308        }
1309        BOOST_UBLAS_INLINE
1310        iterator1 find1 (int rank, size_type i, size_type j) {
1311            if (rank == 1) {
1312                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
1313                i = (std::max) (i, lower_i);
1314                size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
1315                i = (std::min) (i, upper_i);
1316            }
1317            return iterator1 (*this, data ().find1 (rank, i, j));
1318        }
1319        BOOST_UBLAS_INLINE
1320        const_iterator2 find2 (int rank, size_type i, size_type j) const {
1321            if (rank == 1) {
1322                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
1323                j = (std::max) (j, lower_j);
1324                size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
1325                j = (std::min) (j, upper_j);
1326            }
1327            return const_iterator2 (*this, data ().find2 (rank, i, j));
1328        }
1329        BOOST_UBLAS_INLINE
1330        iterator2 find2 (int rank, size_type i, size_type j) {
1331            if (rank == 1) {
1332                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
1333                j = (std::max) (j, lower_j);
1334                size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
1335                j = (std::min) (j, upper_j);
1336            }
1337            return iterator2 (*this, data ().find2 (rank, i, j));
1338        }
1339
1340        // Iterators simply are indices.
1341
1342#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1343        class const_iterator1:
1344            public container_const_reference<banded_adaptor>,
1345            public random_access_iterator_base<typename iterator_restrict_traits<
1346                                                   typename const_subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
1347                                               const_iterator1, value_type> {
1348        public:
1349            typedef typename const_subiterator1_type::value_type value_type;
1350            typedef typename const_subiterator1_type::difference_type difference_type;
1351            typedef typename const_subiterator1_type::reference reference;
1352            typedef typename const_subiterator1_type::pointer pointer;
1353
1354            typedef const_iterator2 dual_iterator_type;
1355            typedef const_reverse_iterator2 dual_reverse_iterator_type;
1356
1357            // Construction and destruction
1358            BOOST_UBLAS_INLINE
1359            const_iterator1 ():
1360                container_const_reference<self_type> (), it1_ () {}
1361            BOOST_UBLAS_INLINE
1362            const_iterator1 (const self_type &m, const const_subiterator1_type &it1):
1363                container_const_reference<self_type> (m), it1_ (it1) {}
1364            BOOST_UBLAS_INLINE
1365            const_iterator1 (const iterator1 &it):
1366                container_const_reference<self_type> (it ()), it1_ (it.it1_) {}
1367
1368            // Arithmetic
1369            BOOST_UBLAS_INLINE
1370            const_iterator1 &operator ++ () {
1371                ++ it1_;
1372                return *this;
1373            }
1374            BOOST_UBLAS_INLINE
1375            const_iterator1 &operator -- () {
1376                -- it1_;
1377                return *this;
1378            }
1379            BOOST_UBLAS_INLINE
1380            const_iterator1 &operator += (difference_type n) {
1381                it1_ += n;
1382                return *this;
1383            }
1384            BOOST_UBLAS_INLINE
1385            const_iterator1 &operator -= (difference_type n) {
1386                it1_ -= n;
1387                return *this;
1388            }
1389            BOOST_UBLAS_INLINE
1390            difference_type operator - (const const_iterator1 &it) const {
1391                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1392                return it1_ - it.it1_;
1393            }
1394
1395            // Dereference
1396            BOOST_UBLAS_INLINE
1397            const_reference operator * () const {
1398                size_type i = index1 ();
1399                size_type j = index2 ();
1400                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
1401                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
1402#ifdef BOOST_UBLAS_OWN_BANDED
1403                size_type k = (std::max) (i, j);
1404                size_type l = (*this) ().lower () + j - i;
1405                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
1406                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1407                    return *it1_;
1408#else
1409                size_type k = j;
1410                size_type l = (*this) ().upper () + i - j;
1411                if (k < (*this) ().size2 () &&
1412                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1413                    return *it1_;
1414#endif
1415                return (*this) () (i, j);
1416            }
1417            BOOST_UBLAS_INLINE
1418            const_reference operator [] (difference_type n) const {
1419                return *(*this + n);
1420            }
1421
1422#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1423            BOOST_UBLAS_INLINE
1424#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1425            typename self_type::
1426#endif
1427            const_iterator2 begin () const {
1428                return (*this) ().find2 (1, index1 (), 0);
1429            }
1430            BOOST_UBLAS_INLINE
1431#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1432            typename self_type::
1433#endif
1434            const_iterator2 end () const {
1435                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
1436            }
1437            BOOST_UBLAS_INLINE
1438#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1439            typename self_type::
1440#endif
1441            const_reverse_iterator2 rbegin () const {
1442                return const_reverse_iterator2 (end ());
1443            }
1444            BOOST_UBLAS_INLINE
1445#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1446            typename self_type::
1447#endif
1448            const_reverse_iterator2 rend () const {
1449                return const_reverse_iterator2 (begin ());
1450            }
1451#endif
1452
1453            // Indices
1454            BOOST_UBLAS_INLINE
1455            size_type index1 () const {
1456                return it1_.index1 ();
1457            }
1458            BOOST_UBLAS_INLINE
1459            size_type index2 () const {
1460                return it1_.index2 ();
1461            }
1462
1463            // Assignment
1464            BOOST_UBLAS_INLINE
1465            const_iterator1 &operator = (const const_iterator1 &it) {
1466                container_const_reference<self_type>::assign (&it ());
1467                it1_ = it.it1_;
1468                return *this;
1469            }
1470
1471            // Comparison
1472            BOOST_UBLAS_INLINE
1473            bool operator == (const const_iterator1 &it) const {
1474                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1475                return it1_ == it.it1_;
1476            }
1477            BOOST_UBLAS_INLINE
1478            bool operator < (const const_iterator1 &it) const {
1479                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1480                return it1_ < it.it1_;
1481            }
1482
1483        private:
1484            const_subiterator1_type it1_;
1485        };
1486#endif
1487
1488        BOOST_UBLAS_INLINE
1489        const_iterator1 begin1 () const {
1490            return find1 (0, 0, 0);
1491        }
1492        BOOST_UBLAS_INLINE
1493        const_iterator1 end1 () const {
1494            return find1 (0, size1 (), 0);
1495        }
1496
1497#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1498        class iterator1:
1499            public container_reference<banded_adaptor>,
1500            public random_access_iterator_base<typename iterator_restrict_traits<
1501                                                   typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
1502                                               iterator1, value_type> {
1503        public:
1504            typedef typename subiterator1_type::value_type value_type;
1505            typedef typename subiterator1_type::difference_type difference_type;
1506            typedef typename subiterator1_type::reference reference;
1507            typedef typename subiterator1_type::pointer pointer;
1508
1509            typedef iterator2 dual_iterator_type;
1510            typedef reverse_iterator2 dual_reverse_iterator_type;
1511
1512            // Construction and destruction
1513            BOOST_UBLAS_INLINE
1514            iterator1 ():
1515                container_reference<self_type> (), it1_ () {}
1516            BOOST_UBLAS_INLINE
1517            iterator1 (self_type &m, const subiterator1_type &it1):
1518                container_reference<self_type> (m), it1_ (it1) {}
1519
1520            // Arithmetic
1521            BOOST_UBLAS_INLINE
1522            iterator1 &operator ++ () {
1523                ++ it1_;
1524                return *this;
1525            }
1526            BOOST_UBLAS_INLINE
1527            iterator1 &operator -- () {
1528                -- it1_;
1529                return *this;
1530            }
1531            BOOST_UBLAS_INLINE
1532            iterator1 &operator += (difference_type n) {
1533                it1_ += n;
1534                return *this;
1535            }
1536            BOOST_UBLAS_INLINE
1537            iterator1 &operator -= (difference_type n) {
1538                it1_ -= n;
1539                return *this;
1540            }
1541            BOOST_UBLAS_INLINE
1542            difference_type operator - (const iterator1 &it) const {
1543                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1544                return it1_ - it.it1_;
1545            }
1546
1547            // Dereference
1548            BOOST_UBLAS_INLINE
1549            reference operator * () const {
1550                size_type i = index1 ();
1551                size_type j = index2 ();
1552                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
1553                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
1554#ifdef BOOST_UBLAS_OWN_BANDED
1555                size_type k = (std::max) (i, j);
1556                size_type l = (*this) ().lower () + j - i;
1557                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
1558                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1559                    return *it1_;
1560#else
1561                size_type k = j;
1562                size_type l = (*this) ().upper () + i - j;
1563                if (k < (*this) ().size2 () &&
1564                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1565                    return *it1_;
1566#endif
1567                return (*this) () (i, j);
1568            }
1569            BOOST_UBLAS_INLINE
1570            reference operator [] (difference_type n) const {
1571                return *(*this + n);
1572            }
1573
1574#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1575            BOOST_UBLAS_INLINE
1576#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1577            typename self_type::
1578#endif
1579            iterator2 begin () const {
1580                return (*this) ().find2 (1, index1 (), 0);
1581            }
1582            BOOST_UBLAS_INLINE
1583#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1584            typename self_type::
1585#endif
1586            iterator2 end () const {
1587                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
1588            }
1589            BOOST_UBLAS_INLINE
1590#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1591            typename self_type::
1592#endif
1593            reverse_iterator2 rbegin () const {
1594                return reverse_iterator2 (end ());
1595            }
1596            BOOST_UBLAS_INLINE
1597#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1598            typename self_type::
1599#endif
1600            reverse_iterator2 rend () const {
1601                return reverse_iterator2 (begin ());
1602            }
1603#endif
1604
1605            // Indices
1606            BOOST_UBLAS_INLINE
1607            size_type index1 () const {
1608                return it1_.index1 ();
1609            }
1610            BOOST_UBLAS_INLINE
1611            size_type index2 () const {
1612                return it1_.index2 ();
1613            }
1614
1615            // Assignment
1616            BOOST_UBLAS_INLINE
1617            iterator1 &operator = (const iterator1 &it) {
1618                container_reference<self_type>::assign (&it ());
1619                it1_ = it.it1_;
1620                return *this;
1621            }
1622
1623            // Comparison
1624            BOOST_UBLAS_INLINE
1625            bool operator == (const iterator1 &it) const {
1626                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1627                return it1_ == it.it1_;
1628            }
1629            BOOST_UBLAS_INLINE
1630            bool operator < (const iterator1 &it) const {
1631                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1632                return it1_ < it.it1_;
1633            }
1634
1635        private:
1636            subiterator1_type it1_;
1637
1638            friend class const_iterator1;
1639        };
1640#endif
1641
1642        BOOST_UBLAS_INLINE
1643        iterator1 begin1 () {
1644            return find1 (0, 0, 0);
1645        }
1646        BOOST_UBLAS_INLINE
1647        iterator1 end1 () {
1648            return find1 (0, size1 (), 0);
1649        }
1650
1651#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1652        class const_iterator2:
1653            public container_const_reference<banded_adaptor>,
1654            public random_access_iterator_base<packed_random_access_iterator_tag,
1655                                               const_iterator2, value_type> {
1656        public:
1657            typedef typename iterator_restrict_traits<typename const_subiterator2_type::iterator_category,
1658                                                      packed_random_access_iterator_tag>::iterator_category iterator_category;
1659            typedef typename const_subiterator2_type::value_type value_type;
1660            typedef typename const_subiterator2_type::difference_type difference_type;
1661            typedef typename const_subiterator2_type::reference reference;
1662            typedef typename const_subiterator2_type::pointer pointer;
1663
1664            typedef const_iterator1 dual_iterator_type;
1665            typedef const_reverse_iterator1 dual_reverse_iterator_type;
1666
1667            // Construction and destruction
1668            BOOST_UBLAS_INLINE
1669            const_iterator2 ():
1670                container_const_reference<self_type> (), it2_ () {}
1671            BOOST_UBLAS_INLINE
1672            const_iterator2 (const self_type &m, const const_subiterator2_type &it2):
1673                container_const_reference<self_type> (m), it2_ (it2) {}
1674            BOOST_UBLAS_INLINE
1675            const_iterator2 (const iterator2 &it):
1676                container_const_reference<self_type> (it ()), it2_ (it.it2_) {}
1677
1678            // Arithmetic
1679            BOOST_UBLAS_INLINE
1680            const_iterator2 &operator ++ () {
1681                ++ it2_;
1682                return *this;
1683            }
1684            BOOST_UBLAS_INLINE
1685            const_iterator2 &operator -- () {
1686                -- it2_;
1687                return *this;
1688            }
1689            BOOST_UBLAS_INLINE
1690            const_iterator2 &operator += (difference_type n) {
1691                it2_ += n;
1692                return *this;
1693            }
1694            BOOST_UBLAS_INLINE
1695            const_iterator2 &operator -= (difference_type n) {
1696                it2_ -= n;
1697                return *this;
1698            }
1699            BOOST_UBLAS_INLINE
1700            difference_type operator - (const const_iterator2 &it) const {
1701                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1702                return it2_ - it.it2_;
1703            }
1704
1705            // Dereference
1706            BOOST_UBLAS_INLINE
1707            const_reference operator * () const {
1708                size_type i = index1 ();
1709                size_type j = index2 ();
1710                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
1711                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
1712#ifdef BOOST_UBLAS_OWN_BANDED
1713                size_type k = (std::max) (i, j);
1714                size_type l = (*this) ().lower () + j - i;
1715                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
1716                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1717                    return *it2_;
1718#else
1719                size_type k = j;
1720                size_type l = (*this) ().upper () + i - j;
1721                if (k < (*this) ().size2 () &&
1722                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1723                    return *it2_;
1724#endif
1725                return (*this) () (i, j);
1726            }
1727            BOOST_UBLAS_INLINE
1728            const_reference operator [] (difference_type n) const {
1729                return *(*this + n);
1730            }
1731
1732#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1733            BOOST_UBLAS_INLINE
1734#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1735            typename self_type::
1736#endif
1737            const_iterator1 begin () const {
1738                return (*this) ().find1 (1, 0, index2 ());
1739            }
1740            BOOST_UBLAS_INLINE
1741#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1742            typename self_type::
1743#endif
1744            const_iterator1 end () const {
1745                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
1746            }
1747            BOOST_UBLAS_INLINE
1748#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1749            typename self_type::
1750#endif
1751            const_reverse_iterator1 rbegin () const {
1752                return const_reverse_iterator1 (end ());
1753            }
1754            BOOST_UBLAS_INLINE
1755#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1756            typename self_type::
1757#endif
1758            const_reverse_iterator1 rend () const {
1759                return const_reverse_iterator1 (begin ());
1760            }
1761#endif
1762
1763            // Indices
1764            BOOST_UBLAS_INLINE
1765            size_type index1 () const {
1766                return it2_.index1 ();
1767            }
1768            BOOST_UBLAS_INLINE
1769            size_type index2 () const {
1770                return it2_.index2 ();
1771            }
1772
1773            // Assignment
1774            BOOST_UBLAS_INLINE
1775            const_iterator2 &operator = (const const_iterator2 &it) {
1776                container_const_reference<self_type>::assign (&it ());
1777                it2_ = it.it2_;
1778                return *this;
1779            }
1780
1781            // Comparison
1782            BOOST_UBLAS_INLINE
1783            bool operator == (const const_iterator2 &it) const {
1784                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1785                return it2_ == it.it2_;
1786            }
1787            BOOST_UBLAS_INLINE
1788            bool operator < (const const_iterator2 &it) const {
1789                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1790                return it2_ < it.it2_;
1791            }
1792
1793        private:
1794            const_subiterator2_type it2_;
1795        };
1796#endif
1797
1798        BOOST_UBLAS_INLINE
1799        const_iterator2 begin2 () const {
1800            return find2 (0, 0, 0);
1801        }
1802        BOOST_UBLAS_INLINE
1803        const_iterator2 end2 () const {
1804            return find2 (0, 0, size2 ());
1805        }
1806
1807#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1808        class iterator2:
1809            public container_reference<banded_adaptor>,
1810            public random_access_iterator_base<typename iterator_restrict_traits<
1811                                                   typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
1812                                               iterator2, value_type> {
1813        public:
1814            typedef typename subiterator2_type::value_type value_type;
1815            typedef typename subiterator2_type::difference_type difference_type;
1816            typedef typename subiterator2_type::reference reference;
1817            typedef typename subiterator2_type::pointer pointer;
1818
1819            typedef iterator1 dual_iterator_type;
1820            typedef reverse_iterator1 dual_reverse_iterator_type;
1821
1822            // Construction and destruction
1823            BOOST_UBLAS_INLINE
1824            iterator2 ():
1825                container_reference<self_type> (), it2_ () {}
1826            BOOST_UBLAS_INLINE
1827            iterator2 (self_type &m, const subiterator2_type &it2):
1828                container_reference<self_type> (m), it2_ (it2) {}
1829
1830            // Arithmetic
1831            BOOST_UBLAS_INLINE
1832            iterator2 &operator ++ () {
1833                ++ it2_;
1834                return *this;
1835            }
1836            BOOST_UBLAS_INLINE
1837            iterator2 &operator -- () {
1838                -- it2_;
1839                return *this;
1840            }
1841            BOOST_UBLAS_INLINE
1842            iterator2 &operator += (difference_type n) {
1843                it2_ += n;
1844                return *this;
1845            }
1846            BOOST_UBLAS_INLINE
1847            iterator2 &operator -= (difference_type n) {
1848                it2_ -= n;
1849                return *this;
1850            }
1851            BOOST_UBLAS_INLINE
1852            difference_type operator - (const iterator2 &it) const {
1853                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1854                return it2_ - it.it2_;
1855            }
1856
1857            // Dereference
1858            BOOST_UBLAS_INLINE
1859            reference operator * () const {
1860                size_type i = index1 ();
1861                size_type j = index2 ();
1862                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
1863                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
1864#ifdef BOOST_UBLAS_OWN_BANDED
1865                size_type k = (std::max) (i, j);
1866                size_type l = (*this) ().lower () + j - i;
1867                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
1868                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1869                    return *it2_;
1870#else
1871                size_type k = j;
1872                size_type l = (*this) ().upper () + i - j;
1873                if (k < (*this) ().size2 () &&
1874                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1875                    return *it2_;
1876#endif
1877                return (*this) () (i, j);
1878            }
1879            BOOST_UBLAS_INLINE
1880            reference operator [] (difference_type n) const {
1881                return *(*this + n);
1882            }
1883
1884#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1885            BOOST_UBLAS_INLINE
1886#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1887            typename self_type::
1888#endif
1889            iterator1 begin () const {
1890                return (*this) ().find1 (1, 0, index2 ());
1891            }
1892            BOOST_UBLAS_INLINE
1893#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1894            typename self_type::
1895#endif
1896            iterator1 end () const {
1897                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
1898            }
1899            BOOST_UBLAS_INLINE
1900#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1901            typename self_type::
1902#endif
1903            reverse_iterator1 rbegin () const {
1904                return reverse_iterator1 (end ());
1905            }
1906            BOOST_UBLAS_INLINE
1907#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1908            typename self_type::
1909#endif
1910            reverse_iterator1 rend () const {
1911                return reverse_iterator1 (begin ());
1912            }
1913#endif
1914
1915            // Indices
1916            BOOST_UBLAS_INLINE
1917            size_type index1 () const {
1918                return it2_.index1 ();
1919            }
1920            BOOST_UBLAS_INLINE
1921            size_type index2 () const {
1922                return it2_.index2 ();
1923            }
1924
1925            // Assignment
1926            BOOST_UBLAS_INLINE
1927            iterator2 &operator = (const iterator2 &it) {
1928                container_reference<self_type>::assign (&it ());
1929                it2_ = it.it2_;
1930                return *this;
1931            }
1932
1933            // Comparison
1934            BOOST_UBLAS_INLINE
1935            bool operator == (const iterator2 &it) const {
1936                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1937                return it2_ == it.it2_;
1938            }
1939            BOOST_UBLAS_INLINE
1940            bool operator < (const iterator2 &it) const {
1941                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1942                return it2_ < it.it2_;
1943            }
1944
1945        private:
1946            subiterator2_type it2_;
1947
1948            friend class const_iterator2;
1949        };
1950#endif
1951
1952        BOOST_UBLAS_INLINE
1953        iterator2 begin2 () {
1954            return find2 (0, 0, 0);
1955        }
1956        BOOST_UBLAS_INLINE
1957        iterator2 end2 () {
1958            return find2 (0, 0, size2 ());
1959        }
1960
1961        // Reverse iterators
1962
1963        BOOST_UBLAS_INLINE
1964        const_reverse_iterator1 rbegin1 () const {
1965            return const_reverse_iterator1 (end1 ());
1966        }
1967        BOOST_UBLAS_INLINE
1968        const_reverse_iterator1 rend1 () const {
1969            return const_reverse_iterator1 (begin1 ());
1970        }
1971
1972        BOOST_UBLAS_INLINE
1973        reverse_iterator1 rbegin1 () {
1974            return reverse_iterator1 (end1 ());
1975        }
1976        BOOST_UBLAS_INLINE
1977        reverse_iterator1 rend1 () {
1978            return reverse_iterator1 (begin1 ());
1979        }
1980
1981        BOOST_UBLAS_INLINE
1982        const_reverse_iterator2 rbegin2 () const {
1983            return const_reverse_iterator2 (end2 ());
1984        }
1985        BOOST_UBLAS_INLINE
1986        const_reverse_iterator2 rend2 () const {
1987            return const_reverse_iterator2 (begin2 ());
1988        }
1989
1990        BOOST_UBLAS_INLINE
1991        reverse_iterator2 rbegin2 () {
1992            return reverse_iterator2 (end2 ());
1993        }
1994        BOOST_UBLAS_INLINE
1995        reverse_iterator2 rend2 () {
1996            return reverse_iterator2 (begin2 ());
1997        }
1998
1999    private:
2000        matrix_closure_type data_;
2001        size_type lower_;
2002        size_type upper_;
2003        typedef const value_type const_value_type;
2004        static const_value_type zero_;
2005    };
2006
2007    // Specialization for temporary_traits
2008    template <class M>
2009    struct vector_temporary_traits< banded_adaptor<M> >
2010    : vector_temporary_traits< M > {} ;
2011    template <class M>
2012    struct vector_temporary_traits< const banded_adaptor<M> >
2013    : vector_temporary_traits< M > {} ;
2014
2015    template <class M>
2016    struct matrix_temporary_traits< banded_adaptor<M> >
2017    : matrix_temporary_traits< M > {} ;
2018    template <class M>
2019    struct matrix_temporary_traits< const banded_adaptor<M> >
2020    : matrix_temporary_traits< M > {} ;
2021
2022
2023    template<class M>
2024    typename banded_adaptor<M>::const_value_type banded_adaptor<M>::zero_ = value_type/*zero*/();
2025
2026    /** \brief A diagonal matrix adaptator: convert a any matrix into a diagonal matrix expression
2027     *
2028     * For a \f$(m\times m)\f$-dimensional matrix, the \c diagonal_adaptor will provide a diagonal matrix
2029     * with \f$0 \leq i < m\f$ and \f$0 \leq j < m\f$, if \f$i\neq j\f$ then \f$b_{i,j}=0\f$.
2030     *
2031     * Storage and location are based on those of the underlying matrix. This is important because
2032     * a \c diagonal_adaptor does not copy the matrix data to a new place. Therefore, modifying values
2033     * in a \c diagonal_adaptor matrix will also modify the underlying matrix too.
2034     *
2035     * \tparam M the type of matrix used to generate the diagonal matrix
2036     */
2037
2038    template<class M>
2039    class diagonal_adaptor:
2040        public banded_adaptor<M> {
2041    public:
2042        typedef M matrix_type;
2043        typedef banded_adaptor<M> adaptor_type;
2044
2045        // Construction and destruction
2046        BOOST_UBLAS_INLINE
2047        diagonal_adaptor ():
2048            adaptor_type () {}
2049        BOOST_UBLAS_INLINE
2050        diagonal_adaptor (matrix_type &data):
2051            adaptor_type (data) {}
2052        BOOST_UBLAS_INLINE
2053        ~diagonal_adaptor () {}
2054
2055        // Assignment
2056        BOOST_UBLAS_INLINE
2057        diagonal_adaptor &operator = (const diagonal_adaptor &m) {
2058            adaptor_type::operator = (m);
2059            return *this;
2060        }
2061        template<class AE>
2062        BOOST_UBLAS_INLINE
2063        diagonal_adaptor &operator = (const matrix_expression<AE> &ae) {
2064            adaptor_type::operator = (ae);
2065            return *this;
2066        }
2067    };
2068
2069}}}
2070
2071#endif
Note: See TracBrowser for help on using the repository browser.