00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef BOOST_UBLAS_HERMITIAN_H
00014 #define BOOST_UBLAS_HERMITIAN_H
00015
00016 #include <boost/numeric/ublas/matrix.hpp>
00017 #include <boost/numeric/ublas/triangular.hpp>
00018 #include <boost/numeric/ublas/detail/temporary.hpp>
00019
00020
00021
00022
00023 namespace boost { namespace numeric { namespace ublas {
00024
00025 template<class M>
00026 bool is_hermitian (const M &m) {
00027 typedef typename M::size_type size_type;
00028
00029 if (m.size1 () != m.size2 ())
00030 return false;
00031 size_type size = BOOST_UBLAS_SAME (m.size1 (), m.size2 ());
00032 for (size_type i = 0; i < size; ++ i) {
00033 for (size_type j = i; j < size; ++ j) {
00034 if (m (i, j) != conj (m (j, i)))
00035 return false;
00036 }
00037 }
00038 return true;
00039 }
00040
00041 #ifdef BOOST_UBLAS_STRICT_HERMITIAN
00042
00043 template<class M>
00044 class hermitian_matrix_element:
00045 public container_reference<M> {
00046 public:
00047 typedef M matrix_type;
00048 typedef typename M::size_type size_type;
00049 typedef typename M::value_type value_type;
00050 typedef const value_type &const_reference;
00051 typedef value_type &reference;
00052 typedef value_type *pointer;
00053
00054
00055 BOOST_UBLAS_INLINE
00056 hermitian_matrix_element (matrix_type &m, size_type i, size_type j, value_type d):
00057 container_reference<matrix_type> (m), i_ (i), j_ (j), d_ (d), dirty_ (false) {}
00058 BOOST_UBLAS_INLINE
00059 ~hermitian_matrix_element () {
00060 if (dirty_)
00061 (*this) ().insert_element (i_, j_, d_);
00062 }
00063
00064
00065 BOOST_UBLAS_INLINE
00066 hermitian_matrix_element &operator = (const hermitian_matrix_element &p) {
00067
00068 d_ = p.d_;
00069 dirty_ = true;
00070 return *this;
00071 }
00072 template<class D>
00073 BOOST_UBLAS_INLINE
00074 hermitian_matrix_element &operator = (const D &d) {
00075 d_ = d;
00076 dirty_ = true;
00077 return *this;
00078 }
00079 template<class D>
00080 BOOST_UBLAS_INLINE
00081 hermitian_matrix_element &operator += (const D &d) {
00082 d_ += d;
00083 dirty_ = true;
00084 return *this;
00085 }
00086 template<class D>
00087 BOOST_UBLAS_INLINE
00088 hermitian_matrix_element &operator -= (const D &d) {
00089 d_ -= d;
00090 dirty_ = true;
00091 return *this;
00092 }
00093 template<class D>
00094 BOOST_UBLAS_INLINE
00095 hermitian_matrix_element &operator *= (const D &d) {
00096 d_ *= d;
00097 dirty_ = true;
00098 return *this;
00099 }
00100 template<class D>
00101 BOOST_UBLAS_INLINE
00102 hermitian_matrix_element &operator /= (const D &d) {
00103 d_ /= d;
00104 dirty_ = true;
00105 return *this;
00106 }
00107
00108
00109 template<class D>
00110 BOOST_UBLAS_INLINE
00111 bool operator == (const D &d) const {
00112 return d_ == d;
00113 }
00114 template<class D>
00115 BOOST_UBLAS_INLINE
00116 bool operator != (const D &d) const {
00117 return d_ != d;
00118 }
00119
00120
00121 BOOST_UBLAS_INLINE
00122 operator const_reference () const {
00123 return d_;
00124 }
00125
00126
00127 BOOST_UBLAS_INLINE
00128 void swap (hermitian_matrix_element p) {
00129 if (this != &p) {
00130 dirty_ = true;
00131 p.dirty_ = true;
00132 std::swap (d_, p.d_);
00133 }
00134 }
00135 BOOST_UBLAS_INLINE
00136 friend void swap (hermitian_matrix_element p1, hermitian_matrix_element p2) {
00137 p1.swap (p2);
00138 }
00139
00140 private:
00141 size_type i_;
00142 size_type j_;
00143 value_type d_;
00144 bool dirty_;
00145 };
00146
00147 template<class M>
00148 struct type_traits<hermitian_matrix_element<M> > {
00149 typedef typename M::value_type element_type;
00150 typedef type_traits<hermitian_matrix_element<M> > self_type;
00151 typedef typename type_traits<element_type>::value_type value_type;
00152 typedef typename type_traits<element_type>::const_reference const_reference;
00153 typedef hermitian_matrix_element<M> reference;
00154 typedef typename type_traits<element_type>::real_type real_type;
00155 typedef typename type_traits<element_type>::precision_type precision_type;
00156
00157 static const unsigned plus_complexity = type_traits<element_type>::plus_complexity;
00158 static const unsigned multiplies_complexity = type_traits<element_type>::multiplies_complexity;
00159
00160 static
00161 BOOST_UBLAS_INLINE
00162 real_type real (const_reference t) {
00163 return type_traits<element_type>::real (t);
00164 }
00165 static
00166 BOOST_UBLAS_INLINE
00167 real_type imag (const_reference t) {
00168 return type_traits<element_type>::imag (t);
00169 }
00170 static
00171 BOOST_UBLAS_INLINE
00172 value_type conj (const_reference t) {
00173 return type_traits<element_type>::conj (t);
00174 }
00175
00176 static
00177 BOOST_UBLAS_INLINE
00178 real_type type_abs (const_reference t) {
00179 return type_traits<element_type>::type_abs (t);
00180 }
00181 static
00182 BOOST_UBLAS_INLINE
00183 value_type type_sqrt (const_reference t) {
00184 return type_traits<element_type>::type_sqrt (t);
00185 }
00186
00187 static
00188 BOOST_UBLAS_INLINE
00189 real_type norm_1 (const_reference t) {
00190 return type_traits<element_type>::norm_1 (t);
00191 }
00192 static
00193 BOOST_UBLAS_INLINE
00194 real_type norm_2 (const_reference t) {
00195 return type_traits<element_type>::norm_2 (t);
00196 }
00197 static
00198 BOOST_UBLAS_INLINE
00199 real_type norm_inf (const_reference t) {
00200 return type_traits<element_type>::norm_inf (t);
00201 }
00202
00203 static
00204 BOOST_UBLAS_INLINE
00205 bool equals (const_reference t1, const_reference t2) {
00206 return type_traits<element_type>::equals (t1, t2);
00207 }
00208 };
00209
00210 template<class M1, class T2>
00211 struct promote_traits<hermitian_matrix_element<M1>, T2> {
00212 typedef typename promote_traits<typename hermitian_matrix_element<M1>::value_type, T2>::promote_type promote_type;
00213 };
00214 template<class T1, class M2>
00215 struct promote_traits<T1, hermitian_matrix_element<M2> > {
00216 typedef typename promote_traits<T1, typename hermitian_matrix_element<M2>::value_type>::promote_type promote_type;
00217 };
00218 template<class M1, class M2>
00219 struct promote_traits<hermitian_matrix_element<M1>, hermitian_matrix_element<M2> > {
00220 typedef typename promote_traits<typename hermitian_matrix_element<M1>::value_type,
00221 typename hermitian_matrix_element<M2>::value_type>::promote_type promote_type;
00222 };
00223
00224 #endif
00225
00243 template<class T, class TRI, class L, class A>
00244 class hermitian_matrix:
00245 public matrix_container<hermitian_matrix<T, TRI, L, A> > {
00246
00247 typedef T &true_reference;
00248 typedef T *pointer;
00249 typedef TRI triangular_type;
00250 typedef L layout_type;
00251 typedef hermitian_matrix<T, TRI, L, A> self_type;
00252 public:
00253 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00254 using matrix_container<self_type>::operator ();
00255 #endif
00256 typedef typename A::size_type size_type;
00257 typedef typename A::difference_type difference_type;
00258 typedef T value_type;
00259
00260
00261 typedef const T const_reference;
00262 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
00263 typedef T &reference;
00264 #else
00265 typedef hermitian_matrix_element<self_type> reference;
00266 #endif
00267 typedef A array_type;
00268
00269 typedef const matrix_reference<const self_type> const_closure_type;
00270 typedef matrix_reference<self_type> closure_type;
00271 typedef vector<T, A> vector_temporary_type;
00272 typedef matrix<T, L, A> matrix_temporary_type;
00273 typedef packed_tag storage_category;
00274 typedef typename L::orientation_category orientation_category;
00275
00276
00277 BOOST_UBLAS_INLINE
00278 hermitian_matrix ():
00279 matrix_container<self_type> (),
00280 size_ (0), data_ (0) {}
00281 BOOST_UBLAS_INLINE
00282 hermitian_matrix (size_type size):
00283 matrix_container<self_type> (),
00284 size_ (BOOST_UBLAS_SAME (size, size)), data_ (triangular_type::packed_size (layout_type (), size, size)) {
00285 }
00286 BOOST_UBLAS_INLINE
00287 hermitian_matrix (size_type size1, size_type size2):
00288 matrix_container<self_type> (),
00289 size_ (BOOST_UBLAS_SAME (size1, size2)), data_ (triangular_type::packed_size (layout_type (), size1, size2)) {
00290 }
00291 BOOST_UBLAS_INLINE
00292 hermitian_matrix (size_type size, const array_type &data):
00293 matrix_container<self_type> (),
00294 size_ (size), data_ (data) {}
00295 BOOST_UBLAS_INLINE
00296 hermitian_matrix (const hermitian_matrix &m):
00297 matrix_container<self_type> (),
00298 size_ (m.size_), data_ (m.data_) {}
00299 template<class AE>
00300 BOOST_UBLAS_INLINE
00301 hermitian_matrix (const matrix_expression<AE> &ae):
00302 matrix_container<self_type> (),
00303 size_ (BOOST_UBLAS_SAME (ae ().size1 (), ae ().size2 ())),
00304 data_ (triangular_type::packed_size (layout_type (), size_, size_)) {
00305 matrix_assign<scalar_assign> (*this, ae);
00306 }
00307
00308
00309 BOOST_UBLAS_INLINE
00310 size_type size1 () const {
00311 return size_;
00312 }
00313 BOOST_UBLAS_INLINE
00314 size_type size2 () const {
00315 return size_;
00316 }
00317
00318
00319 BOOST_UBLAS_INLINE
00320 const array_type &data () const {
00321 return data_;
00322 }
00323 BOOST_UBLAS_INLINE
00324 array_type &data () {
00325 return data_;
00326 }
00327
00328
00329 BOOST_UBLAS_INLINE
00330 void resize (size_type size, bool preserve = true) {
00331 if (preserve) {
00332 self_type temporary (size, size);
00333 detail::matrix_resize_preserve<layout_type, triangular_type> (*this, temporary);
00334 }
00335 else {
00336 data ().resize (triangular_type::packed_size (layout_type (), size, size));
00337 size_ = size;
00338 }
00339 }
00340 BOOST_UBLAS_INLINE
00341 void resize (size_type size1, size_type size2, bool preserve = true) {
00342 resize (BOOST_UBLAS_SAME (size1, size2), preserve);
00343 }
00344 BOOST_UBLAS_INLINE
00345 void resize_packed_preserve (size_type size) {
00346 size_ = BOOST_UBLAS_SAME (size, size);
00347 data ().resize (triangular_type::packed_size (layout_type (), size_, size_), value_type ());
00348 }
00349
00350
00351 BOOST_UBLAS_INLINE
00352 const_reference operator () (size_type i, size_type j) const {
00353 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00354 BOOST_UBLAS_CHECK (j < size_, bad_index ());
00355
00356
00357
00358 if (triangular_type::other (i, j))
00359 return data () [triangular_type::element (layout_type (), i, size_, j, size_)];
00360 else
00361 return type_traits<value_type>::conj (data () [triangular_type::element (layout_type (), j, size_, i, size_)]);
00362 }
00363 BOOST_UBLAS_INLINE
00364 true_reference at_element (size_type i, size_type j) {
00365 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00366 BOOST_UBLAS_CHECK (j < size_, bad_index ());
00367 BOOST_UBLAS_CHECK (triangular_type::other (i, j), bad_index ());
00368 return data () [triangular_type::element (layout_type (), i, size_, j, size_)];
00369 }
00370 BOOST_UBLAS_INLINE
00371 reference operator () (size_type i, size_type j) {
00372 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
00373 if (!triangular_type::other (i, j)) {
00374 bad_index ().raise ();
00375
00376 }
00377 return at_element (i, j);
00378 #else
00379 if (triangular_type::other (i, j))
00380 return reference (*this, i, j, data () [triangular_type::element (layout_type (), i, size_, j, size_)]);
00381 else
00382 return reference (*this, i, j, type_traits<value_type>::conj (data () [triangular_type::element (layout_type (), j, size_, i, size_)]));
00383 #endif
00384 }
00385
00386
00387 BOOST_UBLAS_INLINE
00388 true_reference insert_element (size_type i, size_type j, const_reference t) {
00389 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00390 BOOST_UBLAS_CHECK (j < size_, bad_index ());
00391 if (triangular_type::other (i, j)) {
00392 return (data () [triangular_type::element (layout_type (), i, size_, j, size_)] = t);
00393 } else {
00394 return (data () [triangular_type::element (layout_type (), j, size_, i, size_)] = type_traits<value_type>::conj (t));
00395 }
00396 }
00397 BOOST_UBLAS_INLINE
00398 void erase_element (size_type i, size_type j) {
00399 BOOST_UBLAS_CHECK (i < size_, bad_index ());
00400 BOOST_UBLAS_CHECK (j < size_, bad_index ());
00401 data () [triangular_type::element (layout_type (), i, size_, j, size_)] = value_type();
00402 }
00403
00404
00405 BOOST_UBLAS_INLINE
00406 void clear () {
00407 std::fill (data ().begin (), data ().end (), value_type());
00408 }
00409
00410
00411 BOOST_UBLAS_INLINE
00412 hermitian_matrix &operator = (const hermitian_matrix &m) {
00413 size_ = m.size_;
00414 data () = m.data ();
00415 return *this;
00416 }
00417 BOOST_UBLAS_INLINE
00418 hermitian_matrix &assign_temporary (hermitian_matrix &m) {
00419 swap (m);
00420 return *this;
00421 }
00422 template<class AE>
00423 BOOST_UBLAS_INLINE
00424 hermitian_matrix &operator = (const matrix_expression<AE> &ae) {
00425 self_type temporary (ae);
00426 return assign_temporary (temporary);
00427 }
00428 template<class AE>
00429 BOOST_UBLAS_INLINE
00430 hermitian_matrix &assign (const matrix_expression<AE> &ae) {
00431 matrix_assign<scalar_assign> (*this, ae);
00432 return *this;
00433 }
00434 template<class AE>
00435 BOOST_UBLAS_INLINE
00436 hermitian_matrix& operator += (const matrix_expression<AE> &ae) {
00437 self_type temporary (*this + ae);
00438 return assign_temporary (temporary);
00439 }
00440 template<class AE>
00441 BOOST_UBLAS_INLINE
00442 hermitian_matrix &plus_assign (const matrix_expression<AE> &ae) {
00443 matrix_assign<scalar_plus_assign> (*this, ae);
00444 return *this;
00445 }
00446 template<class AE>
00447 BOOST_UBLAS_INLINE
00448 hermitian_matrix& operator -= (const matrix_expression<AE> &ae) {
00449 self_type temporary (*this - ae);
00450 return assign_temporary (temporary);
00451 }
00452 template<class AE>
00453 BOOST_UBLAS_INLINE
00454 hermitian_matrix &minus_assign (const matrix_expression<AE> &ae) {
00455 matrix_assign<scalar_minus_assign> (*this, ae);
00456 return *this;
00457 }
00458 template<class AT>
00459 BOOST_UBLAS_INLINE
00460 hermitian_matrix& operator *= (const AT &at) {
00461
00462
00463
00464 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
00465 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
00466 return *this;
00467 }
00468 template<class AT>
00469 BOOST_UBLAS_INLINE
00470 hermitian_matrix& operator /= (const AT &at) {
00471
00472
00473
00474 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
00475 matrix_assign_scalar<scalar_divides_assign> (*this, at);
00476 return *this;
00477 }
00478
00479
00480 BOOST_UBLAS_INLINE
00481 void swap (hermitian_matrix &m) {
00482 if (this != &m) {
00483 std::swap (size_, m.size_);
00484 data ().swap (m.data ());
00485 }
00486 }
00487 BOOST_UBLAS_INLINE
00488 friend void swap (hermitian_matrix &m1, hermitian_matrix &m2) {
00489 m1.swap (m2);
00490 }
00491
00492
00493 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00494 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
00495 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
00496 typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
00497 typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
00498 #else
00499 class const_iterator1;
00500 class iterator1;
00501 class const_iterator2;
00502 class iterator2;
00503 #endif
00504 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
00505 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
00506 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
00507 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
00508
00509
00510 BOOST_UBLAS_INLINE
00511 const_iterator1 find1 (int , size_type i, size_type j) const {
00512 return const_iterator1 (*this, i, j);
00513 }
00514 BOOST_UBLAS_INLINE
00515 iterator1 find1 (int rank, size_type i, size_type j) {
00516 if (rank == 1)
00517 i = triangular_type::mutable_restrict1 (i, j, size1(), size2());
00518 if (rank == 0)
00519 i = triangular_type::global_mutable_restrict1 (i, size1(), j, size2());
00520 return iterator1 (*this, i, j);
00521 }
00522 BOOST_UBLAS_INLINE
00523 const_iterator2 find2 (int , size_type i, size_type j) const {
00524 return const_iterator2 (*this, i, j);
00525 }
00526 BOOST_UBLAS_INLINE
00527 iterator2 find2 (int rank, size_type i, size_type j) {
00528 if (rank == 1)
00529 j = triangular_type::mutable_restrict2 (i, j, size1(), size2());
00530 if (rank == 0)
00531 j = triangular_type::global_mutable_restrict2 (i, size1(), j, size2());
00532 return iterator2 (*this, i, j);
00533 }
00534
00535
00536
00537 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00538 class const_iterator1:
00539 public container_const_reference<hermitian_matrix>,
00540 public random_access_iterator_base<packed_random_access_iterator_tag,
00541 const_iterator1, value_type> {
00542 public:
00543 typedef typename hermitian_matrix::value_type value_type;
00544 typedef typename hermitian_matrix::difference_type difference_type;
00545 typedef typename hermitian_matrix::const_reference reference;
00546 typedef const typename hermitian_matrix::pointer pointer;
00547
00548 typedef const_iterator2 dual_iterator_type;
00549 typedef const_reverse_iterator2 dual_reverse_iterator_type;
00550
00551
00552 BOOST_UBLAS_INLINE
00553 const_iterator1 ():
00554 container_const_reference<self_type> (), it1_ (), it2_ () {}
00555 BOOST_UBLAS_INLINE
00556 const_iterator1 (const self_type &m, size_type it1, size_type it2):
00557 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
00558 BOOST_UBLAS_INLINE
00559 const_iterator1 (const iterator1 &it):
00560 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
00561
00562
00563 BOOST_UBLAS_INLINE
00564 const_iterator1 &operator ++ () {
00565 ++ it1_;
00566 return *this;
00567 }
00568 BOOST_UBLAS_INLINE
00569 const_iterator1 &operator -- () {
00570 -- it1_;
00571 return *this;
00572 }
00573 BOOST_UBLAS_INLINE
00574 const_iterator1 &operator += (difference_type n) {
00575 it1_ += n;
00576 return *this;
00577 }
00578 BOOST_UBLAS_INLINE
00579 const_iterator1 &operator -= (difference_type n) {
00580 it1_ -= n;
00581 return *this;
00582 }
00583 BOOST_UBLAS_INLINE
00584 difference_type operator - (const const_iterator1 &it) const {
00585 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00586 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00587 return it1_ - it.it1_;
00588 }
00589
00590
00591 BOOST_UBLAS_INLINE
00592 const_reference operator * () const {
00593 return (*this) () (it1_, it2_);
00594 }
00595 BOOST_UBLAS_INLINE
00596 const_reference operator [] (difference_type n) const {
00597 return *(*this + n);
00598 }
00599
00600 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00601 BOOST_UBLAS_INLINE
00602 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00603 typename self_type::
00604 #endif
00605 const_iterator2 begin () const {
00606 return (*this) ().find2 (1, it1_, 0);
00607 }
00608 BOOST_UBLAS_INLINE
00609 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00610 typename self_type::
00611 #endif
00612 const_iterator2 end () const {
00613 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
00614 }
00615 BOOST_UBLAS_INLINE
00616 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00617 typename self_type::
00618 #endif
00619 const_reverse_iterator2 rbegin () const {
00620 return const_reverse_iterator2 (end ());
00621 }
00622 BOOST_UBLAS_INLINE
00623 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00624 typename self_type::
00625 #endif
00626 const_reverse_iterator2 rend () const {
00627 return const_reverse_iterator2 (begin ());
00628 }
00629 #endif
00630
00631
00632 BOOST_UBLAS_INLINE
00633 size_type index1 () const {
00634 return it1_;
00635 }
00636 BOOST_UBLAS_INLINE
00637 size_type index2 () const {
00638 return it2_;
00639 }
00640
00641
00642 BOOST_UBLAS_INLINE
00643 const_iterator1 &operator = (const const_iterator1 &it) {
00644 container_const_reference<self_type>::assign (&it ());
00645 it1_ = it.it1_;
00646 it2_ = it.it2_;
00647 return *this;
00648 }
00649
00650
00651 BOOST_UBLAS_INLINE
00652 bool operator == (const const_iterator1 &it) const {
00653 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00654 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00655 return it1_ == it.it1_;
00656 }
00657 BOOST_UBLAS_INLINE
00658 bool operator < (const const_iterator1 &it) const {
00659 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00660 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00661 return it1_ < it.it1_;
00662 }
00663
00664 private:
00665 size_type it1_;
00666 size_type it2_;
00667 };
00668 #endif
00669
00670 BOOST_UBLAS_INLINE
00671 const_iterator1 begin1 () const {
00672 return find1 (0, 0, 0);
00673 }
00674 BOOST_UBLAS_INLINE
00675 const_iterator1 end1 () const {
00676 return find1 (0, size_, 0);
00677 }
00678
00679 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00680 class iterator1:
00681 public container_reference<hermitian_matrix>,
00682 public random_access_iterator_base<packed_random_access_iterator_tag,
00683 iterator1, value_type> {
00684 public:
00685 typedef typename hermitian_matrix::value_type value_type;
00686 typedef typename hermitian_matrix::difference_type difference_type;
00687 typedef typename hermitian_matrix::true_reference reference;
00688 typedef typename hermitian_matrix::pointer pointer;
00689
00690 typedef iterator2 dual_iterator_type;
00691 typedef reverse_iterator2 dual_reverse_iterator_type;
00692
00693
00694 BOOST_UBLAS_INLINE
00695 iterator1 ():
00696 container_reference<self_type> (), it1_ (), it2_ () {}
00697 BOOST_UBLAS_INLINE
00698 iterator1 (self_type &m, size_type it1, size_type it2):
00699 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
00700
00701
00702 BOOST_UBLAS_INLINE
00703 iterator1 &operator ++ () {
00704 ++ it1_;
00705 return *this;
00706 }
00707 BOOST_UBLAS_INLINE
00708 iterator1 &operator -- () {
00709 -- it1_;
00710 return *this;
00711 }
00712 BOOST_UBLAS_INLINE
00713 iterator1 &operator += (difference_type n) {
00714 it1_ += n;
00715 return *this;
00716 }
00717 BOOST_UBLAS_INLINE
00718 iterator1 &operator -= (difference_type n) {
00719 it1_ -= n;
00720 return *this;
00721 }
00722 BOOST_UBLAS_INLINE
00723 difference_type operator - (const iterator1 &it) const {
00724 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00725 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00726 return it1_ - it.it1_;
00727 }
00728
00729
00730 BOOST_UBLAS_INLINE
00731 reference operator * () const {
00732 return (*this) ().at_element (it1_, it2_);
00733 }
00734 BOOST_UBLAS_INLINE
00735 reference operator [] (difference_type n) const {
00736 return *(*this + n);
00737 }
00738
00739 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00740 BOOST_UBLAS_INLINE
00741 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00742 typename self_type::
00743 #endif
00744 iterator2 begin () const {
00745 return (*this) ().find2 (1, it1_, 0);
00746 }
00747 BOOST_UBLAS_INLINE
00748 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00749 typename self_type::
00750 #endif
00751 iterator2 end () const {
00752 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
00753 }
00754 BOOST_UBLAS_INLINE
00755 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00756 typename self_type::
00757 #endif
00758 reverse_iterator2 rbegin () const {
00759 return reverse_iterator2 (end ());
00760 }
00761 BOOST_UBLAS_INLINE
00762 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00763 typename self_type::
00764 #endif
00765 reverse_iterator2 rend () const {
00766 return reverse_iterator2 (begin ());
00767 }
00768 #endif
00769
00770
00771 BOOST_UBLAS_INLINE
00772 size_type index1 () const {
00773 return it1_;
00774 }
00775 BOOST_UBLAS_INLINE
00776 size_type index2 () const {
00777 return it2_;
00778 }
00779
00780
00781 BOOST_UBLAS_INLINE
00782 iterator1 &operator = (const iterator1 &it) {
00783 container_reference<self_type>::assign (&it ());
00784 it1_ = it.it1_;
00785 it2_ = it.it2_;
00786 return *this;
00787 }
00788
00789
00790 BOOST_UBLAS_INLINE
00791 bool operator == (const iterator1 &it) const {
00792 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00793 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00794 return it1_ == it.it1_;
00795 }
00796 BOOST_UBLAS_INLINE
00797 bool operator < (const iterator1 &it) const {
00798 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00799 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00800 return it1_ < it.it1_;
00801 }
00802
00803 private:
00804 size_type it1_;
00805 size_type it2_;
00806
00807 friend class const_iterator1;
00808 };
00809 #endif
00810
00811 BOOST_UBLAS_INLINE
00812 iterator1 begin1 () {
00813 return find1 (0, 0, 0);
00814 }
00815 BOOST_UBLAS_INLINE
00816 iterator1 end1 () {
00817 return find1 (0, size_, 0);
00818 }
00819
00820 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00821 class const_iterator2:
00822 public container_const_reference<hermitian_matrix>,
00823 public random_access_iterator_base<packed_random_access_iterator_tag,
00824 const_iterator2, value_type> {
00825 public:
00826 typedef typename hermitian_matrix::value_type value_type;
00827 typedef typename hermitian_matrix::difference_type difference_type;
00828 typedef typename hermitian_matrix::const_reference reference;
00829 typedef const typename hermitian_matrix::pointer pointer;
00830
00831 typedef const_iterator1 dual_iterator_type;
00832 typedef const_reverse_iterator1 dual_reverse_iterator_type;
00833
00834
00835 BOOST_UBLAS_INLINE
00836 const_iterator2 ():
00837 container_const_reference<self_type> (), it1_ (), it2_ () {}
00838 BOOST_UBLAS_INLINE
00839 const_iterator2 (const self_type &m, size_type it1, size_type it2):
00840 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
00841 BOOST_UBLAS_INLINE
00842 const_iterator2 (const iterator2 &it):
00843 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
00844
00845
00846 BOOST_UBLAS_INLINE
00847 const_iterator2 &operator ++ () {
00848 ++ it2_;
00849 return *this;
00850 }
00851 BOOST_UBLAS_INLINE
00852 const_iterator2 &operator -- () {
00853 -- it2_;
00854 return *this;
00855 }
00856 BOOST_UBLAS_INLINE
00857 const_iterator2 &operator += (difference_type n) {
00858 it2_ += n;
00859 return *this;
00860 }
00861 BOOST_UBLAS_INLINE
00862 const_iterator2 &operator -= (difference_type n) {
00863 it2_ -= n;
00864 return *this;
00865 }
00866 BOOST_UBLAS_INLINE
00867 difference_type operator - (const const_iterator2 &it) const {
00868 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00869 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
00870 return it2_ - it.it2_;
00871 }
00872
00873
00874 BOOST_UBLAS_INLINE
00875 const_reference operator * () const {
00876 return (*this) () (it1_, it2_);
00877 }
00878 BOOST_UBLAS_INLINE
00879 const_reference operator [] (difference_type n) const {
00880 return *(*this + n);
00881 }
00882
00883 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00884 BOOST_UBLAS_INLINE
00885 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00886 typename self_type::
00887 #endif
00888 const_iterator1 begin () const {
00889 return (*this) ().find1 (1, 0, it2_);
00890 }
00891 BOOST_UBLAS_INLINE
00892 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00893 typename self_type::
00894 #endif
00895 const_iterator1 end () const {
00896 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
00897 }
00898 BOOST_UBLAS_INLINE
00899 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00900 typename self_type::
00901 #endif
00902 const_reverse_iterator1 rbegin () const {
00903 return const_reverse_iterator1 (end ());
00904 }
00905 BOOST_UBLAS_INLINE
00906 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00907 typename self_type::
00908 #endif
00909 const_reverse_iterator1 rend () const {
00910 return const_reverse_iterator1 (begin ());
00911 }
00912 #endif
00913
00914
00915 BOOST_UBLAS_INLINE
00916 size_type index1 () const {
00917 return it1_;
00918 }
00919 BOOST_UBLAS_INLINE
00920 size_type index2 () const {
00921 return it2_;
00922 }
00923
00924
00925 BOOST_UBLAS_INLINE
00926 const_iterator2 &operator = (const const_iterator2 &it) {
00927 container_const_reference<self_type>::assign (&it ());
00928 it1_ = it.it1_;
00929 it2_ = it.it2_;
00930 return *this;
00931 }
00932
00933
00934 BOOST_UBLAS_INLINE
00935 bool operator == (const const_iterator2 &it) const {
00936 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00937 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
00938 return it2_ == it.it2_;
00939 }
00940 BOOST_UBLAS_INLINE
00941 bool operator < (const const_iterator2 &it) const {
00942 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00943 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
00944 return it2_ < it.it2_;
00945 }
00946
00947 private:
00948 size_type it1_;
00949 size_type it2_;
00950 };
00951 #endif
00952
00953 BOOST_UBLAS_INLINE
00954 const_iterator2 begin2 () const {
00955 return find2 (0, 0, 0);
00956 }
00957 BOOST_UBLAS_INLINE
00958 const_iterator2 end2 () const {
00959 return find2 (0, 0, size_);
00960 }
00961
00962 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00963 class iterator2:
00964 public container_reference<hermitian_matrix>,
00965 public random_access_iterator_base<packed_random_access_iterator_tag,
00966 iterator2, value_type> {
00967 public:
00968 typedef typename hermitian_matrix::value_type value_type;
00969 typedef typename hermitian_matrix::difference_type difference_type;
00970 typedef typename hermitian_matrix::true_reference reference;
00971 typedef typename hermitian_matrix::pointer pointer;
00972
00973 typedef iterator1 dual_iterator_type;
00974 typedef reverse_iterator1 dual_reverse_iterator_type;
00975
00976
00977 BOOST_UBLAS_INLINE
00978 iterator2 ():
00979 container_reference<self_type> (), it1_ (), it2_ () {}
00980 BOOST_UBLAS_INLINE
00981 iterator2 (self_type &m, size_type it1, size_type it2):
00982 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
00983
00984
00985 BOOST_UBLAS_INLINE
00986 iterator2 &operator ++ () {
00987 ++ it2_;
00988 return *this;
00989 }
00990 BOOST_UBLAS_INLINE
00991 iterator2 &operator -- () {
00992 -- it2_;
00993 return *this;
00994 }
00995 BOOST_UBLAS_INLINE
00996 iterator2 &operator += (difference_type n) {
00997 it2_ += n;
00998 return *this;
00999 }
01000 BOOST_UBLAS_INLINE
01001 iterator2 &operator -= (difference_type n) {
01002 it2_ -= n;
01003 return *this;
01004 }
01005 BOOST_UBLAS_INLINE
01006 difference_type operator - (const iterator2 &it) const {
01007 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01008 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
01009 return it2_ - it.it2_;
01010 }
01011
01012
01013 BOOST_UBLAS_INLINE
01014 reference operator * () const {
01015 return (*this) ().at_element (it1_, it2_);
01016 }
01017 BOOST_UBLAS_INLINE
01018 reference operator [] (difference_type n) const {
01019 return *(*this + n);
01020 }
01021
01022 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01023 BOOST_UBLAS_INLINE
01024 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01025 typename self_type::
01026 #endif
01027 iterator1 begin () const {
01028 return (*this) ().find1 (1, 0, it2_);
01029 }
01030 BOOST_UBLAS_INLINE
01031 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01032 typename self_type::
01033 #endif
01034 iterator1 end () const {
01035 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
01036 }
01037 BOOST_UBLAS_INLINE
01038 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01039 typename self_type::
01040 #endif
01041 reverse_iterator1 rbegin () const {
01042 return reverse_iterator1 (end ());
01043 }
01044 BOOST_UBLAS_INLINE
01045 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01046 typename self_type::
01047 #endif
01048 reverse_iterator1 rend () const {
01049 return reverse_iterator1 (begin ());
01050 }
01051 #endif
01052
01053
01054 BOOST_UBLAS_INLINE
01055 size_type index1 () const {
01056 return it1_;
01057 }
01058 BOOST_UBLAS_INLINE
01059 size_type index2 () const {
01060 return it2_;
01061 }
01062
01063
01064 BOOST_UBLAS_INLINE
01065 iterator2 &operator = (const iterator2 &it) {
01066 container_reference<self_type>::assign (&it ());
01067 it1_ = it.it1_;
01068 it2_ = it.it2_;
01069 return *this;
01070 }
01071
01072
01073 BOOST_UBLAS_INLINE
01074 bool operator == (const iterator2 &it) const {
01075 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01076 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
01077 return it2_ == it.it2_;
01078 }
01079 BOOST_UBLAS_INLINE
01080 bool operator < (const iterator2 &it) const {
01081 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01082 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
01083 return it2_ < it.it2_;
01084 }
01085
01086 private:
01087 size_type it1_;
01088 size_type it2_;
01089
01090 friend class const_iterator2;
01091 };
01092 #endif
01093
01094 BOOST_UBLAS_INLINE
01095 iterator2 begin2 () {
01096 return find2 (0, 0, 0);
01097 }
01098 BOOST_UBLAS_INLINE
01099 iterator2 end2 () {
01100 return find2 (0, 0, size_);
01101 }
01102
01103
01104
01105 BOOST_UBLAS_INLINE
01106 const_reverse_iterator1 rbegin1 () const {
01107 return const_reverse_iterator1 (end1 ());
01108 }
01109 BOOST_UBLAS_INLINE
01110 const_reverse_iterator1 rend1 () const {
01111 return const_reverse_iterator1 (begin1 ());
01112 }
01113
01114 BOOST_UBLAS_INLINE
01115 reverse_iterator1 rbegin1 () {
01116 return reverse_iterator1 (end1 ());
01117 }
01118 BOOST_UBLAS_INLINE
01119 reverse_iterator1 rend1 () {
01120 return reverse_iterator1 (begin1 ());
01121 }
01122
01123 BOOST_UBLAS_INLINE
01124 const_reverse_iterator2 rbegin2 () const {
01125 return const_reverse_iterator2 (end2 ());
01126 }
01127 BOOST_UBLAS_INLINE
01128 const_reverse_iterator2 rend2 () const {
01129 return const_reverse_iterator2 (begin2 ());
01130 }
01131
01132 BOOST_UBLAS_INLINE
01133 reverse_iterator2 rbegin2 () {
01134 return reverse_iterator2 (end2 ());
01135 }
01136 BOOST_UBLAS_INLINE
01137 reverse_iterator2 rend2 () {
01138 return reverse_iterator2 (begin2 ());
01139 }
01140
01141 private:
01142 size_type size_;
01143 array_type data_;
01144 };
01145
01155 template<class M, class TRI>
01156 class hermitian_adaptor:
01157 public matrix_expression<hermitian_adaptor<M, TRI> > {
01158
01159 typedef hermitian_adaptor<M, TRI> self_type;
01160 typedef typename M::value_type &true_reference;
01161 public:
01162 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
01163 using matrix_expression<self_type>::operator ();
01164 #endif
01165 typedef const M const_matrix_type;
01166 typedef M matrix_type;
01167 typedef TRI triangular_type;
01168 typedef typename M::size_type size_type;
01169 typedef typename M::difference_type difference_type;
01170 typedef typename M::value_type value_type;
01171 typedef typename M::value_type const_reference;
01172 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
01173 typedef typename boost::mpl::if_<boost::is_const<M>,
01174 typename M::value_type,
01175 typename M::reference>::type reference;
01176 #else
01177 typedef typename boost::mpl::if_<boost::is_const<M>,
01178 typename M::value_type,
01179 hermitian_matrix_element<self_type> >::type reference;
01180 #endif
01181 typedef typename boost::mpl::if_<boost::is_const<M>,
01182 typename M::const_closure_type,
01183 typename M::closure_type>::type matrix_closure_type;
01184 typedef const self_type const_closure_type;
01185 typedef self_type closure_type;
01186
01187
01188
01189 typedef typename storage_restrict_traits<typename M::storage_category,
01190 packed_proxy_tag>::storage_category storage_category;
01191 typedef typename M::orientation_category orientation_category;
01192
01193
01194 BOOST_UBLAS_INLINE
01195 hermitian_adaptor (matrix_type &data):
01196 matrix_expression<self_type> (),
01197 data_ (data) {
01198 BOOST_UBLAS_CHECK (data_.size1 () == data_.size2 (), bad_size ());
01199 }
01200 BOOST_UBLAS_INLINE
01201 hermitian_adaptor (const hermitian_adaptor &m):
01202 matrix_expression<self_type> (),
01203 data_ (m.data_) {
01204 BOOST_UBLAS_CHECK (data_.size1 () == data_.size2 (), bad_size ());
01205 }
01206
01207
01208 BOOST_UBLAS_INLINE
01209 size_type size1 () const {
01210 return data_.size1 ();
01211 }
01212 BOOST_UBLAS_INLINE
01213 size_type size2 () const {
01214 return data_.size2 ();
01215 }
01216
01217
01218 BOOST_UBLAS_INLINE
01219 const matrix_closure_type &data () const {
01220 return data_;
01221 }
01222 BOOST_UBLAS_INLINE
01223 matrix_closure_type &data () {
01224 return data_;
01225 }
01226
01227
01228 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
01229 BOOST_UBLAS_INLINE
01230 const_reference operator () (size_type i, size_type j) const {
01231 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
01232 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
01233
01234
01235
01236 if (triangular_type::other (i, j))
01237 return data () (i, j);
01238 else
01239 return type_traits<value_type>::conj (data () (j, i));
01240 }
01241 BOOST_UBLAS_INLINE
01242 reference operator () (size_type i, size_type j) {
01243 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
01244 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
01245 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
01246 if (triangular_type::other (i, j))
01247 return data () (i, j);
01248 else {
01249 external_logic ().raise ();
01250 return conj_ = type_traits<value_type>::conj (data () (j, i));
01251 }
01252 #else
01253 if (triangular_type::other (i, j))
01254 return reference (*this, i, j, data () (i, j));
01255 else
01256 return reference (*this, i, j, type_traits<value_type>::conj (data () (j, i)));
01257 #endif
01258 }
01259 BOOST_UBLAS_INLINE
01260 true_reference insert_element (size_type i, size_type j, value_type t) {
01261 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
01262 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
01263
01264
01265
01266 if (triangular_type::other (i, j))
01267 return data () (i, j) = t;
01268 else
01269 return data () (j, i) = type_traits<value_type>::conj (t);
01270 }
01271 #else
01272 BOOST_UBLAS_INLINE
01273 reference operator () (size_type i, size_type j) {
01274 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
01275 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
01276 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
01277 if (triangular_type::other (i, j))
01278 return data () (i, j);
01279 else {
01280 external_logic ().raise ();
01281 return conj_ = type_traits<value_type>::conj (data () (j, i));
01282 }
01283 #else
01284 if (triangular_type::other (i, j))
01285 return reference (*this, i, j, data () (i, j));
01286 else
01287 return reference (*this, i, j, type_traits<value_type>::conj (data () (j, i)));
01288 #endif
01289 }
01290 BOOST_UBLAS_INLINE
01291 true_reference insert_element (size_type i, size_type j, value_type t) {
01292 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
01293 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
01294
01295
01296
01297 if (triangular_type::other (i, j))
01298 return data () (i, j) = t;
01299 else
01300 return data () (j, i) = type_traits<value_type>::conj (t);
01301 }
01302 #endif
01303
01304
01305 BOOST_UBLAS_INLINE
01306 hermitian_adaptor &operator = (const hermitian_adaptor &m) {
01307 matrix_assign<scalar_assign, triangular_type> (*this, m);
01308 return *this;
01309 }
01310 BOOST_UBLAS_INLINE
01311 hermitian_adaptor &assign_temporary (hermitian_adaptor &m) {
01312 *this = m;
01313 return *this;
01314 }
01315 template<class AE>
01316 BOOST_UBLAS_INLINE
01317 hermitian_adaptor &operator = (const matrix_expression<AE> &ae) {
01318 matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (ae));
01319 return *this;
01320 }
01321 template<class AE>
01322 BOOST_UBLAS_INLINE
01323 hermitian_adaptor &assign (const matrix_expression<AE> &ae) {
01324 matrix_assign<scalar_assign, triangular_type> (*this, ae);
01325 return *this;
01326 }
01327 template<class AE>
01328 BOOST_UBLAS_INLINE
01329 hermitian_adaptor& operator += (const matrix_expression<AE> &ae) {
01330 matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (*this + ae));
01331 return *this;
01332 }
01333 template<class AE>
01334 BOOST_UBLAS_INLINE
01335 hermitian_adaptor &plus_assign (const matrix_expression<AE> &ae) {
01336 matrix_assign<scalar_plus_assign, triangular_type> (*this, ae);
01337 return *this;
01338 }
01339 template<class AE>
01340 BOOST_UBLAS_INLINE
01341 hermitian_adaptor& operator -= (const matrix_expression<AE> &ae) {
01342 matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (*this - ae));
01343 return *this;
01344 }
01345 template<class AE>
01346 BOOST_UBLAS_INLINE
01347 hermitian_adaptor &minus_assign (const matrix_expression<AE> &ae) {
01348 matrix_assign<scalar_minus_assign, triangular_type> (*this, ae);
01349 return *this;
01350 }
01351 template<class AT>
01352 BOOST_UBLAS_INLINE
01353 hermitian_adaptor& operator *= (const AT &at) {
01354
01355
01356
01357 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
01358 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
01359 return *this;
01360 }
01361 template<class AT>
01362 BOOST_UBLAS_INLINE
01363 hermitian_adaptor& operator /= (const AT &at) {
01364
01365
01366
01367 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
01368 matrix_assign_scalar<scalar_divides_assign> (*this, at);
01369 return *this;
01370 }
01371
01372
01373 BOOST_UBLAS_INLINE
01374 bool same_closure (const hermitian_adaptor &ha) const {
01375 return (*this).data ().same_closure (ha.data ());
01376 }
01377
01378
01379 BOOST_UBLAS_INLINE
01380 void swap (hermitian_adaptor &m) {
01381 if (this != &m)
01382 matrix_swap<scalar_swap, triangular_type> (*this, m);
01383 }
01384 BOOST_UBLAS_INLINE
01385 friend void swap (hermitian_adaptor &m1, hermitian_adaptor &m2) {
01386 m1.swap (m2);
01387 }
01388
01389
01390 private:
01391
01392 typedef typename M::const_iterator1 const_subiterator1_type;
01393 typedef typename boost::mpl::if_<boost::is_const<M>,
01394 typename M::const_iterator1,
01395 typename M::iterator1>::type subiterator1_type;
01396 typedef typename M::const_iterator2 const_subiterator2_type;
01397 typedef typename boost::mpl::if_<boost::is_const<M>,
01398 typename M::const_iterator2,
01399 typename M::iterator2>::type subiterator2_type;
01400
01401 public:
01402 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01403 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
01404 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
01405 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
01406 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
01407 #else
01408 class const_iterator1;
01409 class iterator1;
01410 class const_iterator2;
01411 class iterator2;
01412 #endif
01413 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
01414 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
01415 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
01416 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
01417
01418
01419 BOOST_UBLAS_INLINE
01420 const_iterator1 find1 (int rank, size_type i, size_type j) const {
01421 if (triangular_type::other (i, j)) {
01422 if (triangular_type::other (size1 (), j)) {
01423 return const_iterator1 (*this, 0, 0,
01424 data ().find1 (rank, i, j), data ().find1 (rank, size1 (), j),
01425 data ().find2 (rank, size2 (), size1 ()), data ().find2 (rank, size2 (), size1 ()));
01426 } else {
01427 return const_iterator1 (*this, 0, 1,
01428 data ().find1 (rank, i, j), data ().find1 (rank, j, j),
01429 data ().find2 (rank, j, j), data ().find2 (rank, j, size1 ()));
01430 }
01431 } else {
01432 if (triangular_type::other (size1 (), j)) {
01433 return const_iterator1 (*this, 1, 0,
01434 data ().find1 (rank, j, j), data ().find1 (rank, size1 (), j),
01435 data ().find2 (rank, j, i), data ().find2 (rank, j, j));
01436 } else {
01437 return const_iterator1 (*this, 1, 1,
01438 data ().find1 (rank, size1 (), size2 ()), data ().find1 (rank, size1 (), size2 ()),
01439 data ().find2 (rank, j, i), data ().find2 (rank, j, size1 ()));
01440 }
01441 }
01442 }
01443 BOOST_UBLAS_INLINE
01444 iterator1 find1 (int rank, size_type i, size_type j) {
01445 if (rank == 1)
01446 i = triangular_type::mutable_restrict1 (i, j, size1(), size2());
01447 if (rank == 0)
01448 i = triangular_type::global_mutable_restrict1 (i, size1(), j, size2());
01449 return iterator1 (*this, data ().find1 (rank, i, j));
01450 }
01451 BOOST_UBLAS_INLINE
01452 const_iterator2 find2 (int rank, size_type i, size_type j) const {
01453 if (triangular_type::other (i, j)) {
01454 if (triangular_type::other (i, size2 ())) {
01455 return const_iterator2 (*this, 1, 1,
01456 data ().find1 (rank, size2 (), size1 ()), data ().find1 (rank, size2 (), size1 ()),
01457 data ().find2 (rank, i, j), data ().find2 (rank, i, size2 ()));
01458 } else {
01459 return const_iterator2 (*this, 1, 0,
01460 data ().find1 (rank, i, i), data ().find1 (rank, size2 (), i),
01461 data ().find2 (rank, i, j), data ().find2 (rank, i, i));
01462 }
01463 } else {
01464 if (triangular_type::other (i, size2 ())) {
01465 return const_iterator2 (*this, 0, 1,
01466 data ().find1 (rank, j, i), data ().find1 (rank, i, i),
01467 data ().find2 (rank, i, i), data ().find2 (rank, i, size2 ()));
01468 } else {
01469 return const_iterator2 (*this, 0, 0,
01470 data ().find1 (rank, j, i), data ().find1 (rank, size2 (), i),
01471 data ().find2 (rank, size1 (), size2 ()), data ().find2 (rank, size2 (), size2 ()));
01472 }
01473 }
01474 }
01475 BOOST_UBLAS_INLINE
01476 iterator2 find2 (int rank, size_type i, size_type j) {
01477 if (rank == 1)
01478 j = triangular_type::mutable_restrict2 (i, j, size1(), size2());
01479 if (rank == 0)
01480 j = triangular_type::global_mutable_restrict2 (i, size1(), j, size2());
01481 return iterator2 (*this, data ().find2 (rank, i, j));
01482 }
01483
01484
01485
01486 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01487 class const_iterator1:
01488 public container_const_reference<hermitian_adaptor>,
01489 public random_access_iterator_base<typename iterator_restrict_traits<
01490 typename const_subiterator1_type::iterator_category, dense_random_access_iterator_tag>::iterator_category,
01491 const_iterator1, value_type> {
01492 public:
01493 typedef typename const_subiterator1_type::value_type value_type;
01494 typedef typename const_subiterator1_type::difference_type difference_type;
01495
01496
01497 typedef typename const_subiterator1_type::value_type reference;
01498 typedef typename const_subiterator1_type::pointer pointer;
01499
01500 typedef const_iterator2 dual_iterator_type;
01501 typedef const_reverse_iterator2 dual_reverse_iterator_type;
01502
01503
01504 BOOST_UBLAS_INLINE
01505 const_iterator1 ():
01506 container_const_reference<self_type> (),
01507 begin_ (-1), end_ (-1), current_ (-1),
01508 it1_begin_ (), it1_end_ (), it1_ (),
01509 it2_begin_ (), it2_end_ (), it2_ () {}
01510 BOOST_UBLAS_INLINE
01511 const_iterator1 (const self_type &m, int begin, int end,
01512 const const_subiterator1_type &it1_begin, const const_subiterator1_type &it1_end,
01513 const const_subiterator2_type &it2_begin, const const_subiterator2_type &it2_end):
01514 container_const_reference<self_type> (m),
01515 begin_ (begin), end_ (end), current_ (begin),
01516 it1_begin_ (it1_begin), it1_end_ (it1_end), it1_ (it1_begin_),
01517 it2_begin_ (it2_begin), it2_end_ (it2_end), it2_ (it2_begin_) {
01518 if (current_ == 0 && it1_ == it1_end_)
01519 current_ = 1;
01520 if (current_ == 1 && it2_ == it2_end_)
01521 current_ = 0;
01522 if ((current_ == 0 && it1_ == it1_end_) ||
01523 (current_ == 1 && it2_ == it2_end_))
01524 current_ = end_;
01525 BOOST_UBLAS_CHECK (current_ == end_ ||
01526 (current_ == 0 && it1_ != it1_end_) ||
01527 (current_ == 1 && it2_ != it2_end_), internal_logic ());
01528 }
01529
01530
01531 BOOST_UBLAS_INLINE
01532 const_iterator1 (const iterator1 &it):
01533 container_const_reference<self_type> (it ()),
01534 begin_ (it.begin_), end_ (it.end_), current_ (it.current_),
01535 it1_begin_ (it.it1_begin_), it1_end_ (it.it1_end_), it1_ (it.it1_),
01536 it2_begin_ (it.it2_begin_), it2_end_ (it.it2_end_), it2_ (it.it2_) {
01537 BOOST_UBLAS_CHECK (current_ == end_ ||
01538 (current_ == 0 && it1_ != it1_end_) ||
01539 (current_ == 1 && it2_ != it2_end_), internal_logic ());
01540 }
01541
01542
01543 BOOST_UBLAS_INLINE
01544 const_iterator1 &operator ++ () {
01545 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
01546 if (current_ == 0) {
01547 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
01548 ++ it1_;
01549 if (it1_ == it1_end_ && end_ == 1) {
01550 it2_ = it2_begin_;
01551 current_ = 1;
01552 }
01553 } else {
01554 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
01555 ++ it2_;
01556 if (it2_ == it2_end_ && end_ == 0) {
01557 it1_ = it1_begin_;
01558 current_ = 0;
01559 }
01560 }
01561 return *this;
01562 }
01563 BOOST_UBLAS_INLINE
01564 const_iterator1 &operator -- () {
01565 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
01566 if (current_ == 0) {
01567 if (it1_ == it1_begin_ && begin_ == 1) {
01568 it2_ = it2_end_;
01569 BOOST_UBLAS_CHECK (it2_ != it2_begin_, internal_logic ());
01570 -- it2_;
01571 current_ = 1;
01572 } else {
01573 -- it1_;
01574 }
01575 } else {
01576 if (it2_ == it2_begin_ && begin_ == 0) {
01577 it1_ = it1_end_;
01578 BOOST_UBLAS_CHECK (it1_ != it1_begin_, internal_logic ());
01579 -- it1_;
01580 current_ = 0;
01581 } else {
01582 -- it2_;
01583 }
01584 }
01585 return *this;
01586 }
01587 BOOST_UBLAS_INLINE
01588 const_iterator1 &operator += (difference_type n) {
01589 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
01590 if (current_ == 0) {
01591 size_type d = (std::min) (n, it1_end_ - it1_);
01592 it1_ += d;
01593 n -= d;
01594 if (n > 0 || (end_ == 1 && it1_ == it1_end_)) {
01595 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
01596 d = (std::min) (n, it2_end_ - it2_begin_);
01597 it2_ = it2_begin_ + d;
01598 n -= d;
01599 current_ = 1;
01600 }
01601 } else {
01602 size_type d = (std::min) (n, it2_end_ - it2_);
01603 it2_ += d;
01604 n -= d;
01605 if (n > 0 || (end_ == 0 && it2_ == it2_end_)) {
01606 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
01607 d = (std::min) (n, it1_end_ - it1_begin_);
01608 it1_ = it1_begin_ + d;
01609 n -= d;
01610 current_ = 0;
01611 }
01612 }
01613 BOOST_UBLAS_CHECK (n == 0, external_logic ());
01614 return *this;
01615 }
01616 BOOST_UBLAS_INLINE
01617 const_iterator1 &operator -= (difference_type n) {
01618 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
01619 if (current_ == 0) {
01620 size_type d = (std::min) (n, it1_ - it1_begin_);
01621 it1_ -= d;
01622 n -= d;
01623 if (n > 0) {
01624 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
01625 d = (std::min) (n, it2_end_ - it2_begin_);
01626 it2_ = it2_end_ - d;
01627 n -= d;
01628 current_ = 1;
01629 }
01630 } else {
01631 size_type d = (std::min) (n, it2_ - it2_begin_);
01632 it2_ -= d;
01633 n -= d;
01634 if (n > 0) {
01635 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
01636 d = (std::min) (n, it1_end_ - it1_begin_);
01637 it1_ = it1_end_ - d;
01638 n -= d;
01639 current_ = 0;
01640 }
01641 }
01642 BOOST_UBLAS_CHECK (n == 0, external_logic ());
01643 return *this;
01644 }
01645 BOOST_UBLAS_INLINE
01646 difference_type operator - (const const_iterator1 &it) const {
01647 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01648 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
01649 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
01650 BOOST_UBLAS_CHECK ( end_ == it.end_, internal_logic ());
01651 if (current_ == 0 && it.current_ == 0) {
01652 return it1_ - it.it1_;
01653 } else if (current_ == 0 && it.current_ == 1) {
01654 if (end_ == 1 && it.end_ == 1) {
01655 return (it1_ - it.it1_end_) + (it.it2_begin_ - it.it2_);
01656 } else {
01657 return (it1_ - it.it1_begin_) + (it.it2_end_ - it.it2_);
01658 }
01659
01660 } else if (current_ == 1 && it.current_ == 0) {
01661 if (end_ == 1 && it.end_ == 1) {
01662 return (it2_ - it.it2_begin_) + (it.it1_end_ - it.it1_);
01663 } else {
01664 return (it2_ - it.it2_end_) + (it.it1_begin_ - it.it1_);
01665 }
01666 } else {
01667 return it2_ - it.it2_;
01668 }
01669 }
01670
01671
01672 BOOST_UBLAS_INLINE
01673 const_reference operator * () const {
01674 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
01675 if (current_ == 0) {
01676 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
01677 if (triangular_type::other (index1 (), index2 ()))
01678 return *it1_;
01679 else
01680 return type_traits<value_type>::conj (*it1_);
01681 } else {
01682 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
01683 if (triangular_type::other (index1 (), index2 ()))
01684 return *it2_;
01685 else
01686 return type_traits<value_type>::conj (*it2_);
01687 }
01688 }
01689 BOOST_UBLAS_INLINE
01690 const_reference operator [] (difference_type n) const {
01691 return *(*this + n);
01692 }
01693
01694 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01695 BOOST_UBLAS_INLINE
01696 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01697 typename self_type::
01698 #endif
01699 const_iterator2 begin () const {
01700 return (*this) ().find2 (1, index1 (), 0);
01701 }
01702 BOOST_UBLAS_INLINE
01703 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01704 typename self_type::
01705 #endif
01706 const_iterator2 end () const {
01707 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
01708 }
01709 BOOST_UBLAS_INLINE
01710 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01711 typename self_type::
01712 #endif
01713 const_reverse_iterator2 rbegin () const {
01714 return const_reverse_iterator2 (end ());
01715 }
01716 BOOST_UBLAS_INLINE
01717 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01718 typename self_type::
01719 #endif
01720 const_reverse_iterator2 rend () const {
01721 return const_reverse_iterator2 (begin ());
01722 }
01723 #endif
01724
01725
01726 BOOST_UBLAS_INLINE
01727 size_type index1 () const {
01728 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
01729 if (current_ == 0) {
01730 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
01731 return it1_.index1 ();
01732 } else {
01733 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
01734 return it2_.index2 ();
01735 }
01736 }
01737 BOOST_UBLAS_INLINE
01738 size_type index2 () const {
01739 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
01740 if (current_ == 0) {
01741 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
01742 return it1_.index2 ();
01743 } else {
01744 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
01745 return it2_.index1 ();
01746 }
01747 }
01748
01749
01750 BOOST_UBLAS_INLINE
01751 const_iterator1 &operator = (const const_iterator1 &it) {
01752 container_const_reference<self_type>::assign (&it ());
01753 begin_ = it.begin_;
01754 end_ = it.end_;
01755 current_ = it.current_;
01756 it1_begin_ = it.it1_begin_;
01757 it1_end_ = it.it1_end_;
01758 it1_ = it.it1_;
01759 it2_begin_ = it.it2_begin_;
01760 it2_end_ = it.it2_end_;
01761 it2_ = it.it2_;
01762 return *this;
01763 }
01764
01765
01766 BOOST_UBLAS_INLINE
01767 bool operator == (const const_iterator1 &it) const {
01768 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01769 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
01770 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
01771 BOOST_UBLAS_CHECK ( end_ == it.end_, internal_logic ());
01772 return (current_ == 0 && it.current_ == 0 && it1_ == it.it1_) ||
01773 (current_ == 1 && it.current_ == 1 && it2_ == it.it2_);
01774 }
01775 BOOST_UBLAS_INLINE
01776 bool operator < (const const_iterator1 &it) const {
01777 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01778 return it - *this > 0;
01779 }
01780
01781 private:
01782 int begin_;
01783 int end_;
01784 int current_;
01785 const_subiterator1_type it1_begin_;
01786 const_subiterator1_type it1_end_;
01787 const_subiterator1_type it1_;
01788 const_subiterator2_type it2_begin_;
01789 const_subiterator2_type it2_end_;
01790 const_subiterator2_type it2_;
01791 };
01792 #endif
01793
01794 BOOST_UBLAS_INLINE
01795 const_iterator1 begin1 () const {
01796 return find1 (0, 0, 0);
01797 }
01798 BOOST_UBLAS_INLINE
01799 const_iterator1 end1 () const {
01800 return find1 (0, size1 (), 0);
01801 }
01802
01803 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01804 class iterator1:
01805 public container_reference<hermitian_adaptor>,
01806 public random_access_iterator_base<typename iterator_restrict_traits<
01807 typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
01808 iterator1, value_type> {
01809 public:
01810 typedef typename subiterator1_type::value_type value_type;
01811 typedef typename subiterator1_type::difference_type difference_type;
01812 typedef typename subiterator1_type::reference reference;
01813 typedef typename subiterator1_type::pointer pointer;
01814
01815 typedef iterator2 dual_iterator_type;
01816 typedef reverse_iterator2 dual_reverse_iterator_type;
01817
01818
01819 BOOST_UBLAS_INLINE
01820 iterator1 ():
01821 container_reference<self_type> (), it1_ () {}
01822 BOOST_UBLAS_INLINE
01823 iterator1 (self_type &m, const subiterator1_type &it1):
01824 container_reference<self_type> (m), it1_ (it1) {}
01825
01826
01827 BOOST_UBLAS_INLINE
01828 iterator1 &operator ++ () {
01829 ++ it1_;
01830 return *this;
01831 }
01832 BOOST_UBLAS_INLINE
01833 iterator1 &operator -- () {
01834 -- it1_;
01835 return *this;
01836 }
01837 BOOST_UBLAS_INLINE
01838 iterator1 &operator += (difference_type n) {
01839 it1_ += n;
01840 return *this;
01841 }
01842 BOOST_UBLAS_INLINE
01843 iterator1 &operator -= (difference_type n) {
01844 it1_ -= n;
01845 return *this;
01846 }
01847 BOOST_UBLAS_INLINE
01848 difference_type operator - (const iterator1 &it) const {
01849 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01850 return it1_ - it.it1_;
01851 }
01852
01853
01854 BOOST_UBLAS_INLINE
01855 reference operator * () const {
01856 return *it1_;
01857 }
01858 BOOST_UBLAS_INLINE
01859 reference operator [] (difference_type n) const {
01860 return *(*this + n);
01861 }
01862
01863 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01864 BOOST_UBLAS_INLINE
01865 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01866 typename self_type::
01867 #endif
01868 iterator2 begin () const {
01869 return (*this) ().find2 (1, index1 (), 0);
01870 }
01871 BOOST_UBLAS_INLINE
01872 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01873 typename self_type::
01874 #endif
01875 iterator2 end () const {
01876 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
01877 }
01878 BOOST_UBLAS_INLINE
01879 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01880 typename self_type::
01881 #endif
01882 reverse_iterator2 rbegin () const {
01883 return reverse_iterator2 (end ());
01884 }
01885 BOOST_UBLAS_INLINE
01886 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01887 typename self_type::
01888 #endif
01889 reverse_iterator2 rend () const {
01890 return reverse_iterator2 (begin ());
01891 }
01892 #endif
01893
01894
01895 BOOST_UBLAS_INLINE
01896 size_type index1 () const {
01897 return it1_.index1 ();
01898 }
01899 BOOST_UBLAS_INLINE
01900 size_type index2 () const {
01901 return it1_.index2 ();
01902 }
01903
01904
01905 BOOST_UBLAS_INLINE
01906 iterator1 &operator = (const iterator1 &it) {
01907 container_reference<self_type>::assign (&it ());
01908 it1_ = it.it1_;
01909 return *this;
01910 }
01911
01912
01913 BOOST_UBLAS_INLINE
01914 bool operator == (const iterator1 &it) const {
01915 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01916 return it1_ == it.it1_;
01917 }
01918 BOOST_UBLAS_INLINE
01919 bool operator < (const iterator1 &it) const {
01920 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01921 return it1_ < it.it1_;
01922 }
01923
01924 private:
01925 subiterator1_type it1_;
01926
01927 friend class const_iterator1;
01928 };
01929 #endif
01930
01931 BOOST_UBLAS_INLINE
01932 iterator1 begin1 () {
01933 return find1 (0, 0, 0);
01934 }
01935 BOOST_UBLAS_INLINE
01936 iterator1 end1 () {
01937 return find1 (0, size1 (), 0);
01938 }
01939
01940 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01941 class const_iterator2:
01942 public container_const_reference<hermitian_adaptor>,
01943 public random_access_iterator_base<typename iterator_restrict_traits<
01944 typename const_subiterator2_type::iterator_category, dense_random_access_iterator_tag>::iterator_category,
01945 const_iterator2, value_type> {
01946 public:
01947 typedef typename const_subiterator2_type::value_type value_type;
01948 typedef typename const_subiterator2_type::difference_type difference_type;
01949
01950
01951 typedef typename const_subiterator2_type::value_type reference;
01952 typedef typename const_subiterator2_type::pointer pointer;
01953
01954 typedef const_iterator1 dual_iterator_type;
01955 typedef const_reverse_iterator1 dual_reverse_iterator_type;
01956
01957
01958 BOOST_UBLAS_INLINE
01959 const_iterator2 ():
01960 container_const_reference<self_type> (),
01961 begin_ (-1), end_ (-1), current_ (-1),
01962 it1_begin_ (), it1_end_ (), it1_ (),
01963 it2_begin_ (), it2_end_ (), it2_ () {}
01964 BOOST_UBLAS_INLINE
01965 const_iterator2 (const self_type &m, int begin, int end,
01966 const const_subiterator1_type &it1_begin, const const_subiterator1_type &it1_end,
01967 const const_subiterator2_type &it2_begin, const const_subiterator2_type &it2_end):
01968 container_const_reference<self_type> (m),
01969 begin_ (begin), end_ (end), current_ (begin),
01970 it1_begin_ (it1_begin), it1_end_ (it1_end), it1_ (it1_begin_),
01971 it2_begin_ (it2_begin), it2_end_ (it2_end), it2_ (it2_begin_) {
01972 if (current_ == 0 && it1_ == it1_end_)
01973 current_ = 1;
01974 if (current_ == 1 && it2_ == it2_end_)
01975 current_ = 0;
01976 if ((current_ == 0 && it1_ == it1_end_) ||
01977 (current_ == 1 && it2_ == it2_end_))
01978 current_ = end_;
01979 BOOST_UBLAS_CHECK (current_ == end_ ||
01980 (current_ == 0 && it1_ != it1_end_) ||
01981 (current_ == 1 && it2_ != it2_end_), internal_logic ());
01982 }
01983
01984
01985 BOOST_UBLAS_INLINE
01986 const_iterator2 (const iterator2 &it):
01987 container_const_reference<self_type> (it ()),
01988 begin_ (it.begin_), end_ (it.end_), current_ (it.current_),
01989 it1_begin_ (it.it1_begin_), it1_end_ (it.it1_end_), it1_ (it.it1_),
01990 it2_begin_ (it.it2_begin_), it2_end_ (it.it2_end_), it2_ (it.it2_) {
01991 BOOST_UBLAS_CHECK (current_ == end_ ||
01992 (current_ == 0 && it1_ != it1_end_) ||
01993 (current_ == 1 && it2_ != it2_end_), internal_logic ());
01994 }
01995
01996
01997 BOOST_UBLAS_INLINE
01998 const_iterator2 &operator ++ () {
01999 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
02000 if (current_ == 0) {
02001 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
02002 ++ it1_;
02003 if (it1_ == it1_end_ && end_ == 1) {
02004 it2_ = it2_begin_;
02005 current_ = 1;
02006 }
02007 } else {
02008 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
02009 ++ it2_;
02010 if (it2_ == it2_end_ && end_ == 0) {
02011 it1_ = it1_begin_;
02012 current_ = 0;
02013 }
02014 }
02015 return *this;
02016 }
02017 BOOST_UBLAS_INLINE
02018 const_iterator2 &operator -- () {
02019 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
02020 if (current_ == 0) {
02021 if (it1_ == it1_begin_ && begin_ == 1) {
02022 it2_ = it2_end_;
02023 BOOST_UBLAS_CHECK (it2_ != it2_begin_, internal_logic ());
02024 -- it2_;
02025 current_ = 1;
02026 } else {
02027 -- it1_;
02028 }
02029 } else {
02030 if (it2_ == it2_begin_ && begin_ == 0) {
02031 it1_ = it1_end_;
02032 BOOST_UBLAS_CHECK (it1_ != it1_begin_, internal_logic ());
02033 -- it1_;
02034 current_ = 0;
02035 } else {
02036 -- it2_;
02037 }
02038 }
02039 return *this;
02040 }
02041 BOOST_UBLAS_INLINE
02042 const_iterator2 &operator += (difference_type n) {
02043 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
02044 if (current_ == 0) {
02045 size_type d = (std::min) (n, it1_end_ - it1_);
02046 it1_ += d;
02047 n -= d;
02048 if (n > 0 || (end_ == 1 && it1_ == it1_end_)) {
02049 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
02050 d = (std::min) (n, it2_end_ - it2_begin_);
02051 it2_ = it2_begin_ + d;
02052 n -= d;
02053 current_ = 1;
02054 }
02055 } else {
02056 size_type d = (std::min) (n, it2_end_ - it2_);
02057 it2_ += d;
02058 n -= d;
02059 if (n > 0 || (end_ == 0 && it2_ == it2_end_)) {
02060 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
02061 d = (std::min) (n, it1_end_ - it1_begin_);
02062 it1_ = it1_begin_ + d;
02063 n -= d;
02064 current_ = 0;
02065 }
02066 }
02067 BOOST_UBLAS_CHECK (n == 0, external_logic ());
02068 return *this;
02069 }
02070 BOOST_UBLAS_INLINE
02071 const_iterator2 &operator -= (difference_type n) {
02072 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
02073 if (current_ == 0) {
02074 size_type d = (std::min) (n, it1_ - it1_begin_);
02075 it1_ -= d;
02076 n -= d;
02077 if (n > 0) {
02078 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
02079 d = (std::min) (n, it2_end_ - it2_begin_);
02080 it2_ = it2_end_ - d;
02081 n -= d;
02082 current_ = 1;
02083 }
02084 } else {
02085 size_type d = (std::min) (n, it2_ - it2_begin_);
02086 it2_ -= d;
02087 n -= d;
02088 if (n > 0) {
02089 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
02090 d = (std::min) (n, it1_end_ - it1_begin_);
02091 it1_ = it1_end_ - d;
02092 n -= d;
02093 current_ = 0;
02094 }
02095 }
02096 BOOST_UBLAS_CHECK (n == 0, external_logic ());
02097 return *this;
02098 }
02099 BOOST_UBLAS_INLINE
02100 difference_type operator - (const const_iterator2 &it) const {
02101 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02102 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
02103 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
02104 BOOST_UBLAS_CHECK ( end_ == it.end_, internal_logic ());
02105 if (current_ == 0 && it.current_ == 0) {
02106 return it1_ - it.it1_;
02107 } else if (current_ == 0 && it.current_ == 1) {
02108 if (end_ == 1 && it.end_ == 1) {
02109 return (it1_ - it.it1_end_) + (it.it2_begin_ - it.it2_);
02110 } else {
02111 return (it1_ - it.it1_begin_) + (it.it2_end_ - it.it2_);
02112 }
02113
02114 } else if (current_ == 1 && it.current_ == 0) {
02115 if (end_ == 1 && it.end_ == 1) {
02116 return (it2_ - it.it2_begin_) + (it.it1_end_ - it.it1_);
02117 } else {
02118 return (it2_ - it.it2_end_) + (it.it1_begin_ - it.it1_);
02119 }
02120 } else {
02121 return it2_ - it.it2_;
02122 }
02123 }
02124
02125
02126 BOOST_UBLAS_INLINE
02127 const_reference operator * () const {
02128 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
02129 if (current_ == 0) {
02130 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
02131 if (triangular_type::other (index1 (), index2 ()))
02132 return *it1_;
02133 else
02134 return type_traits<value_type>::conj (*it1_);
02135 } else {
02136 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
02137 if (triangular_type::other (index1 (), index2 ()))
02138 return *it2_;
02139 else
02140 return type_traits<value_type>::conj (*it2_);
02141 }
02142 }
02143 BOOST_UBLAS_INLINE
02144 const_reference operator [] (difference_type n) const {
02145 return *(*this + n);
02146 }
02147
02148 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
02149 BOOST_UBLAS_INLINE
02150 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02151 typename self_type::
02152 #endif
02153 const_iterator1 begin () const {
02154 return (*this) ().find1 (1, 0, index2 ());
02155 }
02156 BOOST_UBLAS_INLINE
02157 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02158 typename self_type::
02159 #endif
02160 const_iterator1 end () const {
02161 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
02162 }
02163 BOOST_UBLAS_INLINE
02164 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02165 typename self_type::
02166 #endif
02167 const_reverse_iterator1 rbegin () const {
02168 return const_reverse_iterator1 (end ());
02169 }
02170 BOOST_UBLAS_INLINE
02171 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02172 typename self_type::
02173 #endif
02174 const_reverse_iterator1 rend () const {
02175 return const_reverse_iterator1 (begin ());
02176 }
02177 #endif
02178
02179
02180 BOOST_UBLAS_INLINE
02181 size_type index1 () const {
02182 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
02183 if (current_ == 0) {
02184 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
02185 return it1_.index2 ();
02186 } else {
02187 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
02188 return it2_.index1 ();
02189 }
02190 }
02191 BOOST_UBLAS_INLINE
02192 size_type index2 () const {
02193 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
02194 if (current_ == 0) {
02195 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
02196 return it1_.index1 ();
02197 } else {
02198 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
02199 return it2_.index2 ();
02200 }
02201 }
02202
02203
02204 BOOST_UBLAS_INLINE
02205 const_iterator2 &operator = (const const_iterator2 &it) {
02206 container_const_reference<self_type>::assign (&it ());
02207 begin_ = it.begin_;
02208 end_ = it.end_;
02209 current_ = it.current_;
02210 it1_begin_ = it.it1_begin_;
02211 it1_end_ = it.it1_end_;
02212 it1_ = it.it1_;
02213 it2_begin_ = it.it2_begin_;
02214 it2_end_ = it.it2_end_;
02215 it2_ = it.it2_;
02216 return *this;
02217 }
02218
02219
02220 BOOST_UBLAS_INLINE
02221 bool operator == (const const_iterator2 &it) const {
02222 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02223 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
02224 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
02225 BOOST_UBLAS_CHECK ( end_ == it.end_, internal_logic ());
02226 return (current_ == 0 && it.current_ == 0 && it1_ == it.it1_) ||
02227 (current_ == 1 && it.current_ == 1 && it2_ == it.it2_);
02228 }
02229 BOOST_UBLAS_INLINE
02230 bool operator < (const const_iterator2 &it) const {
02231 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02232 return it - *this > 0;
02233 }
02234
02235 private:
02236 int begin_;
02237 int end_;
02238 int current_;
02239 const_subiterator1_type it1_begin_;
02240 const_subiterator1_type it1_end_;
02241 const_subiterator1_type it1_;
02242 const_subiterator2_type it2_begin_;
02243 const_subiterator2_type it2_end_;
02244 const_subiterator2_type it2_;
02245 };
02246 #endif
02247
02248 BOOST_UBLAS_INLINE
02249 const_iterator2 begin2 () const {
02250 return find2 (0, 0, 0);
02251 }
02252 BOOST_UBLAS_INLINE
02253 const_iterator2 end2 () const {
02254 return find2 (0, 0, size2 ());
02255 }
02256
02257 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
02258 class iterator2:
02259 public container_reference<hermitian_adaptor>,
02260 public random_access_iterator_base<typename iterator_restrict_traits<
02261 typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
02262 iterator2, value_type> {
02263 public:
02264 typedef typename subiterator2_type::value_type value_type;
02265 typedef typename subiterator2_type::difference_type difference_type;
02266 typedef typename subiterator2_type::reference reference;
02267 typedef typename subiterator2_type::pointer pointer;
02268
02269 typedef iterator1 dual_iterator_type;
02270 typedef reverse_iterator1 dual_reverse_iterator_type;
02271
02272
02273 BOOST_UBLAS_INLINE
02274 iterator2 ():
02275 container_reference<self_type> (), it2_ () {}
02276 BOOST_UBLAS_INLINE
02277 iterator2 (self_type &m, const subiterator2_type &it2):
02278 container_reference<self_type> (m), it2_ (it2) {}
02279
02280
02281 BOOST_UBLAS_INLINE
02282 iterator2 &operator ++ () {
02283 ++ it2_;
02284 return *this;
02285 }
02286 BOOST_UBLAS_INLINE
02287 iterator2 &operator -- () {
02288 -- it2_;
02289 return *this;
02290 }
02291 BOOST_UBLAS_INLINE
02292 iterator2 &operator += (difference_type n) {
02293 it2_ += n;
02294 return *this;
02295 }
02296 BOOST_UBLAS_INLINE
02297 iterator2 &operator -= (difference_type n) {
02298 it2_ -= n;
02299 return *this;
02300 }
02301 BOOST_UBLAS_INLINE
02302 difference_type operator - (const iterator2 &it) const {
02303 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02304 return it2_ - it.it2_;
02305 }
02306
02307
02308 BOOST_UBLAS_INLINE
02309 reference operator * () const {
02310 return *it2_;
02311 }
02312 BOOST_UBLAS_INLINE
02313 reference operator [] (difference_type n) const {
02314 return *(*this + n);
02315 }
02316
02317 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
02318 BOOST_UBLAS_INLINE
02319 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02320 typename self_type::
02321 #endif
02322 iterator1 begin () const {
02323 return (*this) ().find1 (1, 0, index2 ());
02324 }
02325 BOOST_UBLAS_INLINE
02326 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02327 typename self_type::
02328 #endif
02329 iterator1 end () const {
02330 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
02331 }
02332 BOOST_UBLAS_INLINE
02333 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02334 typename self_type::
02335 #endif
02336 reverse_iterator1 rbegin () const {
02337 return reverse_iterator1 (end ());
02338 }
02339 BOOST_UBLAS_INLINE
02340 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02341 typename self_type::
02342 #endif
02343 reverse_iterator1 rend () const {
02344 return reverse_iterator1 (begin ());
02345 }
02346 #endif
02347
02348
02349 BOOST_UBLAS_INLINE
02350 size_type index1 () const {
02351 return it2_.index1 ();
02352 }
02353 BOOST_UBLAS_INLINE
02354 size_type index2 () const {
02355 return it2_.index2 ();
02356 }
02357
02358
02359 BOOST_UBLAS_INLINE
02360 iterator2 &operator = (const iterator2 &it) {
02361 container_reference<self_type>::assign (&it ());
02362 it2_ = it.it2_;
02363 return *this;
02364 }
02365
02366
02367 BOOST_UBLAS_INLINE
02368 bool operator == (const iterator2 &it) const {
02369 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02370 return it2_ == it.it2_;
02371 }
02372 BOOST_UBLAS_INLINE
02373 bool operator < (const iterator2 &it) const {
02374 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02375 return it2_ < it.it2_;
02376 }
02377
02378 private:
02379 subiterator2_type it2_;
02380
02381 friend class const_iterator2;
02382 };
02383 #endif
02384
02385 BOOST_UBLAS_INLINE
02386 iterator2 begin2 () {
02387 return find2 (0, 0, 0);
02388 }
02389 BOOST_UBLAS_INLINE
02390 iterator2 end2 () {
02391 return find2 (0, 0, size2 ());
02392 }
02393
02394
02395
02396 BOOST_UBLAS_INLINE
02397 const_reverse_iterator1 rbegin1 () const {
02398 return const_reverse_iterator1 (end1 ());
02399 }
02400 BOOST_UBLAS_INLINE
02401 const_reverse_iterator1 rend1 () const {
02402 return const_reverse_iterator1 (begin1 ());
02403 }
02404
02405 BOOST_UBLAS_INLINE
02406 reverse_iterator1 rbegin1 () {
02407 return reverse_iterator1 (end1 ());
02408 }
02409 BOOST_UBLAS_INLINE
02410 reverse_iterator1 rend1 () {
02411 return reverse_iterator1 (begin1 ());
02412 }
02413
02414 BOOST_UBLAS_INLINE
02415 const_reverse_iterator2 rbegin2 () const {
02416 return const_reverse_iterator2 (end2 ());
02417 }
02418 BOOST_UBLAS_INLINE
02419 const_reverse_iterator2 rend2 () const {
02420 return const_reverse_iterator2 (begin2 ());
02421 }
02422
02423 BOOST_UBLAS_INLINE
02424 reverse_iterator2 rbegin2 () {
02425 return reverse_iterator2 (end2 ());
02426 }
02427 BOOST_UBLAS_INLINE
02428 reverse_iterator2 rend2 () {
02429 return reverse_iterator2 (begin2 ());
02430 }
02431
02432 private:
02433 matrix_closure_type data_;
02434 static value_type conj_;
02435 };
02436
02437 template<class M, class TRI>
02438 typename hermitian_adaptor<M, TRI>::value_type hermitian_adaptor<M, TRI>::conj_;
02439
02440
02441 template <class M, class TRI>
02442 struct vector_temporary_traits< hermitian_adaptor<M, TRI> >
02443 : vector_temporary_traits< M > {} ;
02444 template <class M, class TRI>
02445 struct vector_temporary_traits< const hermitian_adaptor<M, TRI> >
02446 : vector_temporary_traits< M > {} ;
02447
02448 template <class M, class TRI>
02449 struct matrix_temporary_traits< hermitian_adaptor<M, TRI> >
02450 : matrix_temporary_traits< M > {} ;
02451 template <class M, class TRI>
02452 struct matrix_temporary_traits< const hermitian_adaptor<M, TRI> >
02453 : matrix_temporary_traits< M > {} ;
02454
02455 }}}
02456
02457 #endif