Update contrib.
2 // Copyright (c) 2000-2002
3 // Joerg Walter, Mathias Koch
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.
13 // The authors gratefully acknowledge the support of
14 // GeNeSys mbH & Co. KG in producing this work.
17 #ifndef _BOOST_UBLAS_BANDED_
18 #define _BOOST_UBLAS_BANDED_
20 #include <boost/numeric/ublas/matrix.hpp>
21 #include <boost/numeric/ublas/detail/temporary.hpp>
23 // Iterators based on ideas of Jeremy Siek
25 namespace boost { namespace numeric { namespace ublas {
27 // Array based banded matrix class
28 template<class T, class L, class A>
30 public matrix_container<banded_matrix<T, L, A> > {
33 typedef L layout_type;
34 typedef banded_matrix<T, L, A> self_type;
36 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
37 using matrix_container<self_type>::operator ();
39 typedef typename A::size_type size_type;
40 typedef typename A::difference_type difference_type;
42 typedef const T &const_reference;
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;
52 // Construction and destruction
55 matrix_container<self_type> (),
56 size1_ (0), size2_ (0),
57 lower_ (0), upper_ (0), data_ (0) {}
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)) {
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) {}
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_) {}
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);
86 size_type size1 () const {
90 size_type size2 () const {
94 size_type lower () const {
98 size_type upper () const {
104 const array_type &data () const {
108 array_type &data () {
114 void resize (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0, bool preserve = true) {
116 self_type temporary (size1, size2, lower, upper);
117 detail::matrix_resize_preserve<layout_type> (*this, temporary);
120 data ().resize ((std::max) (size1, size2) * (lower + 1 + upper));
129 void resize_packed_preserve (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0) {
134 data ().resize ((std::max) (size1, size2) * (lower + 1 + upper), value_type ());
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_)];
150 const size_type k = j;
151 const size_type l = upper_ + i - j;
153 l < lower_ + 1 + upper_)
154 return data () [layout_type::element (k, size2_,
155 l, lower_ + 1 + upper_)];
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_)];
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_)];
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_)];
187 const size_type k = j;
188 const size_type l = upper_ + i - j;
190 l < lower_ + 1 + upper_)
191 return data () [layout_type::element (k, size2_,
192 l, lower_ + 1 + upper_)];
194 bad_index ().raise ();
195 // arbitary return value
196 return const_cast<reference>(zero_);
199 // Element assignment
201 reference insert_element (size_type i, size_type j, const_reference t) {
202 return (operator () (i, j) = t);
205 void erase_element (size_type i, size_type j) {
206 operator () (i, j) = value_type/*zero*/();
212 std::fill (data ().begin (), data ().end (), value_type/*zero*/());
217 banded_matrix &operator = (const banded_matrix &m) {
226 banded_matrix &assign_temporary (banded_matrix &m) {
232 banded_matrix &operator = (const matrix_expression<AE> &ae) {
233 self_type temporary (ae, lower_, upper_);
234 return assign_temporary (temporary);
238 banded_matrix &assign (const matrix_expression<AE> &ae) {
239 matrix_assign<scalar_assign> (*this, ae);
244 banded_matrix& operator += (const matrix_expression<AE> &ae) {
245 self_type temporary (*this + ae, lower_, upper_);
246 return assign_temporary (temporary);
250 banded_matrix &plus_assign (const matrix_expression<AE> &ae) {
251 matrix_assign<scalar_plus_assign> (*this, ae);
256 banded_matrix& operator -= (const matrix_expression<AE> &ae) {
257 self_type temporary (*this - ae, lower_, upper_);
258 return assign_temporary (temporary);
262 banded_matrix &minus_assign (const matrix_expression<AE> &ae) {
263 matrix_assign<scalar_minus_assign> (*this, ae);
268 banded_matrix& operator *= (const AT &at) {
269 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
274 banded_matrix& operator /= (const AT &at) {
275 matrix_assign_scalar<scalar_divides_assign> (*this, at);
281 void swap (banded_matrix &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 ());
291 friend void swap (banded_matrix &m1, banded_matrix &m2) {
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;
302 class const_iterator1;
304 class const_iterator2;
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;
314 const_iterator1 find1 (int rank, size_type i, size_type j) const {
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);
321 return const_iterator1 (*this, i, j);
324 iterator1 find1 (int rank, size_type i, size_type j) {
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);
331 return iterator1 (*this, i, j);
334 const_iterator2 find2 (int rank, size_type i, size_type j) const {
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);
341 return const_iterator2 (*this, i, j);
344 iterator2 find2 (int rank, size_type i, size_type j) {
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);
351 return iterator2 (*this, i, j);
354 // Iterators simply are indices.
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> {
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;
367 typedef const_iterator2 dual_iterator_type;
368 typedef const_reverse_iterator2 dual_reverse_iterator_type;
370 // Construction and destruction
373 container_const_reference<self_type> (), it1_ (), it2_ () {}
375 const_iterator1 (const self_type &m, size_type it1, size_type it2):
376 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
378 const_iterator1 (const iterator1 &it):
379 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
383 const_iterator1 &operator ++ () {
388 const_iterator1 &operator -- () {
393 const_iterator1 &operator += (difference_type n) {
398 const_iterator1 &operator -= (difference_type n) {
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_;
411 const_reference operator * () const {
412 return (*this) () (it1_, it2_);
415 const_reference operator [] (difference_type n) const {
419 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
421 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
424 const_iterator2 begin () const {
425 return (*this) ().find2 (1, it1_, 0);
428 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
431 const_iterator2 end () const {
432 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
435 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
438 const_reverse_iterator2 rbegin () const {
439 return const_reverse_iterator2 (end ());
442 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
445 const_reverse_iterator2 rend () const {
446 return const_reverse_iterator2 (begin ());
452 size_type index1 () const {
456 size_type index2 () const {
462 const_iterator1 &operator = (const const_iterator1 &it) {
463 container_const_reference<self_type>::assign (&it ());
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_;
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_;
490 const_iterator1 begin1 () const {
491 return find1 (0, 0, 0);
494 const_iterator1 end1 () const {
495 return find1 (0, size1_, 0);
498 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
500 public container_reference<banded_matrix>,
501 public random_access_iterator_base<packed_random_access_iterator_tag,
502 iterator1, value_type> {
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;
509 typedef iterator2 dual_iterator_type;
510 typedef reverse_iterator2 dual_reverse_iterator_type;
512 // Construction and destruction
515 container_reference<self_type> (), it1_ (), it2_ () {}
517 iterator1 (self_type &m, size_type it1, size_type it2):
518 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
522 iterator1 &operator ++ () {
527 iterator1 &operator -- () {
532 iterator1 &operator += (difference_type n) {
537 iterator1 &operator -= (difference_type n) {
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_;
550 reference operator * () const {
551 return (*this) ().at_element (it1_, it2_);
554 reference operator [] (difference_type n) const {
558 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
560 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
563 iterator2 begin () const {
564 return (*this) ().find2 (1, it1_, 0);
567 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
570 iterator2 end () const {
571 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
574 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
577 reverse_iterator2 rbegin () const {
578 return reverse_iterator2 (end ());
581 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
584 reverse_iterator2 rend () const {
585 return reverse_iterator2 (begin ());
591 size_type index1 () const {
595 size_type index2 () const {
601 iterator1 &operator = (const iterator1 &it) {
602 container_reference<self_type>::assign (&it ());
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_;
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_;
626 friend class const_iterator1;
631 iterator1 begin1 () {
632 return find1 (0, 0, 0);
636 return find1 (0, size1_, 0);
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> {
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;
650 typedef const_iterator1 dual_iterator_type;
651 typedef const_reverse_iterator1 dual_reverse_iterator_type;
653 // Construction and destruction
656 container_const_reference<self_type> (), it1_ (), it2_ () {}
658 const_iterator2 (const self_type &m, size_type it1, size_type it2):
659 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
661 const_iterator2 (const iterator2 &it):
662 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
666 const_iterator2 &operator ++ () {
671 const_iterator2 &operator -- () {
676 const_iterator2 &operator += (difference_type n) {
681 const_iterator2 &operator -= (difference_type n) {
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_;
694 const_reference operator * () const {
695 return (*this) () (it1_, it2_);
698 const_reference operator [] (difference_type n) const {
702 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
704 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
707 const_iterator1 begin () const {
708 return (*this) ().find1 (1, 0, it2_);
711 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
714 const_iterator1 end () const {
715 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
718 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
721 const_reverse_iterator1 rbegin () const {
722 return const_reverse_iterator1 (end ());
725 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
728 const_reverse_iterator1 rend () const {
729 return const_reverse_iterator1 (begin ());
735 size_type index1 () const {
739 size_type index2 () const {
745 const_iterator2 &operator = (const const_iterator2 &it) {
746 container_const_reference<self_type>::assign (&it ());
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_;
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_;
773 const_iterator2 begin2 () const {
774 return find2 (0, 0, 0);
777 const_iterator2 end2 () const {
778 return find2 (0, 0, size2_);
781 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
783 public container_reference<banded_matrix>,
784 public random_access_iterator_base<packed_random_access_iterator_tag,
785 iterator2, value_type> {
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;
792 typedef iterator1 dual_iterator_type;
793 typedef reverse_iterator1 dual_reverse_iterator_type;
795 // Construction and destruction
798 container_reference<self_type> (), it1_ (), it2_ () {}
800 iterator2 (self_type &m, size_type it1, size_type it2):
801 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
805 iterator2 &operator ++ () {
810 iterator2 &operator -- () {
815 iterator2 &operator += (difference_type n) {
820 iterator2 &operator -= (difference_type n) {
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_;
833 reference operator * () const {
834 return (*this) ().at_element (it1_, it2_);
837 reference operator [] (difference_type n) const {
841 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
843 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
846 iterator1 begin () const {
847 return (*this) ().find1 (1, 0, it2_);
850 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
853 iterator1 end () const {
854 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
857 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
860 reverse_iterator1 rbegin () const {
861 return reverse_iterator1 (end ());
864 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
867 reverse_iterator1 rend () const {
868 return reverse_iterator1 (begin ());
874 size_type index1 () const {
878 size_type index2 () const {
884 iterator2 &operator = (const iterator2 &it) {
885 container_reference<self_type>::assign (&it ());
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_;
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_;
909 friend class const_iterator2;
914 iterator2 begin2 () {
915 return find2 (0, 0, 0);
919 return find2 (0, 0, size2_);
925 const_reverse_iterator1 rbegin1 () const {
926 return const_reverse_iterator1 (end1 ());
929 const_reverse_iterator1 rend1 () const {
930 return const_reverse_iterator1 (begin1 ());
934 reverse_iterator1 rbegin1 () {
935 return reverse_iterator1 (end1 ());
938 reverse_iterator1 rend1 () {
939 return reverse_iterator1 (begin1 ());
943 const_reverse_iterator2 rbegin2 () const {
944 return const_reverse_iterator2 (end2 ());
947 const_reverse_iterator2 rend2 () const {
948 return const_reverse_iterator2 (begin2 ());
952 reverse_iterator2 rbegin2 () {
953 return reverse_iterator2 (end2 ());
956 reverse_iterator2 rend2 () {
957 return reverse_iterator2 (begin2 ());
966 typedef const value_type const_value_type;
967 static const_value_type zero_;
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*/();
974 // Diagonal matrix class
975 template<class T, class L, class A>
976 class diagonal_matrix:
977 public banded_matrix<T, L, A> {
979 typedef typename A::size_type size_type;
980 typedef banded_matrix<T, L, A> matrix_type;
981 typedef A array_type;
983 // Construction and destruction
988 diagonal_matrix (size_type size):
989 matrix_type (size, size) {}
991 diagonal_matrix (size_type size, const array_type& data):
992 matrix_type (size, size, 0, 0, data) {}
994 diagonal_matrix (size_type size1, size_type size2):
995 matrix_type (size1, size2) {}
998 diagonal_matrix (const matrix_expression<AE> &ae):
1001 ~diagonal_matrix () {}
1005 diagonal_matrix &operator = (const diagonal_matrix &m) {
1006 matrix_type::operator = (m);
1011 diagonal_matrix &operator = (const matrix_expression<AE> &ae) {
1012 matrix_type::operator = (ae);
1017 // Banded matrix adaptor class
1019 class banded_adaptor:
1020 public matrix_expression<banded_adaptor<M> > {
1022 typedef banded_adaptor<M> self_type;
1024 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1025 using matrix_expression<self_type>::operator ();
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;
1048 // Construction and destruction
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) {}
1054 banded_adaptor (const banded_adaptor &m):
1055 matrix_expression<self_type> (),
1056 data_ (m.data_), lower_ (m.lower_), upper_ (m.upper_) {}
1060 size_type size1 () const {
1061 return data_.size1 ();
1064 size_type size2 () const {
1065 return data_.size2 ();
1068 size_type lower () const {
1072 size_type upper () const {
1076 // Storage accessors
1078 const matrix_closure_type &data () const {
1082 matrix_closure_type &data () {
1087 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
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);
1100 size_type l = upper_ + i - j;
1102 l < lower_ + 1 + upper_)
1103 return data () (i, j);
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);
1119 size_type l = upper_ + i - j;
1121 l < lower_ + 1 + upper_)
1122 return data () (i, j);
1124 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
1125 bad_index ().raise ();
1127 return const_cast<reference>(zero_);
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);
1142 size_type l = upper_ + i - j;
1144 l < lower_ + 1 + upper_)
1145 return data () (i, j);
1147 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
1148 bad_index ().raise ();
1150 return const_cast<reference>(zero_);
1156 banded_adaptor &operator = (const banded_adaptor &m) {
1157 matrix_assign<scalar_assign> (*this, m);
1161 banded_adaptor &assign_temporary (banded_adaptor &m) {
1167 banded_adaptor &operator = (const matrix_expression<AE> &ae) {
1168 matrix_assign<scalar_assign> (*this, matrix<value_type> (ae));
1173 banded_adaptor &assign (const matrix_expression<AE> &ae) {
1174 matrix_assign<scalar_assign> (*this, ae);
1179 banded_adaptor& operator += (const matrix_expression<AE> &ae) {
1180 matrix_assign<scalar_assign> (*this, matrix<value_type> (*this + ae));
1185 banded_adaptor &plus_assign (const matrix_expression<AE> &ae) {
1186 matrix_assign<scalar_plus_assign> (*this, ae);
1191 banded_adaptor& operator -= (const matrix_expression<AE> &ae) {
1192 matrix_assign<scalar_assign> (*this, matrix<value_type> (*this - ae));
1197 banded_adaptor &minus_assign (const matrix_expression<AE> &ae) {
1198 matrix_assign<scalar_minus_assign> (*this, ae);
1203 banded_adaptor& operator *= (const AT &at) {
1204 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
1209 banded_adaptor& operator /= (const AT &at) {
1210 matrix_assign_scalar<scalar_divides_assign> (*this, at);
1214 // Closure comparison
1216 bool same_closure (const banded_adaptor &ba) const {
1217 return (*this).data ().same_closure (ba.data ());
1222 void swap (banded_adaptor &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);
1230 friend void swap (banded_adaptor &m1, banded_adaptor &m2) {
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;
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;
1253 class const_iterator1;
1255 class const_iterator2;
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;
1265 const_iterator1 find1 (int rank, size_type i, size_type j) const {
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);
1272 return const_iterator1 (*this, data ().find1 (rank, i, j));
1275 iterator1 find1 (int rank, size_type i, size_type j) {
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);
1282 return iterator1 (*this, data ().find1 (rank, i, j));
1285 const_iterator2 find2 (int rank, size_type i, size_type j) const {
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);
1292 return const_iterator2 (*this, data ().find2 (rank, i, j));
1295 iterator2 find2 (int rank, size_type i, size_type j) {
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);
1302 return iterator2 (*this, data ().find2 (rank, i, j));
1305 // Iterators simply are indices.
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> {
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;
1319 typedef const_iterator2 dual_iterator_type;
1320 typedef const_reverse_iterator2 dual_reverse_iterator_type;
1322 // Construction and destruction
1325 container_const_reference<self_type> (), it1_ () {}
1327 const_iterator1 (const self_type &m, const const_subiterator1_type &it1):
1328 container_const_reference<self_type> (m), it1_ (it1) {}
1330 const_iterator1 (const iterator1 &it):
1331 container_const_reference<self_type> (it ()), it1_ (it.it1_) {}
1335 const_iterator1 &operator ++ () {
1340 const_iterator1 &operator -- () {
1345 const_iterator1 &operator += (difference_type n) {
1350 const_iterator1 &operator -= (difference_type n) {
1355 difference_type operator - (const const_iterator1 &it) const {
1356 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1357 return it1_ - it.it1_;
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 ())
1375 size_type l = (*this) ().upper () + i - j;
1376 if (k < (*this) ().size2 () &&
1377 l < (*this) ().lower () + 1 + (*this) ().upper ())
1380 return (*this) () (i, j);
1383 const_reference operator [] (difference_type n) const {
1384 return *(*this + n);
1387 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1389 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1390 typename self_type::
1392 const_iterator2 begin () const {
1393 return (*this) ().find2 (1, index1 (), 0);
1396 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1397 typename self_type::
1399 const_iterator2 end () const {
1400 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
1403 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1404 typename self_type::
1406 const_reverse_iterator2 rbegin () const {
1407 return const_reverse_iterator2 (end ());
1410 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1411 typename self_type::
1413 const_reverse_iterator2 rend () const {
1414 return const_reverse_iterator2 (begin ());
1420 size_type index1 () const {
1421 return it1_.index1 ();
1424 size_type index2 () const {
1425 return it1_.index2 ();
1430 const_iterator1 &operator = (const const_iterator1 &it) {
1431 container_const_reference<self_type>::assign (&it ());
1438 bool operator == (const const_iterator1 &it) const {
1439 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1440 return it1_ == it.it1_;
1443 bool operator < (const const_iterator1 &it) const {
1444 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1445 return it1_ < it.it1_;
1449 const_subiterator1_type it1_;
1454 const_iterator1 begin1 () const {
1455 return find1 (0, 0, 0);
1458 const_iterator1 end1 () const {
1459 return find1 (0, size1 (), 0);
1462 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
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> {
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;
1474 typedef iterator2 dual_iterator_type;
1475 typedef reverse_iterator2 dual_reverse_iterator_type;
1477 // Construction and destruction
1480 container_reference<self_type> (), it1_ () {}
1482 iterator1 (self_type &m, const subiterator1_type &it1):
1483 container_reference<self_type> (m), it1_ (it1) {}
1487 iterator1 &operator ++ () {
1492 iterator1 &operator -- () {
1497 iterator1 &operator += (difference_type n) {
1502 iterator1 &operator -= (difference_type n) {
1507 difference_type operator - (const iterator1 &it) const {
1508 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1509 return it1_ - it.it1_;
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 ())
1527 size_type l = (*this) ().upper () + i - j;
1528 if (k < (*this) ().size2 () &&
1529 l < (*this) ().lower () + 1 + (*this) ().upper ())
1532 return (*this) () (i, j);
1535 reference operator [] (difference_type n) const {
1536 return *(*this + n);
1539 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1541 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1542 typename self_type::
1544 iterator2 begin () const {
1545 return (*this) ().find2 (1, index1 (), 0);
1548 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1549 typename self_type::
1551 iterator2 end () const {
1552 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
1555 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1556 typename self_type::
1558 reverse_iterator2 rbegin () const {
1559 return reverse_iterator2 (end ());
1562 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1563 typename self_type::
1565 reverse_iterator2 rend () const {
1566 return reverse_iterator2 (begin ());
1572 size_type index1 () const {
1573 return it1_.index1 ();
1576 size_type index2 () const {
1577 return it1_.index2 ();
1582 iterator1 &operator = (const iterator1 &it) {
1583 container_reference<self_type>::assign (&it ());
1590 bool operator == (const iterator1 &it) const {
1591 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1592 return it1_ == it.it1_;
1595 bool operator < (const iterator1 &it) const {
1596 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1597 return it1_ < it.it1_;
1601 subiterator1_type it1_;
1603 friend class const_iterator1;
1608 iterator1 begin1 () {
1609 return find1 (0, 0, 0);
1613 return find1 (0, size1 (), 0);
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> {
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;
1629 typedef const_iterator1 dual_iterator_type;
1630 typedef const_reverse_iterator1 dual_reverse_iterator_type;
1632 // Construction and destruction
1635 container_const_reference<self_type> (), it2_ () {}
1637 const_iterator2 (const self_type &m, const const_subiterator2_type &it2):
1638 container_const_reference<self_type> (m), it2_ (it2) {}
1640 const_iterator2 (const iterator2 &it):
1641 container_const_reference<self_type> (it ()), it2_ (it.it2_) {}
1645 const_iterator2 &operator ++ () {
1650 const_iterator2 &operator -- () {
1655 const_iterator2 &operator += (difference_type n) {
1660 const_iterator2 &operator -= (difference_type n) {
1665 difference_type operator - (const const_iterator2 &it) const {
1666 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1667 return it2_ - it.it2_;
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 ())
1685 size_type l = (*this) ().upper () + i - j;
1686 if (k < (*this) ().size2 () &&
1687 l < (*this) ().lower () + 1 + (*this) ().upper ())
1690 return (*this) () (i, j);
1693 const_reference operator [] (difference_type n) const {
1694 return *(*this + n);
1697 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1699 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1700 typename self_type::
1702 const_iterator1 begin () const {
1703 return (*this) ().find1 (1, 0, index2 ());
1706 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1707 typename self_type::
1709 const_iterator1 end () const {
1710 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
1713 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1714 typename self_type::
1716 const_reverse_iterator1 rbegin () const {
1717 return const_reverse_iterator1 (end ());
1720 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1721 typename self_type::
1723 const_reverse_iterator1 rend () const {
1724 return const_reverse_iterator1 (begin ());
1730 size_type index1 () const {
1731 return it2_.index1 ();
1734 size_type index2 () const {
1735 return it2_.index2 ();
1740 const_iterator2 &operator = (const const_iterator2 &it) {
1741 container_const_reference<self_type>::assign (&it ());
1748 bool operator == (const const_iterator2 &it) const {
1749 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1750 return it2_ == it.it2_;
1753 bool operator < (const const_iterator2 &it) const {
1754 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1755 return it2_ < it.it2_;
1759 const_subiterator2_type it2_;
1764 const_iterator2 begin2 () const {
1765 return find2 (0, 0, 0);
1768 const_iterator2 end2 () const {
1769 return find2 (0, 0, size2 ());
1772 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
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> {
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;
1784 typedef iterator1 dual_iterator_type;
1785 typedef reverse_iterator1 dual_reverse_iterator_type;
1787 // Construction and destruction
1790 container_reference<self_type> (), it2_ () {}
1792 iterator2 (self_type &m, const subiterator2_type &it2):
1793 container_reference<self_type> (m), it2_ (it2) {}
1797 iterator2 &operator ++ () {
1802 iterator2 &operator -- () {
1807 iterator2 &operator += (difference_type n) {
1812 iterator2 &operator -= (difference_type n) {
1817 difference_type operator - (const iterator2 &it) const {
1818 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1819 return it2_ - it.it2_;
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 ())
1837 size_type l = (*this) ().upper () + i - j;
1838 if (k < (*this) ().size2 () &&
1839 l < (*this) ().lower () + 1 + (*this) ().upper ())
1842 return (*this) () (i, j);
1845 reference operator [] (difference_type n) const {
1846 return *(*this + n);
1849 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1851 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1852 typename self_type::
1854 iterator1 begin () const {
1855 return (*this) ().find1 (1, 0, index2 ());
1858 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1859 typename self_type::
1861 iterator1 end () const {
1862 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
1865 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1866 typename self_type::
1868 reverse_iterator1 rbegin () const {
1869 return reverse_iterator1 (end ());
1872 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1873 typename self_type::
1875 reverse_iterator1 rend () const {
1876 return reverse_iterator1 (begin ());
1882 size_type index1 () const {
1883 return it2_.index1 ();
1886 size_type index2 () const {
1887 return it2_.index2 ();
1892 iterator2 &operator = (const iterator2 &it) {
1893 container_reference<self_type>::assign (&it ());
1900 bool operator == (const iterator2 &it) const {
1901 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1902 return it2_ == it.it2_;
1905 bool operator < (const iterator2 &it) const {
1906 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1907 return it2_ < it.it2_;
1911 subiterator2_type it2_;
1913 friend class const_iterator2;
1918 iterator2 begin2 () {
1919 return find2 (0, 0, 0);
1923 return find2 (0, 0, size2 ());
1926 // Reverse iterators
1929 const_reverse_iterator1 rbegin1 () const {
1930 return const_reverse_iterator1 (end1 ());
1933 const_reverse_iterator1 rend1 () const {
1934 return const_reverse_iterator1 (begin1 ());
1938 reverse_iterator1 rbegin1 () {
1939 return reverse_iterator1 (end1 ());
1942 reverse_iterator1 rend1 () {
1943 return reverse_iterator1 (begin1 ());
1947 const_reverse_iterator2 rbegin2 () const {
1948 return const_reverse_iterator2 (end2 ());
1951 const_reverse_iterator2 rend2 () const {
1952 return const_reverse_iterator2 (begin2 ());
1956 reverse_iterator2 rbegin2 () {
1957 return reverse_iterator2 (end2 ());
1960 reverse_iterator2 rend2 () {
1961 return reverse_iterator2 (begin2 ());
1965 matrix_closure_type data_;
1968 typedef const value_type const_value_type;
1969 static const_value_type zero_;
1972 // Specialization for temporary_traits
1974 struct vector_temporary_traits< banded_adaptor<M> >
1975 : vector_temporary_traits< M > {} ;
1977 struct vector_temporary_traits< const banded_adaptor<M> >
1978 : vector_temporary_traits< M > {} ;
1981 struct matrix_temporary_traits< banded_adaptor<M> >
1982 : matrix_temporary_traits< M > {} ;
1984 struct matrix_temporary_traits< const banded_adaptor<M> >
1985 : matrix_temporary_traits< M > {} ;
1989 typename banded_adaptor<M>::const_value_type banded_adaptor<M>::zero_ = value_type/*zero*/();
1991 // Diagonal matrix adaptor class
1993 class diagonal_adaptor:
1994 public banded_adaptor<M> {
1996 typedef M matrix_type;
1997 typedef banded_adaptor<M> adaptor_type;
1999 // Construction and destruction
2001 diagonal_adaptor ():
2004 diagonal_adaptor (matrix_type &data):
2005 adaptor_type (data) {}
2007 ~diagonal_adaptor () {}
2011 diagonal_adaptor &operator = (const diagonal_adaptor &m) {
2012 adaptor_type::operator = (m);
2017 diagonal_adaptor &operator = (const matrix_expression<AE> &ae) {
2018 adaptor_type::operator = (ae);