source: NonGTP/Boost/boost/numeric/ublas/banded.hpp @ 857

Revision 857, 72.2 KB checked in by igarcia, 19 years ago (diff)
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
415#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
416            BOOST_UBLAS_INLINE
417#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
418            typename self_type::
419#endif
420            const_iterator2 begin () const {
421                return (*this) ().find2 (1, it1_, 0);
422            }
423            BOOST_UBLAS_INLINE
424#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
425            typename self_type::
426#endif
427            const_iterator2 end () const {
428                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
429            }
430            BOOST_UBLAS_INLINE
431#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
432            typename self_type::
433#endif
434            const_reverse_iterator2 rbegin () const {
435                return const_reverse_iterator2 (end ());
436            }
437            BOOST_UBLAS_INLINE
438#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
439            typename self_type::
440#endif
441            const_reverse_iterator2 rend () const {
442                return const_reverse_iterator2 (begin ());
443            }
444#endif
445
446            // Indices
447            BOOST_UBLAS_INLINE
448            size_type index1 () const {
449                return it1_;
450            }
451            BOOST_UBLAS_INLINE
452            size_type index2 () const {
453                return it2_;
454            }
455
456            // Assignment
457            BOOST_UBLAS_INLINE
458            const_iterator1 &operator = (const const_iterator1 &it) {
459                container_const_reference<self_type>::assign (&it ());
460                it1_ = it.it1_;
461                it2_ = it.it2_;
462                return *this;
463            }
464
465            // Comparison
466            BOOST_UBLAS_INLINE
467            bool operator == (const const_iterator1 &it) const {
468                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
469                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
470                return it1_ == it.it1_;
471            }
472            BOOST_UBLAS_INLINE
473            bool operator < (const const_iterator1 &it) const {
474                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
475                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
476                return it1_ < it.it1_;
477            }
478
479        private:
480            size_type it1_;
481            size_type it2_;
482        };
483#endif
484
485        BOOST_UBLAS_INLINE
486        const_iterator1 begin1 () const {
487            return find1 (0, 0, 0);
488        }
489        BOOST_UBLAS_INLINE
490        const_iterator1 end1 () const {
491            return find1 (0, size1_, 0);
492        }
493
494#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
495        class iterator1:
496            public container_reference<banded_matrix>,
497            public random_access_iterator_base<packed_random_access_iterator_tag,
498                                               iterator1, value_type> {
499        public:
500            typedef typename banded_matrix::value_type value_type;
501            typedef typename banded_matrix::difference_type difference_type;
502            typedef typename banded_matrix::reference reference;
503            typedef typename banded_matrix::pointer pointer;
504
505            typedef iterator2 dual_iterator_type;
506            typedef reverse_iterator2 dual_reverse_iterator_type;
507
508            // Construction and destruction
509            BOOST_UBLAS_INLINE
510            iterator1 ():
511                container_reference<self_type> (), it1_ (), it2_ () {}
512            BOOST_UBLAS_INLINE
513            iterator1 (self_type &m, size_type it1, size_type it2):
514                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
515
516            // Arithmetic
517            BOOST_UBLAS_INLINE
518            iterator1 &operator ++ () {
519                ++ it1_;
520                return *this;
521            }
522            BOOST_UBLAS_INLINE
523            iterator1 &operator -- () {
524                -- it1_;
525                return *this;
526            }
527            BOOST_UBLAS_INLINE
528            iterator1 &operator += (difference_type n) {
529                it1_ += n;
530                return *this;
531            }
532            BOOST_UBLAS_INLINE
533            iterator1 &operator -= (difference_type n) {
534                it1_ -= n;
535                return *this;
536            }
537            BOOST_UBLAS_INLINE
538            difference_type operator - (const iterator1 &it) const {
539                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
540                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
541                return it1_ - it.it1_;
542            }
543
544            // Dereference
545            BOOST_UBLAS_INLINE
546            reference operator * () const {
547                return (*this) ().at_element (it1_, it2_);
548            }
549
550#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
551            BOOST_UBLAS_INLINE
552#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
553            typename self_type::
554#endif
555            iterator2 begin () const {
556                return (*this) ().find2 (1, it1_, 0);
557            }
558            BOOST_UBLAS_INLINE
559#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
560            typename self_type::
561#endif
562            iterator2 end () const {
563                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
564            }
565            BOOST_UBLAS_INLINE
566#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
567            typename self_type::
568#endif
569            reverse_iterator2 rbegin () const {
570                return reverse_iterator2 (end ());
571            }
572            BOOST_UBLAS_INLINE
573#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
574            typename self_type::
575#endif
576            reverse_iterator2 rend () const {
577                return reverse_iterator2 (begin ());
578            }
579#endif
580
581            // Indices
582            BOOST_UBLAS_INLINE
583            size_type index1 () const {
584                return it1_;
585            }
586            BOOST_UBLAS_INLINE
587            size_type index2 () const {
588                return it2_;
589            }
590
591            // Assignment
592            BOOST_UBLAS_INLINE
593            iterator1 &operator = (const iterator1 &it) {
594                container_reference<self_type>::assign (&it ());
595                it1_ = it.it1_;
596                it2_ = it.it2_;
597                return *this;
598            }
599
600            // Comparison
601            BOOST_UBLAS_INLINE
602            bool operator == (const iterator1 &it) const {
603                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
604                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
605                return it1_ == it.it1_;
606            }
607            BOOST_UBLAS_INLINE
608            bool operator < (const iterator1 &it) const {
609                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
610                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
611                return it1_ < it.it1_;
612            }
613
614        private:
615            size_type it1_;
616            size_type it2_;
617
618            friend class const_iterator1;
619        };
620#endif
621
622        BOOST_UBLAS_INLINE
623        iterator1 begin1 () {
624            return find1 (0, 0, 0);
625        }
626        BOOST_UBLAS_INLINE
627        iterator1 end1 () {
628            return find1 (0, size1_, 0);
629        }
630
631#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
632        class const_iterator2:
633            public container_const_reference<banded_matrix>,
634            public random_access_iterator_base<packed_random_access_iterator_tag,
635                                               const_iterator2, value_type> {
636        public:
637            typedef typename banded_matrix::value_type value_type;
638            typedef typename banded_matrix::difference_type difference_type;
639            typedef typename banded_matrix::const_reference reference;
640            typedef const typename banded_matrix::pointer pointer;
641
642            typedef const_iterator1 dual_iterator_type;
643            typedef const_reverse_iterator1 dual_reverse_iterator_type;
644
645            // Construction and destruction
646            BOOST_UBLAS_INLINE
647            const_iterator2 ():
648                container_const_reference<self_type> (), it1_ (), it2_ () {}
649            BOOST_UBLAS_INLINE
650            const_iterator2 (const self_type &m, size_type it1, size_type it2):
651                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
652            BOOST_UBLAS_INLINE
653            const_iterator2 (const iterator2 &it):
654                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
655
656            // Arithmetic
657            BOOST_UBLAS_INLINE
658            const_iterator2 &operator ++ () {
659                ++ it2_;
660                return *this;
661            }
662            BOOST_UBLAS_INLINE
663            const_iterator2 &operator -- () {
664                -- it2_;
665                return *this;
666            }
667            BOOST_UBLAS_INLINE
668            const_iterator2 &operator += (difference_type n) {
669                it2_ += n;
670                return *this;
671            }
672            BOOST_UBLAS_INLINE
673            const_iterator2 &operator -= (difference_type n) {
674                it2_ -= n;
675                return *this;
676            }
677            BOOST_UBLAS_INLINE
678            difference_type operator - (const const_iterator2 &it) const {
679                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
680                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
681                return it2_ - it.it2_;
682            }
683
684            // Dereference
685            BOOST_UBLAS_INLINE
686            const_reference operator * () const {
687                return (*this) () (it1_, it2_);
688            }
689
690#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
691            BOOST_UBLAS_INLINE
692#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
693            typename self_type::
694#endif
695            const_iterator1 begin () const {
696                return (*this) ().find1 (1, 0, it2_);
697            }
698            BOOST_UBLAS_INLINE
699#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
700            typename self_type::
701#endif
702            const_iterator1 end () const {
703                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
704            }
705            BOOST_UBLAS_INLINE
706#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
707            typename self_type::
708#endif
709            const_reverse_iterator1 rbegin () const {
710                return const_reverse_iterator1 (end ());
711            }
712            BOOST_UBLAS_INLINE
713#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
714            typename self_type::
715#endif
716            const_reverse_iterator1 rend () const {
717                return const_reverse_iterator1 (begin ());
718            }
719#endif
720
721            // Indices
722            BOOST_UBLAS_INLINE
723            size_type index1 () const {
724                return it1_;
725            }
726            BOOST_UBLAS_INLINE
727            size_type index2 () const {
728                return it2_;
729            }
730
731            // Assignment
732            BOOST_UBLAS_INLINE
733            const_iterator2 &operator = (const const_iterator2 &it) {
734                container_const_reference<self_type>::assign (&it ());
735                it1_ = it.it1_;
736                it2_ = it.it2_;
737                return *this;
738            }
739
740            // Comparison
741            BOOST_UBLAS_INLINE
742            bool operator == (const const_iterator2 &it) const {
743                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
744                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
745                return it2_ == it.it2_;
746            }
747            BOOST_UBLAS_INLINE
748            bool operator < (const const_iterator2 &it) const {
749                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
750                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
751                return it2_ < it.it2_;
752            }
753
754        private:
755            size_type it1_;
756            size_type it2_;
757        };
758#endif
759
760        BOOST_UBLAS_INLINE
761        const_iterator2 begin2 () const {
762            return find2 (0, 0, 0);
763        }
764        BOOST_UBLAS_INLINE
765        const_iterator2 end2 () const {
766            return find2 (0, 0, size2_);
767        }
768
769#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
770        class iterator2:
771            public container_reference<banded_matrix>,
772            public random_access_iterator_base<packed_random_access_iterator_tag,
773                                               iterator2, value_type> {
774        public:
775            typedef typename banded_matrix::value_type value_type;
776            typedef typename banded_matrix::difference_type difference_type;
777            typedef typename banded_matrix::reference reference;
778            typedef typename banded_matrix::pointer pointer;
779
780            typedef iterator1 dual_iterator_type;
781            typedef reverse_iterator1 dual_reverse_iterator_type;
782
783            // Construction and destruction
784            BOOST_UBLAS_INLINE
785            iterator2 ():
786                container_reference<self_type> (), it1_ (), it2_ () {}
787            BOOST_UBLAS_INLINE
788            iterator2 (self_type &m, size_type it1, size_type it2):
789                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
790
791            // Arithmetic
792            BOOST_UBLAS_INLINE
793            iterator2 &operator ++ () {
794                ++ it2_;
795                return *this;
796            }
797            BOOST_UBLAS_INLINE
798            iterator2 &operator -- () {
799                -- it2_;
800                return *this;
801            }
802            BOOST_UBLAS_INLINE
803            iterator2 &operator += (difference_type n) {
804                it2_ += n;
805                return *this;
806            }
807            BOOST_UBLAS_INLINE
808            iterator2 &operator -= (difference_type n) {
809                it2_ -= n;
810                return *this;
811            }
812            BOOST_UBLAS_INLINE
813            difference_type operator - (const iterator2 &it) const {
814                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
815                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
816                return it2_ - it.it2_;
817            }
818
819            // Dereference
820            BOOST_UBLAS_INLINE
821            reference operator * () const {
822                return (*this) ().at_element (it1_, it2_);
823            }
824
825#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
826            BOOST_UBLAS_INLINE
827#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
828            typename self_type::
829#endif
830            iterator1 begin () const {
831                return (*this) ().find1 (1, 0, it2_);
832            }
833            BOOST_UBLAS_INLINE
834#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
835            typename self_type::
836#endif
837            iterator1 end () const {
838                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
839            }
840            BOOST_UBLAS_INLINE
841#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
842            typename self_type::
843#endif
844            reverse_iterator1 rbegin () const {
845                return reverse_iterator1 (end ());
846            }
847            BOOST_UBLAS_INLINE
848#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
849            typename self_type::
850#endif
851            reverse_iterator1 rend () const {
852                return reverse_iterator1 (begin ());
853            }
854#endif
855
856            // Indices
857            BOOST_UBLAS_INLINE
858            size_type index1 () const {
859                return it1_;
860            }
861            BOOST_UBLAS_INLINE
862            size_type index2 () const {
863                return it2_;
864            }
865
866            // Assignment
867            BOOST_UBLAS_INLINE
868            iterator2 &operator = (const iterator2 &it) {
869                container_reference<self_type>::assign (&it ());
870                it1_ = it.it1_;
871                it2_ = it.it2_;
872                return *this;
873            }
874
875            // Comparison
876            BOOST_UBLAS_INLINE
877            bool operator == (const iterator2 &it) const {
878                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
879                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
880                return it2_ == it.it2_;
881            }
882            BOOST_UBLAS_INLINE
883            bool operator < (const iterator2 &it) const {
884                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
885                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
886                return it2_ < it.it2_;
887            }
888
889        private:
890            size_type it1_;
891            size_type it2_;
892
893            friend class const_iterator2;
894        };
895#endif
896
897        BOOST_UBLAS_INLINE
898        iterator2 begin2 () {
899            return find2 (0, 0, 0);
900        }
901        BOOST_UBLAS_INLINE
902        iterator2 end2 () {
903            return find2 (0, 0, size2_);
904        }
905
906        // Reverse iterators
907
908        BOOST_UBLAS_INLINE
909        const_reverse_iterator1 rbegin1 () const {
910            return const_reverse_iterator1 (end1 ());
911        }
912        BOOST_UBLAS_INLINE
913        const_reverse_iterator1 rend1 () const {
914            return const_reverse_iterator1 (begin1 ());
915        }
916
917        BOOST_UBLAS_INLINE
918        reverse_iterator1 rbegin1 () {
919            return reverse_iterator1 (end1 ());
920        }
921        BOOST_UBLAS_INLINE
922        reverse_iterator1 rend1 () {
923            return reverse_iterator1 (begin1 ());
924        }
925
926        BOOST_UBLAS_INLINE
927        const_reverse_iterator2 rbegin2 () const {
928            return const_reverse_iterator2 (end2 ());
929        }
930        BOOST_UBLAS_INLINE
931        const_reverse_iterator2 rend2 () const {
932            return const_reverse_iterator2 (begin2 ());
933        }
934
935        BOOST_UBLAS_INLINE
936        reverse_iterator2 rbegin2 () {
937            return reverse_iterator2 (end2 ());
938        }
939        BOOST_UBLAS_INLINE
940        reverse_iterator2 rend2 () {
941            return reverse_iterator2 (begin2 ());
942        }
943
944    private:
945        size_type size1_;
946        size_type size2_;
947        size_type lower_;
948        size_type upper_;
949        array_type data_;
950        typedef const value_type const_value_type;
951        static const_value_type zero_;
952    };
953
954    template<class T, class L, class A>
955    typename banded_matrix<T, L, A>::const_value_type banded_matrix<T, L, A>::zero_ = value_type/*zero*/();
956
957
958    // Diagonal matrix class
959    template<class T, class L, class A>
960    class diagonal_matrix:
961        public banded_matrix<T, L, A> {
962    public:
963        typedef typename A::size_type size_type;
964        typedef banded_matrix<T, L, A> matrix_type;
965        typedef A array_type;
966
967        // Construction and destruction
968        BOOST_UBLAS_INLINE
969        diagonal_matrix ():
970            matrix_type () {}
971        BOOST_UBLAS_INLINE
972        diagonal_matrix (size_type size):
973            matrix_type (size, size) {}
974        BOOST_UBLAS_INLINE
975        diagonal_matrix (size_type size, const array_type& data):
976            matrix_type (size, size, 0, 0, data) {}
977        BOOST_UBLAS_INLINE
978        diagonal_matrix (size_type size1, size_type size2):
979            matrix_type (size1, size2) {}
980        template<class AE>
981        BOOST_UBLAS_INLINE
982        diagonal_matrix (const matrix_expression<AE> &ae):
983            matrix_type (ae) {}
984        BOOST_UBLAS_INLINE
985        ~diagonal_matrix () {}
986
987        // Assignment
988        BOOST_UBLAS_INLINE
989        diagonal_matrix &operator = (const diagonal_matrix &m) {
990            matrix_type::operator = (m);
991            return *this;
992        }
993        template<class AE>
994        BOOST_UBLAS_INLINE
995        diagonal_matrix &operator = (const matrix_expression<AE> &ae) {
996            matrix_type::operator = (ae);
997            return *this;
998        }
999    };
1000
1001    // Banded matrix adaptor class
1002    template<class M>
1003    class banded_adaptor:
1004        public matrix_expression<banded_adaptor<M> > {
1005
1006        typedef banded_adaptor<M> self_type;
1007    public:
1008#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1009        using matrix_expression<self_type>::operator ();
1010#endif
1011        typedef const M const_matrix_type;
1012        typedef M matrix_type;
1013        typedef typename M::size_type size_type;
1014        typedef typename M::difference_type difference_type;
1015        typedef typename M::value_type value_type;
1016        typedef typename M::const_reference const_reference;
1017        typedef typename boost::mpl::if_<boost::is_const<M>,
1018                                          typename M::const_reference,
1019                                          typename M::reference>::type reference;
1020        typedef typename boost::mpl::if_<boost::is_const<M>,
1021                                          typename M::const_closure_type,
1022                                          typename M::closure_type>::type matrix_closure_type;
1023        typedef const self_type const_closure_type;
1024        typedef self_type closure_type;
1025        // Replaced by _temporary_traits to avoid type requirements on M
1026        //typedef typename M::vector_temporary_type vector_temporary_type;
1027        //typedef typename M::matrix_temporary_type matrix_temporary_type;
1028        typedef typename storage_restrict_traits<typename M::storage_category,
1029                                                 packed_proxy_tag>::storage_category storage_category;
1030        typedef typename M::orientation_category orientation_category;
1031
1032        // Construction and destruction
1033        BOOST_UBLAS_INLINE
1034        banded_adaptor (matrix_type &data, size_type lower = 0, size_type upper = 0):
1035            matrix_expression<self_type> (),
1036            data_ (data), lower_ (lower), upper_ (upper) {}
1037        BOOST_UBLAS_INLINE
1038        banded_adaptor (const banded_adaptor &m):
1039            matrix_expression<self_type> (),
1040            data_ (m.data_), lower_ (m.lower_), upper_ (m.upper_) {}
1041
1042        // Accessors
1043        BOOST_UBLAS_INLINE
1044        size_type size1 () const {
1045            return data_.size1 ();
1046        }
1047        BOOST_UBLAS_INLINE
1048        size_type size2 () const {
1049            return data_.size2 ();
1050        }
1051        BOOST_UBLAS_INLINE
1052        size_type lower () const {
1053            return lower_;
1054        }
1055        BOOST_UBLAS_INLINE
1056        size_type upper () const {
1057            return upper_;
1058        }
1059
1060        // Storage accessors
1061        BOOST_UBLAS_INLINE
1062        const matrix_closure_type &data () const {
1063            return data_;
1064        }
1065        BOOST_UBLAS_INLINE
1066        matrix_closure_type &data () {
1067            return data_;
1068        }
1069
1070        // Element access
1071#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
1072        BOOST_UBLAS_INLINE
1073        const_reference operator () (size_type i, size_type j) const {
1074            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1075            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1076#ifdef BOOST_UBLAS_OWN_BANDED
1077            size_type k = (std::max) (i, j);
1078            size_type l = lower_ + j - i;
1079            if (k < (std::max) (size1 (), size2 ()) &&
1080                l < lower_ + 1 + upper_)
1081                return data () (i, j);
1082#else
1083            size_type k = j;
1084            size_type l = upper_ + i - j;
1085            if (k < size2 () &&
1086                l < lower_ + 1 + upper_)
1087                return data () (i, j);
1088#endif
1089            return zero_;
1090        }
1091        BOOST_UBLAS_INLINE
1092        reference operator () (size_type i, size_type j) {
1093            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1094            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1095#ifdef BOOST_UBLAS_OWN_BANDED
1096            size_type k = (std::max) (i, j);
1097            size_type l = lower_ + j - i;
1098            if (k < (std::max) (size1 (), size2 ()) &&
1099                l < lower_ + 1 + upper_)
1100                return data () (i, j);
1101#else
1102            size_type k = j;
1103            size_type l = upper_ + i - j;
1104            if (k < size2 () &&
1105                l < lower_ + 1 + upper_)
1106                return data () (i, j);
1107#endif
1108#ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
1109            bad_index ().raise ();
1110#endif
1111            return const_cast<reference>(zero_);
1112        }
1113#else
1114        BOOST_UBLAS_INLINE
1115        reference operator () (size_type i, size_type j) const {
1116            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1117            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1118#ifdef BOOST_UBLAS_OWN_BANDED
1119            size_type k = (std::max) (i, j);
1120            size_type l = lower_ + j - i;
1121            if (k < (std::max) (size1 (), size2 ()) &&
1122                l < lower_ + 1 + upper_)
1123                return data () (i, j);
1124#else
1125            size_type k = j;
1126            size_type l = upper_ + i - j;
1127            if (k < size2 () &&
1128                l < lower_ + 1 + upper_)
1129                return data () (i, j);
1130#endif
1131#ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
1132            bad_index ().raise ();
1133#endif
1134            return const_cast<reference>(zero_);
1135        }
1136#endif
1137
1138        // Assignment
1139        BOOST_UBLAS_INLINE
1140        banded_adaptor &operator = (const banded_adaptor &m) {
1141            matrix_assign<scalar_assign> (*this, m);
1142            return *this;
1143        }
1144        BOOST_UBLAS_INLINE
1145        banded_adaptor &assign_temporary (banded_adaptor &m) {
1146            *this = m;
1147            return *this;
1148        }
1149        template<class AE>
1150        BOOST_UBLAS_INLINE
1151        banded_adaptor &operator = (const matrix_expression<AE> &ae) {
1152            matrix_assign<scalar_assign> (*this, matrix<value_type> (ae));
1153            return *this;
1154        }
1155        template<class AE>
1156        BOOST_UBLAS_INLINE
1157        banded_adaptor &assign (const matrix_expression<AE> &ae) {
1158            matrix_assign<scalar_assign> (*this, ae);
1159            return *this;
1160        }
1161        template<class AE>
1162        BOOST_UBLAS_INLINE
1163        banded_adaptor& operator += (const matrix_expression<AE> &ae) {
1164            matrix_assign<scalar_assign> (*this, matrix<value_type> (*this + ae));
1165            return *this;
1166        }
1167        template<class AE>
1168        BOOST_UBLAS_INLINE
1169        banded_adaptor &plus_assign (const matrix_expression<AE> &ae) {
1170            matrix_assign<scalar_plus_assign> (*this, ae);
1171            return *this;
1172        }
1173        template<class AE>
1174        BOOST_UBLAS_INLINE
1175        banded_adaptor& operator -= (const matrix_expression<AE> &ae) {
1176            matrix_assign<scalar_assign> (*this, matrix<value_type> (*this - ae));
1177            return *this;
1178        }
1179        template<class AE>
1180        BOOST_UBLAS_INLINE
1181        banded_adaptor &minus_assign (const matrix_expression<AE> &ae) {
1182            matrix_assign<scalar_minus_assign> (*this, ae);
1183            return *this;
1184        }
1185        template<class AT>
1186        BOOST_UBLAS_INLINE
1187        banded_adaptor& operator *= (const AT &at) {
1188            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
1189            return *this;
1190        }
1191        template<class AT>
1192        BOOST_UBLAS_INLINE
1193        banded_adaptor& operator /= (const AT &at) {
1194            matrix_assign_scalar<scalar_divides_assign> (*this, at);
1195            return *this;
1196        }
1197
1198        // Closure comparison
1199        BOOST_UBLAS_INLINE
1200        bool same_closure (const banded_adaptor &ba) const {
1201            return (*this).data ().same_closure (ba.data ());
1202        }
1203
1204        // Swapping
1205        BOOST_UBLAS_INLINE
1206        void swap (banded_adaptor &m) {
1207            if (this != &m) {
1208                BOOST_UBLAS_CHECK (lower_ == m.lower_, bad_size ());
1209                BOOST_UBLAS_CHECK (upper_ == m.upper_, bad_size ());
1210                matrix_swap<scalar_swap> (*this, m);
1211            }
1212        }
1213        BOOST_UBLAS_INLINE
1214        friend void swap (banded_adaptor &m1, banded_adaptor &m2) {
1215            m1.swap (m2);
1216        }
1217
1218        // Iterator types
1219    private:
1220        // Use the matrix iterator
1221        typedef typename M::const_iterator1 const_subiterator1_type;
1222        typedef typename boost::mpl::if_<boost::is_const<M>,
1223                                          typename M::const_iterator1,
1224                                          typename M::iterator1>::type subiterator1_type;
1225        typedef typename M::const_iterator2 const_subiterator2_type;
1226        typedef typename boost::mpl::if_<boost::is_const<M>,
1227                                          typename M::const_iterator2,
1228                                          typename M::iterator2>::type subiterator2_type;
1229
1230    public:
1231#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1232        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
1233        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
1234        typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
1235        typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
1236#else
1237        class const_iterator1;
1238        class iterator1;
1239        class const_iterator2;
1240        class iterator2;
1241#endif
1242        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
1243        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
1244        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
1245        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
1246
1247        // Element lookup
1248        BOOST_UBLAS_INLINE
1249        const_iterator1 find1 (int rank, size_type i, size_type j) const {
1250            if (rank == 1) {
1251                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
1252                i = (std::max) (i, lower_i);
1253                size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
1254                i = (std::min) (i, upper_i);
1255            }
1256            return const_iterator1 (*this, data ().find1 (rank, i, j));
1257        }
1258        BOOST_UBLAS_INLINE
1259        iterator1 find1 (int rank, size_type i, size_type j) {
1260            if (rank == 1) {
1261                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
1262                i = (std::max) (i, lower_i);
1263                size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
1264                i = (std::min) (i, upper_i);
1265            }
1266            return iterator1 (*this, data ().find1 (rank, i, j));
1267        }
1268        BOOST_UBLAS_INLINE
1269        const_iterator2 find2 (int rank, size_type i, size_type j) const {
1270            if (rank == 1) {
1271                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
1272                j = (std::max) (j, lower_j);
1273                size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
1274                j = (std::min) (j, upper_j);
1275            }
1276            return const_iterator2 (*this, data ().find2 (rank, i, j));
1277        }
1278        BOOST_UBLAS_INLINE
1279        iterator2 find2 (int rank, size_type i, size_type j) {
1280            if (rank == 1) {
1281                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
1282                j = (std::max) (j, lower_j);
1283                size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
1284                j = (std::min) (j, upper_j);
1285            }
1286            return iterator2 (*this, data ().find2 (rank, i, j));
1287        }
1288
1289        // Iterators simply are indices.
1290
1291#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1292        class const_iterator1:
1293            public container_const_reference<banded_adaptor>,
1294            public random_access_iterator_base<typename iterator_restrict_traits<
1295                                                   typename const_subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
1296                                               const_iterator1, value_type> {
1297        public:
1298            typedef typename const_subiterator1_type::value_type value_type;
1299            typedef typename const_subiterator1_type::difference_type difference_type;
1300            typedef typename const_subiterator1_type::reference reference;
1301            typedef typename const_subiterator1_type::pointer pointer;
1302
1303            typedef const_iterator2 dual_iterator_type;
1304            typedef const_reverse_iterator2 dual_reverse_iterator_type;
1305
1306            // Construction and destruction
1307            BOOST_UBLAS_INLINE
1308            const_iterator1 ():
1309                container_const_reference<self_type> (), it1_ () {}
1310            BOOST_UBLAS_INLINE
1311            const_iterator1 (const self_type &m, const const_subiterator1_type &it1):
1312                container_const_reference<self_type> (m), it1_ (it1) {}
1313            BOOST_UBLAS_INLINE
1314            const_iterator1 (const iterator1 &it):
1315                container_const_reference<self_type> (it ()), it1_ (it.it1_) {}
1316
1317            // Arithmetic
1318            BOOST_UBLAS_INLINE
1319            const_iterator1 &operator ++ () {
1320                ++ it1_;
1321                return *this;
1322            }
1323            BOOST_UBLAS_INLINE
1324            const_iterator1 &operator -- () {
1325                -- it1_;
1326                return *this;
1327            }
1328            BOOST_UBLAS_INLINE
1329            const_iterator1 &operator += (difference_type n) {
1330                it1_ += n;
1331                return *this;
1332            }
1333            BOOST_UBLAS_INLINE
1334            const_iterator1 &operator -= (difference_type n) {
1335                it1_ -= n;
1336                return *this;
1337            }
1338            BOOST_UBLAS_INLINE
1339            difference_type operator - (const const_iterator1 &it) const {
1340                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1341                return it1_ - it.it1_;
1342            }
1343
1344            // Dereference
1345            BOOST_UBLAS_INLINE
1346            const_reference operator * () const {
1347                size_type i = index1 ();
1348                size_type j = index2 ();
1349                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
1350                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
1351#ifdef BOOST_UBLAS_OWN_BANDED
1352                size_type k = (std::max) (i, j);
1353                size_type l = (*this) ().lower () + j - i;
1354                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
1355                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1356                    return *it1_;
1357#else
1358                size_type k = j;
1359                size_type l = (*this) ().upper () + i - j;
1360                if (k < (*this) ().size2 () &&
1361                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1362                    return *it1_;
1363#endif
1364                return (*this) () (i, j);
1365            }
1366
1367#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1368            BOOST_UBLAS_INLINE
1369#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1370            typename self_type::
1371#endif
1372            const_iterator2 begin () const {
1373                return (*this) ().find2 (1, index1 (), 0);
1374            }
1375            BOOST_UBLAS_INLINE
1376#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1377            typename self_type::
1378#endif
1379            const_iterator2 end () const {
1380                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
1381            }
1382            BOOST_UBLAS_INLINE
1383#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1384            typename self_type::
1385#endif
1386            const_reverse_iterator2 rbegin () const {
1387                return const_reverse_iterator2 (end ());
1388            }
1389            BOOST_UBLAS_INLINE
1390#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1391            typename self_type::
1392#endif
1393            const_reverse_iterator2 rend () const {
1394                return const_reverse_iterator2 (begin ());
1395            }
1396#endif
1397
1398            // Indices
1399            BOOST_UBLAS_INLINE
1400            size_type index1 () const {
1401                return it1_.index1 ();
1402            }
1403            BOOST_UBLAS_INLINE
1404            size_type index2 () const {
1405                return it1_.index2 ();
1406            }
1407
1408            // Assignment
1409            BOOST_UBLAS_INLINE
1410            const_iterator1 &operator = (const const_iterator1 &it) {
1411                container_const_reference<self_type>::assign (&it ());
1412                it1_ = it.it1_;
1413                return *this;
1414            }
1415
1416            // Comparison
1417            BOOST_UBLAS_INLINE
1418            bool operator == (const const_iterator1 &it) const {
1419                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1420                return it1_ == it.it1_;
1421            }
1422            BOOST_UBLAS_INLINE
1423            bool operator < (const const_iterator1 &it) const {
1424                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1425                return it1_ < it.it1_;
1426            }
1427
1428        private:
1429            const_subiterator1_type it1_;
1430        };
1431#endif
1432
1433        BOOST_UBLAS_INLINE
1434        const_iterator1 begin1 () const {
1435            return find1 (0, 0, 0);
1436        }
1437        BOOST_UBLAS_INLINE
1438        const_iterator1 end1 () const {
1439            return find1 (0, size1 (), 0);
1440        }
1441
1442#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1443        class iterator1:
1444            public container_reference<banded_adaptor>,
1445            public random_access_iterator_base<typename iterator_restrict_traits<
1446                                                   typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
1447                                               iterator1, value_type> {
1448        public:
1449            typedef typename subiterator1_type::value_type value_type;
1450            typedef typename subiterator1_type::difference_type difference_type;
1451            typedef typename subiterator1_type::reference reference;
1452            typedef typename subiterator1_type::pointer pointer;
1453
1454            typedef iterator2 dual_iterator_type;
1455            typedef reverse_iterator2 dual_reverse_iterator_type;
1456
1457            // Construction and destruction
1458            BOOST_UBLAS_INLINE
1459            iterator1 ():
1460                container_reference<self_type> (), it1_ () {}
1461            BOOST_UBLAS_INLINE
1462            iterator1 (self_type &m, const subiterator1_type &it1):
1463                container_reference<self_type> (m), it1_ (it1) {}
1464
1465            // Arithmetic
1466            BOOST_UBLAS_INLINE
1467            iterator1 &operator ++ () {
1468                ++ it1_;
1469                return *this;
1470            }
1471            BOOST_UBLAS_INLINE
1472            iterator1 &operator -- () {
1473                -- it1_;
1474                return *this;
1475            }
1476            BOOST_UBLAS_INLINE
1477            iterator1 &operator += (difference_type n) {
1478                it1_ += n;
1479                return *this;
1480            }
1481            BOOST_UBLAS_INLINE
1482            iterator1 &operator -= (difference_type n) {
1483                it1_ -= n;
1484                return *this;
1485            }
1486            BOOST_UBLAS_INLINE
1487            difference_type operator - (const iterator1 &it) const {
1488                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1489                return it1_ - it.it1_;
1490            }
1491
1492            // Dereference
1493            BOOST_UBLAS_INLINE
1494            reference operator * () const {
1495                size_type i = index1 ();
1496                size_type j = index2 ();
1497                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
1498                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
1499#ifdef BOOST_UBLAS_OWN_BANDED
1500                size_type k = (std::max) (i, j);
1501                size_type l = (*this) ().lower () + j - i;
1502                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
1503                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1504                    return *it1_;
1505#else
1506                size_type k = j;
1507                size_type l = (*this) ().upper () + i - j;
1508                if (k < (*this) ().size2 () &&
1509                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1510                    return *it1_;
1511#endif
1512                return (*this) () (i, j);
1513            }
1514
1515#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1516            BOOST_UBLAS_INLINE
1517#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1518            typename self_type::
1519#endif
1520            iterator2 begin () const {
1521                return (*this) ().find2 (1, index1 (), 0);
1522            }
1523            BOOST_UBLAS_INLINE
1524#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1525            typename self_type::
1526#endif
1527            iterator2 end () const {
1528                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
1529            }
1530            BOOST_UBLAS_INLINE
1531#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1532            typename self_type::
1533#endif
1534            reverse_iterator2 rbegin () const {
1535                return reverse_iterator2 (end ());
1536            }
1537            BOOST_UBLAS_INLINE
1538#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1539            typename self_type::
1540#endif
1541            reverse_iterator2 rend () const {
1542                return reverse_iterator2 (begin ());
1543            }
1544#endif
1545
1546            // Indices
1547            BOOST_UBLAS_INLINE
1548            size_type index1 () const {
1549                return it1_.index1 ();
1550            }
1551            BOOST_UBLAS_INLINE
1552            size_type index2 () const {
1553                return it1_.index2 ();
1554            }
1555
1556            // Assignment
1557            BOOST_UBLAS_INLINE
1558            iterator1 &operator = (const iterator1 &it) {
1559                container_reference<self_type>::assign (&it ());
1560                it1_ = it.it1_;
1561                return *this;
1562            }
1563
1564            // Comparison
1565            BOOST_UBLAS_INLINE
1566            bool operator == (const iterator1 &it) const {
1567                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1568                return it1_ == it.it1_;
1569            }
1570            BOOST_UBLAS_INLINE
1571            bool operator < (const iterator1 &it) const {
1572                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1573                return it1_ < it.it1_;
1574            }
1575
1576        private:
1577            subiterator1_type it1_;
1578
1579            friend class const_iterator1;
1580        };
1581#endif
1582
1583        BOOST_UBLAS_INLINE
1584        iterator1 begin1 () {
1585            return find1 (0, 0, 0);
1586        }
1587        BOOST_UBLAS_INLINE
1588        iterator1 end1 () {
1589            return find1 (0, size1 (), 0);
1590        }
1591
1592#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1593        class const_iterator2:
1594            public container_const_reference<banded_adaptor>,
1595            public random_access_iterator_base<packed_random_access_iterator_tag,
1596                                               const_iterator2, value_type> {
1597        public:
1598            typedef typename iterator_restrict_traits<typename const_subiterator2_type::iterator_category,
1599                                                      packed_random_access_iterator_tag>::iterator_category iterator_category;
1600            typedef typename const_subiterator2_type::value_type value_type;
1601            typedef typename const_subiterator2_type::difference_type difference_type;
1602            typedef typename const_subiterator2_type::reference reference;
1603            typedef typename const_subiterator2_type::pointer pointer;
1604
1605            typedef const_iterator1 dual_iterator_type;
1606            typedef const_reverse_iterator1 dual_reverse_iterator_type;
1607
1608            // Construction and destruction
1609            BOOST_UBLAS_INLINE
1610            const_iterator2 ():
1611                container_const_reference<self_type> (), it2_ () {}
1612            BOOST_UBLAS_INLINE
1613            const_iterator2 (const self_type &m, const const_subiterator2_type &it2):
1614                container_const_reference<self_type> (m), it2_ (it2) {}
1615            BOOST_UBLAS_INLINE
1616            const_iterator2 (const iterator2 &it):
1617                container_const_reference<self_type> (it ()), it2_ (it.it2_) {}
1618
1619            // Arithmetic
1620            BOOST_UBLAS_INLINE
1621            const_iterator2 &operator ++ () {
1622                ++ it2_;
1623                return *this;
1624            }
1625            BOOST_UBLAS_INLINE
1626            const_iterator2 &operator -- () {
1627                -- it2_;
1628                return *this;
1629            }
1630            BOOST_UBLAS_INLINE
1631            const_iterator2 &operator += (difference_type n) {
1632                it2_ += n;
1633                return *this;
1634            }
1635            BOOST_UBLAS_INLINE
1636            const_iterator2 &operator -= (difference_type n) {
1637                it2_ -= n;
1638                return *this;
1639            }
1640            BOOST_UBLAS_INLINE
1641            difference_type operator - (const const_iterator2 &it) const {
1642                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1643                return it2_ - it.it2_;
1644            }
1645
1646            // Dereference
1647            BOOST_UBLAS_INLINE
1648            const_reference operator * () const {
1649                size_type i = index1 ();
1650                size_type j = index2 ();
1651                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
1652                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
1653#ifdef BOOST_UBLAS_OWN_BANDED
1654                size_type k = (std::max) (i, j);
1655                size_type l = (*this) ().lower () + j - i;
1656                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
1657                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1658                    return *it2_;
1659#else
1660                size_type k = j;
1661                size_type l = (*this) ().upper () + i - j;
1662                if (k < (*this) ().size2 () &&
1663                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1664                    return *it2_;
1665#endif
1666                return (*this) () (i, j);
1667            }
1668
1669#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1670            BOOST_UBLAS_INLINE
1671#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1672            typename self_type::
1673#endif
1674            const_iterator1 begin () const {
1675                return (*this) ().find1 (1, 0, index2 ());
1676            }
1677            BOOST_UBLAS_INLINE
1678#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1679            typename self_type::
1680#endif
1681            const_iterator1 end () const {
1682                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
1683            }
1684            BOOST_UBLAS_INLINE
1685#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1686            typename self_type::
1687#endif
1688            const_reverse_iterator1 rbegin () const {
1689                return const_reverse_iterator1 (end ());
1690            }
1691            BOOST_UBLAS_INLINE
1692#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1693            typename self_type::
1694#endif
1695            const_reverse_iterator1 rend () const {
1696                return const_reverse_iterator1 (begin ());
1697            }
1698#endif
1699
1700            // Indices
1701            BOOST_UBLAS_INLINE
1702            size_type index1 () const {
1703                return it2_.index1 ();
1704            }
1705            BOOST_UBLAS_INLINE
1706            size_type index2 () const {
1707                return it2_.index2 ();
1708            }
1709
1710            // Assignment
1711            BOOST_UBLAS_INLINE
1712            const_iterator2 &operator = (const const_iterator2 &it) {
1713                container_const_reference<self_type>::assign (&it ());
1714                it2_ = it.it2_;
1715                return *this;
1716            }
1717
1718            // Comparison
1719            BOOST_UBLAS_INLINE
1720            bool operator == (const const_iterator2 &it) const {
1721                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1722                return it2_ == it.it2_;
1723            }
1724            BOOST_UBLAS_INLINE
1725            bool operator < (const const_iterator2 &it) const {
1726                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1727                return it2_ < it.it2_;
1728            }
1729
1730        private:
1731            const_subiterator2_type it2_;
1732        };
1733#endif
1734
1735        BOOST_UBLAS_INLINE
1736        const_iterator2 begin2 () const {
1737            return find2 (0, 0, 0);
1738        }
1739        BOOST_UBLAS_INLINE
1740        const_iterator2 end2 () const {
1741            return find2 (0, 0, size2 ());
1742        }
1743
1744#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1745        class iterator2:
1746            public container_reference<banded_adaptor>,
1747            public random_access_iterator_base<typename iterator_restrict_traits<
1748                                                   typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
1749                                               iterator2, value_type> {
1750        public:
1751            typedef typename subiterator2_type::value_type value_type;
1752            typedef typename subiterator2_type::difference_type difference_type;
1753            typedef typename subiterator2_type::reference reference;
1754            typedef typename subiterator2_type::pointer pointer;
1755
1756            typedef iterator1 dual_iterator_type;
1757            typedef reverse_iterator1 dual_reverse_iterator_type;
1758
1759            // Construction and destruction
1760            BOOST_UBLAS_INLINE
1761            iterator2 ():
1762                container_reference<self_type> (), it2_ () {}
1763            BOOST_UBLAS_INLINE
1764            iterator2 (self_type &m, const subiterator2_type &it2):
1765                container_reference<self_type> (m), it2_ (it2) {}
1766
1767            // Arithmetic
1768            BOOST_UBLAS_INLINE
1769            iterator2 &operator ++ () {
1770                ++ it2_;
1771                return *this;
1772            }
1773            BOOST_UBLAS_INLINE
1774            iterator2 &operator -- () {
1775                -- it2_;
1776                return *this;
1777            }
1778            BOOST_UBLAS_INLINE
1779            iterator2 &operator += (difference_type n) {
1780                it2_ += n;
1781                return *this;
1782            }
1783            BOOST_UBLAS_INLINE
1784            iterator2 &operator -= (difference_type n) {
1785                it2_ -= n;
1786                return *this;
1787            }
1788            BOOST_UBLAS_INLINE
1789            difference_type operator - (const iterator2 &it) const {
1790                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1791                return it2_ - it.it2_;
1792            }
1793
1794            // Dereference
1795            BOOST_UBLAS_INLINE
1796            reference operator * () const {
1797                size_type i = index1 ();
1798                size_type j = index2 ();
1799                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
1800                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
1801#ifdef BOOST_UBLAS_OWN_BANDED
1802                size_type k = (std::max) (i, j);
1803                size_type l = (*this) ().lower () + j - i;
1804                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
1805                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1806                    return *it2_;
1807#else
1808                size_type k = j;
1809                size_type l = (*this) ().upper () + i - j;
1810                if (k < (*this) ().size2 () &&
1811                    l < (*this) ().lower () + 1 + (*this) ().upper ())
1812                    return *it2_;
1813#endif
1814                return (*this) () (i, j);
1815            }
1816
1817#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1818            BOOST_UBLAS_INLINE
1819#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1820            typename self_type::
1821#endif
1822            iterator1 begin () const {
1823                return (*this) ().find1 (1, 0, index2 ());
1824            }
1825            BOOST_UBLAS_INLINE
1826#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1827            typename self_type::
1828#endif
1829            iterator1 end () const {
1830                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
1831            }
1832            BOOST_UBLAS_INLINE
1833#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1834            typename self_type::
1835#endif
1836            reverse_iterator1 rbegin () const {
1837                return reverse_iterator1 (end ());
1838            }
1839            BOOST_UBLAS_INLINE
1840#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1841            typename self_type::
1842#endif
1843            reverse_iterator1 rend () const {
1844                return reverse_iterator1 (begin ());
1845            }
1846#endif
1847
1848            // Indices
1849            BOOST_UBLAS_INLINE
1850            size_type index1 () const {
1851                return it2_.index1 ();
1852            }
1853            BOOST_UBLAS_INLINE
1854            size_type index2 () const {
1855                return it2_.index2 ();
1856            }
1857
1858            // Assignment
1859            BOOST_UBLAS_INLINE
1860            iterator2 &operator = (const iterator2 &it) {
1861                container_reference<self_type>::assign (&it ());
1862                it2_ = it.it2_;
1863                return *this;
1864            }
1865
1866            // Comparison
1867            BOOST_UBLAS_INLINE
1868            bool operator == (const iterator2 &it) const {
1869                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1870                return it2_ == it.it2_;
1871            }
1872            BOOST_UBLAS_INLINE
1873            bool operator < (const iterator2 &it) const {
1874                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1875                return it2_ < it.it2_;
1876            }
1877
1878        private:
1879            subiterator2_type it2_;
1880
1881            friend class const_iterator2;
1882        };
1883#endif
1884
1885        BOOST_UBLAS_INLINE
1886        iterator2 begin2 () {
1887            return find2 (0, 0, 0);
1888        }
1889        BOOST_UBLAS_INLINE
1890        iterator2 end2 () {
1891            return find2 (0, 0, size2 ());
1892        }
1893
1894        // Reverse iterators
1895
1896        BOOST_UBLAS_INLINE
1897        const_reverse_iterator1 rbegin1 () const {
1898            return const_reverse_iterator1 (end1 ());
1899        }
1900        BOOST_UBLAS_INLINE
1901        const_reverse_iterator1 rend1 () const {
1902            return const_reverse_iterator1 (begin1 ());
1903        }
1904
1905        BOOST_UBLAS_INLINE
1906        reverse_iterator1 rbegin1 () {
1907            return reverse_iterator1 (end1 ());
1908        }
1909        BOOST_UBLAS_INLINE
1910        reverse_iterator1 rend1 () {
1911            return reverse_iterator1 (begin1 ());
1912        }
1913
1914        BOOST_UBLAS_INLINE
1915        const_reverse_iterator2 rbegin2 () const {
1916            return const_reverse_iterator2 (end2 ());
1917        }
1918        BOOST_UBLAS_INLINE
1919        const_reverse_iterator2 rend2 () const {
1920            return const_reverse_iterator2 (begin2 ());
1921        }
1922
1923        BOOST_UBLAS_INLINE
1924        reverse_iterator2 rbegin2 () {
1925            return reverse_iterator2 (end2 ());
1926        }
1927        BOOST_UBLAS_INLINE
1928        reverse_iterator2 rend2 () {
1929            return reverse_iterator2 (begin2 ());
1930        }
1931
1932    private:
1933        matrix_closure_type data_;
1934        size_type lower_;
1935        size_type upper_;
1936        typedef const value_type const_value_type;
1937        static const_value_type zero_;
1938    };
1939
1940    // Specialization for temporary_traits
1941    template <class M>
1942    struct vector_temporary_traits< banded_adaptor<M> >
1943    : vector_temporary_traits< M > {} ;
1944
1945    template <class M>
1946    struct matrix_temporary_traits< banded_adaptor<M> >
1947    : matrix_temporary_traits< M > {} ;
1948
1949
1950    template<class M>
1951    typename banded_adaptor<M>::const_value_type banded_adaptor<M>::zero_ = value_type/*zero*/();
1952
1953    // Diagonal matrix adaptor class
1954    template<class M>
1955    class diagonal_adaptor:
1956        public banded_adaptor<M> {
1957    public:
1958        typedef M matrix_type;
1959        typedef banded_adaptor<M> adaptor_type;
1960
1961        // Construction and destruction
1962        BOOST_UBLAS_INLINE
1963        diagonal_adaptor ():
1964            adaptor_type () {}
1965        BOOST_UBLAS_INLINE
1966        diagonal_adaptor (matrix_type &data):
1967            adaptor_type (data) {}
1968        BOOST_UBLAS_INLINE
1969        ~diagonal_adaptor () {}
1970
1971        // Assignment
1972        BOOST_UBLAS_INLINE
1973        diagonal_adaptor &operator = (const diagonal_adaptor &m) {
1974            adaptor_type::operator = (m);
1975            return *this;
1976        }
1977        template<class AE>
1978        BOOST_UBLAS_INLINE
1979        diagonal_adaptor &operator = (const matrix_expression<AE> &ae) {
1980            adaptor_type::operator = (ae);
1981            return *this;
1982        }
1983    };
1984
1985}}}
1986
1987#endif
Note: See TracBrowser for help on using the repository browser.