File indexing completed on 2024-11-15 09:20:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_UBLAS_HERMITIAN_H
0014 #define BOOST_UBLAS_HERMITIAN_H
0015
0016 #include <boost/numeric/ublas/matrix.hpp>
0017 #include <boost/numeric/ublas/triangular.hpp> // for resize_preserve
0018 #include <boost/numeric/ublas/detail/temporary.hpp>
0019
0020
0021
0022
0023 namespace boost { namespace numeric { namespace ublas {
0024
0025 template<class M>
0026 bool is_hermitian (const M &m) {
0027 typedef typename M::size_type size_type;
0028
0029 if (m.size1 () != m.size2 ())
0030 return false;
0031 size_type size = BOOST_UBLAS_SAME (m.size1 (), m.size2 ());
0032 for (size_type i = 0; i < size; ++ i) {
0033 for (size_type j = i; j < size; ++ j) {
0034 if (m (i, j) != conj (m (j, i)))
0035 return false;
0036 }
0037 }
0038 return true;
0039 }
0040
0041 #ifdef BOOST_UBLAS_STRICT_HERMITIAN
0042
0043 template<class M>
0044 class hermitian_matrix_element:
0045 public container_reference<M> {
0046 public:
0047 typedef M matrix_type;
0048 typedef typename M::size_type size_type;
0049 typedef typename M::value_type value_type;
0050 typedef const value_type &const_reference;
0051 typedef value_type &reference;
0052 typedef value_type *pointer;
0053
0054
0055 BOOST_UBLAS_INLINE
0056 hermitian_matrix_element (matrix_type &m, size_type i, size_type j, value_type d):
0057 container_reference<matrix_type> (m), i_ (i), j_ (j), d_ (d), dirty_ (false) {}
0058 BOOST_UBLAS_INLINE
0059 ~hermitian_matrix_element () {
0060 if (dirty_)
0061 (*this) ().insert_element (i_, j_, d_);
0062 }
0063
0064
0065 BOOST_UBLAS_INLINE
0066 hermitian_matrix_element &operator = (const hermitian_matrix_element &p) {
0067
0068 d_ = p.d_;
0069 dirty_ = true;
0070 return *this;
0071 }
0072 template<class D>
0073 BOOST_UBLAS_INLINE
0074 hermitian_matrix_element &operator = (const D &d) {
0075 d_ = d;
0076 dirty_ = true;
0077 return *this;
0078 }
0079 template<class D>
0080 BOOST_UBLAS_INLINE
0081 hermitian_matrix_element &operator += (const D &d) {
0082 d_ += d;
0083 dirty_ = true;
0084 return *this;
0085 }
0086 template<class D>
0087 BOOST_UBLAS_INLINE
0088 hermitian_matrix_element &operator -= (const D &d) {
0089 d_ -= d;
0090 dirty_ = true;
0091 return *this;
0092 }
0093 template<class D>
0094 BOOST_UBLAS_INLINE
0095 hermitian_matrix_element &operator *= (const D &d) {
0096 d_ *= d;
0097 dirty_ = true;
0098 return *this;
0099 }
0100 template<class D>
0101 BOOST_UBLAS_INLINE
0102 hermitian_matrix_element &operator /= (const D &d) {
0103 d_ /= d;
0104 dirty_ = true;
0105 return *this;
0106 }
0107
0108
0109 template<class D>
0110 BOOST_UBLAS_INLINE
0111 bool operator == (const D &d) const {
0112 return d_ == d;
0113 }
0114 template<class D>
0115 BOOST_UBLAS_INLINE
0116 bool operator != (const D &d) const {
0117 return d_ != d;
0118 }
0119
0120
0121 BOOST_UBLAS_INLINE
0122 operator const_reference () const {
0123 return d_;
0124 }
0125
0126
0127 BOOST_UBLAS_INLINE
0128 void swap (hermitian_matrix_element p) {
0129 if (this != &p) {
0130 dirty_ = true;
0131 p.dirty_ = true;
0132 std::swap (d_, p.d_);
0133 }
0134 }
0135 BOOST_UBLAS_INLINE
0136 friend void swap (hermitian_matrix_element p1, hermitian_matrix_element p2) {
0137 p1.swap (p2);
0138 }
0139
0140 private:
0141 size_type i_;
0142 size_type j_;
0143 value_type d_;
0144 bool dirty_;
0145 };
0146
0147 template<class M>
0148 struct type_traits<hermitian_matrix_element<M> > {
0149 typedef typename M::value_type element_type;
0150 typedef type_traits<hermitian_matrix_element<M> > self_type;
0151 typedef typename type_traits<element_type>::value_type value_type;
0152 typedef typename type_traits<element_type>::const_reference const_reference;
0153 typedef hermitian_matrix_element<M> reference;
0154 typedef typename type_traits<element_type>::real_type real_type;
0155 typedef typename type_traits<element_type>::precision_type precision_type;
0156
0157 static const unsigned plus_complexity = type_traits<element_type>::plus_complexity;
0158 static const unsigned multiplies_complexity = type_traits<element_type>::multiplies_complexity;
0159
0160 static
0161 BOOST_UBLAS_INLINE
0162 real_type real (const_reference t) {
0163 return type_traits<element_type>::real (t);
0164 }
0165 static
0166 BOOST_UBLAS_INLINE
0167 real_type imag (const_reference t) {
0168 return type_traits<element_type>::imag (t);
0169 }
0170 static
0171 BOOST_UBLAS_INLINE
0172 value_type conj (const_reference t) {
0173 return type_traits<element_type>::conj (t);
0174 }
0175
0176 static
0177 BOOST_UBLAS_INLINE
0178 real_type type_abs (const_reference t) {
0179 return type_traits<element_type>::type_abs (t);
0180 }
0181 static
0182 BOOST_UBLAS_INLINE
0183 value_type type_sqrt (const_reference t) {
0184 return type_traits<element_type>::type_sqrt (t);
0185 }
0186
0187 static
0188 BOOST_UBLAS_INLINE
0189 real_type norm_1 (const_reference t) {
0190 return type_traits<element_type>::norm_1 (t);
0191 }
0192 static
0193 BOOST_UBLAS_INLINE
0194 real_type norm_2 (const_reference t) {
0195 return type_traits<element_type>::norm_2 (t);
0196 }
0197 static
0198 BOOST_UBLAS_INLINE
0199 real_type norm_inf (const_reference t) {
0200 return type_traits<element_type>::norm_inf (t);
0201 }
0202
0203 static
0204 BOOST_UBLAS_INLINE
0205 bool equals (const_reference t1, const_reference t2) {
0206 return type_traits<element_type>::equals (t1, t2);
0207 }
0208 };
0209
0210 template<class M1, class T2>
0211 struct promote_traits<hermitian_matrix_element<M1>, T2> {
0212 typedef typename promote_traits<typename hermitian_matrix_element<M1>::value_type, T2>::promote_type promote_type;
0213 };
0214 template<class T1, class M2>
0215 struct promote_traits<T1, hermitian_matrix_element<M2> > {
0216 typedef typename promote_traits<T1, typename hermitian_matrix_element<M2>::value_type>::promote_type promote_type;
0217 };
0218 template<class M1, class M2>
0219 struct promote_traits<hermitian_matrix_element<M1>, hermitian_matrix_element<M2> > {
0220 typedef typename promote_traits<typename hermitian_matrix_element<M1>::value_type,
0221 typename hermitian_matrix_element<M2>::value_type>::promote_type promote_type;
0222 };
0223
0224 #endif
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 template<class T, class TRI, class L, class A>
0244 class hermitian_matrix:
0245 public matrix_container<hermitian_matrix<T, TRI, L, A> > {
0246
0247 typedef T &true_reference;
0248 typedef T *pointer;
0249 typedef TRI triangular_type;
0250 typedef L layout_type;
0251 typedef hermitian_matrix<T, TRI, L, A> self_type;
0252 public:
0253 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0254 using matrix_container<self_type>::operator ();
0255 #endif
0256 typedef typename A::size_type size_type;
0257 typedef typename A::difference_type difference_type;
0258 typedef T value_type;
0259
0260
0261 typedef const T const_reference;
0262 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
0263 typedef T &reference;
0264 #else
0265 typedef hermitian_matrix_element<self_type> reference;
0266 #endif
0267 typedef A array_type;
0268
0269 typedef const matrix_reference<const self_type> const_closure_type;
0270 typedef matrix_reference<self_type> closure_type;
0271 typedef vector<T, A> vector_temporary_type;
0272 typedef matrix<T, L, A> matrix_temporary_type;
0273 typedef packed_tag storage_category;
0274 typedef typename L::orientation_category orientation_category;
0275
0276
0277 BOOST_UBLAS_INLINE
0278 hermitian_matrix ():
0279 matrix_container<self_type> (),
0280 size_ (0), data_ (0) {}
0281 BOOST_UBLAS_INLINE
0282 hermitian_matrix (size_type size):
0283 matrix_container<self_type> (),
0284 size_ (BOOST_UBLAS_SAME (size, size)), data_ (triangular_type::packed_size (layout_type (), size, size)) {
0285 }
0286 BOOST_UBLAS_INLINE
0287 hermitian_matrix (size_type size1, size_type size2):
0288 matrix_container<self_type> (),
0289 size_ (BOOST_UBLAS_SAME (size1, size2)), data_ (triangular_type::packed_size (layout_type (), size1, size2)) {
0290 }
0291 BOOST_UBLAS_INLINE
0292 hermitian_matrix (size_type size, const array_type &data):
0293 matrix_container<self_type> (),
0294 size_ (size), data_ (data) {}
0295 BOOST_UBLAS_INLINE
0296 hermitian_matrix (const hermitian_matrix &m):
0297 matrix_container<self_type> (),
0298 size_ (m.size_), data_ (m.data_) {}
0299 template<class AE>
0300 BOOST_UBLAS_INLINE
0301 hermitian_matrix (const matrix_expression<AE> &ae):
0302 matrix_container<self_type> (),
0303 size_ (BOOST_UBLAS_SAME (ae ().size1 (), ae ().size2 ())),
0304 data_ (triangular_type::packed_size (layout_type (), size_, size_)) {
0305 matrix_assign<scalar_assign> (*this, ae);
0306 }
0307
0308
0309 BOOST_UBLAS_INLINE
0310 size_type size1 () const {
0311 return size_;
0312 }
0313 BOOST_UBLAS_INLINE
0314 size_type size2 () const {
0315 return size_;
0316 }
0317
0318
0319 BOOST_UBLAS_INLINE
0320 const array_type &data () const {
0321 return data_;
0322 }
0323 BOOST_UBLAS_INLINE
0324 array_type &data () {
0325 return data_;
0326 }
0327
0328
0329 BOOST_UBLAS_INLINE
0330 void resize (size_type size, bool preserve = true) {
0331 if (preserve) {
0332 self_type temporary (size, size);
0333 detail::matrix_resize_preserve<layout_type, triangular_type> (*this, temporary);
0334 }
0335 else {
0336 data ().resize (triangular_type::packed_size (layout_type (), size, size));
0337 size_ = size;
0338 }
0339 }
0340 BOOST_UBLAS_INLINE
0341 void resize (size_type size1, size_type size2, bool preserve = true) {
0342 resize (BOOST_UBLAS_SAME (size1, size2), preserve);
0343 }
0344 BOOST_UBLAS_INLINE
0345 void resize_packed_preserve (size_type size) {
0346 size_ = BOOST_UBLAS_SAME (size, size);
0347 data ().resize (triangular_type::packed_size (layout_type (), size_, size_), value_type ());
0348 }
0349
0350
0351 BOOST_UBLAS_INLINE
0352 const_reference operator () (size_type i, size_type j) const {
0353 BOOST_UBLAS_CHECK (i < size_, bad_index ());
0354 BOOST_UBLAS_CHECK (j < size_, bad_index ());
0355
0356
0357
0358 if (triangular_type::other (i, j))
0359 return data () [triangular_type::element (layout_type (), i, size_, j, size_)];
0360 else
0361 return type_traits<value_type>::conj (data () [triangular_type::element (layout_type (), j, size_, i, size_)]);
0362 }
0363 BOOST_UBLAS_INLINE
0364 true_reference at_element (size_type i, size_type j) {
0365 BOOST_UBLAS_CHECK (i < size_, bad_index ());
0366 BOOST_UBLAS_CHECK (j < size_, bad_index ());
0367 BOOST_UBLAS_CHECK (triangular_type::other (i, j), bad_index ());
0368 return data () [triangular_type::element (layout_type (), i, size_, j, size_)];
0369 }
0370 BOOST_UBLAS_INLINE
0371 reference operator () (size_type i, size_type j) {
0372 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
0373 if (!triangular_type::other (i, j)) {
0374 bad_index ().raise ();
0375
0376 }
0377 return at_element (i, j);
0378 #else
0379 if (triangular_type::other (i, j))
0380 return reference (*this, i, j, data () [triangular_type::element (layout_type (), i, size_, j, size_)]);
0381 else
0382 return reference (*this, i, j, type_traits<value_type>::conj (data () [triangular_type::element (layout_type (), j, size_, i, size_)]));
0383 #endif
0384 }
0385
0386
0387 BOOST_UBLAS_INLINE
0388 true_reference insert_element (size_type i, size_type j, const_reference t) {
0389 BOOST_UBLAS_CHECK (i < size_, bad_index ());
0390 BOOST_UBLAS_CHECK (j < size_, bad_index ());
0391 if (triangular_type::other (i, j)) {
0392 return (data () [triangular_type::element (layout_type (), i, size_, j, size_)] = t);
0393 } else {
0394 return (data () [triangular_type::element (layout_type (), j, size_, i, size_)] = type_traits<value_type>::conj (t));
0395 }
0396 }
0397 BOOST_UBLAS_INLINE
0398 void erase_element (size_type i, size_type j) {
0399 BOOST_UBLAS_CHECK (i < size_, bad_index ());
0400 BOOST_UBLAS_CHECK (j < size_, bad_index ());
0401 data () [triangular_type::element (layout_type (), i, size_, j, size_)] = value_type();
0402 }
0403
0404
0405 BOOST_UBLAS_INLINE
0406 void clear () {
0407 std::fill (data ().begin (), data ().end (), value_type());
0408 }
0409
0410
0411 BOOST_UBLAS_INLINE
0412 hermitian_matrix &operator = (const hermitian_matrix &m) {
0413 size_ = m.size_;
0414 data () = m.data ();
0415 return *this;
0416 }
0417 BOOST_UBLAS_INLINE
0418 hermitian_matrix &assign_temporary (hermitian_matrix &m) {
0419 swap (m);
0420 return *this;
0421 }
0422 template<class AE>
0423 BOOST_UBLAS_INLINE
0424 hermitian_matrix &operator = (const matrix_expression<AE> &ae) {
0425 self_type temporary (ae);
0426 return assign_temporary (temporary);
0427 }
0428 template<class AE>
0429 BOOST_UBLAS_INLINE
0430 hermitian_matrix &assign (const matrix_expression<AE> &ae) {
0431 matrix_assign<scalar_assign> (*this, ae);
0432 return *this;
0433 }
0434 template<class AE>
0435 BOOST_UBLAS_INLINE
0436 hermitian_matrix& operator += (const matrix_expression<AE> &ae) {
0437 self_type temporary (*this + ae);
0438 return assign_temporary (temporary);
0439 }
0440 template<class AE>
0441 BOOST_UBLAS_INLINE
0442 hermitian_matrix &plus_assign (const matrix_expression<AE> &ae) {
0443 matrix_assign<scalar_plus_assign> (*this, ae);
0444 return *this;
0445 }
0446 template<class AE>
0447 BOOST_UBLAS_INLINE
0448 hermitian_matrix& operator -= (const matrix_expression<AE> &ae) {
0449 self_type temporary (*this - ae);
0450 return assign_temporary (temporary);
0451 }
0452 template<class AE>
0453 BOOST_UBLAS_INLINE
0454 hermitian_matrix &minus_assign (const matrix_expression<AE> &ae) {
0455 matrix_assign<scalar_minus_assign> (*this, ae);
0456 return *this;
0457 }
0458 template<class AT>
0459 BOOST_UBLAS_INLINE
0460 hermitian_matrix& operator *= (const AT &at) {
0461
0462
0463
0464 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
0465 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
0466 return *this;
0467 }
0468 template<class AT>
0469 BOOST_UBLAS_INLINE
0470 hermitian_matrix& operator /= (const AT &at) {
0471
0472
0473
0474 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
0475 matrix_assign_scalar<scalar_divides_assign> (*this, at);
0476 return *this;
0477 }
0478
0479
0480 BOOST_UBLAS_INLINE
0481 void swap (hermitian_matrix &m) {
0482 if (this != &m) {
0483 std::swap (size_, m.size_);
0484 data ().swap (m.data ());
0485 }
0486 }
0487 BOOST_UBLAS_INLINE
0488 friend void swap (hermitian_matrix &m1, hermitian_matrix &m2) {
0489 m1.swap (m2);
0490 }
0491
0492
0493 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0494 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
0495 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
0496 typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
0497 typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
0498 #else
0499 class const_iterator1;
0500 class iterator1;
0501 class const_iterator2;
0502 class iterator2;
0503 #endif
0504 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
0505 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
0506 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
0507 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
0508
0509
0510 BOOST_UBLAS_INLINE
0511 const_iterator1 find1 (int , size_type i, size_type j) const {
0512 return const_iterator1 (*this, i, j);
0513 }
0514 BOOST_UBLAS_INLINE
0515 iterator1 find1 (int rank, size_type i, size_type j) {
0516 if (rank == 1)
0517 i = triangular_type::mutable_restrict1 (i, j, size1(), size2());
0518 if (rank == 0)
0519 i = triangular_type::global_mutable_restrict1 (i, size1(), j, size2());
0520 return iterator1 (*this, i, j);
0521 }
0522 BOOST_UBLAS_INLINE
0523 const_iterator2 find2 (int , size_type i, size_type j) const {
0524 return const_iterator2 (*this, i, j);
0525 }
0526 BOOST_UBLAS_INLINE
0527 iterator2 find2 (int rank, size_type i, size_type j) {
0528 if (rank == 1)
0529 j = triangular_type::mutable_restrict2 (i, j, size1(), size2());
0530 if (rank == 0)
0531 j = triangular_type::global_mutable_restrict2 (i, size1(), j, size2());
0532 return iterator2 (*this, i, j);
0533 }
0534
0535
0536
0537 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0538 class const_iterator1:
0539 public container_const_reference<hermitian_matrix>,
0540 public random_access_iterator_base<packed_random_access_iterator_tag,
0541 const_iterator1, value_type> {
0542 public:
0543 typedef typename hermitian_matrix::value_type value_type;
0544 typedef typename hermitian_matrix::difference_type difference_type;
0545 typedef typename hermitian_matrix::const_reference reference;
0546 typedef const typename hermitian_matrix::pointer pointer;
0547
0548 typedef const_iterator2 dual_iterator_type;
0549 typedef const_reverse_iterator2 dual_reverse_iterator_type;
0550
0551
0552 BOOST_UBLAS_INLINE
0553 const_iterator1 ():
0554 container_const_reference<self_type> (), it1_ (), it2_ () {}
0555 BOOST_UBLAS_INLINE
0556 const_iterator1 (const self_type &m, size_type it1, size_type it2):
0557 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
0558 BOOST_UBLAS_INLINE
0559 const_iterator1 (const iterator1 &it):
0560 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
0561
0562
0563 BOOST_UBLAS_INLINE
0564 const_iterator1 &operator ++ () {
0565 ++ it1_;
0566 return *this;
0567 }
0568 BOOST_UBLAS_INLINE
0569 const_iterator1 &operator -- () {
0570 -- it1_;
0571 return *this;
0572 }
0573 BOOST_UBLAS_INLINE
0574 const_iterator1 &operator += (difference_type n) {
0575 it1_ += n;
0576 return *this;
0577 }
0578 BOOST_UBLAS_INLINE
0579 const_iterator1 &operator -= (difference_type n) {
0580 it1_ -= n;
0581 return *this;
0582 }
0583 BOOST_UBLAS_INLINE
0584 difference_type operator - (const const_iterator1 &it) const {
0585 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0586 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0587 return it1_ - it.it1_;
0588 }
0589
0590
0591 BOOST_UBLAS_INLINE
0592 const_reference operator * () const {
0593 return (*this) () (it1_, it2_);
0594 }
0595 BOOST_UBLAS_INLINE
0596 const_reference operator [] (difference_type n) const {
0597 return *(*this + n);
0598 }
0599
0600 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0601 BOOST_UBLAS_INLINE
0602 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0603 typename self_type::
0604 #endif
0605 const_iterator2 begin () const {
0606 return (*this) ().find2 (1, it1_, 0);
0607 }
0608 BOOST_UBLAS_INLINE
0609 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0610 typename self_type::
0611 #endif
0612 const_iterator2 cbegin () const {
0613 return begin ();
0614 }
0615 BOOST_UBLAS_INLINE
0616 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0617 typename self_type::
0618 #endif
0619 const_iterator2 end () const {
0620 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
0621 }
0622 BOOST_UBLAS_INLINE
0623 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0624 typename self_type::
0625 #endif
0626 const_iterator2 cend () const {
0627 return end ();
0628 }
0629 BOOST_UBLAS_INLINE
0630 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0631 typename self_type::
0632 #endif
0633 const_reverse_iterator2 rbegin () const {
0634 return const_reverse_iterator2 (end ());
0635 }
0636 BOOST_UBLAS_INLINE
0637 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0638 typename self_type::
0639 #endif
0640 const_reverse_iterator2 crbegin () const {
0641 return rbegin ();
0642 }
0643 BOOST_UBLAS_INLINE
0644 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0645 typename self_type::
0646 #endif
0647 const_reverse_iterator2 rend () const {
0648 return const_reverse_iterator2 (begin ());
0649 }
0650 BOOST_UBLAS_INLINE
0651 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0652 typename self_type::
0653 #endif
0654 const_reverse_iterator2 crend () const {
0655 return rend ();
0656 }
0657 #endif
0658
0659
0660 BOOST_UBLAS_INLINE
0661 size_type index1 () const {
0662 return it1_;
0663 }
0664 BOOST_UBLAS_INLINE
0665 size_type index2 () const {
0666 return it2_;
0667 }
0668
0669
0670 BOOST_UBLAS_INLINE
0671 const_iterator1 &operator = (const const_iterator1 &it) {
0672 container_const_reference<self_type>::assign (&it ());
0673 it1_ = it.it1_;
0674 it2_ = it.it2_;
0675 return *this;
0676 }
0677
0678
0679 BOOST_UBLAS_INLINE
0680 bool operator == (const const_iterator1 &it) const {
0681 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0682 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0683 return it1_ == it.it1_;
0684 }
0685 BOOST_UBLAS_INLINE
0686 bool operator < (const const_iterator1 &it) const {
0687 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0688 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0689 return it1_ < it.it1_;
0690 }
0691
0692 private:
0693 size_type it1_;
0694 size_type it2_;
0695 };
0696 #endif
0697
0698 BOOST_UBLAS_INLINE
0699 const_iterator1 begin1 () const {
0700 return find1 (0, 0, 0);
0701 }
0702 BOOST_UBLAS_INLINE
0703 const_iterator1 cbegin1 () const {
0704 return begin1 ();
0705 }
0706 BOOST_UBLAS_INLINE
0707 const_iterator1 end1 () const {
0708 return find1 (0, size_, 0);
0709 }
0710 BOOST_UBLAS_INLINE
0711 const_iterator1 cend1 () const {
0712 return end1 ();
0713 }
0714
0715 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0716 class iterator1:
0717 public container_reference<hermitian_matrix>,
0718 public random_access_iterator_base<packed_random_access_iterator_tag,
0719 iterator1, value_type> {
0720 public:
0721 typedef typename hermitian_matrix::value_type value_type;
0722 typedef typename hermitian_matrix::difference_type difference_type;
0723 typedef typename hermitian_matrix::true_reference reference;
0724 typedef typename hermitian_matrix::pointer pointer;
0725
0726 typedef iterator2 dual_iterator_type;
0727 typedef reverse_iterator2 dual_reverse_iterator_type;
0728
0729
0730 BOOST_UBLAS_INLINE
0731 iterator1 ():
0732 container_reference<self_type> (), it1_ (), it2_ () {}
0733 BOOST_UBLAS_INLINE
0734 iterator1 (self_type &m, size_type it1, size_type it2):
0735 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
0736
0737
0738 BOOST_UBLAS_INLINE
0739 iterator1 &operator ++ () {
0740 ++ it1_;
0741 return *this;
0742 }
0743 BOOST_UBLAS_INLINE
0744 iterator1 &operator -- () {
0745 -- it1_;
0746 return *this;
0747 }
0748 BOOST_UBLAS_INLINE
0749 iterator1 &operator += (difference_type n) {
0750 it1_ += n;
0751 return *this;
0752 }
0753 BOOST_UBLAS_INLINE
0754 iterator1 &operator -= (difference_type n) {
0755 it1_ -= n;
0756 return *this;
0757 }
0758 BOOST_UBLAS_INLINE
0759 difference_type operator - (const iterator1 &it) const {
0760 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0761 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0762 return it1_ - it.it1_;
0763 }
0764
0765
0766 BOOST_UBLAS_INLINE
0767 reference operator * () const {
0768 return (*this) ().at_element (it1_, it2_);
0769 }
0770 BOOST_UBLAS_INLINE
0771 reference operator [] (difference_type n) const {
0772 return *(*this + n);
0773 }
0774
0775 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0776 BOOST_UBLAS_INLINE
0777 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0778 typename self_type::
0779 #endif
0780 iterator2 begin () const {
0781 return (*this) ().find2 (1, it1_, 0);
0782 }
0783 BOOST_UBLAS_INLINE
0784 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0785 typename self_type::
0786 #endif
0787 iterator2 end () const {
0788 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
0789 }
0790 BOOST_UBLAS_INLINE
0791 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0792 typename self_type::
0793 #endif
0794 reverse_iterator2 rbegin () const {
0795 return reverse_iterator2 (end ());
0796 }
0797 BOOST_UBLAS_INLINE
0798 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0799 typename self_type::
0800 #endif
0801 reverse_iterator2 rend () const {
0802 return reverse_iterator2 (begin ());
0803 }
0804 #endif
0805
0806
0807 BOOST_UBLAS_INLINE
0808 size_type index1 () const {
0809 return it1_;
0810 }
0811 BOOST_UBLAS_INLINE
0812 size_type index2 () const {
0813 return it2_;
0814 }
0815
0816
0817 BOOST_UBLAS_INLINE
0818 iterator1 &operator = (const iterator1 &it) {
0819 container_reference<self_type>::assign (&it ());
0820 it1_ = it.it1_;
0821 it2_ = it.it2_;
0822 return *this;
0823 }
0824
0825
0826 BOOST_UBLAS_INLINE
0827 bool operator == (const iterator1 &it) const {
0828 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0829 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0830 return it1_ == it.it1_;
0831 }
0832 BOOST_UBLAS_INLINE
0833 bool operator < (const iterator1 &it) const {
0834 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0835 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0836 return it1_ < it.it1_;
0837 }
0838
0839 private:
0840 size_type it1_;
0841 size_type it2_;
0842
0843 friend class const_iterator1;
0844 };
0845 #endif
0846
0847 BOOST_UBLAS_INLINE
0848 iterator1 begin1 () {
0849 return find1 (0, 0, 0);
0850 }
0851 BOOST_UBLAS_INLINE
0852 iterator1 end1 () {
0853 return find1 (0, size_, 0);
0854 }
0855
0856 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0857 class const_iterator2:
0858 public container_const_reference<hermitian_matrix>,
0859 public random_access_iterator_base<packed_random_access_iterator_tag,
0860 const_iterator2, value_type> {
0861 public:
0862 typedef typename hermitian_matrix::value_type value_type;
0863 typedef typename hermitian_matrix::difference_type difference_type;
0864 typedef typename hermitian_matrix::const_reference reference;
0865 typedef const typename hermitian_matrix::pointer pointer;
0866
0867 typedef const_iterator1 dual_iterator_type;
0868 typedef const_reverse_iterator1 dual_reverse_iterator_type;
0869
0870
0871 BOOST_UBLAS_INLINE
0872 const_iterator2 ():
0873 container_const_reference<self_type> (), it1_ (), it2_ () {}
0874 BOOST_UBLAS_INLINE
0875 const_iterator2 (const self_type &m, size_type it1, size_type it2):
0876 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
0877 BOOST_UBLAS_INLINE
0878 const_iterator2 (const iterator2 &it):
0879 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
0880
0881
0882 BOOST_UBLAS_INLINE
0883 const_iterator2 &operator ++ () {
0884 ++ it2_;
0885 return *this;
0886 }
0887 BOOST_UBLAS_INLINE
0888 const_iterator2 &operator -- () {
0889 -- it2_;
0890 return *this;
0891 }
0892 BOOST_UBLAS_INLINE
0893 const_iterator2 &operator += (difference_type n) {
0894 it2_ += n;
0895 return *this;
0896 }
0897 BOOST_UBLAS_INLINE
0898 const_iterator2 &operator -= (difference_type n) {
0899 it2_ -= n;
0900 return *this;
0901 }
0902 BOOST_UBLAS_INLINE
0903 difference_type operator - (const const_iterator2 &it) const {
0904 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0905 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
0906 return it2_ - it.it2_;
0907 }
0908
0909
0910 BOOST_UBLAS_INLINE
0911 const_reference operator * () const {
0912 return (*this) () (it1_, it2_);
0913 }
0914 BOOST_UBLAS_INLINE
0915 const_reference operator [] (difference_type n) const {
0916 return *(*this + n);
0917 }
0918
0919 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0920 BOOST_UBLAS_INLINE
0921 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0922 typename self_type::
0923 #endif
0924 const_iterator1 begin () const {
0925 return (*this) ().find1 (1, 0, it2_);
0926 }
0927 BOOST_UBLAS_INLINE
0928 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0929 typename self_type::
0930 #endif
0931 const_iterator1 cbegin () const {
0932 return begin ();
0933 }
0934 BOOST_UBLAS_INLINE
0935 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0936 typename self_type::
0937 #endif
0938 const_iterator1 end () const {
0939 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
0940 }
0941 BOOST_UBLAS_INLINE
0942 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0943 typename self_type::
0944 #endif
0945 const_iterator1 cend () const {
0946 return end ();
0947 }
0948 BOOST_UBLAS_INLINE
0949 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0950 typename self_type::
0951 #endif
0952 const_reverse_iterator1 rbegin () const {
0953 return const_reverse_iterator1 (end ());
0954 }
0955 BOOST_UBLAS_INLINE
0956 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0957 typename self_type::
0958 #endif
0959 const_iterator1 crbegin () const {
0960 return rbegin ();
0961 }
0962 BOOST_UBLAS_INLINE
0963 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0964 typename self_type::
0965 #endif
0966 const_reverse_iterator1 rend () const {
0967 return const_reverse_iterator1 (begin ());
0968 }
0969 BOOST_UBLAS_INLINE
0970 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
0971 typename self_type::
0972 #endif
0973 const_iterator1 crend () const {
0974 return rend ();
0975 }
0976 #endif
0977
0978
0979 BOOST_UBLAS_INLINE
0980 size_type index1 () const {
0981 return it1_;
0982 }
0983 BOOST_UBLAS_INLINE
0984 size_type index2 () const {
0985 return it2_;
0986 }
0987
0988
0989 BOOST_UBLAS_INLINE
0990 const_iterator2 &operator = (const const_iterator2 &it) {
0991 container_const_reference<self_type>::assign (&it ());
0992 it1_ = it.it1_;
0993 it2_ = it.it2_;
0994 return *this;
0995 }
0996
0997
0998 BOOST_UBLAS_INLINE
0999 bool operator == (const const_iterator2 &it) const {
1000 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1001 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1002 return it2_ == it.it2_;
1003 }
1004 BOOST_UBLAS_INLINE
1005 bool operator < (const const_iterator2 &it) const {
1006 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1007 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1008 return it2_ < it.it2_;
1009 }
1010
1011 private:
1012 size_type it1_;
1013 size_type it2_;
1014 };
1015 #endif
1016
1017 BOOST_UBLAS_INLINE
1018 const_iterator2 begin2 () const {
1019 return find2 (0, 0, 0);
1020 }
1021 BOOST_UBLAS_INLINE
1022 const_iterator2 cbegin2 () const {
1023 return begin2 ();
1024 }
1025 BOOST_UBLAS_INLINE
1026 const_iterator2 end2 () const {
1027 return find2 (0, 0, size_);
1028 }
1029 BOOST_UBLAS_INLINE
1030 const_iterator2 cend2 () const {
1031 return end2 ();
1032 }
1033
1034 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1035 class iterator2:
1036 public container_reference<hermitian_matrix>,
1037 public random_access_iterator_base<packed_random_access_iterator_tag,
1038 iterator2, value_type> {
1039 public:
1040 typedef typename hermitian_matrix::value_type value_type;
1041 typedef typename hermitian_matrix::difference_type difference_type;
1042 typedef typename hermitian_matrix::true_reference reference;
1043 typedef typename hermitian_matrix::pointer pointer;
1044
1045 typedef iterator1 dual_iterator_type;
1046 typedef reverse_iterator1 dual_reverse_iterator_type;
1047
1048
1049 BOOST_UBLAS_INLINE
1050 iterator2 ():
1051 container_reference<self_type> (), it1_ (), it2_ () {}
1052 BOOST_UBLAS_INLINE
1053 iterator2 (self_type &m, size_type it1, size_type it2):
1054 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
1055
1056
1057 BOOST_UBLAS_INLINE
1058 iterator2 &operator ++ () {
1059 ++ it2_;
1060 return *this;
1061 }
1062 BOOST_UBLAS_INLINE
1063 iterator2 &operator -- () {
1064 -- it2_;
1065 return *this;
1066 }
1067 BOOST_UBLAS_INLINE
1068 iterator2 &operator += (difference_type n) {
1069 it2_ += n;
1070 return *this;
1071 }
1072 BOOST_UBLAS_INLINE
1073 iterator2 &operator -= (difference_type n) {
1074 it2_ -= n;
1075 return *this;
1076 }
1077 BOOST_UBLAS_INLINE
1078 difference_type operator - (const iterator2 &it) const {
1079 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1080 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1081 return it2_ - it.it2_;
1082 }
1083
1084
1085 BOOST_UBLAS_INLINE
1086 reference operator * () const {
1087 return (*this) ().at_element (it1_, it2_);
1088 }
1089 BOOST_UBLAS_INLINE
1090 reference operator [] (difference_type n) const {
1091 return *(*this + n);
1092 }
1093
1094 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1095 BOOST_UBLAS_INLINE
1096 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1097 typename self_type::
1098 #endif
1099 iterator1 begin () const {
1100 return (*this) ().find1 (1, 0, it2_);
1101 }
1102 BOOST_UBLAS_INLINE
1103 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1104 typename self_type::
1105 #endif
1106 iterator1 end () const {
1107 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
1108 }
1109 BOOST_UBLAS_INLINE
1110 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1111 typename self_type::
1112 #endif
1113 reverse_iterator1 rbegin () const {
1114 return reverse_iterator1 (end ());
1115 }
1116 BOOST_UBLAS_INLINE
1117 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1118 typename self_type::
1119 #endif
1120 reverse_iterator1 rend () const {
1121 return reverse_iterator1 (begin ());
1122 }
1123 #endif
1124
1125
1126 BOOST_UBLAS_INLINE
1127 size_type index1 () const {
1128 return it1_;
1129 }
1130 BOOST_UBLAS_INLINE
1131 size_type index2 () const {
1132 return it2_;
1133 }
1134
1135
1136 BOOST_UBLAS_INLINE
1137 iterator2 &operator = (const iterator2 &it) {
1138 container_reference<self_type>::assign (&it ());
1139 it1_ = it.it1_;
1140 it2_ = it.it2_;
1141 return *this;
1142 }
1143
1144
1145 BOOST_UBLAS_INLINE
1146 bool operator == (const iterator2 &it) const {
1147 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1148 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1149 return it2_ == it.it2_;
1150 }
1151 BOOST_UBLAS_INLINE
1152 bool operator < (const iterator2 &it) const {
1153 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1154 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1155 return it2_ < it.it2_;
1156 }
1157
1158 private:
1159 size_type it1_;
1160 size_type it2_;
1161
1162 friend class const_iterator2;
1163 };
1164 #endif
1165
1166 BOOST_UBLAS_INLINE
1167 iterator2 begin2 () {
1168 return find2 (0, 0, 0);
1169 }
1170 BOOST_UBLAS_INLINE
1171 iterator2 end2 () {
1172 return find2 (0, 0, size_);
1173 }
1174
1175
1176
1177 BOOST_UBLAS_INLINE
1178 const_reverse_iterator1 rbegin1 () const {
1179 return const_reverse_iterator1 (end1 ());
1180 }
1181 BOOST_UBLAS_INLINE
1182 const_reverse_iterator1 crbegin1 () const {
1183 return rbegin1 ();
1184 }
1185 BOOST_UBLAS_INLINE
1186 const_reverse_iterator1 rend1 () const {
1187 return const_reverse_iterator1 (begin1 ());
1188 }
1189 BOOST_UBLAS_INLINE
1190 const_reverse_iterator1 crend1 () const {
1191 return rend1 ();
1192 }
1193
1194 BOOST_UBLAS_INLINE
1195 reverse_iterator1 rbegin1 () {
1196 return reverse_iterator1 (end1 ());
1197 }
1198 BOOST_UBLAS_INLINE
1199 reverse_iterator1 rend1 () {
1200 return reverse_iterator1 (begin1 ());
1201 }
1202
1203 BOOST_UBLAS_INLINE
1204 const_reverse_iterator2 rbegin2 () const {
1205 return const_reverse_iterator2 (end2 ());
1206 }
1207 BOOST_UBLAS_INLINE
1208 const_reverse_iterator2 crbegin2 () const {
1209 return rbegin2();
1210 }
1211 BOOST_UBLAS_INLINE
1212 const_reverse_iterator2 rend2 () const {
1213 return const_reverse_iterator2 (begin2 ());
1214 }
1215 BOOST_UBLAS_INLINE
1216 const_reverse_iterator2 crend2 () const {
1217 return rend2 ();
1218 }
1219
1220 BOOST_UBLAS_INLINE
1221 reverse_iterator2 rbegin2 () {
1222 return reverse_iterator2 (end2 ());
1223 }
1224 BOOST_UBLAS_INLINE
1225 reverse_iterator2 rend2 () {
1226 return reverse_iterator2 (begin2 ());
1227 }
1228
1229 private:
1230 size_type size_;
1231 array_type data_;
1232 };
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243 template<class M, class TRI>
1244 class hermitian_adaptor:
1245 public matrix_expression<hermitian_adaptor<M, TRI> > {
1246
1247 typedef hermitian_adaptor<M, TRI> self_type;
1248 typedef typename M::value_type &true_reference;
1249 public:
1250 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1251 using matrix_expression<self_type>::operator ();
1252 #endif
1253 typedef const M const_matrix_type;
1254 typedef M matrix_type;
1255 typedef TRI triangular_type;
1256 typedef typename M::size_type size_type;
1257 typedef typename M::difference_type difference_type;
1258 typedef typename M::value_type value_type;
1259 typedef typename M::value_type const_reference;
1260 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
1261 typedef typename boost::mpl::if_<boost::is_const<M>,
1262 typename M::value_type,
1263 typename M::reference>::type reference;
1264 #else
1265 typedef typename boost::mpl::if_<boost::is_const<M>,
1266 typename M::value_type,
1267 hermitian_matrix_element<self_type> >::type reference;
1268 #endif
1269 typedef typename boost::mpl::if_<boost::is_const<M>,
1270 typename M::const_closure_type,
1271 typename M::closure_type>::type matrix_closure_type;
1272 typedef const self_type const_closure_type;
1273 typedef self_type closure_type;
1274
1275
1276
1277 typedef typename storage_restrict_traits<typename M::storage_category,
1278 packed_proxy_tag>::storage_category storage_category;
1279 typedef typename M::orientation_category orientation_category;
1280
1281
1282 BOOST_UBLAS_INLINE
1283 hermitian_adaptor (matrix_type &data):
1284 matrix_expression<self_type> (),
1285 data_ (data) {
1286 BOOST_UBLAS_CHECK (data_.size1 () == data_.size2 (), bad_size ());
1287 }
1288 BOOST_UBLAS_INLINE
1289 hermitian_adaptor (const hermitian_adaptor &m):
1290 matrix_expression<self_type> (),
1291 data_ (m.data_) {
1292 BOOST_UBLAS_CHECK (data_.size1 () == data_.size2 (), bad_size ());
1293 }
1294
1295
1296 BOOST_UBLAS_INLINE
1297 size_type size1 () const {
1298 return data_.size1 ();
1299 }
1300 BOOST_UBLAS_INLINE
1301 size_type size2 () const {
1302 return data_.size2 ();
1303 }
1304
1305
1306 BOOST_UBLAS_INLINE
1307 const matrix_closure_type &data () const {
1308 return data_;
1309 }
1310 BOOST_UBLAS_INLINE
1311 matrix_closure_type &data () {
1312 return data_;
1313 }
1314
1315
1316 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
1317 BOOST_UBLAS_INLINE
1318 const_reference operator () (size_type i, size_type j) const {
1319 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1320 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1321
1322
1323
1324 if (triangular_type::other (i, j))
1325 return data () (i, j);
1326 else
1327 return type_traits<value_type>::conj (data () (j, i));
1328 }
1329 BOOST_UBLAS_INLINE
1330 reference operator () (size_type i, size_type j) {
1331 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1332 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1333 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
1334 if (triangular_type::other (i, j))
1335 return data () (i, j);
1336 else {
1337 external_logic ().raise ();
1338 return conj_ = type_traits<value_type>::conj (data () (j, i));
1339 }
1340 #else
1341 if (triangular_type::other (i, j))
1342 return reference (*this, i, j, data () (i, j));
1343 else
1344 return reference (*this, i, j, type_traits<value_type>::conj (data () (j, i)));
1345 #endif
1346 }
1347 BOOST_UBLAS_INLINE
1348 true_reference insert_element (size_type i, size_type j, value_type t) {
1349 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1350 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1351
1352
1353
1354 if (triangular_type::other (i, j))
1355 return data () (i, j) = t;
1356 else
1357 return data () (j, i) = type_traits<value_type>::conj (t);
1358 }
1359 #else
1360 BOOST_UBLAS_INLINE
1361 reference operator () (size_type i, size_type j) {
1362 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1363 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1364 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
1365 if (triangular_type::other (i, j))
1366 return data () (i, j);
1367 else {
1368 external_logic ().raise ();
1369 return conj_ = type_traits<value_type>::conj (data () (j, i));
1370 }
1371 #else
1372 if (triangular_type::other (i, j))
1373 return reference (*this, i, j, data () (i, j));
1374 else
1375 return reference (*this, i, j, type_traits<value_type>::conj (data () (j, i)));
1376 #endif
1377 }
1378 BOOST_UBLAS_INLINE
1379 true_reference insert_element (size_type i, size_type j, value_type t) {
1380 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
1381 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
1382
1383
1384
1385 if (triangular_type::other (i, j))
1386 return data () (i, j) = t;
1387 else
1388 return data () (j, i) = type_traits<value_type>::conj (t);
1389 }
1390 #endif
1391
1392
1393 BOOST_UBLAS_INLINE
1394 hermitian_adaptor &operator = (const hermitian_adaptor &m) {
1395 matrix_assign<scalar_assign, triangular_type> (*this, m);
1396 return *this;
1397 }
1398 BOOST_UBLAS_INLINE
1399 hermitian_adaptor &assign_temporary (hermitian_adaptor &m) {
1400 *this = m;
1401 return *this;
1402 }
1403 template<class AE>
1404 BOOST_UBLAS_INLINE
1405 hermitian_adaptor &operator = (const matrix_expression<AE> &ae) {
1406 matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (ae));
1407 return *this;
1408 }
1409 template<class AE>
1410 BOOST_UBLAS_INLINE
1411 hermitian_adaptor &assign (const matrix_expression<AE> &ae) {
1412 matrix_assign<scalar_assign, triangular_type> (*this, ae);
1413 return *this;
1414 }
1415 template<class AE>
1416 BOOST_UBLAS_INLINE
1417 hermitian_adaptor& operator += (const matrix_expression<AE> &ae) {
1418 matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (*this + ae));
1419 return *this;
1420 }
1421 template<class AE>
1422 BOOST_UBLAS_INLINE
1423 hermitian_adaptor &plus_assign (const matrix_expression<AE> &ae) {
1424 matrix_assign<scalar_plus_assign, triangular_type> (*this, ae);
1425 return *this;
1426 }
1427 template<class AE>
1428 BOOST_UBLAS_INLINE
1429 hermitian_adaptor& operator -= (const matrix_expression<AE> &ae) {
1430 matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (*this - ae));
1431 return *this;
1432 }
1433 template<class AE>
1434 BOOST_UBLAS_INLINE
1435 hermitian_adaptor &minus_assign (const matrix_expression<AE> &ae) {
1436 matrix_assign<scalar_minus_assign, triangular_type> (*this, ae);
1437 return *this;
1438 }
1439 template<class AT>
1440 BOOST_UBLAS_INLINE
1441 hermitian_adaptor& operator *= (const AT &at) {
1442
1443
1444
1445 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
1446 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
1447 return *this;
1448 }
1449 template<class AT>
1450 BOOST_UBLAS_INLINE
1451 hermitian_adaptor& operator /= (const AT &at) {
1452
1453
1454
1455 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
1456 matrix_assign_scalar<scalar_divides_assign> (*this, at);
1457 return *this;
1458 }
1459
1460
1461 BOOST_UBLAS_INLINE
1462 bool same_closure (const hermitian_adaptor &ha) const {
1463 return (*this).data ().same_closure (ha.data ());
1464 }
1465
1466
1467 BOOST_UBLAS_INLINE
1468 void swap (hermitian_adaptor &m) {
1469 if (this != &m)
1470 matrix_swap<scalar_swap, triangular_type> (*this, m);
1471 }
1472 BOOST_UBLAS_INLINE
1473 friend void swap (hermitian_adaptor &m1, hermitian_adaptor &m2) {
1474 m1.swap (m2);
1475 }
1476
1477
1478 private:
1479
1480 typedef typename M::const_iterator1 const_subiterator1_type;
1481 typedef typename boost::mpl::if_<boost::is_const<M>,
1482 typename M::const_iterator1,
1483 typename M::iterator1>::type subiterator1_type;
1484 typedef typename M::const_iterator2 const_subiterator2_type;
1485 typedef typename boost::mpl::if_<boost::is_const<M>,
1486 typename M::const_iterator2,
1487 typename M::iterator2>::type subiterator2_type;
1488
1489 public:
1490 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1491 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
1492 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
1493 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
1494 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
1495 #else
1496 class const_iterator1;
1497 class iterator1;
1498 class const_iterator2;
1499 class iterator2;
1500 #endif
1501 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
1502 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
1503 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
1504 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
1505
1506
1507 BOOST_UBLAS_INLINE
1508 const_iterator1 find1 (int rank, size_type i, size_type j) const {
1509 if (triangular_type::other (i, j)) {
1510 if (triangular_type::other (size1 (), j)) {
1511 return const_iterator1 (*this, 0, 0,
1512 data ().find1 (rank, i, j), data ().find1 (rank, size1 (), j),
1513 data ().find2 (rank, size2 (), size1 ()), data ().find2 (rank, size2 (), size1 ()));
1514 } else {
1515 return const_iterator1 (*this, 0, 1,
1516 data ().find1 (rank, i, j), data ().find1 (rank, j, j),
1517 data ().find2 (rank, j, j), data ().find2 (rank, j, size1 ()));
1518 }
1519 } else {
1520 if (triangular_type::other (size1 (), j)) {
1521 return const_iterator1 (*this, 1, 0,
1522 data ().find1 (rank, j, j), data ().find1 (rank, size1 (), j),
1523 data ().find2 (rank, j, i), data ().find2 (rank, j, j));
1524 } else {
1525 return const_iterator1 (*this, 1, 1,
1526 data ().find1 (rank, size1 (), size2 ()), data ().find1 (rank, size1 (), size2 ()),
1527 data ().find2 (rank, j, i), data ().find2 (rank, j, size1 ()));
1528 }
1529 }
1530 }
1531 BOOST_UBLAS_INLINE
1532 iterator1 find1 (int rank, size_type i, size_type j) {
1533 if (rank == 1)
1534 i = triangular_type::mutable_restrict1 (i, j, size1(), size2());
1535 if (rank == 0)
1536 i = triangular_type::global_mutable_restrict1 (i, size1(), j, size2());
1537 return iterator1 (*this, data ().find1 (rank, i, j));
1538 }
1539 BOOST_UBLAS_INLINE
1540 const_iterator2 find2 (int rank, size_type i, size_type j) const {
1541 if (triangular_type::other (i, j)) {
1542 if (triangular_type::other (i, size2 ())) {
1543 return const_iterator2 (*this, 1, 1,
1544 data ().find1 (rank, size2 (), size1 ()), data ().find1 (rank, size2 (), size1 ()),
1545 data ().find2 (rank, i, j), data ().find2 (rank, i, size2 ()));
1546 } else {
1547 return const_iterator2 (*this, 1, 0,
1548 data ().find1 (rank, i, i), data ().find1 (rank, size2 (), i),
1549 data ().find2 (rank, i, j), data ().find2 (rank, i, i));
1550 }
1551 } else {
1552 if (triangular_type::other (i, size2 ())) {
1553 return const_iterator2 (*this, 0, 1,
1554 data ().find1 (rank, j, i), data ().find1 (rank, i, i),
1555 data ().find2 (rank, i, i), data ().find2 (rank, i, size2 ()));
1556 } else {
1557 return const_iterator2 (*this, 0, 0,
1558 data ().find1 (rank, j, i), data ().find1 (rank, size2 (), i),
1559 data ().find2 (rank, size1 (), size2 ()), data ().find2 (rank, size2 (), size2 ()));
1560 }
1561 }
1562 }
1563 BOOST_UBLAS_INLINE
1564 iterator2 find2 (int rank, size_type i, size_type j) {
1565 if (rank == 1)
1566 j = triangular_type::mutable_restrict2 (i, j, size1(), size2());
1567 if (rank == 0)
1568 j = triangular_type::global_mutable_restrict2 (i, size1(), j, size2());
1569 return iterator2 (*this, data ().find2 (rank, i, j));
1570 }
1571
1572
1573
1574 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1575 class const_iterator1:
1576 public container_const_reference<hermitian_adaptor>,
1577 public random_access_iterator_base<typename iterator_restrict_traits<
1578 typename const_subiterator1_type::iterator_category, dense_random_access_iterator_tag>::iterator_category,
1579 const_iterator1, value_type> {
1580 public:
1581 typedef typename const_subiterator1_type::value_type value_type;
1582 typedef typename const_subiterator1_type::difference_type difference_type;
1583
1584
1585 typedef typename const_subiterator1_type::value_type reference;
1586 typedef typename const_subiterator1_type::pointer pointer;
1587
1588 typedef const_iterator2 dual_iterator_type;
1589 typedef const_reverse_iterator2 dual_reverse_iterator_type;
1590
1591
1592 BOOST_UBLAS_INLINE
1593 const_iterator1 ():
1594 container_const_reference<self_type> (),
1595 begin_ (-1), end_ (-1), current_ (-1),
1596 it1_begin_ (), it1_end_ (), it1_ (),
1597 it2_begin_ (), it2_end_ (), it2_ () {}
1598 BOOST_UBLAS_INLINE
1599 const_iterator1 (const self_type &m, int begin, int end,
1600 const const_subiterator1_type &it1_begin, const const_subiterator1_type &it1_end,
1601 const const_subiterator2_type &it2_begin, const const_subiterator2_type &it2_end):
1602 container_const_reference<self_type> (m),
1603 begin_ (begin), end_ (end), current_ (begin),
1604 it1_begin_ (it1_begin), it1_end_ (it1_end), it1_ (it1_begin_),
1605 it2_begin_ (it2_begin), it2_end_ (it2_end), it2_ (it2_begin_) {
1606 if (current_ == 0 && it1_ == it1_end_)
1607 current_ = 1;
1608 if (current_ == 1 && it2_ == it2_end_)
1609 current_ = 0;
1610 if ((current_ == 0 && it1_ == it1_end_) ||
1611 (current_ == 1 && it2_ == it2_end_))
1612 current_ = end_;
1613 BOOST_UBLAS_CHECK (current_ == end_ ||
1614 (current_ == 0 && it1_ != it1_end_) ||
1615 (current_ == 1 && it2_ != it2_end_), internal_logic ());
1616 }
1617
1618
1619 BOOST_UBLAS_INLINE
1620 const_iterator1 (const iterator1 &it):
1621 container_const_reference<self_type> (it ()),
1622 begin_ (it.begin_), end_ (it.end_), current_ (it.current_),
1623 it1_begin_ (it.it1_begin_), it1_end_ (it.it1_end_), it1_ (it.it1_),
1624 it2_begin_ (it.it2_begin_), it2_end_ (it.it2_end_), it2_ (it.it2_) {
1625 BOOST_UBLAS_CHECK (current_ == end_ ||
1626 (current_ == 0 && it1_ != it1_end_) ||
1627 (current_ == 1 && it2_ != it2_end_), internal_logic ());
1628 }
1629
1630
1631 BOOST_UBLAS_INLINE
1632 const_iterator1 &operator ++ () {
1633 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
1634 if (current_ == 0) {
1635 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
1636 ++ it1_;
1637 if (it1_ == it1_end_ && end_ == 1) {
1638 it2_ = it2_begin_;
1639 current_ = 1;
1640 }
1641 } else {
1642 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
1643 ++ it2_;
1644 if (it2_ == it2_end_ && end_ == 0) {
1645 it1_ = it1_begin_;
1646 current_ = 0;
1647 }
1648 }
1649 return *this;
1650 }
1651 BOOST_UBLAS_INLINE
1652 const_iterator1 &operator -- () {
1653 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
1654 if (current_ == 0) {
1655 if (it1_ == it1_begin_ && begin_ == 1) {
1656 it2_ = it2_end_;
1657 BOOST_UBLAS_CHECK (it2_ != it2_begin_, internal_logic ());
1658 -- it2_;
1659 current_ = 1;
1660 } else {
1661 -- it1_;
1662 }
1663 } else {
1664 if (it2_ == it2_begin_ && begin_ == 0) {
1665 it1_ = it1_end_;
1666 BOOST_UBLAS_CHECK (it1_ != it1_begin_, internal_logic ());
1667 -- it1_;
1668 current_ = 0;
1669 } else {
1670 -- it2_;
1671 }
1672 }
1673 return *this;
1674 }
1675 BOOST_UBLAS_INLINE
1676 const_iterator1 &operator += (difference_type n) {
1677 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
1678 if (current_ == 0) {
1679 size_type d = (std::min) (n, it1_end_ - it1_);
1680 it1_ += d;
1681 n -= d;
1682 if (n > 0 || (end_ == 1 && it1_ == it1_end_)) {
1683 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
1684 d = (std::min) (n, it2_end_ - it2_begin_);
1685 it2_ = it2_begin_ + d;
1686 n -= d;
1687 current_ = 1;
1688 }
1689 } else {
1690 size_type d = (std::min) (n, it2_end_ - it2_);
1691 it2_ += d;
1692 n -= d;
1693 if (n > 0 || (end_ == 0 && it2_ == it2_end_)) {
1694 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
1695 d = (std::min) (n, it1_end_ - it1_begin_);
1696 it1_ = it1_begin_ + d;
1697 n -= d;
1698 current_ = 0;
1699 }
1700 }
1701 BOOST_UBLAS_CHECK (n == 0, external_logic ());
1702 return *this;
1703 }
1704 BOOST_UBLAS_INLINE
1705 const_iterator1 &operator -= (difference_type n) {
1706 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
1707 if (current_ == 0) {
1708 size_type d = (std::min) (n, it1_ - it1_begin_);
1709 it1_ -= d;
1710 n -= d;
1711 if (n > 0) {
1712 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
1713 d = (std::min) (n, it2_end_ - it2_begin_);
1714 it2_ = it2_end_ - d;
1715 n -= d;
1716 current_ = 1;
1717 }
1718 } else {
1719 size_type d = (std::min) (n, it2_ - it2_begin_);
1720 it2_ -= d;
1721 n -= d;
1722 if (n > 0) {
1723 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
1724 d = (std::min) (n, it1_end_ - it1_begin_);
1725 it1_ = it1_end_ - d;
1726 n -= d;
1727 current_ = 0;
1728 }
1729 }
1730 BOOST_UBLAS_CHECK (n == 0, external_logic ());
1731 return *this;
1732 }
1733 BOOST_UBLAS_INLINE
1734 difference_type operator - (const const_iterator1 &it) const {
1735 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1736 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
1737 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
1738 BOOST_UBLAS_CHECK ( end_ == it.end_, internal_logic ());
1739 if (current_ == 0 && it.current_ == 0) {
1740 return it1_ - it.it1_;
1741 } else if (current_ == 0 && it.current_ == 1) {
1742 if (end_ == 1 && it.end_ == 1) {
1743 return (it1_ - it.it1_end_) + (it.it2_begin_ - it.it2_);
1744 } else {
1745 return (it1_ - it.it1_begin_) + (it.it2_end_ - it.it2_);
1746 }
1747
1748 } else if (current_ == 1 && it.current_ == 0) {
1749 if (end_ == 1 && it.end_ == 1) {
1750 return (it2_ - it.it2_begin_) + (it.it1_end_ - it.it1_);
1751 } else {
1752 return (it2_ - it.it2_end_) + (it.it1_begin_ - it.it1_);
1753 }
1754 } else {
1755 return it2_ - it.it2_;
1756 }
1757 }
1758
1759
1760 BOOST_UBLAS_INLINE
1761 const_reference operator * () const {
1762 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
1763 if (current_ == 0) {
1764 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
1765 if (triangular_type::other (index1 (), index2 ()))
1766 return *it1_;
1767 else
1768 return type_traits<value_type>::conj (*it1_);
1769 } else {
1770 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
1771 if (triangular_type::other (index1 (), index2 ()))
1772 return *it2_;
1773 else
1774 return type_traits<value_type>::conj (*it2_);
1775 }
1776 }
1777 BOOST_UBLAS_INLINE
1778 const_reference operator [] (difference_type n) const {
1779 return *(*this + n);
1780 }
1781
1782 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1783 BOOST_UBLAS_INLINE
1784 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1785 typename self_type::
1786 #endif
1787 const_iterator2 begin () const {
1788 return (*this) ().find2 (1, index1 (), 0);
1789 }
1790 BOOST_UBLAS_INLINE
1791 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1792 typename self_type::
1793 #endif
1794 const_iterator2 cbegin () const {
1795 return begin ();
1796 }
1797 BOOST_UBLAS_INLINE
1798 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1799 typename self_type::
1800 #endif
1801 const_iterator2 end () const {
1802 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
1803 }
1804 BOOST_UBLAS_INLINE
1805 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1806 typename self_type::
1807 #endif
1808 const_iterator2 cend () const {
1809 return end ();
1810 }
1811 BOOST_UBLAS_INLINE
1812 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1813 typename self_type::
1814 #endif
1815 const_reverse_iterator2 rbegin () const {
1816 return const_reverse_iterator2 (end ());
1817 }
1818 BOOST_UBLAS_INLINE
1819 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1820 typename self_type::
1821 #endif
1822 const_reverse_iterator2 crbegin () const {
1823 return rbegin ();
1824 }
1825 BOOST_UBLAS_INLINE
1826 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1827 typename self_type::
1828 #endif
1829 const_reverse_iterator2 rend () const {
1830 return const_reverse_iterator2 (begin ());
1831 }
1832 BOOST_UBLAS_INLINE
1833 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1834 typename self_type::
1835 #endif
1836 const_reverse_iterator2 crend () const {
1837 return rend ();
1838 }
1839 #endif
1840
1841
1842 BOOST_UBLAS_INLINE
1843 size_type index1 () const {
1844 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
1845 if (current_ == 0) {
1846 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
1847 return it1_.index1 ();
1848 } else {
1849 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
1850 return it2_.index2 ();
1851 }
1852 }
1853 BOOST_UBLAS_INLINE
1854 size_type index2 () const {
1855 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
1856 if (current_ == 0) {
1857 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
1858 return it1_.index2 ();
1859 } else {
1860 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
1861 return it2_.index1 ();
1862 }
1863 }
1864
1865
1866 BOOST_UBLAS_INLINE
1867 const_iterator1 &operator = (const const_iterator1 &it) {
1868 container_const_reference<self_type>::assign (&it ());
1869 begin_ = it.begin_;
1870 end_ = it.end_;
1871 current_ = it.current_;
1872 it1_begin_ = it.it1_begin_;
1873 it1_end_ = it.it1_end_;
1874 it1_ = it.it1_;
1875 it2_begin_ = it.it2_begin_;
1876 it2_end_ = it.it2_end_;
1877 it2_ = it.it2_;
1878 return *this;
1879 }
1880
1881
1882 BOOST_UBLAS_INLINE
1883 bool operator == (const const_iterator1 &it) const {
1884 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1885 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
1886 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
1887 BOOST_UBLAS_CHECK ( end_ == it.end_, internal_logic ());
1888 return (current_ == 0 && it.current_ == 0 && it1_ == it.it1_) ||
1889 (current_ == 1 && it.current_ == 1 && it2_ == it.it2_);
1890 }
1891 BOOST_UBLAS_INLINE
1892 bool operator < (const const_iterator1 &it) const {
1893 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1894 return it - *this > 0;
1895 }
1896
1897 private:
1898 int begin_;
1899 int end_;
1900 int current_;
1901 const_subiterator1_type it1_begin_;
1902 const_subiterator1_type it1_end_;
1903 const_subiterator1_type it1_;
1904 const_subiterator2_type it2_begin_;
1905 const_subiterator2_type it2_end_;
1906 const_subiterator2_type it2_;
1907 };
1908 #endif
1909
1910 BOOST_UBLAS_INLINE
1911 const_iterator1 begin1 () const {
1912 return find1 (0, 0, 0);
1913 }
1914 BOOST_UBLAS_INLINE
1915 const_iterator1 cbegin1 () const {
1916 return begin1 ();
1917 }
1918 BOOST_UBLAS_INLINE
1919 const_iterator1 end1 () const {
1920 return find1 (0, size1 (), 0);
1921 }
1922 BOOST_UBLAS_INLINE
1923 const_iterator1 cend1 () const {
1924 return end1 ();
1925 }
1926
1927 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1928 class iterator1:
1929 public container_reference<hermitian_adaptor>,
1930 public random_access_iterator_base<typename iterator_restrict_traits<
1931 typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
1932 iterator1, value_type> {
1933 public:
1934 typedef typename subiterator1_type::value_type value_type;
1935 typedef typename subiterator1_type::difference_type difference_type;
1936 typedef typename subiterator1_type::reference reference;
1937 typedef typename subiterator1_type::pointer pointer;
1938
1939 typedef iterator2 dual_iterator_type;
1940 typedef reverse_iterator2 dual_reverse_iterator_type;
1941
1942
1943 BOOST_UBLAS_INLINE
1944 iterator1 ():
1945 container_reference<self_type> (), it1_ () {}
1946 BOOST_UBLAS_INLINE
1947 iterator1 (self_type &m, const subiterator1_type &it1):
1948 container_reference<self_type> (m), it1_ (it1) {}
1949
1950
1951 BOOST_UBLAS_INLINE
1952 iterator1 &operator ++ () {
1953 ++ it1_;
1954 return *this;
1955 }
1956 BOOST_UBLAS_INLINE
1957 iterator1 &operator -- () {
1958 -- it1_;
1959 return *this;
1960 }
1961 BOOST_UBLAS_INLINE
1962 iterator1 &operator += (difference_type n) {
1963 it1_ += n;
1964 return *this;
1965 }
1966 BOOST_UBLAS_INLINE
1967 iterator1 &operator -= (difference_type n) {
1968 it1_ -= n;
1969 return *this;
1970 }
1971 BOOST_UBLAS_INLINE
1972 difference_type operator - (const iterator1 &it) const {
1973 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1974 return it1_ - it.it1_;
1975 }
1976
1977
1978 BOOST_UBLAS_INLINE
1979 reference operator * () const {
1980 return *it1_;
1981 }
1982 BOOST_UBLAS_INLINE
1983 reference operator [] (difference_type n) const {
1984 return *(*this + n);
1985 }
1986
1987 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1988 BOOST_UBLAS_INLINE
1989 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1990 typename self_type::
1991 #endif
1992 iterator2 begin () const {
1993 return (*this) ().find2 (1, index1 (), 0);
1994 }
1995 BOOST_UBLAS_INLINE
1996 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
1997 typename self_type::
1998 #endif
1999 iterator2 end () const {
2000 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
2001 }
2002 BOOST_UBLAS_INLINE
2003 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2004 typename self_type::
2005 #endif
2006 reverse_iterator2 rbegin () const {
2007 return reverse_iterator2 (end ());
2008 }
2009 BOOST_UBLAS_INLINE
2010 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2011 typename self_type::
2012 #endif
2013 reverse_iterator2 rend () const {
2014 return reverse_iterator2 (begin ());
2015 }
2016 #endif
2017
2018
2019 BOOST_UBLAS_INLINE
2020 size_type index1 () const {
2021 return it1_.index1 ();
2022 }
2023 BOOST_UBLAS_INLINE
2024 size_type index2 () const {
2025 return it1_.index2 ();
2026 }
2027
2028
2029 BOOST_UBLAS_INLINE
2030 iterator1 &operator = (const iterator1 &it) {
2031 container_reference<self_type>::assign (&it ());
2032 it1_ = it.it1_;
2033 return *this;
2034 }
2035
2036
2037 BOOST_UBLAS_INLINE
2038 bool operator == (const iterator1 &it) const {
2039 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2040 return it1_ == it.it1_;
2041 }
2042 BOOST_UBLAS_INLINE
2043 bool operator < (const iterator1 &it) const {
2044 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2045 return it1_ < it.it1_;
2046 }
2047
2048 private:
2049 subiterator1_type it1_;
2050
2051 friend class const_iterator1;
2052 };
2053 #endif
2054
2055 BOOST_UBLAS_INLINE
2056 iterator1 begin1 () {
2057 return find1 (0, 0, 0);
2058 }
2059 BOOST_UBLAS_INLINE
2060 iterator1 end1 () {
2061 return find1 (0, size1 (), 0);
2062 }
2063
2064 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
2065 class const_iterator2:
2066 public container_const_reference<hermitian_adaptor>,
2067 public random_access_iterator_base<typename iterator_restrict_traits<
2068 typename const_subiterator2_type::iterator_category, dense_random_access_iterator_tag>::iterator_category,
2069 const_iterator2, value_type> {
2070 public:
2071 typedef typename const_subiterator2_type::value_type value_type;
2072 typedef typename const_subiterator2_type::difference_type difference_type;
2073
2074
2075 typedef typename const_subiterator2_type::value_type reference;
2076 typedef typename const_subiterator2_type::pointer pointer;
2077
2078 typedef const_iterator1 dual_iterator_type;
2079 typedef const_reverse_iterator1 dual_reverse_iterator_type;
2080
2081
2082 BOOST_UBLAS_INLINE
2083 const_iterator2 ():
2084 container_const_reference<self_type> (),
2085 begin_ (-1), end_ (-1), current_ (-1),
2086 it1_begin_ (), it1_end_ (), it1_ (),
2087 it2_begin_ (), it2_end_ (), it2_ () {}
2088 BOOST_UBLAS_INLINE
2089 const_iterator2 (const self_type &m, int begin, int end,
2090 const const_subiterator1_type &it1_begin, const const_subiterator1_type &it1_end,
2091 const const_subiterator2_type &it2_begin, const const_subiterator2_type &it2_end):
2092 container_const_reference<self_type> (m),
2093 begin_ (begin), end_ (end), current_ (begin),
2094 it1_begin_ (it1_begin), it1_end_ (it1_end), it1_ (it1_begin_),
2095 it2_begin_ (it2_begin), it2_end_ (it2_end), it2_ (it2_begin_) {
2096 if (current_ == 0 && it1_ == it1_end_)
2097 current_ = 1;
2098 if (current_ == 1 && it2_ == it2_end_)
2099 current_ = 0;
2100 if ((current_ == 0 && it1_ == it1_end_) ||
2101 (current_ == 1 && it2_ == it2_end_))
2102 current_ = end_;
2103 BOOST_UBLAS_CHECK (current_ == end_ ||
2104 (current_ == 0 && it1_ != it1_end_) ||
2105 (current_ == 1 && it2_ != it2_end_), internal_logic ());
2106 }
2107
2108
2109 BOOST_UBLAS_INLINE
2110 const_iterator2 (const iterator2 &it):
2111 container_const_reference<self_type> (it ()),
2112 begin_ (it.begin_), end_ (it.end_), current_ (it.current_),
2113 it1_begin_ (it.it1_begin_), it1_end_ (it.it1_end_), it1_ (it.it1_),
2114 it2_begin_ (it.it2_begin_), it2_end_ (it.it2_end_), it2_ (it.it2_) {
2115 BOOST_UBLAS_CHECK (current_ == end_ ||
2116 (current_ == 0 && it1_ != it1_end_) ||
2117 (current_ == 1 && it2_ != it2_end_), internal_logic ());
2118 }
2119
2120
2121 BOOST_UBLAS_INLINE
2122 const_iterator2 &operator ++ () {
2123 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
2124 if (current_ == 0) {
2125 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
2126 ++ it1_;
2127 if (it1_ == it1_end_ && end_ == 1) {
2128 it2_ = it2_begin_;
2129 current_ = 1;
2130 }
2131 } else {
2132 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
2133 ++ it2_;
2134 if (it2_ == it2_end_ && end_ == 0) {
2135 it1_ = it1_begin_;
2136 current_ = 0;
2137 }
2138 }
2139 return *this;
2140 }
2141 BOOST_UBLAS_INLINE
2142 const_iterator2 &operator -- () {
2143 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
2144 if (current_ == 0) {
2145 if (it1_ == it1_begin_ && begin_ == 1) {
2146 it2_ = it2_end_;
2147 BOOST_UBLAS_CHECK (it2_ != it2_begin_, internal_logic ());
2148 -- it2_;
2149 current_ = 1;
2150 } else {
2151 -- it1_;
2152 }
2153 } else {
2154 if (it2_ == it2_begin_ && begin_ == 0) {
2155 it1_ = it1_end_;
2156 BOOST_UBLAS_CHECK (it1_ != it1_begin_, internal_logic ());
2157 -- it1_;
2158 current_ = 0;
2159 } else {
2160 -- it2_;
2161 }
2162 }
2163 return *this;
2164 }
2165 BOOST_UBLAS_INLINE
2166 const_iterator2 &operator += (difference_type n) {
2167 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
2168 if (current_ == 0) {
2169 size_type d = (std::min) (n, it1_end_ - it1_);
2170 it1_ += d;
2171 n -= d;
2172 if (n > 0 || (end_ == 1 && it1_ == it1_end_)) {
2173 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
2174 d = (std::min) (n, it2_end_ - it2_begin_);
2175 it2_ = it2_begin_ + d;
2176 n -= d;
2177 current_ = 1;
2178 }
2179 } else {
2180 size_type d = (std::min) (n, it2_end_ - it2_);
2181 it2_ += d;
2182 n -= d;
2183 if (n > 0 || (end_ == 0 && it2_ == it2_end_)) {
2184 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
2185 d = (std::min) (n, it1_end_ - it1_begin_);
2186 it1_ = it1_begin_ + d;
2187 n -= d;
2188 current_ = 0;
2189 }
2190 }
2191 BOOST_UBLAS_CHECK (n == 0, external_logic ());
2192 return *this;
2193 }
2194 BOOST_UBLAS_INLINE
2195 const_iterator2 &operator -= (difference_type n) {
2196 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
2197 if (current_ == 0) {
2198 size_type d = (std::min) (n, it1_ - it1_begin_);
2199 it1_ -= d;
2200 n -= d;
2201 if (n > 0) {
2202 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
2203 d = (std::min) (n, it2_end_ - it2_begin_);
2204 it2_ = it2_end_ - d;
2205 n -= d;
2206 current_ = 1;
2207 }
2208 } else {
2209 size_type d = (std::min) (n, it2_ - it2_begin_);
2210 it2_ -= d;
2211 n -= d;
2212 if (n > 0) {
2213 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
2214 d = (std::min) (n, it1_end_ - it1_begin_);
2215 it1_ = it1_end_ - d;
2216 n -= d;
2217 current_ = 0;
2218 }
2219 }
2220 BOOST_UBLAS_CHECK (n == 0, external_logic ());
2221 return *this;
2222 }
2223 BOOST_UBLAS_INLINE
2224 difference_type operator - (const const_iterator2 &it) const {
2225 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2226 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
2227 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
2228 BOOST_UBLAS_CHECK ( end_ == it.end_, internal_logic ());
2229 if (current_ == 0 && it.current_ == 0) {
2230 return it1_ - it.it1_;
2231 } else if (current_ == 0 && it.current_ == 1) {
2232 if (end_ == 1 && it.end_ == 1) {
2233 return (it1_ - it.it1_end_) + (it.it2_begin_ - it.it2_);
2234 } else {
2235 return (it1_ - it.it1_begin_) + (it.it2_end_ - it.it2_);
2236 }
2237
2238 } else if (current_ == 1 && it.current_ == 0) {
2239 if (end_ == 1 && it.end_ == 1) {
2240 return (it2_ - it.it2_begin_) + (it.it1_end_ - it.it1_);
2241 } else {
2242 return (it2_ - it.it2_end_) + (it.it1_begin_ - it.it1_);
2243 }
2244 } else {
2245 return it2_ - it.it2_;
2246 }
2247 }
2248
2249
2250 BOOST_UBLAS_INLINE
2251 const_reference operator * () const {
2252 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
2253 if (current_ == 0) {
2254 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
2255 if (triangular_type::other (index1 (), index2 ()))
2256 return *it1_;
2257 else
2258 return type_traits<value_type>::conj (*it1_);
2259 } else {
2260 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
2261 if (triangular_type::other (index1 (), index2 ()))
2262 return *it2_;
2263 else
2264 return type_traits<value_type>::conj (*it2_);
2265 }
2266 }
2267 BOOST_UBLAS_INLINE
2268 const_reference operator [] (difference_type n) const {
2269 return *(*this + n);
2270 }
2271
2272 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
2273 BOOST_UBLAS_INLINE
2274 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2275 typename self_type::
2276 #endif
2277 const_iterator1 begin () const {
2278 return (*this) ().find1 (1, 0, index2 ());
2279 }
2280 BOOST_UBLAS_INLINE
2281 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2282 typename self_type::
2283 #endif
2284 const_iterator1 cbegin () const {
2285 return begin ();
2286 }
2287 BOOST_UBLAS_INLINE
2288 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2289 typename self_type::
2290 #endif
2291 const_iterator1 end () const {
2292 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
2293 }
2294 BOOST_UBLAS_INLINE
2295 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2296 typename self_type::
2297 #endif
2298 const_iterator1 cend () const {
2299 return end ();
2300 }
2301 BOOST_UBLAS_INLINE
2302 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2303 typename self_type::
2304 #endif
2305 const_reverse_iterator1 rbegin () const {
2306 return const_reverse_iterator1 (end ());
2307 }
2308 BOOST_UBLAS_INLINE
2309 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2310 typename self_type::
2311 #endif
2312 const_reverse_iterator1 crbegin () const {
2313 return rbegin ();
2314 }
2315 BOOST_UBLAS_INLINE
2316 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2317 typename self_type::
2318 #endif
2319 const_reverse_iterator1 rend () const {
2320 return const_reverse_iterator1 (begin ());
2321 }
2322 BOOST_UBLAS_INLINE
2323 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2324 typename self_type::
2325 #endif
2326 const_reverse_iterator1 crend () const {
2327 return end ();
2328 }
2329 #endif
2330
2331
2332 BOOST_UBLAS_INLINE
2333 size_type index1 () const {
2334 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
2335 if (current_ == 0) {
2336 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
2337 return it1_.index2 ();
2338 } else {
2339 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
2340 return it2_.index1 ();
2341 }
2342 }
2343 BOOST_UBLAS_INLINE
2344 size_type index2 () const {
2345 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
2346 if (current_ == 0) {
2347 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
2348 return it1_.index1 ();
2349 } else {
2350 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
2351 return it2_.index2 ();
2352 }
2353 }
2354
2355
2356 BOOST_UBLAS_INLINE
2357 const_iterator2 &operator = (const const_iterator2 &it) {
2358 container_const_reference<self_type>::assign (&it ());
2359 begin_ = it.begin_;
2360 end_ = it.end_;
2361 current_ = it.current_;
2362 it1_begin_ = it.it1_begin_;
2363 it1_end_ = it.it1_end_;
2364 it1_ = it.it1_;
2365 it2_begin_ = it.it2_begin_;
2366 it2_end_ = it.it2_end_;
2367 it2_ = it.it2_;
2368 return *this;
2369 }
2370
2371
2372 BOOST_UBLAS_INLINE
2373 bool operator == (const const_iterator2 &it) const {
2374 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2375 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
2376 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
2377 BOOST_UBLAS_CHECK ( end_ == it.end_, internal_logic ());
2378 return (current_ == 0 && it.current_ == 0 && it1_ == it.it1_) ||
2379 (current_ == 1 && it.current_ == 1 && it2_ == it.it2_);
2380 }
2381 BOOST_UBLAS_INLINE
2382 bool operator < (const const_iterator2 &it) const {
2383 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2384 return it - *this > 0;
2385 }
2386
2387 private:
2388 int begin_;
2389 int end_;
2390 int current_;
2391 const_subiterator1_type it1_begin_;
2392 const_subiterator1_type it1_end_;
2393 const_subiterator1_type it1_;
2394 const_subiterator2_type it2_begin_;
2395 const_subiterator2_type it2_end_;
2396 const_subiterator2_type it2_;
2397 };
2398 #endif
2399
2400 BOOST_UBLAS_INLINE
2401 const_iterator2 begin2 () const {
2402 return find2 (0, 0, 0);
2403 }
2404 BOOST_UBLAS_INLINE
2405 const_iterator2 cbegin2 () const {
2406 return begin2 ();
2407 }
2408 BOOST_UBLAS_INLINE
2409 const_iterator2 end2 () const {
2410 return find2 (0, 0, size2 ());
2411 }
2412 BOOST_UBLAS_INLINE
2413 const_iterator2 cend2 () const {
2414 return end2 ();
2415 }
2416
2417 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
2418 class iterator2:
2419 public container_reference<hermitian_adaptor>,
2420 public random_access_iterator_base<typename iterator_restrict_traits<
2421 typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
2422 iterator2, value_type> {
2423 public:
2424 typedef typename subiterator2_type::value_type value_type;
2425 typedef typename subiterator2_type::difference_type difference_type;
2426 typedef typename subiterator2_type::reference reference;
2427 typedef typename subiterator2_type::pointer pointer;
2428
2429 typedef iterator1 dual_iterator_type;
2430 typedef reverse_iterator1 dual_reverse_iterator_type;
2431
2432
2433 BOOST_UBLAS_INLINE
2434 iterator2 ():
2435 container_reference<self_type> (), it2_ () {}
2436 BOOST_UBLAS_INLINE
2437 iterator2 (self_type &m, const subiterator2_type &it2):
2438 container_reference<self_type> (m), it2_ (it2) {}
2439
2440
2441 BOOST_UBLAS_INLINE
2442 iterator2 &operator ++ () {
2443 ++ it2_;
2444 return *this;
2445 }
2446 BOOST_UBLAS_INLINE
2447 iterator2 &operator -- () {
2448 -- it2_;
2449 return *this;
2450 }
2451 BOOST_UBLAS_INLINE
2452 iterator2 &operator += (difference_type n) {
2453 it2_ += n;
2454 return *this;
2455 }
2456 BOOST_UBLAS_INLINE
2457 iterator2 &operator -= (difference_type n) {
2458 it2_ -= n;
2459 return *this;
2460 }
2461 BOOST_UBLAS_INLINE
2462 difference_type operator - (const iterator2 &it) const {
2463 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2464 return it2_ - it.it2_;
2465 }
2466
2467
2468 BOOST_UBLAS_INLINE
2469 reference operator * () const {
2470 return *it2_;
2471 }
2472 BOOST_UBLAS_INLINE
2473 reference operator [] (difference_type n) const {
2474 return *(*this + n);
2475 }
2476
2477 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
2478 BOOST_UBLAS_INLINE
2479 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2480 typename self_type::
2481 #endif
2482 iterator1 begin () const {
2483 return (*this) ().find1 (1, 0, index2 ());
2484 }
2485 BOOST_UBLAS_INLINE
2486 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2487 typename self_type::
2488 #endif
2489 iterator1 end () const {
2490 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
2491 }
2492 BOOST_UBLAS_INLINE
2493 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2494 typename self_type::
2495 #endif
2496 reverse_iterator1 rbegin () const {
2497 return reverse_iterator1 (end ());
2498 }
2499 BOOST_UBLAS_INLINE
2500 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
2501 typename self_type::
2502 #endif
2503 reverse_iterator1 rend () const {
2504 return reverse_iterator1 (begin ());
2505 }
2506 #endif
2507
2508
2509 BOOST_UBLAS_INLINE
2510 size_type index1 () const {
2511 return it2_.index1 ();
2512 }
2513 BOOST_UBLAS_INLINE
2514 size_type index2 () const {
2515 return it2_.index2 ();
2516 }
2517
2518
2519 BOOST_UBLAS_INLINE
2520 iterator2 &operator = (const iterator2 &it) {
2521 container_reference<self_type>::assign (&it ());
2522 it2_ = it.it2_;
2523 return *this;
2524 }
2525
2526
2527 BOOST_UBLAS_INLINE
2528 bool operator == (const iterator2 &it) const {
2529 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2530 return it2_ == it.it2_;
2531 }
2532 BOOST_UBLAS_INLINE
2533 bool operator < (const iterator2 &it) const {
2534 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2535 return it2_ < it.it2_;
2536 }
2537
2538 private:
2539 subiterator2_type it2_;
2540
2541 friend class const_iterator2;
2542 };
2543 #endif
2544
2545 BOOST_UBLAS_INLINE
2546 iterator2 begin2 () {
2547 return find2 (0, 0, 0);
2548 }
2549 BOOST_UBLAS_INLINE
2550 iterator2 end2 () {
2551 return find2 (0, 0, size2 ());
2552 }
2553
2554
2555
2556 BOOST_UBLAS_INLINE
2557 const_reverse_iterator1 rbegin1 () const {
2558 return const_reverse_iterator1 (end1 ());
2559 }
2560 BOOST_UBLAS_INLINE
2561 const_reverse_iterator1 crbegin1 () const {
2562 return rbegin1();
2563 }
2564 BOOST_UBLAS_INLINE
2565 const_reverse_iterator1 rend1 () const {
2566 return const_reverse_iterator1 (begin1 ());
2567 }
2568 BOOST_UBLAS_INLINE
2569 const_reverse_iterator1 crend1 () const {
2570 return rend1 ();
2571 }
2572
2573 BOOST_UBLAS_INLINE
2574 reverse_iterator1 rbegin1 () {
2575 return reverse_iterator1 (end1 ());
2576 }
2577 BOOST_UBLAS_INLINE
2578 reverse_iterator1 rend1 () {
2579 return reverse_iterator1 (begin1 ());
2580 }
2581
2582 BOOST_UBLAS_INLINE
2583 const_reverse_iterator2 rbegin2 () const {
2584 return const_reverse_iterator2 (end2 ());
2585 }
2586 BOOST_UBLAS_INLINE
2587 const_reverse_iterator2 crbegin2 () const {
2588 return rbegin2 ();
2589 }
2590 BOOST_UBLAS_INLINE
2591 const_reverse_iterator2 rend2 () const {
2592 return const_reverse_iterator2 (begin2 ());
2593 }
2594 BOOST_UBLAS_INLINE
2595 const_reverse_iterator2 crend2 () const {
2596 return rend2 ();
2597 }
2598
2599 BOOST_UBLAS_INLINE
2600 reverse_iterator2 rbegin2 () {
2601 return reverse_iterator2 (end2 ());
2602 }
2603 BOOST_UBLAS_INLINE
2604 reverse_iterator2 rend2 () {
2605 return reverse_iterator2 (begin2 ());
2606 }
2607
2608 private:
2609 matrix_closure_type data_;
2610 static value_type conj_;
2611 };
2612
2613 template<class M, class TRI>
2614 typename hermitian_adaptor<M, TRI>::value_type hermitian_adaptor<M, TRI>::conj_;
2615
2616
2617 template <class M, class TRI>
2618 struct vector_temporary_traits< hermitian_adaptor<M, TRI> >
2619 : vector_temporary_traits< M > {} ;
2620 template <class M, class TRI>
2621 struct vector_temporary_traits< const hermitian_adaptor<M, TRI> >
2622 : vector_temporary_traits< M > {} ;
2623
2624 template <class M, class TRI>
2625 struct matrix_temporary_traits< hermitian_adaptor<M, TRI> >
2626 : matrix_temporary_traits< M > {} ;
2627 template <class M, class TRI>
2628 struct matrix_temporary_traits< const hermitian_adaptor<M, TRI> >
2629 : matrix_temporary_traits< M > {} ;
2630
2631 }}}
2632
2633 #endif