Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/numeric/ublas/banded.hpp @ 47

Last change on this file since 47 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

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