annotate DEPENDENCIES/generic/include/boost/numeric/ublas/hermitian.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //
Chris@16 2 // Copyright (c) 2000-2010
Chris@16 3 // Joerg Walter, Mathias Koch, David Bellot
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //
Chris@16 9 // The authors gratefully acknowledge the support of
Chris@16 10 // GeNeSys mbH & Co. KG in producing this work.
Chris@16 11 //
Chris@16 12
Chris@16 13 #ifndef BOOST_UBLAS_HERMITIAN_H
Chris@16 14 #define BOOST_UBLAS_HERMITIAN_H
Chris@16 15
Chris@16 16 #include <boost/numeric/ublas/matrix.hpp>
Chris@16 17 #include <boost/numeric/ublas/triangular.hpp> // for resize_preserve
Chris@16 18 #include <boost/numeric/ublas/detail/temporary.hpp>
Chris@16 19
Chris@16 20 // Iterators based on ideas of Jeremy Siek
Chris@16 21 // Hermitian matrices are square. Thanks to Peter Schmitteckert for spotting this.
Chris@16 22
Chris@16 23 namespace boost { namespace numeric { namespace ublas {
Chris@16 24
Chris@16 25 template<class M>
Chris@16 26 bool is_hermitian (const M &m) {
Chris@16 27 typedef typename M::size_type size_type;
Chris@16 28
Chris@16 29 if (m.size1 () != m.size2 ())
Chris@16 30 return false;
Chris@16 31 size_type size = BOOST_UBLAS_SAME (m.size1 (), m.size2 ());
Chris@16 32 for (size_type i = 0; i < size; ++ i) {
Chris@16 33 for (size_type j = i; j < size; ++ j) {
Chris@16 34 if (m (i, j) != conj (m (j, i)))
Chris@16 35 return false;
Chris@16 36 }
Chris@16 37 }
Chris@16 38 return true;
Chris@16 39 }
Chris@16 40
Chris@16 41 #ifdef BOOST_UBLAS_STRICT_HERMITIAN
Chris@16 42
Chris@16 43 template<class M>
Chris@16 44 class hermitian_matrix_element:
Chris@16 45 public container_reference<M> {
Chris@16 46 public:
Chris@16 47 typedef M matrix_type;
Chris@16 48 typedef typename M::size_type size_type;
Chris@16 49 typedef typename M::value_type value_type;
Chris@16 50 typedef const value_type &const_reference;
Chris@16 51 typedef value_type &reference;
Chris@16 52 typedef value_type *pointer;
Chris@16 53
Chris@16 54 // Construction and destruction
Chris@16 55 BOOST_UBLAS_INLINE
Chris@16 56 hermitian_matrix_element (matrix_type &m, size_type i, size_type j, value_type d):
Chris@16 57 container_reference<matrix_type> (m), i_ (i), j_ (j), d_ (d), dirty_ (false) {}
Chris@16 58 BOOST_UBLAS_INLINE
Chris@16 59 ~hermitian_matrix_element () {
Chris@16 60 if (dirty_)
Chris@16 61 (*this) ().insert_element (i_, j_, d_);
Chris@16 62 }
Chris@16 63
Chris@16 64 // Assignment
Chris@16 65 BOOST_UBLAS_INLINE
Chris@16 66 hermitian_matrix_element &operator = (const hermitian_matrix_element &p) {
Chris@16 67 // Overide the implict copy assignment
Chris@16 68 d_ = p.d_;
Chris@16 69 dirty_ = true;
Chris@16 70 return *this;
Chris@16 71 }
Chris@16 72 template<class D>
Chris@16 73 BOOST_UBLAS_INLINE
Chris@16 74 hermitian_matrix_element &operator = (const D &d) {
Chris@16 75 d_ = d;
Chris@16 76 dirty_ = true;
Chris@16 77 return *this;
Chris@16 78 }
Chris@16 79 template<class D>
Chris@16 80 BOOST_UBLAS_INLINE
Chris@16 81 hermitian_matrix_element &operator += (const D &d) {
Chris@16 82 d_ += d;
Chris@16 83 dirty_ = true;
Chris@16 84 return *this;
Chris@16 85 }
Chris@16 86 template<class D>
Chris@16 87 BOOST_UBLAS_INLINE
Chris@16 88 hermitian_matrix_element &operator -= (const D &d) {
Chris@16 89 d_ -= d;
Chris@16 90 dirty_ = true;
Chris@16 91 return *this;
Chris@16 92 }
Chris@16 93 template<class D>
Chris@16 94 BOOST_UBLAS_INLINE
Chris@16 95 hermitian_matrix_element &operator *= (const D &d) {
Chris@16 96 d_ *= d;
Chris@16 97 dirty_ = true;
Chris@16 98 return *this;
Chris@16 99 }
Chris@16 100 template<class D>
Chris@16 101 BOOST_UBLAS_INLINE
Chris@16 102 hermitian_matrix_element &operator /= (const D &d) {
Chris@16 103 d_ /= d;
Chris@16 104 dirty_ = true;
Chris@16 105 return *this;
Chris@16 106 }
Chris@16 107
Chris@16 108 // Comparison
Chris@16 109 template<class D>
Chris@16 110 BOOST_UBLAS_INLINE
Chris@16 111 bool operator == (const D &d) const {
Chris@16 112 return d_ == d;
Chris@16 113 }
Chris@16 114 template<class D>
Chris@16 115 BOOST_UBLAS_INLINE
Chris@16 116 bool operator != (const D &d) const {
Chris@16 117 return d_ != d;
Chris@16 118 }
Chris@16 119
Chris@16 120 // Conversion
Chris@16 121 BOOST_UBLAS_INLINE
Chris@16 122 operator const_reference () const {
Chris@16 123 return d_;
Chris@16 124 }
Chris@16 125
Chris@16 126 // Swapping
Chris@16 127 BOOST_UBLAS_INLINE
Chris@16 128 void swap (hermitian_matrix_element p) {
Chris@16 129 if (this != &p) {
Chris@16 130 dirty_ = true;
Chris@16 131 p.dirty_ = true;
Chris@16 132 std::swap (d_, p.d_);
Chris@16 133 }
Chris@16 134 }
Chris@16 135 BOOST_UBLAS_INLINE
Chris@16 136 friend void swap (hermitian_matrix_element p1, hermitian_matrix_element p2) {
Chris@16 137 p1.swap (p2);
Chris@16 138 }
Chris@16 139
Chris@16 140 private:
Chris@16 141 size_type i_;
Chris@16 142 size_type j_;
Chris@16 143 value_type d_;
Chris@16 144 bool dirty_;
Chris@16 145 };
Chris@16 146
Chris@16 147 template<class M>
Chris@16 148 struct type_traits<hermitian_matrix_element<M> > {
Chris@16 149 typedef typename M::value_type element_type;
Chris@16 150 typedef type_traits<hermitian_matrix_element<M> > self_type;
Chris@16 151 typedef typename type_traits<element_type>::value_type value_type;
Chris@16 152 typedef typename type_traits<element_type>::const_reference const_reference;
Chris@16 153 typedef hermitian_matrix_element<M> reference;
Chris@16 154 typedef typename type_traits<element_type>::real_type real_type;
Chris@16 155 typedef typename type_traits<element_type>::precision_type precision_type;
Chris@16 156
Chris@16 157 static const unsigned plus_complexity = type_traits<element_type>::plus_complexity;
Chris@16 158 static const unsigned multiplies_complexity = type_traits<element_type>::multiplies_complexity;
Chris@16 159
Chris@16 160 static
Chris@16 161 BOOST_UBLAS_INLINE
Chris@16 162 real_type real (const_reference t) {
Chris@16 163 return type_traits<element_type>::real (t);
Chris@16 164 }
Chris@16 165 static
Chris@16 166 BOOST_UBLAS_INLINE
Chris@16 167 real_type imag (const_reference t) {
Chris@16 168 return type_traits<element_type>::imag (t);
Chris@16 169 }
Chris@16 170 static
Chris@16 171 BOOST_UBLAS_INLINE
Chris@16 172 value_type conj (const_reference t) {
Chris@16 173 return type_traits<element_type>::conj (t);
Chris@16 174 }
Chris@16 175
Chris@16 176 static
Chris@16 177 BOOST_UBLAS_INLINE
Chris@16 178 real_type type_abs (const_reference t) {
Chris@16 179 return type_traits<element_type>::type_abs (t);
Chris@16 180 }
Chris@16 181 static
Chris@16 182 BOOST_UBLAS_INLINE
Chris@16 183 value_type type_sqrt (const_reference t) {
Chris@16 184 return type_traits<element_type>::type_sqrt (t);
Chris@16 185 }
Chris@16 186
Chris@16 187 static
Chris@16 188 BOOST_UBLAS_INLINE
Chris@16 189 real_type norm_1 (const_reference t) {
Chris@16 190 return type_traits<element_type>::norm_1 (t);
Chris@16 191 }
Chris@16 192 static
Chris@16 193 BOOST_UBLAS_INLINE
Chris@16 194 real_type norm_2 (const_reference t) {
Chris@16 195 return type_traits<element_type>::norm_2 (t);
Chris@16 196 }
Chris@16 197 static
Chris@16 198 BOOST_UBLAS_INLINE
Chris@16 199 real_type norm_inf (const_reference t) {
Chris@16 200 return type_traits<element_type>::norm_inf (t);
Chris@16 201 }
Chris@16 202
Chris@16 203 static
Chris@16 204 BOOST_UBLAS_INLINE
Chris@16 205 bool equals (const_reference t1, const_reference t2) {
Chris@16 206 return type_traits<element_type>::equals (t1, t2);
Chris@16 207 }
Chris@16 208 };
Chris@16 209
Chris@16 210 template<class M1, class T2>
Chris@16 211 struct promote_traits<hermitian_matrix_element<M1>, T2> {
Chris@16 212 typedef typename promote_traits<typename hermitian_matrix_element<M1>::value_type, T2>::promote_type promote_type;
Chris@16 213 };
Chris@16 214 template<class T1, class M2>
Chris@16 215 struct promote_traits<T1, hermitian_matrix_element<M2> > {
Chris@16 216 typedef typename promote_traits<T1, typename hermitian_matrix_element<M2>::value_type>::promote_type promote_type;
Chris@16 217 };
Chris@16 218 template<class M1, class M2>
Chris@16 219 struct promote_traits<hermitian_matrix_element<M1>, hermitian_matrix_element<M2> > {
Chris@16 220 typedef typename promote_traits<typename hermitian_matrix_element<M1>::value_type,
Chris@16 221 typename hermitian_matrix_element<M2>::value_type>::promote_type promote_type;
Chris@16 222 };
Chris@16 223
Chris@16 224 #endif
Chris@16 225 /** \brief A hermitian matrix of values of type \c T
Chris@16 226 *
Chris@16 227 * For a \f$(n \times n)\f$-dimensional matrix and \f$ 0 \leq i < n, 0 \leq j < n\f$, every element
Chris@16 228 * \f$m_{i,j}\f$ is mapped to the \f$(i.n + j)\f$-th element of the container for row major orientation
Chris@16 229 * or the \f$(i + j.m)\f$-th element of the container for column major orientation. And
Chris@16 230 * \f$\forall i,j\f$, \f$m_{i,j} = \overline{m_{i,j}}\f$.
Chris@16 231 *
Chris@16 232 * Orientation and storage can also be specified, otherwise a row major and unbounded array are used.
Chris@16 233 * It is \b not required by the storage to initialize elements of the matrix.
Chris@16 234 * Moreover, only the given triangular matrix is stored and the storage of hermitian matrices is packed.
Chris@16 235 *
Chris@16 236 * See http://en.wikipedia.org/wiki/Hermitian_matrix for more details on hermitian matrices.
Chris@16 237 *
Chris@16 238 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 239 * \tparam TRI the type of triangular matrix is either \c lower or \c upper. Default is \c lower
Chris@16 240 * \tparam L the storage organization. It is either \c row_major or \c column_major. Default is \c row_major
Chris@16 241 * \tparam A the type of Storage array. Default is \unbounded_array.
Chris@16 242 */
Chris@16 243 template<class T, class TRI, class L, class A>
Chris@16 244 class hermitian_matrix:
Chris@16 245 public matrix_container<hermitian_matrix<T, TRI, L, A> > {
Chris@16 246
Chris@16 247 typedef T &true_reference;
Chris@16 248 typedef T *pointer;
Chris@16 249 typedef TRI triangular_type;
Chris@16 250 typedef L layout_type;
Chris@16 251 typedef hermitian_matrix<T, TRI, L, A> self_type;
Chris@16 252 public:
Chris@16 253 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 254 using matrix_container<self_type>::operator ();
Chris@16 255 #endif
Chris@16 256 typedef typename A::size_type size_type;
Chris@16 257 typedef typename A::difference_type difference_type;
Chris@16 258 typedef T value_type;
Chris@16 259 // FIXME no better way to not return the address of a temporary?
Chris@16 260 // typedef const T &const_reference;
Chris@16 261 typedef const T const_reference;
Chris@16 262 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
Chris@16 263 typedef T &reference;
Chris@16 264 #else
Chris@16 265 typedef hermitian_matrix_element<self_type> reference;
Chris@16 266 #endif
Chris@16 267 typedef A array_type;
Chris@16 268
Chris@16 269 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 270 typedef matrix_reference<self_type> closure_type;
Chris@16 271 typedef vector<T, A> vector_temporary_type;
Chris@16 272 typedef matrix<T, L, A> matrix_temporary_type; // general sub-matrix
Chris@16 273 typedef packed_tag storage_category;
Chris@16 274 typedef typename L::orientation_category orientation_category;
Chris@16 275
Chris@16 276 // Construction and destruction
Chris@16 277 BOOST_UBLAS_INLINE
Chris@16 278 hermitian_matrix ():
Chris@16 279 matrix_container<self_type> (),
Chris@16 280 size_ (0), data_ (0) {}
Chris@16 281 BOOST_UBLAS_INLINE
Chris@16 282 hermitian_matrix (size_type size):
Chris@16 283 matrix_container<self_type> (),
Chris@16 284 size_ (BOOST_UBLAS_SAME (size, size)), data_ (triangular_type::packed_size (layout_type (), size, size)) {
Chris@16 285 }
Chris@16 286 BOOST_UBLAS_INLINE
Chris@16 287 hermitian_matrix (size_type size1, size_type size2):
Chris@16 288 matrix_container<self_type> (),
Chris@16 289 size_ (BOOST_UBLAS_SAME (size1, size2)), data_ (triangular_type::packed_size (layout_type (), size1, size2)) {
Chris@16 290 }
Chris@16 291 BOOST_UBLAS_INLINE
Chris@16 292 hermitian_matrix (size_type size, const array_type &data):
Chris@16 293 matrix_container<self_type> (),
Chris@16 294 size_ (size), data_ (data) {}
Chris@16 295 BOOST_UBLAS_INLINE
Chris@16 296 hermitian_matrix (const hermitian_matrix &m):
Chris@16 297 matrix_container<self_type> (),
Chris@16 298 size_ (m.size_), data_ (m.data_) {}
Chris@16 299 template<class AE>
Chris@16 300 BOOST_UBLAS_INLINE
Chris@16 301 hermitian_matrix (const matrix_expression<AE> &ae):
Chris@16 302 matrix_container<self_type> (),
Chris@16 303 size_ (BOOST_UBLAS_SAME (ae ().size1 (), ae ().size2 ())),
Chris@16 304 data_ (triangular_type::packed_size (layout_type (), size_, size_)) {
Chris@16 305 matrix_assign<scalar_assign> (*this, ae);
Chris@16 306 }
Chris@16 307
Chris@16 308 // Accessors
Chris@16 309 BOOST_UBLAS_INLINE
Chris@16 310 size_type size1 () const {
Chris@16 311 return size_;
Chris@16 312 }
Chris@16 313 BOOST_UBLAS_INLINE
Chris@16 314 size_type size2 () const {
Chris@16 315 return size_;
Chris@16 316 }
Chris@16 317
Chris@16 318 // Storage accessors
Chris@16 319 BOOST_UBLAS_INLINE
Chris@16 320 const array_type &data () const {
Chris@16 321 return data_;
Chris@16 322 }
Chris@16 323 BOOST_UBLAS_INLINE
Chris@16 324 array_type &data () {
Chris@16 325 return data_;
Chris@16 326 }
Chris@16 327
Chris@16 328 // Resizing
Chris@16 329 BOOST_UBLAS_INLINE
Chris@16 330 void resize (size_type size, bool preserve = true) {
Chris@16 331 if (preserve) {
Chris@16 332 self_type temporary (size, size);
Chris@16 333 detail::matrix_resize_preserve<layout_type, triangular_type> (*this, temporary);
Chris@16 334 }
Chris@16 335 else {
Chris@16 336 data ().resize (triangular_type::packed_size (layout_type (), size, size));
Chris@16 337 size_ = size;
Chris@16 338 }
Chris@16 339 }
Chris@16 340 BOOST_UBLAS_INLINE
Chris@16 341 void resize (size_type size1, size_type size2, bool preserve = true) {
Chris@16 342 resize (BOOST_UBLAS_SAME (size1, size2), preserve);
Chris@16 343 }
Chris@16 344 BOOST_UBLAS_INLINE
Chris@16 345 void resize_packed_preserve (size_type size) {
Chris@16 346 size_ = BOOST_UBLAS_SAME (size, size);
Chris@16 347 data ().resize (triangular_type::packed_size (layout_type (), size_, size_), value_type ());
Chris@16 348 }
Chris@16 349
Chris@16 350 // Element access
Chris@16 351 BOOST_UBLAS_INLINE
Chris@16 352 const_reference operator () (size_type i, size_type j) const {
Chris@16 353 BOOST_UBLAS_CHECK (i < size_, bad_index ());
Chris@16 354 BOOST_UBLAS_CHECK (j < size_, bad_index ());
Chris@16 355 // if (i == j)
Chris@16 356 // return type_traits<value_type>::real (data () [triangular_type::element (layout_type (), i, size_, i, size_)]);
Chris@16 357 // else
Chris@16 358 if (triangular_type::other (i, j))
Chris@16 359 return data () [triangular_type::element (layout_type (), i, size_, j, size_)];
Chris@16 360 else
Chris@16 361 return type_traits<value_type>::conj (data () [triangular_type::element (layout_type (), j, size_, i, size_)]);
Chris@16 362 }
Chris@16 363 BOOST_UBLAS_INLINE
Chris@16 364 true_reference at_element (size_type i, size_type j) {
Chris@16 365 BOOST_UBLAS_CHECK (i < size_, bad_index ());
Chris@16 366 BOOST_UBLAS_CHECK (j < size_, bad_index ());
Chris@16 367 BOOST_UBLAS_CHECK (triangular_type::other (i, j), bad_index ());
Chris@16 368 return data () [triangular_type::element (layout_type (), i, size_, j, size_)];
Chris@16 369 }
Chris@16 370 BOOST_UBLAS_INLINE
Chris@16 371 reference operator () (size_type i, size_type j) {
Chris@16 372 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
Chris@16 373 if (!triangular_type::other (i, j)) {
Chris@16 374 bad_index ().raise ();
Chris@16 375 // NEVER reached
Chris@16 376 }
Chris@16 377 return at_element (i, j);
Chris@16 378 #else
Chris@16 379 if (triangular_type::other (i, j))
Chris@16 380 return reference (*this, i, j, data () [triangular_type::element (layout_type (), i, size_, j, size_)]);
Chris@16 381 else
Chris@16 382 return reference (*this, i, j, type_traits<value_type>::conj (data () [triangular_type::element (layout_type (), j, size_, i, size_)]));
Chris@16 383 #endif
Chris@16 384 }
Chris@16 385
Chris@16 386 // Element assignemnt
Chris@16 387 BOOST_UBLAS_INLINE
Chris@16 388 true_reference insert_element (size_type i, size_type j, const_reference t) {
Chris@16 389 BOOST_UBLAS_CHECK (i < size_, bad_index ());
Chris@16 390 BOOST_UBLAS_CHECK (j < size_, bad_index ());
Chris@16 391 if (triangular_type::other (i, j)) {
Chris@16 392 return (data () [triangular_type::element (layout_type (), i, size_, j, size_)] = t);
Chris@16 393 } else {
Chris@16 394 return (data () [triangular_type::element (layout_type (), j, size_, i, size_)] = type_traits<value_type>::conj (t));
Chris@16 395 }
Chris@16 396 }
Chris@16 397 BOOST_UBLAS_INLINE
Chris@16 398 void erase_element (size_type i, size_type j) {
Chris@16 399 BOOST_UBLAS_CHECK (i < size_, bad_index ());
Chris@16 400 BOOST_UBLAS_CHECK (j < size_, bad_index ());
Chris@16 401 data () [triangular_type::element (layout_type (), i, size_, j, size_)] = value_type/*zero*/();
Chris@16 402 }
Chris@16 403
Chris@16 404 // Zeroing
Chris@16 405 BOOST_UBLAS_INLINE
Chris@16 406 void clear () {
Chris@16 407 std::fill (data ().begin (), data ().end (), value_type/*zero*/());
Chris@16 408 }
Chris@16 409
Chris@16 410 // Assignment
Chris@16 411 BOOST_UBLAS_INLINE
Chris@16 412 hermitian_matrix &operator = (const hermitian_matrix &m) {
Chris@16 413 size_ = m.size_;
Chris@16 414 data () = m.data ();
Chris@16 415 return *this;
Chris@16 416 }
Chris@16 417 BOOST_UBLAS_INLINE
Chris@16 418 hermitian_matrix &assign_temporary (hermitian_matrix &m) {
Chris@16 419 swap (m);
Chris@16 420 return *this;
Chris@16 421 }
Chris@16 422 template<class AE>
Chris@16 423 BOOST_UBLAS_INLINE
Chris@16 424 hermitian_matrix &operator = (const matrix_expression<AE> &ae) {
Chris@16 425 self_type temporary (ae);
Chris@16 426 return assign_temporary (temporary);
Chris@16 427 }
Chris@16 428 template<class AE>
Chris@16 429 BOOST_UBLAS_INLINE
Chris@16 430 hermitian_matrix &assign (const matrix_expression<AE> &ae) {
Chris@16 431 matrix_assign<scalar_assign> (*this, ae);
Chris@16 432 return *this;
Chris@16 433 }
Chris@16 434 template<class AE>
Chris@16 435 BOOST_UBLAS_INLINE
Chris@16 436 hermitian_matrix& operator += (const matrix_expression<AE> &ae) {
Chris@16 437 self_type temporary (*this + ae);
Chris@16 438 return assign_temporary (temporary);
Chris@16 439 }
Chris@16 440 template<class AE>
Chris@16 441 BOOST_UBLAS_INLINE
Chris@16 442 hermitian_matrix &plus_assign (const matrix_expression<AE> &ae) {
Chris@16 443 matrix_assign<scalar_plus_assign> (*this, ae);
Chris@16 444 return *this;
Chris@16 445 }
Chris@16 446 template<class AE>
Chris@16 447 BOOST_UBLAS_INLINE
Chris@16 448 hermitian_matrix& operator -= (const matrix_expression<AE> &ae) {
Chris@16 449 self_type temporary (*this - ae);
Chris@16 450 return assign_temporary (temporary);
Chris@16 451 }
Chris@16 452 template<class AE>
Chris@16 453 BOOST_UBLAS_INLINE
Chris@16 454 hermitian_matrix &minus_assign (const matrix_expression<AE> &ae) {
Chris@16 455 matrix_assign<scalar_minus_assign> (*this, ae);
Chris@16 456 return *this;
Chris@16 457 }
Chris@16 458 template<class AT>
Chris@16 459 BOOST_UBLAS_INLINE
Chris@16 460 hermitian_matrix& operator *= (const AT &at) {
Chris@16 461 // Multiplication is only allowed for real scalars,
Chris@16 462 // otherwise the resulting matrix isn't hermitian.
Chris@16 463 // Thanks to Peter Schmitteckert for spotting this.
Chris@16 464 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
Chris@16 465 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 466 return *this;
Chris@16 467 }
Chris@16 468 template<class AT>
Chris@16 469 BOOST_UBLAS_INLINE
Chris@16 470 hermitian_matrix& operator /= (const AT &at) {
Chris@16 471 // Multiplication is only allowed for real scalars,
Chris@16 472 // otherwise the resulting matrix isn't hermitian.
Chris@16 473 // Thanks to Peter Schmitteckert for spotting this.
Chris@16 474 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
Chris@16 475 matrix_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 476 return *this;
Chris@16 477 }
Chris@16 478
Chris@16 479 // Swapping
Chris@16 480 BOOST_UBLAS_INLINE
Chris@16 481 void swap (hermitian_matrix &m) {
Chris@16 482 if (this != &m) {
Chris@16 483 std::swap (size_, m.size_);
Chris@16 484 data ().swap (m.data ());
Chris@16 485 }
Chris@16 486 }
Chris@16 487 BOOST_UBLAS_INLINE
Chris@16 488 friend void swap (hermitian_matrix &m1, hermitian_matrix &m2) {
Chris@16 489 m1.swap (m2);
Chris@16 490 }
Chris@16 491
Chris@16 492 // Iterator types
Chris@16 493 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 494 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
Chris@16 495 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
Chris@16 496 typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
Chris@16 497 typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
Chris@16 498 #else
Chris@16 499 class const_iterator1;
Chris@16 500 class iterator1;
Chris@16 501 class const_iterator2;
Chris@16 502 class iterator2;
Chris@16 503 #endif
Chris@16 504 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 505 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
Chris@16 506 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 507 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
Chris@16 508
Chris@16 509 // Element lookup
Chris@16 510 BOOST_UBLAS_INLINE
Chris@16 511 const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
Chris@16 512 return const_iterator1 (*this, i, j);
Chris@16 513 }
Chris@16 514 BOOST_UBLAS_INLINE
Chris@16 515 iterator1 find1 (int rank, size_type i, size_type j) {
Chris@16 516 if (rank == 1)
Chris@16 517 i = triangular_type::mutable_restrict1 (i, j, size1(), size2());
Chris@16 518 if (rank == 0)
Chris@16 519 i = triangular_type::global_mutable_restrict1 (i, size1(), j, size2());
Chris@16 520 return iterator1 (*this, i, j);
Chris@16 521 }
Chris@16 522 BOOST_UBLAS_INLINE
Chris@16 523 const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
Chris@16 524 return const_iterator2 (*this, i, j);
Chris@16 525 }
Chris@16 526 BOOST_UBLAS_INLINE
Chris@16 527 iterator2 find2 (int rank, size_type i, size_type j) {
Chris@16 528 if (rank == 1)
Chris@16 529 j = triangular_type::mutable_restrict2 (i, j, size1(), size2());
Chris@16 530 if (rank == 0)
Chris@16 531 j = triangular_type::global_mutable_restrict2 (i, size1(), j, size2());
Chris@16 532 return iterator2 (*this, i, j);
Chris@16 533 }
Chris@16 534
Chris@16 535 // Iterators simply are indices.
Chris@16 536
Chris@16 537 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 538 class const_iterator1:
Chris@16 539 public container_const_reference<hermitian_matrix>,
Chris@16 540 public random_access_iterator_base<packed_random_access_iterator_tag,
Chris@16 541 const_iterator1, value_type> {
Chris@16 542 public:
Chris@16 543 typedef typename hermitian_matrix::value_type value_type;
Chris@16 544 typedef typename hermitian_matrix::difference_type difference_type;
Chris@16 545 typedef typename hermitian_matrix::const_reference reference;
Chris@16 546 typedef const typename hermitian_matrix::pointer pointer;
Chris@16 547
Chris@16 548 typedef const_iterator2 dual_iterator_type;
Chris@16 549 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 550
Chris@16 551 // Construction and destruction
Chris@16 552 BOOST_UBLAS_INLINE
Chris@16 553 const_iterator1 ():
Chris@16 554 container_const_reference<self_type> (), it1_ (), it2_ () {}
Chris@16 555 BOOST_UBLAS_INLINE
Chris@16 556 const_iterator1 (const self_type &m, size_type it1, size_type it2):
Chris@16 557 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
Chris@16 558 BOOST_UBLAS_INLINE
Chris@16 559 const_iterator1 (const iterator1 &it):
Chris@16 560 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
Chris@16 561
Chris@16 562 // Arithmetic
Chris@16 563 BOOST_UBLAS_INLINE
Chris@16 564 const_iterator1 &operator ++ () {
Chris@16 565 ++ it1_;
Chris@16 566 return *this;
Chris@16 567 }
Chris@16 568 BOOST_UBLAS_INLINE
Chris@16 569 const_iterator1 &operator -- () {
Chris@16 570 -- it1_;
Chris@16 571 return *this;
Chris@16 572 }
Chris@16 573 BOOST_UBLAS_INLINE
Chris@16 574 const_iterator1 &operator += (difference_type n) {
Chris@16 575 it1_ += n;
Chris@16 576 return *this;
Chris@16 577 }
Chris@16 578 BOOST_UBLAS_INLINE
Chris@16 579 const_iterator1 &operator -= (difference_type n) {
Chris@16 580 it1_ -= n;
Chris@16 581 return *this;
Chris@16 582 }
Chris@16 583 BOOST_UBLAS_INLINE
Chris@16 584 difference_type operator - (const const_iterator1 &it) const {
Chris@16 585 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 586 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 587 return it1_ - it.it1_;
Chris@16 588 }
Chris@16 589
Chris@16 590 // Dereference
Chris@16 591 BOOST_UBLAS_INLINE
Chris@16 592 const_reference operator * () const {
Chris@16 593 return (*this) () (it1_, it2_);
Chris@16 594 }
Chris@16 595 BOOST_UBLAS_INLINE
Chris@16 596 const_reference operator [] (difference_type n) const {
Chris@16 597 return *(*this + n);
Chris@16 598 }
Chris@16 599
Chris@16 600 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 601 BOOST_UBLAS_INLINE
Chris@16 602 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 603 typename self_type::
Chris@16 604 #endif
Chris@16 605 const_iterator2 begin () const {
Chris@16 606 return (*this) ().find2 (1, it1_, 0);
Chris@16 607 }
Chris@16 608 BOOST_UBLAS_INLINE
Chris@16 609 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 610 typename self_type::
Chris@16 611 #endif
Chris@101 612 const_iterator2 cbegin () const {
Chris@101 613 return begin ();
Chris@101 614 }
Chris@101 615 BOOST_UBLAS_INLINE
Chris@101 616 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 617 typename self_type::
Chris@101 618 #endif
Chris@16 619 const_iterator2 end () const {
Chris@16 620 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
Chris@16 621 }
Chris@16 622 BOOST_UBLAS_INLINE
Chris@16 623 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 624 typename self_type::
Chris@16 625 #endif
Chris@101 626 const_iterator2 cend () const {
Chris@101 627 return end ();
Chris@101 628 }
Chris@101 629 BOOST_UBLAS_INLINE
Chris@101 630 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 631 typename self_type::
Chris@101 632 #endif
Chris@16 633 const_reverse_iterator2 rbegin () const {
Chris@16 634 return const_reverse_iterator2 (end ());
Chris@16 635 }
Chris@16 636 BOOST_UBLAS_INLINE
Chris@16 637 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 638 typename self_type::
Chris@16 639 #endif
Chris@101 640 const_reverse_iterator2 crbegin () const {
Chris@101 641 return rbegin ();
Chris@101 642 }
Chris@101 643 BOOST_UBLAS_INLINE
Chris@101 644 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 645 typename self_type::
Chris@101 646 #endif
Chris@16 647 const_reverse_iterator2 rend () const {
Chris@16 648 return const_reverse_iterator2 (begin ());
Chris@16 649 }
Chris@101 650 BOOST_UBLAS_INLINE
Chris@101 651 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 652 typename self_type::
Chris@101 653 #endif
Chris@101 654 const_reverse_iterator2 crend () const {
Chris@101 655 return rend ();
Chris@101 656 }
Chris@16 657 #endif
Chris@16 658
Chris@16 659 // Indices
Chris@16 660 BOOST_UBLAS_INLINE
Chris@16 661 size_type index1 () const {
Chris@16 662 return it1_;
Chris@16 663 }
Chris@16 664 BOOST_UBLAS_INLINE
Chris@16 665 size_type index2 () const {
Chris@16 666 return it2_;
Chris@16 667 }
Chris@16 668
Chris@16 669 // Assignment
Chris@16 670 BOOST_UBLAS_INLINE
Chris@16 671 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 672 container_const_reference<self_type>::assign (&it ());
Chris@16 673 it1_ = it.it1_;
Chris@16 674 it2_ = it.it2_;
Chris@16 675 return *this;
Chris@16 676 }
Chris@16 677
Chris@16 678 // Comparison
Chris@16 679 BOOST_UBLAS_INLINE
Chris@16 680 bool operator == (const const_iterator1 &it) const {
Chris@16 681 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 682 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 683 return it1_ == it.it1_;
Chris@16 684 }
Chris@16 685 BOOST_UBLAS_INLINE
Chris@16 686 bool operator < (const const_iterator1 &it) const {
Chris@16 687 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 688 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 689 return it1_ < it.it1_;
Chris@16 690 }
Chris@16 691
Chris@16 692 private:
Chris@16 693 size_type it1_;
Chris@16 694 size_type it2_;
Chris@16 695 };
Chris@16 696 #endif
Chris@16 697
Chris@16 698 BOOST_UBLAS_INLINE
Chris@16 699 const_iterator1 begin1 () const {
Chris@16 700 return find1 (0, 0, 0);
Chris@16 701 }
Chris@16 702 BOOST_UBLAS_INLINE
Chris@101 703 const_iterator1 cbegin1 () const {
Chris@101 704 return begin1 ();
Chris@101 705 }
Chris@101 706 BOOST_UBLAS_INLINE
Chris@16 707 const_iterator1 end1 () const {
Chris@16 708 return find1 (0, size_, 0);
Chris@16 709 }
Chris@101 710 BOOST_UBLAS_INLINE
Chris@101 711 const_iterator1 cend1 () const {
Chris@101 712 return end1 ();
Chris@101 713 }
Chris@16 714
Chris@16 715 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 716 class iterator1:
Chris@16 717 public container_reference<hermitian_matrix>,
Chris@16 718 public random_access_iterator_base<packed_random_access_iterator_tag,
Chris@16 719 iterator1, value_type> {
Chris@16 720 public:
Chris@16 721 typedef typename hermitian_matrix::value_type value_type;
Chris@16 722 typedef typename hermitian_matrix::difference_type difference_type;
Chris@16 723 typedef typename hermitian_matrix::true_reference reference;
Chris@16 724 typedef typename hermitian_matrix::pointer pointer;
Chris@16 725
Chris@16 726 typedef iterator2 dual_iterator_type;
Chris@16 727 typedef reverse_iterator2 dual_reverse_iterator_type;
Chris@16 728
Chris@16 729 // Construction and destruction
Chris@16 730 BOOST_UBLAS_INLINE
Chris@16 731 iterator1 ():
Chris@16 732 container_reference<self_type> (), it1_ (), it2_ () {}
Chris@16 733 BOOST_UBLAS_INLINE
Chris@16 734 iterator1 (self_type &m, size_type it1, size_type it2):
Chris@16 735 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
Chris@16 736
Chris@16 737 // Arithmetic
Chris@16 738 BOOST_UBLAS_INLINE
Chris@16 739 iterator1 &operator ++ () {
Chris@16 740 ++ it1_;
Chris@16 741 return *this;
Chris@16 742 }
Chris@16 743 BOOST_UBLAS_INLINE
Chris@16 744 iterator1 &operator -- () {
Chris@16 745 -- it1_;
Chris@16 746 return *this;
Chris@16 747 }
Chris@16 748 BOOST_UBLAS_INLINE
Chris@16 749 iterator1 &operator += (difference_type n) {
Chris@16 750 it1_ += n;
Chris@16 751 return *this;
Chris@16 752 }
Chris@16 753 BOOST_UBLAS_INLINE
Chris@16 754 iterator1 &operator -= (difference_type n) {
Chris@16 755 it1_ -= n;
Chris@16 756 return *this;
Chris@16 757 }
Chris@16 758 BOOST_UBLAS_INLINE
Chris@16 759 difference_type operator - (const iterator1 &it) const {
Chris@16 760 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 761 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 762 return it1_ - it.it1_;
Chris@16 763 }
Chris@16 764
Chris@16 765 // Dereference
Chris@16 766 BOOST_UBLAS_INLINE
Chris@16 767 reference operator * () const {
Chris@16 768 return (*this) ().at_element (it1_, it2_);
Chris@16 769 }
Chris@16 770 BOOST_UBLAS_INLINE
Chris@16 771 reference operator [] (difference_type n) const {
Chris@16 772 return *(*this + n);
Chris@16 773 }
Chris@16 774
Chris@16 775 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 776 BOOST_UBLAS_INLINE
Chris@16 777 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 778 typename self_type::
Chris@16 779 #endif
Chris@16 780 iterator2 begin () const {
Chris@16 781 return (*this) ().find2 (1, it1_, 0);
Chris@16 782 }
Chris@16 783 BOOST_UBLAS_INLINE
Chris@16 784 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 785 typename self_type::
Chris@16 786 #endif
Chris@16 787 iterator2 end () const {
Chris@16 788 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
Chris@16 789 }
Chris@16 790 BOOST_UBLAS_INLINE
Chris@16 791 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 792 typename self_type::
Chris@16 793 #endif
Chris@16 794 reverse_iterator2 rbegin () const {
Chris@16 795 return reverse_iterator2 (end ());
Chris@16 796 }
Chris@16 797 BOOST_UBLAS_INLINE
Chris@16 798 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 799 typename self_type::
Chris@16 800 #endif
Chris@16 801 reverse_iterator2 rend () const {
Chris@16 802 return reverse_iterator2 (begin ());
Chris@16 803 }
Chris@16 804 #endif
Chris@16 805
Chris@16 806 // Indices
Chris@16 807 BOOST_UBLAS_INLINE
Chris@16 808 size_type index1 () const {
Chris@16 809 return it1_;
Chris@16 810 }
Chris@16 811 BOOST_UBLAS_INLINE
Chris@16 812 size_type index2 () const {
Chris@16 813 return it2_;
Chris@16 814 }
Chris@16 815
Chris@16 816 // Assignment
Chris@16 817 BOOST_UBLAS_INLINE
Chris@16 818 iterator1 &operator = (const iterator1 &it) {
Chris@16 819 container_reference<self_type>::assign (&it ());
Chris@16 820 it1_ = it.it1_;
Chris@16 821 it2_ = it.it2_;
Chris@16 822 return *this;
Chris@16 823 }
Chris@16 824
Chris@16 825 // Comparison
Chris@16 826 BOOST_UBLAS_INLINE
Chris@16 827 bool operator == (const iterator1 &it) const {
Chris@16 828 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 829 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 830 return it1_ == it.it1_;
Chris@16 831 }
Chris@16 832 BOOST_UBLAS_INLINE
Chris@16 833 bool operator < (const iterator1 &it) const {
Chris@16 834 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 835 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 836 return it1_ < it.it1_;
Chris@16 837 }
Chris@16 838
Chris@16 839 private:
Chris@16 840 size_type it1_;
Chris@16 841 size_type it2_;
Chris@16 842
Chris@16 843 friend class const_iterator1;
Chris@16 844 };
Chris@16 845 #endif
Chris@16 846
Chris@16 847 BOOST_UBLAS_INLINE
Chris@16 848 iterator1 begin1 () {
Chris@16 849 return find1 (0, 0, 0);
Chris@16 850 }
Chris@16 851 BOOST_UBLAS_INLINE
Chris@16 852 iterator1 end1 () {
Chris@16 853 return find1 (0, size_, 0);
Chris@16 854 }
Chris@16 855
Chris@16 856 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 857 class const_iterator2:
Chris@16 858 public container_const_reference<hermitian_matrix>,
Chris@16 859 public random_access_iterator_base<packed_random_access_iterator_tag,
Chris@16 860 const_iterator2, value_type> {
Chris@16 861 public:
Chris@16 862 typedef typename hermitian_matrix::value_type value_type;
Chris@16 863 typedef typename hermitian_matrix::difference_type difference_type;
Chris@16 864 typedef typename hermitian_matrix::const_reference reference;
Chris@16 865 typedef const typename hermitian_matrix::pointer pointer;
Chris@16 866
Chris@16 867 typedef const_iterator1 dual_iterator_type;
Chris@16 868 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 869
Chris@16 870 // Construction and destruction
Chris@16 871 BOOST_UBLAS_INLINE
Chris@16 872 const_iterator2 ():
Chris@16 873 container_const_reference<self_type> (), it1_ (), it2_ () {}
Chris@16 874 BOOST_UBLAS_INLINE
Chris@16 875 const_iterator2 (const self_type &m, size_type it1, size_type it2):
Chris@16 876 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
Chris@16 877 BOOST_UBLAS_INLINE
Chris@16 878 const_iterator2 (const iterator2 &it):
Chris@16 879 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
Chris@16 880
Chris@16 881 // Arithmetic
Chris@16 882 BOOST_UBLAS_INLINE
Chris@16 883 const_iterator2 &operator ++ () {
Chris@16 884 ++ it2_;
Chris@16 885 return *this;
Chris@16 886 }
Chris@16 887 BOOST_UBLAS_INLINE
Chris@16 888 const_iterator2 &operator -- () {
Chris@16 889 -- it2_;
Chris@16 890 return *this;
Chris@16 891 }
Chris@16 892 BOOST_UBLAS_INLINE
Chris@16 893 const_iterator2 &operator += (difference_type n) {
Chris@16 894 it2_ += n;
Chris@16 895 return *this;
Chris@16 896 }
Chris@16 897 BOOST_UBLAS_INLINE
Chris@16 898 const_iterator2 &operator -= (difference_type n) {
Chris@16 899 it2_ -= n;
Chris@16 900 return *this;
Chris@16 901 }
Chris@16 902 BOOST_UBLAS_INLINE
Chris@16 903 difference_type operator - (const const_iterator2 &it) const {
Chris@16 904 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 905 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 906 return it2_ - it.it2_;
Chris@16 907 }
Chris@16 908
Chris@16 909 // Dereference
Chris@16 910 BOOST_UBLAS_INLINE
Chris@16 911 const_reference operator * () const {
Chris@16 912 return (*this) () (it1_, it2_);
Chris@16 913 }
Chris@16 914 BOOST_UBLAS_INLINE
Chris@16 915 const_reference operator [] (difference_type n) const {
Chris@16 916 return *(*this + n);
Chris@16 917 }
Chris@16 918
Chris@16 919 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 920 BOOST_UBLAS_INLINE
Chris@16 921 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 922 typename self_type::
Chris@16 923 #endif
Chris@16 924 const_iterator1 begin () const {
Chris@16 925 return (*this) ().find1 (1, 0, it2_);
Chris@16 926 }
Chris@16 927 BOOST_UBLAS_INLINE
Chris@16 928 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 929 typename self_type::
Chris@16 930 #endif
Chris@101 931 const_iterator1 cbegin () const {
Chris@101 932 return begin ();
Chris@101 933 }
Chris@101 934 BOOST_UBLAS_INLINE
Chris@101 935 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 936 typename self_type::
Chris@101 937 #endif
Chris@16 938 const_iterator1 end () const {
Chris@16 939 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
Chris@16 940 }
Chris@16 941 BOOST_UBLAS_INLINE
Chris@16 942 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 943 typename self_type::
Chris@16 944 #endif
Chris@101 945 const_iterator1 cend () const {
Chris@101 946 return end ();
Chris@101 947 }
Chris@101 948 BOOST_UBLAS_INLINE
Chris@101 949 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 950 typename self_type::
Chris@101 951 #endif
Chris@16 952 const_reverse_iterator1 rbegin () const {
Chris@16 953 return const_reverse_iterator1 (end ());
Chris@16 954 }
Chris@16 955 BOOST_UBLAS_INLINE
Chris@16 956 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 957 typename self_type::
Chris@16 958 #endif
Chris@101 959 const_iterator1 crbegin () const {
Chris@101 960 return rbegin ();
Chris@101 961 }
Chris@101 962 BOOST_UBLAS_INLINE
Chris@101 963 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 964 typename self_type::
Chris@101 965 #endif
Chris@16 966 const_reverse_iterator1 rend () const {
Chris@16 967 return const_reverse_iterator1 (begin ());
Chris@16 968 }
Chris@101 969 BOOST_UBLAS_INLINE
Chris@101 970 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 971 typename self_type::
Chris@101 972 #endif
Chris@101 973 const_iterator1 crend () const {
Chris@101 974 return rend ();
Chris@101 975 }
Chris@16 976 #endif
Chris@16 977
Chris@16 978 // Indices
Chris@16 979 BOOST_UBLAS_INLINE
Chris@16 980 size_type index1 () const {
Chris@16 981 return it1_;
Chris@16 982 }
Chris@16 983 BOOST_UBLAS_INLINE
Chris@16 984 size_type index2 () const {
Chris@16 985 return it2_;
Chris@16 986 }
Chris@16 987
Chris@16 988 // Assignment
Chris@16 989 BOOST_UBLAS_INLINE
Chris@16 990 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 991 container_const_reference<self_type>::assign (&it ());
Chris@16 992 it1_ = it.it1_;
Chris@16 993 it2_ = it.it2_;
Chris@16 994 return *this;
Chris@16 995 }
Chris@16 996
Chris@16 997 // Comparison
Chris@16 998 BOOST_UBLAS_INLINE
Chris@16 999 bool operator == (const const_iterator2 &it) const {
Chris@16 1000 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1001 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 1002 return it2_ == it.it2_;
Chris@16 1003 }
Chris@16 1004 BOOST_UBLAS_INLINE
Chris@16 1005 bool operator < (const const_iterator2 &it) const {
Chris@16 1006 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1007 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 1008 return it2_ < it.it2_;
Chris@16 1009 }
Chris@16 1010
Chris@16 1011 private:
Chris@16 1012 size_type it1_;
Chris@16 1013 size_type it2_;
Chris@16 1014 };
Chris@16 1015 #endif
Chris@16 1016
Chris@16 1017 BOOST_UBLAS_INLINE
Chris@16 1018 const_iterator2 begin2 () const {
Chris@16 1019 return find2 (0, 0, 0);
Chris@16 1020 }
Chris@16 1021 BOOST_UBLAS_INLINE
Chris@101 1022 const_iterator2 cbegin2 () const {
Chris@101 1023 return begin2 ();
Chris@101 1024 }
Chris@101 1025 BOOST_UBLAS_INLINE
Chris@16 1026 const_iterator2 end2 () const {
Chris@16 1027 return find2 (0, 0, size_);
Chris@16 1028 }
Chris@101 1029 BOOST_UBLAS_INLINE
Chris@101 1030 const_iterator2 cend2 () const {
Chris@101 1031 return end2 ();
Chris@101 1032 }
Chris@16 1033
Chris@16 1034 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1035 class iterator2:
Chris@16 1036 public container_reference<hermitian_matrix>,
Chris@16 1037 public random_access_iterator_base<packed_random_access_iterator_tag,
Chris@16 1038 iterator2, value_type> {
Chris@16 1039 public:
Chris@16 1040 typedef typename hermitian_matrix::value_type value_type;
Chris@16 1041 typedef typename hermitian_matrix::difference_type difference_type;
Chris@16 1042 typedef typename hermitian_matrix::true_reference reference;
Chris@16 1043 typedef typename hermitian_matrix::pointer pointer;
Chris@16 1044
Chris@16 1045 typedef iterator1 dual_iterator_type;
Chris@16 1046 typedef reverse_iterator1 dual_reverse_iterator_type;
Chris@16 1047
Chris@16 1048 // Construction and destruction
Chris@16 1049 BOOST_UBLAS_INLINE
Chris@16 1050 iterator2 ():
Chris@16 1051 container_reference<self_type> (), it1_ (), it2_ () {}
Chris@16 1052 BOOST_UBLAS_INLINE
Chris@16 1053 iterator2 (self_type &m, size_type it1, size_type it2):
Chris@16 1054 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
Chris@16 1055
Chris@16 1056 // Arithmetic
Chris@16 1057 BOOST_UBLAS_INLINE
Chris@16 1058 iterator2 &operator ++ () {
Chris@16 1059 ++ it2_;
Chris@16 1060 return *this;
Chris@16 1061 }
Chris@16 1062 BOOST_UBLAS_INLINE
Chris@16 1063 iterator2 &operator -- () {
Chris@16 1064 -- it2_;
Chris@16 1065 return *this;
Chris@16 1066 }
Chris@16 1067 BOOST_UBLAS_INLINE
Chris@16 1068 iterator2 &operator += (difference_type n) {
Chris@16 1069 it2_ += n;
Chris@16 1070 return *this;
Chris@16 1071 }
Chris@16 1072 BOOST_UBLAS_INLINE
Chris@16 1073 iterator2 &operator -= (difference_type n) {
Chris@16 1074 it2_ -= n;
Chris@16 1075 return *this;
Chris@16 1076 }
Chris@16 1077 BOOST_UBLAS_INLINE
Chris@16 1078 difference_type operator - (const iterator2 &it) const {
Chris@16 1079 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1080 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 1081 return it2_ - it.it2_;
Chris@16 1082 }
Chris@16 1083
Chris@16 1084 // Dereference
Chris@16 1085 BOOST_UBLAS_INLINE
Chris@16 1086 reference operator * () const {
Chris@16 1087 return (*this) ().at_element (it1_, it2_);
Chris@16 1088 }
Chris@16 1089 BOOST_UBLAS_INLINE
Chris@16 1090 reference operator [] (difference_type n) const {
Chris@16 1091 return *(*this + n);
Chris@16 1092 }
Chris@16 1093
Chris@16 1094 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1095 BOOST_UBLAS_INLINE
Chris@16 1096 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1097 typename self_type::
Chris@16 1098 #endif
Chris@16 1099 iterator1 begin () const {
Chris@16 1100 return (*this) ().find1 (1, 0, it2_);
Chris@16 1101 }
Chris@16 1102 BOOST_UBLAS_INLINE
Chris@16 1103 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1104 typename self_type::
Chris@16 1105 #endif
Chris@16 1106 iterator1 end () const {
Chris@16 1107 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
Chris@16 1108 }
Chris@16 1109 BOOST_UBLAS_INLINE
Chris@16 1110 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1111 typename self_type::
Chris@16 1112 #endif
Chris@16 1113 reverse_iterator1 rbegin () const {
Chris@16 1114 return reverse_iterator1 (end ());
Chris@16 1115 }
Chris@16 1116 BOOST_UBLAS_INLINE
Chris@16 1117 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1118 typename self_type::
Chris@16 1119 #endif
Chris@16 1120 reverse_iterator1 rend () const {
Chris@16 1121 return reverse_iterator1 (begin ());
Chris@16 1122 }
Chris@16 1123 #endif
Chris@16 1124
Chris@16 1125 // Indices
Chris@16 1126 BOOST_UBLAS_INLINE
Chris@16 1127 size_type index1 () const {
Chris@16 1128 return it1_;
Chris@16 1129 }
Chris@16 1130 BOOST_UBLAS_INLINE
Chris@16 1131 size_type index2 () const {
Chris@16 1132 return it2_;
Chris@16 1133 }
Chris@16 1134
Chris@16 1135 // Assignment
Chris@16 1136 BOOST_UBLAS_INLINE
Chris@16 1137 iterator2 &operator = (const iterator2 &it) {
Chris@16 1138 container_reference<self_type>::assign (&it ());
Chris@16 1139 it1_ = it.it1_;
Chris@16 1140 it2_ = it.it2_;
Chris@16 1141 return *this;
Chris@16 1142 }
Chris@16 1143
Chris@16 1144 // Comparison
Chris@16 1145 BOOST_UBLAS_INLINE
Chris@16 1146 bool operator == (const iterator2 &it) const {
Chris@16 1147 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1148 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 1149 return it2_ == it.it2_;
Chris@16 1150 }
Chris@16 1151 BOOST_UBLAS_INLINE
Chris@16 1152 bool operator < (const iterator2 &it) const {
Chris@16 1153 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1154 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 1155 return it2_ < it.it2_;
Chris@16 1156 }
Chris@16 1157
Chris@16 1158 private:
Chris@16 1159 size_type it1_;
Chris@16 1160 size_type it2_;
Chris@16 1161
Chris@16 1162 friend class const_iterator2;
Chris@16 1163 };
Chris@16 1164 #endif
Chris@16 1165
Chris@16 1166 BOOST_UBLAS_INLINE
Chris@16 1167 iterator2 begin2 () {
Chris@16 1168 return find2 (0, 0, 0);
Chris@16 1169 }
Chris@16 1170 BOOST_UBLAS_INLINE
Chris@16 1171 iterator2 end2 () {
Chris@16 1172 return find2 (0, 0, size_);
Chris@16 1173 }
Chris@16 1174
Chris@16 1175 // Reverse iterators
Chris@16 1176
Chris@16 1177 BOOST_UBLAS_INLINE
Chris@16 1178 const_reverse_iterator1 rbegin1 () const {
Chris@16 1179 return const_reverse_iterator1 (end1 ());
Chris@16 1180 }
Chris@16 1181 BOOST_UBLAS_INLINE
Chris@101 1182 const_reverse_iterator1 crbegin1 () const {
Chris@101 1183 return rbegin1 ();
Chris@101 1184 }
Chris@101 1185 BOOST_UBLAS_INLINE
Chris@16 1186 const_reverse_iterator1 rend1 () const {
Chris@16 1187 return const_reverse_iterator1 (begin1 ());
Chris@16 1188 }
Chris@101 1189 BOOST_UBLAS_INLINE
Chris@101 1190 const_reverse_iterator1 crend1 () const {
Chris@101 1191 return rend1 ();
Chris@101 1192 }
Chris@16 1193
Chris@16 1194 BOOST_UBLAS_INLINE
Chris@16 1195 reverse_iterator1 rbegin1 () {
Chris@16 1196 return reverse_iterator1 (end1 ());
Chris@16 1197 }
Chris@16 1198 BOOST_UBLAS_INLINE
Chris@16 1199 reverse_iterator1 rend1 () {
Chris@16 1200 return reverse_iterator1 (begin1 ());
Chris@16 1201 }
Chris@16 1202
Chris@16 1203 BOOST_UBLAS_INLINE
Chris@16 1204 const_reverse_iterator2 rbegin2 () const {
Chris@16 1205 return const_reverse_iterator2 (end2 ());
Chris@16 1206 }
Chris@16 1207 BOOST_UBLAS_INLINE
Chris@101 1208 const_reverse_iterator2 crbegin2 () const {
Chris@101 1209 return rbegin2();
Chris@101 1210 }
Chris@101 1211 BOOST_UBLAS_INLINE
Chris@16 1212 const_reverse_iterator2 rend2 () const {
Chris@16 1213 return const_reverse_iterator2 (begin2 ());
Chris@16 1214 }
Chris@101 1215 BOOST_UBLAS_INLINE
Chris@101 1216 const_reverse_iterator2 crend2 () const {
Chris@101 1217 return rend2 ();
Chris@101 1218 }
Chris@16 1219
Chris@16 1220 BOOST_UBLAS_INLINE
Chris@16 1221 reverse_iterator2 rbegin2 () {
Chris@16 1222 return reverse_iterator2 (end2 ());
Chris@16 1223 }
Chris@16 1224 BOOST_UBLAS_INLINE
Chris@16 1225 reverse_iterator2 rend2 () {
Chris@16 1226 return reverse_iterator2 (begin2 ());
Chris@16 1227 }
Chris@16 1228
Chris@16 1229 private:
Chris@16 1230 size_type size_;
Chris@16 1231 array_type data_;
Chris@16 1232 };
Chris@16 1233
Chris@16 1234 /** \brief A Hermitian matrix adaptator: convert a any matrix into a Hermitian matrix expression
Chris@16 1235 *
Chris@16 1236 * For a \f$(m\times n)\f$-dimensional matrix, the \c hermitian_adaptor will provide a hermitian matrix.
Chris@16 1237 * Storage and location are based on those of the underlying matrix. This is important because
Chris@16 1238 * a \c hermitian_adaptor does not copy the matrix data to a new place. Therefore, modifying values
Chris@16 1239 * in a \c hermitian_adaptor matrix will also modify the underlying matrix too.
Chris@16 1240 *
Chris@16 1241 * \tparam M the type of matrix used to generate a hermitian matrix
Chris@16 1242 */
Chris@16 1243 template<class M, class TRI>
Chris@16 1244 class hermitian_adaptor:
Chris@16 1245 public matrix_expression<hermitian_adaptor<M, TRI> > {
Chris@16 1246
Chris@16 1247 typedef hermitian_adaptor<M, TRI> self_type;
Chris@16 1248 typedef typename M::value_type &true_reference;
Chris@16 1249 public:
Chris@16 1250 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 1251 using matrix_expression<self_type>::operator ();
Chris@16 1252 #endif
Chris@16 1253 typedef const M const_matrix_type;
Chris@16 1254 typedef M matrix_type;
Chris@16 1255 typedef TRI triangular_type;
Chris@16 1256 typedef typename M::size_type size_type;
Chris@16 1257 typedef typename M::difference_type difference_type;
Chris@16 1258 typedef typename M::value_type value_type;
Chris@16 1259 typedef typename M::value_type const_reference;
Chris@16 1260 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
Chris@16 1261 typedef typename boost::mpl::if_<boost::is_const<M>,
Chris@16 1262 typename M::value_type,
Chris@16 1263 typename M::reference>::type reference;
Chris@16 1264 #else
Chris@16 1265 typedef typename boost::mpl::if_<boost::is_const<M>,
Chris@16 1266 typename M::value_type,
Chris@16 1267 hermitian_matrix_element<self_type> >::type reference;
Chris@16 1268 #endif
Chris@16 1269 typedef typename boost::mpl::if_<boost::is_const<M>,
Chris@16 1270 typename M::const_closure_type,
Chris@16 1271 typename M::closure_type>::type matrix_closure_type;
Chris@16 1272 typedef const self_type const_closure_type;
Chris@16 1273 typedef self_type closure_type;
Chris@16 1274 // Replaced by _temporary_traits to avoid type requirements on M
Chris@16 1275 //typedef typename M::vector_temporary_type vector_temporary_type;
Chris@16 1276 //typedef typename M::matrix_temporary_type matrix_temporary_type;
Chris@16 1277 typedef typename storage_restrict_traits<typename M::storage_category,
Chris@16 1278 packed_proxy_tag>::storage_category storage_category;
Chris@16 1279 typedef typename M::orientation_category orientation_category;
Chris@16 1280
Chris@16 1281 // Construction and destruction
Chris@16 1282 BOOST_UBLAS_INLINE
Chris@16 1283 hermitian_adaptor (matrix_type &data):
Chris@16 1284 matrix_expression<self_type> (),
Chris@16 1285 data_ (data) {
Chris@16 1286 BOOST_UBLAS_CHECK (data_.size1 () == data_.size2 (), bad_size ());
Chris@16 1287 }
Chris@16 1288 BOOST_UBLAS_INLINE
Chris@16 1289 hermitian_adaptor (const hermitian_adaptor &m):
Chris@16 1290 matrix_expression<self_type> (),
Chris@16 1291 data_ (m.data_) {
Chris@16 1292 BOOST_UBLAS_CHECK (data_.size1 () == data_.size2 (), bad_size ());
Chris@16 1293 }
Chris@16 1294
Chris@16 1295 // Accessors
Chris@16 1296 BOOST_UBLAS_INLINE
Chris@16 1297 size_type size1 () const {
Chris@16 1298 return data_.size1 ();
Chris@16 1299 }
Chris@16 1300 BOOST_UBLAS_INLINE
Chris@16 1301 size_type size2 () const {
Chris@16 1302 return data_.size2 ();
Chris@16 1303 }
Chris@16 1304
Chris@16 1305 // Storage accessors
Chris@16 1306 BOOST_UBLAS_INLINE
Chris@16 1307 const matrix_closure_type &data () const {
Chris@16 1308 return data_;
Chris@16 1309 }
Chris@16 1310 BOOST_UBLAS_INLINE
Chris@16 1311 matrix_closure_type &data () {
Chris@16 1312 return data_;
Chris@16 1313 }
Chris@16 1314
Chris@16 1315 // Element access
Chris@16 1316 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
Chris@16 1317 BOOST_UBLAS_INLINE
Chris@16 1318 const_reference operator () (size_type i, size_type j) const {
Chris@16 1319 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
Chris@16 1320 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
Chris@16 1321 // if (i == j)
Chris@16 1322 // return type_traits<value_type>::real (data () (i, i));
Chris@16 1323 // else
Chris@16 1324 if (triangular_type::other (i, j))
Chris@16 1325 return data () (i, j);
Chris@16 1326 else
Chris@16 1327 return type_traits<value_type>::conj (data () (j, i));
Chris@16 1328 }
Chris@16 1329 BOOST_UBLAS_INLINE
Chris@16 1330 reference operator () (size_type i, size_type j) {
Chris@16 1331 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
Chris@16 1332 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
Chris@16 1333 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
Chris@16 1334 if (triangular_type::other (i, j))
Chris@16 1335 return data () (i, j);
Chris@16 1336 else {
Chris@16 1337 external_logic ().raise ();
Chris@16 1338 return conj_ = type_traits<value_type>::conj (data () (j, i));
Chris@16 1339 }
Chris@16 1340 #else
Chris@16 1341 if (triangular_type::other (i, j))
Chris@16 1342 return reference (*this, i, j, data () (i, j));
Chris@16 1343 else
Chris@16 1344 return reference (*this, i, j, type_traits<value_type>::conj (data () (j, i)));
Chris@16 1345 #endif
Chris@16 1346 }
Chris@16 1347 BOOST_UBLAS_INLINE
Chris@16 1348 true_reference insert_element (size_type i, size_type j, value_type t) {
Chris@16 1349 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
Chris@16 1350 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
Chris@16 1351 // if (i == j)
Chris@16 1352 // data () (i, i) = type_traits<value_type>::real (t);
Chris@16 1353 // else
Chris@16 1354 if (triangular_type::other (i, j))
Chris@16 1355 return data () (i, j) = t;
Chris@16 1356 else
Chris@16 1357 return data () (j, i) = type_traits<value_type>::conj (t);
Chris@16 1358 }
Chris@16 1359 #else
Chris@16 1360 BOOST_UBLAS_INLINE
Chris@16 1361 reference operator () (size_type i, size_type j) {
Chris@16 1362 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
Chris@16 1363 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
Chris@16 1364 #ifndef BOOST_UBLAS_STRICT_HERMITIAN
Chris@16 1365 if (triangular_type::other (i, j))
Chris@16 1366 return data () (i, j);
Chris@16 1367 else {
Chris@16 1368 external_logic ().raise ();
Chris@16 1369 return conj_ = type_traits<value_type>::conj (data () (j, i));
Chris@16 1370 }
Chris@16 1371 #else
Chris@16 1372 if (triangular_type::other (i, j))
Chris@16 1373 return reference (*this, i, j, data () (i, j));
Chris@16 1374 else
Chris@16 1375 return reference (*this, i, j, type_traits<value_type>::conj (data () (j, i)));
Chris@16 1376 #endif
Chris@16 1377 }
Chris@16 1378 BOOST_UBLAS_INLINE
Chris@16 1379 true_reference insert_element (size_type i, size_type j, value_type t) {
Chris@16 1380 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
Chris@16 1381 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
Chris@16 1382 // if (i == j)
Chris@16 1383 // data () (i, i) = type_traits<value_type>::real (t);
Chris@16 1384 // else
Chris@16 1385 if (triangular_type::other (i, j))
Chris@16 1386 return data () (i, j) = t;
Chris@16 1387 else
Chris@16 1388 return data () (j, i) = type_traits<value_type>::conj (t);
Chris@16 1389 }
Chris@16 1390 #endif
Chris@16 1391
Chris@16 1392 // Assignment
Chris@16 1393 BOOST_UBLAS_INLINE
Chris@16 1394 hermitian_adaptor &operator = (const hermitian_adaptor &m) {
Chris@16 1395 matrix_assign<scalar_assign, triangular_type> (*this, m);
Chris@16 1396 return *this;
Chris@16 1397 }
Chris@16 1398 BOOST_UBLAS_INLINE
Chris@16 1399 hermitian_adaptor &assign_temporary (hermitian_adaptor &m) {
Chris@16 1400 *this = m;
Chris@16 1401 return *this;
Chris@16 1402 }
Chris@16 1403 template<class AE>
Chris@16 1404 BOOST_UBLAS_INLINE
Chris@16 1405 hermitian_adaptor &operator = (const matrix_expression<AE> &ae) {
Chris@16 1406 matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (ae));
Chris@16 1407 return *this;
Chris@16 1408 }
Chris@16 1409 template<class AE>
Chris@16 1410 BOOST_UBLAS_INLINE
Chris@16 1411 hermitian_adaptor &assign (const matrix_expression<AE> &ae) {
Chris@16 1412 matrix_assign<scalar_assign, triangular_type> (*this, ae);
Chris@16 1413 return *this;
Chris@16 1414 }
Chris@16 1415 template<class AE>
Chris@16 1416 BOOST_UBLAS_INLINE
Chris@16 1417 hermitian_adaptor& operator += (const matrix_expression<AE> &ae) {
Chris@16 1418 matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (*this + ae));
Chris@16 1419 return *this;
Chris@16 1420 }
Chris@16 1421 template<class AE>
Chris@16 1422 BOOST_UBLAS_INLINE
Chris@16 1423 hermitian_adaptor &plus_assign (const matrix_expression<AE> &ae) {
Chris@16 1424 matrix_assign<scalar_plus_assign, triangular_type> (*this, ae);
Chris@16 1425 return *this;
Chris@16 1426 }
Chris@16 1427 template<class AE>
Chris@16 1428 BOOST_UBLAS_INLINE
Chris@16 1429 hermitian_adaptor& operator -= (const matrix_expression<AE> &ae) {
Chris@16 1430 matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (*this - ae));
Chris@16 1431 return *this;
Chris@16 1432 }
Chris@16 1433 template<class AE>
Chris@16 1434 BOOST_UBLAS_INLINE
Chris@16 1435 hermitian_adaptor &minus_assign (const matrix_expression<AE> &ae) {
Chris@16 1436 matrix_assign<scalar_minus_assign, triangular_type> (*this, ae);
Chris@16 1437 return *this;
Chris@16 1438 }
Chris@16 1439 template<class AT>
Chris@16 1440 BOOST_UBLAS_INLINE
Chris@16 1441 hermitian_adaptor& operator *= (const AT &at) {
Chris@16 1442 // Multiplication is only allowed for real scalars,
Chris@16 1443 // otherwise the resulting matrix isn't hermitian.
Chris@16 1444 // Thanks to Peter Schmitteckert for spotting this.
Chris@16 1445 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
Chris@16 1446 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 1447 return *this;
Chris@16 1448 }
Chris@16 1449 template<class AT>
Chris@16 1450 BOOST_UBLAS_INLINE
Chris@16 1451 hermitian_adaptor& operator /= (const AT &at) {
Chris@16 1452 // Multiplication is only allowed for real scalars,
Chris@16 1453 // otherwise the resulting matrix isn't hermitian.
Chris@16 1454 // Thanks to Peter Schmitteckert for spotting this.
Chris@16 1455 BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
Chris@16 1456 matrix_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 1457 return *this;
Chris@16 1458 }
Chris@16 1459
Chris@16 1460 // Closure comparison
Chris@16 1461 BOOST_UBLAS_INLINE
Chris@16 1462 bool same_closure (const hermitian_adaptor &ha) const {
Chris@16 1463 return (*this).data ().same_closure (ha.data ());
Chris@16 1464 }
Chris@16 1465
Chris@16 1466 // Swapping
Chris@16 1467 BOOST_UBLAS_INLINE
Chris@16 1468 void swap (hermitian_adaptor &m) {
Chris@16 1469 if (this != &m)
Chris@16 1470 matrix_swap<scalar_swap, triangular_type> (*this, m);
Chris@16 1471 }
Chris@16 1472 BOOST_UBLAS_INLINE
Chris@16 1473 friend void swap (hermitian_adaptor &m1, hermitian_adaptor &m2) {
Chris@16 1474 m1.swap (m2);
Chris@16 1475 }
Chris@16 1476
Chris@16 1477 // Iterator types
Chris@16 1478 private:
Chris@16 1479 // Use matrix iterator
Chris@16 1480 typedef typename M::const_iterator1 const_subiterator1_type;
Chris@16 1481 typedef typename boost::mpl::if_<boost::is_const<M>,
Chris@16 1482 typename M::const_iterator1,
Chris@16 1483 typename M::iterator1>::type subiterator1_type;
Chris@16 1484 typedef typename M::const_iterator2 const_subiterator2_type;
Chris@16 1485 typedef typename boost::mpl::if_<boost::is_const<M>,
Chris@16 1486 typename M::const_iterator2,
Chris@16 1487 typename M::iterator2>::type subiterator2_type;
Chris@16 1488
Chris@16 1489 public:
Chris@16 1490 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1491 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
Chris@16 1492 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
Chris@16 1493 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
Chris@16 1494 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
Chris@16 1495 #else
Chris@16 1496 class const_iterator1;
Chris@16 1497 class iterator1;
Chris@16 1498 class const_iterator2;
Chris@16 1499 class iterator2;
Chris@16 1500 #endif
Chris@16 1501 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 1502 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
Chris@16 1503 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 1504 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
Chris@16 1505
Chris@16 1506 // Element lookup
Chris@16 1507 BOOST_UBLAS_INLINE
Chris@16 1508 const_iterator1 find1 (int rank, size_type i, size_type j) const {
Chris@16 1509 if (triangular_type::other (i, j)) {
Chris@16 1510 if (triangular_type::other (size1 (), j)) {
Chris@16 1511 return const_iterator1 (*this, 0, 0,
Chris@16 1512 data ().find1 (rank, i, j), data ().find1 (rank, size1 (), j),
Chris@16 1513 data ().find2 (rank, size2 (), size1 ()), data ().find2 (rank, size2 (), size1 ()));
Chris@16 1514 } else {
Chris@16 1515 return const_iterator1 (*this, 0, 1,
Chris@16 1516 data ().find1 (rank, i, j), data ().find1 (rank, j, j),
Chris@16 1517 data ().find2 (rank, j, j), data ().find2 (rank, j, size1 ()));
Chris@16 1518 }
Chris@16 1519 } else {
Chris@16 1520 if (triangular_type::other (size1 (), j)) {
Chris@16 1521 return const_iterator1 (*this, 1, 0,
Chris@16 1522 data ().find1 (rank, j, j), data ().find1 (rank, size1 (), j),
Chris@16 1523 data ().find2 (rank, j, i), data ().find2 (rank, j, j));
Chris@16 1524 } else {
Chris@16 1525 return const_iterator1 (*this, 1, 1,
Chris@16 1526 data ().find1 (rank, size1 (), size2 ()), data ().find1 (rank, size1 (), size2 ()),
Chris@16 1527 data ().find2 (rank, j, i), data ().find2 (rank, j, size1 ()));
Chris@16 1528 }
Chris@16 1529 }
Chris@16 1530 }
Chris@16 1531 BOOST_UBLAS_INLINE
Chris@16 1532 iterator1 find1 (int rank, size_type i, size_type j) {
Chris@16 1533 if (rank == 1)
Chris@16 1534 i = triangular_type::mutable_restrict1 (i, j, size1(), size2());
Chris@16 1535 if (rank == 0)
Chris@16 1536 i = triangular_type::global_mutable_restrict1 (i, size1(), j, size2());
Chris@16 1537 return iterator1 (*this, data ().find1 (rank, i, j));
Chris@16 1538 }
Chris@16 1539 BOOST_UBLAS_INLINE
Chris@16 1540 const_iterator2 find2 (int rank, size_type i, size_type j) const {
Chris@16 1541 if (triangular_type::other (i, j)) {
Chris@16 1542 if (triangular_type::other (i, size2 ())) {
Chris@16 1543 return const_iterator2 (*this, 1, 1,
Chris@16 1544 data ().find1 (rank, size2 (), size1 ()), data ().find1 (rank, size2 (), size1 ()),
Chris@16 1545 data ().find2 (rank, i, j), data ().find2 (rank, i, size2 ()));
Chris@16 1546 } else {
Chris@16 1547 return const_iterator2 (*this, 1, 0,
Chris@16 1548 data ().find1 (rank, i, i), data ().find1 (rank, size2 (), i),
Chris@16 1549 data ().find2 (rank, i, j), data ().find2 (rank, i, i));
Chris@16 1550 }
Chris@16 1551 } else {
Chris@16 1552 if (triangular_type::other (i, size2 ())) {
Chris@16 1553 return const_iterator2 (*this, 0, 1,
Chris@16 1554 data ().find1 (rank, j, i), data ().find1 (rank, i, i),
Chris@16 1555 data ().find2 (rank, i, i), data ().find2 (rank, i, size2 ()));
Chris@16 1556 } else {
Chris@16 1557 return const_iterator2 (*this, 0, 0,
Chris@16 1558 data ().find1 (rank, j, i), data ().find1 (rank, size2 (), i),
Chris@16 1559 data ().find2 (rank, size1 (), size2 ()), data ().find2 (rank, size2 (), size2 ()));
Chris@16 1560 }
Chris@16 1561 }
Chris@16 1562 }
Chris@16 1563 BOOST_UBLAS_INLINE
Chris@16 1564 iterator2 find2 (int rank, size_type i, size_type j) {
Chris@16 1565 if (rank == 1)
Chris@16 1566 j = triangular_type::mutable_restrict2 (i, j, size1(), size2());
Chris@16 1567 if (rank == 0)
Chris@16 1568 j = triangular_type::global_mutable_restrict2 (i, size1(), j, size2());
Chris@16 1569 return iterator2 (*this, data ().find2 (rank, i, j));
Chris@16 1570 }
Chris@16 1571
Chris@16 1572 // Iterators simply are indices.
Chris@16 1573
Chris@16 1574 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1575 class const_iterator1:
Chris@16 1576 public container_const_reference<hermitian_adaptor>,
Chris@16 1577 public random_access_iterator_base<typename iterator_restrict_traits<
Chris@16 1578 typename const_subiterator1_type::iterator_category, dense_random_access_iterator_tag>::iterator_category,
Chris@16 1579 const_iterator1, value_type> {
Chris@16 1580 public:
Chris@16 1581 typedef typename const_subiterator1_type::value_type value_type;
Chris@16 1582 typedef typename const_subiterator1_type::difference_type difference_type;
Chris@16 1583 // FIXME no better way to not return the address of a temporary?
Chris@16 1584 // typedef typename const_subiterator1_type::reference reference;
Chris@16 1585 typedef typename const_subiterator1_type::value_type reference;
Chris@16 1586 typedef typename const_subiterator1_type::pointer pointer;
Chris@16 1587
Chris@16 1588 typedef const_iterator2 dual_iterator_type;
Chris@16 1589 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 1590
Chris@16 1591 // Construction and destruction
Chris@16 1592 BOOST_UBLAS_INLINE
Chris@16 1593 const_iterator1 ():
Chris@16 1594 container_const_reference<self_type> (),
Chris@16 1595 begin_ (-1), end_ (-1), current_ (-1),
Chris@16 1596 it1_begin_ (), it1_end_ (), it1_ (),
Chris@16 1597 it2_begin_ (), it2_end_ (), it2_ () {}
Chris@16 1598 BOOST_UBLAS_INLINE
Chris@16 1599 const_iterator1 (const self_type &m, int begin, int end,
Chris@16 1600 const const_subiterator1_type &it1_begin, const const_subiterator1_type &it1_end,
Chris@16 1601 const const_subiterator2_type &it2_begin, const const_subiterator2_type &it2_end):
Chris@16 1602 container_const_reference<self_type> (m),
Chris@16 1603 begin_ (begin), end_ (end), current_ (begin),
Chris@16 1604 it1_begin_ (it1_begin), it1_end_ (it1_end), it1_ (it1_begin_),
Chris@16 1605 it2_begin_ (it2_begin), it2_end_ (it2_end), it2_ (it2_begin_) {
Chris@16 1606 if (current_ == 0 && it1_ == it1_end_)
Chris@16 1607 current_ = 1;
Chris@16 1608 if (current_ == 1 && it2_ == it2_end_)
Chris@16 1609 current_ = 0;
Chris@16 1610 if ((current_ == 0 && it1_ == it1_end_) ||
Chris@16 1611 (current_ == 1 && it2_ == it2_end_))
Chris@16 1612 current_ = end_;
Chris@16 1613 BOOST_UBLAS_CHECK (current_ == end_ ||
Chris@16 1614 (current_ == 0 && it1_ != it1_end_) ||
Chris@16 1615 (current_ == 1 && it2_ != it2_end_), internal_logic ());
Chris@16 1616 }
Chris@16 1617 // FIXME cannot compile
Chris@16 1618 // iterator1 does not have these members!
Chris@16 1619 BOOST_UBLAS_INLINE
Chris@16 1620 const_iterator1 (const iterator1 &it):
Chris@16 1621 container_const_reference<self_type> (it ()),
Chris@16 1622 begin_ (it.begin_), end_ (it.end_), current_ (it.current_),
Chris@16 1623 it1_begin_ (it.it1_begin_), it1_end_ (it.it1_end_), it1_ (it.it1_),
Chris@16 1624 it2_begin_ (it.it2_begin_), it2_end_ (it.it2_end_), it2_ (it.it2_) {
Chris@16 1625 BOOST_UBLAS_CHECK (current_ == end_ ||
Chris@16 1626 (current_ == 0 && it1_ != it1_end_) ||
Chris@16 1627 (current_ == 1 && it2_ != it2_end_), internal_logic ());
Chris@16 1628 }
Chris@16 1629
Chris@16 1630 // Arithmetic
Chris@16 1631 BOOST_UBLAS_INLINE
Chris@16 1632 const_iterator1 &operator ++ () {
Chris@16 1633 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 1634 if (current_ == 0) {
Chris@16 1635 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
Chris@16 1636 ++ it1_;
Chris@16 1637 if (it1_ == it1_end_ && end_ == 1) {
Chris@16 1638 it2_ = it2_begin_;
Chris@16 1639 current_ = 1;
Chris@16 1640 }
Chris@16 1641 } else /* if (current_ == 1) */ {
Chris@16 1642 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
Chris@16 1643 ++ it2_;
Chris@16 1644 if (it2_ == it2_end_ && end_ == 0) {
Chris@16 1645 it1_ = it1_begin_;
Chris@16 1646 current_ = 0;
Chris@16 1647 }
Chris@16 1648 }
Chris@16 1649 return *this;
Chris@16 1650 }
Chris@16 1651 BOOST_UBLAS_INLINE
Chris@16 1652 const_iterator1 &operator -- () {
Chris@16 1653 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 1654 if (current_ == 0) {
Chris@16 1655 if (it1_ == it1_begin_ && begin_ == 1) {
Chris@16 1656 it2_ = it2_end_;
Chris@16 1657 BOOST_UBLAS_CHECK (it2_ != it2_begin_, internal_logic ());
Chris@16 1658 -- it2_;
Chris@16 1659 current_ = 1;
Chris@16 1660 } else {
Chris@16 1661 -- it1_;
Chris@16 1662 }
Chris@16 1663 } else /* if (current_ == 1) */ {
Chris@16 1664 if (it2_ == it2_begin_ && begin_ == 0) {
Chris@16 1665 it1_ = it1_end_;
Chris@16 1666 BOOST_UBLAS_CHECK (it1_ != it1_begin_, internal_logic ());
Chris@16 1667 -- it1_;
Chris@16 1668 current_ = 0;
Chris@16 1669 } else {
Chris@16 1670 -- it2_;
Chris@16 1671 }
Chris@16 1672 }
Chris@16 1673 return *this;
Chris@16 1674 }
Chris@16 1675 BOOST_UBLAS_INLINE
Chris@16 1676 const_iterator1 &operator += (difference_type n) {
Chris@16 1677 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 1678 if (current_ == 0) {
Chris@16 1679 size_type d = (std::min) (n, it1_end_ - it1_);
Chris@16 1680 it1_ += d;
Chris@16 1681 n -= d;
Chris@16 1682 if (n > 0 || (end_ == 1 && it1_ == it1_end_)) {
Chris@16 1683 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
Chris@16 1684 d = (std::min) (n, it2_end_ - it2_begin_);
Chris@16 1685 it2_ = it2_begin_ + d;
Chris@16 1686 n -= d;
Chris@16 1687 current_ = 1;
Chris@16 1688 }
Chris@16 1689 } else /* if (current_ == 1) */ {
Chris@16 1690 size_type d = (std::min) (n, it2_end_ - it2_);
Chris@16 1691 it2_ += d;
Chris@16 1692 n -= d;
Chris@16 1693 if (n > 0 || (end_ == 0 && it2_ == it2_end_)) {
Chris@16 1694 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
Chris@16 1695 d = (std::min) (n, it1_end_ - it1_begin_);
Chris@16 1696 it1_ = it1_begin_ + d;
Chris@16 1697 n -= d;
Chris@16 1698 current_ = 0;
Chris@16 1699 }
Chris@16 1700 }
Chris@16 1701 BOOST_UBLAS_CHECK (n == 0, external_logic ());
Chris@16 1702 return *this;
Chris@16 1703 }
Chris@16 1704 BOOST_UBLAS_INLINE
Chris@16 1705 const_iterator1 &operator -= (difference_type n) {
Chris@16 1706 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 1707 if (current_ == 0) {
Chris@16 1708 size_type d = (std::min) (n, it1_ - it1_begin_);
Chris@16 1709 it1_ -= d;
Chris@16 1710 n -= d;
Chris@16 1711 if (n > 0) {
Chris@16 1712 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
Chris@16 1713 d = (std::min) (n, it2_end_ - it2_begin_);
Chris@16 1714 it2_ = it2_end_ - d;
Chris@16 1715 n -= d;
Chris@16 1716 current_ = 1;
Chris@16 1717 }
Chris@16 1718 } else /* if (current_ == 1) */ {
Chris@16 1719 size_type d = (std::min) (n, it2_ - it2_begin_);
Chris@16 1720 it2_ -= d;
Chris@16 1721 n -= d;
Chris@16 1722 if (n > 0) {
Chris@16 1723 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
Chris@16 1724 d = (std::min) (n, it1_end_ - it1_begin_);
Chris@16 1725 it1_ = it1_end_ - d;
Chris@16 1726 n -= d;
Chris@16 1727 current_ = 0;
Chris@16 1728 }
Chris@16 1729 }
Chris@16 1730 BOOST_UBLAS_CHECK (n == 0, external_logic ());
Chris@16 1731 return *this;
Chris@16 1732 }
Chris@16 1733 BOOST_UBLAS_INLINE
Chris@16 1734 difference_type operator - (const const_iterator1 &it) const {
Chris@16 1735 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1736 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 1737 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
Chris@16 1738 BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
Chris@16 1739 if (current_ == 0 && it.current_ == 0) {
Chris@16 1740 return it1_ - it.it1_;
Chris@16 1741 } else if (current_ == 0 && it.current_ == 1) {
Chris@16 1742 if (end_ == 1 && it.end_ == 1) {
Chris@16 1743 return (it1_ - it.it1_end_) + (it.it2_begin_ - it.it2_);
Chris@16 1744 } else /* if (end_ == 0 && it.end_ == 0) */ {
Chris@16 1745 return (it1_ - it.it1_begin_) + (it.it2_end_ - it.it2_);
Chris@16 1746 }
Chris@16 1747
Chris@16 1748 } else if (current_ == 1 && it.current_ == 0) {
Chris@16 1749 if (end_ == 1 && it.end_ == 1) {
Chris@16 1750 return (it2_ - it.it2_begin_) + (it.it1_end_ - it.it1_);
Chris@16 1751 } else /* if (end_ == 0 && it.end_ == 0) */ {
Chris@16 1752 return (it2_ - it.it2_end_) + (it.it1_begin_ - it.it1_);
Chris@16 1753 }
Chris@16 1754 } else /* if (current_ == 1 && it.current_ == 1) */ {
Chris@16 1755 return it2_ - it.it2_;
Chris@16 1756 }
Chris@16 1757 }
Chris@16 1758
Chris@16 1759 // Dereference
Chris@16 1760 BOOST_UBLAS_INLINE
Chris@16 1761 const_reference operator * () const {
Chris@16 1762 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 1763 if (current_ == 0) {
Chris@16 1764 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
Chris@16 1765 if (triangular_type::other (index1 (), index2 ()))
Chris@16 1766 return *it1_;
Chris@16 1767 else
Chris@16 1768 return type_traits<value_type>::conj (*it1_);
Chris@16 1769 } else /* if (current_ == 1) */ {
Chris@16 1770 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
Chris@16 1771 if (triangular_type::other (index1 (), index2 ()))
Chris@16 1772 return *it2_;
Chris@16 1773 else
Chris@16 1774 return type_traits<value_type>::conj (*it2_);
Chris@16 1775 }
Chris@16 1776 }
Chris@16 1777 BOOST_UBLAS_INLINE
Chris@16 1778 const_reference operator [] (difference_type n) const {
Chris@16 1779 return *(*this + n);
Chris@16 1780 }
Chris@16 1781
Chris@16 1782 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1783 BOOST_UBLAS_INLINE
Chris@16 1784 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1785 typename self_type::
Chris@16 1786 #endif
Chris@16 1787 const_iterator2 begin () const {
Chris@16 1788 return (*this) ().find2 (1, index1 (), 0);
Chris@16 1789 }
Chris@16 1790 BOOST_UBLAS_INLINE
Chris@16 1791 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1792 typename self_type::
Chris@16 1793 #endif
Chris@101 1794 const_iterator2 cbegin () const {
Chris@101 1795 return begin ();
Chris@101 1796 }
Chris@101 1797 BOOST_UBLAS_INLINE
Chris@101 1798 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1799 typename self_type::
Chris@101 1800 #endif
Chris@16 1801 const_iterator2 end () const {
Chris@16 1802 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
Chris@16 1803 }
Chris@16 1804 BOOST_UBLAS_INLINE
Chris@16 1805 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1806 typename self_type::
Chris@16 1807 #endif
Chris@101 1808 const_iterator2 cend () const {
Chris@101 1809 return end ();
Chris@101 1810 }
Chris@101 1811 BOOST_UBLAS_INLINE
Chris@101 1812 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1813 typename self_type::
Chris@101 1814 #endif
Chris@16 1815 const_reverse_iterator2 rbegin () const {
Chris@16 1816 return const_reverse_iterator2 (end ());
Chris@16 1817 }
Chris@16 1818 BOOST_UBLAS_INLINE
Chris@16 1819 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1820 typename self_type::
Chris@16 1821 #endif
Chris@101 1822 const_reverse_iterator2 crbegin () const {
Chris@101 1823 return rbegin ();
Chris@101 1824 }
Chris@101 1825 BOOST_UBLAS_INLINE
Chris@101 1826 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1827 typename self_type::
Chris@101 1828 #endif
Chris@16 1829 const_reverse_iterator2 rend () const {
Chris@16 1830 return const_reverse_iterator2 (begin ());
Chris@16 1831 }
Chris@101 1832 BOOST_UBLAS_INLINE
Chris@101 1833 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1834 typename self_type::
Chris@101 1835 #endif
Chris@101 1836 const_reverse_iterator2 crend () const {
Chris@101 1837 return rend ();
Chris@101 1838 }
Chris@16 1839 #endif
Chris@16 1840
Chris@16 1841 // Indices
Chris@16 1842 BOOST_UBLAS_INLINE
Chris@16 1843 size_type index1 () const {
Chris@16 1844 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 1845 if (current_ == 0) {
Chris@16 1846 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
Chris@16 1847 return it1_.index1 ();
Chris@16 1848 } else /* if (current_ == 1) */ {
Chris@16 1849 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
Chris@16 1850 return it2_.index2 ();
Chris@16 1851 }
Chris@16 1852 }
Chris@16 1853 BOOST_UBLAS_INLINE
Chris@16 1854 size_type index2 () const {
Chris@16 1855 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 1856 if (current_ == 0) {
Chris@16 1857 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
Chris@16 1858 return it1_.index2 ();
Chris@16 1859 } else /* if (current_ == 1) */ {
Chris@16 1860 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
Chris@16 1861 return it2_.index1 ();
Chris@16 1862 }
Chris@16 1863 }
Chris@16 1864
Chris@16 1865 // Assignment
Chris@16 1866 BOOST_UBLAS_INLINE
Chris@16 1867 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 1868 container_const_reference<self_type>::assign (&it ());
Chris@16 1869 begin_ = it.begin_;
Chris@16 1870 end_ = it.end_;
Chris@16 1871 current_ = it.current_;
Chris@16 1872 it1_begin_ = it.it1_begin_;
Chris@16 1873 it1_end_ = it.it1_end_;
Chris@16 1874 it1_ = it.it1_;
Chris@16 1875 it2_begin_ = it.it2_begin_;
Chris@16 1876 it2_end_ = it.it2_end_;
Chris@16 1877 it2_ = it.it2_;
Chris@16 1878 return *this;
Chris@16 1879 }
Chris@16 1880
Chris@16 1881 // Comparison
Chris@16 1882 BOOST_UBLAS_INLINE
Chris@16 1883 bool operator == (const const_iterator1 &it) const {
Chris@16 1884 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1885 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 1886 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
Chris@16 1887 BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
Chris@16 1888 return (current_ == 0 && it.current_ == 0 && it1_ == it.it1_) ||
Chris@16 1889 (current_ == 1 && it.current_ == 1 && it2_ == it.it2_);
Chris@16 1890 }
Chris@16 1891 BOOST_UBLAS_INLINE
Chris@16 1892 bool operator < (const const_iterator1 &it) const {
Chris@16 1893 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1894 return it - *this > 0;
Chris@16 1895 }
Chris@16 1896
Chris@16 1897 private:
Chris@16 1898 int begin_;
Chris@16 1899 int end_;
Chris@16 1900 int current_;
Chris@16 1901 const_subiterator1_type it1_begin_;
Chris@16 1902 const_subiterator1_type it1_end_;
Chris@16 1903 const_subiterator1_type it1_;
Chris@16 1904 const_subiterator2_type it2_begin_;
Chris@16 1905 const_subiterator2_type it2_end_;
Chris@16 1906 const_subiterator2_type it2_;
Chris@16 1907 };
Chris@16 1908 #endif
Chris@16 1909
Chris@16 1910 BOOST_UBLAS_INLINE
Chris@16 1911 const_iterator1 begin1 () const {
Chris@16 1912 return find1 (0, 0, 0);
Chris@16 1913 }
Chris@16 1914 BOOST_UBLAS_INLINE
Chris@101 1915 const_iterator1 cbegin1 () const {
Chris@101 1916 return begin1 ();
Chris@101 1917 }
Chris@101 1918 BOOST_UBLAS_INLINE
Chris@16 1919 const_iterator1 end1 () const {
Chris@16 1920 return find1 (0, size1 (), 0);
Chris@16 1921 }
Chris@101 1922 BOOST_UBLAS_INLINE
Chris@101 1923 const_iterator1 cend1 () const {
Chris@101 1924 return end1 ();
Chris@101 1925 }
Chris@16 1926
Chris@16 1927 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1928 class iterator1:
Chris@16 1929 public container_reference<hermitian_adaptor>,
Chris@16 1930 public random_access_iterator_base<typename iterator_restrict_traits<
Chris@16 1931 typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
Chris@16 1932 iterator1, value_type> {
Chris@16 1933 public:
Chris@16 1934 typedef typename subiterator1_type::value_type value_type;
Chris@16 1935 typedef typename subiterator1_type::difference_type difference_type;
Chris@16 1936 typedef typename subiterator1_type::reference reference;
Chris@16 1937 typedef typename subiterator1_type::pointer pointer;
Chris@16 1938
Chris@16 1939 typedef iterator2 dual_iterator_type;
Chris@16 1940 typedef reverse_iterator2 dual_reverse_iterator_type;
Chris@16 1941
Chris@16 1942 // Construction and destruction
Chris@16 1943 BOOST_UBLAS_INLINE
Chris@16 1944 iterator1 ():
Chris@16 1945 container_reference<self_type> (), it1_ () {}
Chris@16 1946 BOOST_UBLAS_INLINE
Chris@16 1947 iterator1 (self_type &m, const subiterator1_type &it1):
Chris@16 1948 container_reference<self_type> (m), it1_ (it1) {}
Chris@16 1949
Chris@16 1950 // Arithmetic
Chris@16 1951 BOOST_UBLAS_INLINE
Chris@16 1952 iterator1 &operator ++ () {
Chris@16 1953 ++ it1_;
Chris@16 1954 return *this;
Chris@16 1955 }
Chris@16 1956 BOOST_UBLAS_INLINE
Chris@16 1957 iterator1 &operator -- () {
Chris@16 1958 -- it1_;
Chris@16 1959 return *this;
Chris@16 1960 }
Chris@16 1961 BOOST_UBLAS_INLINE
Chris@16 1962 iterator1 &operator += (difference_type n) {
Chris@16 1963 it1_ += n;
Chris@16 1964 return *this;
Chris@16 1965 }
Chris@16 1966 BOOST_UBLAS_INLINE
Chris@16 1967 iterator1 &operator -= (difference_type n) {
Chris@16 1968 it1_ -= n;
Chris@16 1969 return *this;
Chris@16 1970 }
Chris@16 1971 BOOST_UBLAS_INLINE
Chris@16 1972 difference_type operator - (const iterator1 &it) const {
Chris@16 1973 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1974 return it1_ - it.it1_;
Chris@16 1975 }
Chris@16 1976
Chris@16 1977 // Dereference
Chris@16 1978 BOOST_UBLAS_INLINE
Chris@16 1979 reference operator * () const {
Chris@16 1980 return *it1_;
Chris@16 1981 }
Chris@16 1982 BOOST_UBLAS_INLINE
Chris@16 1983 reference operator [] (difference_type n) const {
Chris@16 1984 return *(*this + n);
Chris@16 1985 }
Chris@16 1986
Chris@16 1987 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1988 BOOST_UBLAS_INLINE
Chris@16 1989 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1990 typename self_type::
Chris@16 1991 #endif
Chris@16 1992 iterator2 begin () const {
Chris@16 1993 return (*this) ().find2 (1, index1 (), 0);
Chris@16 1994 }
Chris@16 1995 BOOST_UBLAS_INLINE
Chris@16 1996 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1997 typename self_type::
Chris@16 1998 #endif
Chris@16 1999 iterator2 end () const {
Chris@16 2000 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
Chris@16 2001 }
Chris@16 2002 BOOST_UBLAS_INLINE
Chris@16 2003 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2004 typename self_type::
Chris@16 2005 #endif
Chris@16 2006 reverse_iterator2 rbegin () const {
Chris@16 2007 return reverse_iterator2 (end ());
Chris@16 2008 }
Chris@16 2009 BOOST_UBLAS_INLINE
Chris@16 2010 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2011 typename self_type::
Chris@16 2012 #endif
Chris@16 2013 reverse_iterator2 rend () const {
Chris@16 2014 return reverse_iterator2 (begin ());
Chris@16 2015 }
Chris@16 2016 #endif
Chris@16 2017
Chris@16 2018 // Indices
Chris@16 2019 BOOST_UBLAS_INLINE
Chris@16 2020 size_type index1 () const {
Chris@16 2021 return it1_.index1 ();
Chris@16 2022 }
Chris@16 2023 BOOST_UBLAS_INLINE
Chris@16 2024 size_type index2 () const {
Chris@16 2025 return it1_.index2 ();
Chris@16 2026 }
Chris@16 2027
Chris@16 2028 // Assignment
Chris@16 2029 BOOST_UBLAS_INLINE
Chris@16 2030 iterator1 &operator = (const iterator1 &it) {
Chris@16 2031 container_reference<self_type>::assign (&it ());
Chris@16 2032 it1_ = it.it1_;
Chris@16 2033 return *this;
Chris@16 2034 }
Chris@16 2035
Chris@16 2036 // Comparison
Chris@16 2037 BOOST_UBLAS_INLINE
Chris@16 2038 bool operator == (const iterator1 &it) const {
Chris@16 2039 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2040 return it1_ == it.it1_;
Chris@16 2041 }
Chris@16 2042 BOOST_UBLAS_INLINE
Chris@16 2043 bool operator < (const iterator1 &it) const {
Chris@16 2044 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2045 return it1_ < it.it1_;
Chris@16 2046 }
Chris@16 2047
Chris@16 2048 private:
Chris@16 2049 subiterator1_type it1_;
Chris@16 2050
Chris@16 2051 friend class const_iterator1;
Chris@16 2052 };
Chris@16 2053 #endif
Chris@16 2054
Chris@16 2055 BOOST_UBLAS_INLINE
Chris@16 2056 iterator1 begin1 () {
Chris@16 2057 return find1 (0, 0, 0);
Chris@16 2058 }
Chris@16 2059 BOOST_UBLAS_INLINE
Chris@16 2060 iterator1 end1 () {
Chris@16 2061 return find1 (0, size1 (), 0);
Chris@16 2062 }
Chris@16 2063
Chris@16 2064 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 2065 class const_iterator2:
Chris@16 2066 public container_const_reference<hermitian_adaptor>,
Chris@16 2067 public random_access_iterator_base<typename iterator_restrict_traits<
Chris@16 2068 typename const_subiterator2_type::iterator_category, dense_random_access_iterator_tag>::iterator_category,
Chris@16 2069 const_iterator2, value_type> {
Chris@16 2070 public:
Chris@16 2071 typedef typename const_subiterator2_type::value_type value_type;
Chris@16 2072 typedef typename const_subiterator2_type::difference_type difference_type;
Chris@16 2073 // FIXME no better way to not return the address of a temporary?
Chris@16 2074 // typedef typename const_subiterator2_type::reference reference;
Chris@16 2075 typedef typename const_subiterator2_type::value_type reference;
Chris@16 2076 typedef typename const_subiterator2_type::pointer pointer;
Chris@16 2077
Chris@16 2078 typedef const_iterator1 dual_iterator_type;
Chris@16 2079 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 2080
Chris@16 2081 // Construction and destruction
Chris@16 2082 BOOST_UBLAS_INLINE
Chris@16 2083 const_iterator2 ():
Chris@16 2084 container_const_reference<self_type> (),
Chris@16 2085 begin_ (-1), end_ (-1), current_ (-1),
Chris@16 2086 it1_begin_ (), it1_end_ (), it1_ (),
Chris@16 2087 it2_begin_ (), it2_end_ (), it2_ () {}
Chris@16 2088 BOOST_UBLAS_INLINE
Chris@16 2089 const_iterator2 (const self_type &m, int begin, int end,
Chris@16 2090 const const_subiterator1_type &it1_begin, const const_subiterator1_type &it1_end,
Chris@16 2091 const const_subiterator2_type &it2_begin, const const_subiterator2_type &it2_end):
Chris@16 2092 container_const_reference<self_type> (m),
Chris@16 2093 begin_ (begin), end_ (end), current_ (begin),
Chris@16 2094 it1_begin_ (it1_begin), it1_end_ (it1_end), it1_ (it1_begin_),
Chris@16 2095 it2_begin_ (it2_begin), it2_end_ (it2_end), it2_ (it2_begin_) {
Chris@16 2096 if (current_ == 0 && it1_ == it1_end_)
Chris@16 2097 current_ = 1;
Chris@16 2098 if (current_ == 1 && it2_ == it2_end_)
Chris@16 2099 current_ = 0;
Chris@16 2100 if ((current_ == 0 && it1_ == it1_end_) ||
Chris@16 2101 (current_ == 1 && it2_ == it2_end_))
Chris@16 2102 current_ = end_;
Chris@16 2103 BOOST_UBLAS_CHECK (current_ == end_ ||
Chris@16 2104 (current_ == 0 && it1_ != it1_end_) ||
Chris@16 2105 (current_ == 1 && it2_ != it2_end_), internal_logic ());
Chris@16 2106 }
Chris@16 2107 // FIXME cannot compiler
Chris@16 2108 // iterator2 does not have these members!
Chris@16 2109 BOOST_UBLAS_INLINE
Chris@16 2110 const_iterator2 (const iterator2 &it):
Chris@16 2111 container_const_reference<self_type> (it ()),
Chris@16 2112 begin_ (it.begin_), end_ (it.end_), current_ (it.current_),
Chris@16 2113 it1_begin_ (it.it1_begin_), it1_end_ (it.it1_end_), it1_ (it.it1_),
Chris@16 2114 it2_begin_ (it.it2_begin_), it2_end_ (it.it2_end_), it2_ (it.it2_) {
Chris@16 2115 BOOST_UBLAS_CHECK (current_ == end_ ||
Chris@16 2116 (current_ == 0 && it1_ != it1_end_) ||
Chris@16 2117 (current_ == 1 && it2_ != it2_end_), internal_logic ());
Chris@16 2118 }
Chris@16 2119
Chris@16 2120 // Arithmetic
Chris@16 2121 BOOST_UBLAS_INLINE
Chris@16 2122 const_iterator2 &operator ++ () {
Chris@16 2123 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 2124 if (current_ == 0) {
Chris@16 2125 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
Chris@16 2126 ++ it1_;
Chris@16 2127 if (it1_ == it1_end_ && end_ == 1) {
Chris@16 2128 it2_ = it2_begin_;
Chris@16 2129 current_ = 1;
Chris@16 2130 }
Chris@16 2131 } else /* if (current_ == 1) */ {
Chris@16 2132 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
Chris@16 2133 ++ it2_;
Chris@16 2134 if (it2_ == it2_end_ && end_ == 0) {
Chris@16 2135 it1_ = it1_begin_;
Chris@16 2136 current_ = 0;
Chris@16 2137 }
Chris@16 2138 }
Chris@16 2139 return *this;
Chris@16 2140 }
Chris@16 2141 BOOST_UBLAS_INLINE
Chris@16 2142 const_iterator2 &operator -- () {
Chris@16 2143 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 2144 if (current_ == 0) {
Chris@16 2145 if (it1_ == it1_begin_ && begin_ == 1) {
Chris@16 2146 it2_ = it2_end_;
Chris@16 2147 BOOST_UBLAS_CHECK (it2_ != it2_begin_, internal_logic ());
Chris@16 2148 -- it2_;
Chris@16 2149 current_ = 1;
Chris@16 2150 } else {
Chris@16 2151 -- it1_;
Chris@16 2152 }
Chris@16 2153 } else /* if (current_ == 1) */ {
Chris@16 2154 if (it2_ == it2_begin_ && begin_ == 0) {
Chris@16 2155 it1_ = it1_end_;
Chris@16 2156 BOOST_UBLAS_CHECK (it1_ != it1_begin_, internal_logic ());
Chris@16 2157 -- it1_;
Chris@16 2158 current_ = 0;
Chris@16 2159 } else {
Chris@16 2160 -- it2_;
Chris@16 2161 }
Chris@16 2162 }
Chris@16 2163 return *this;
Chris@16 2164 }
Chris@16 2165 BOOST_UBLAS_INLINE
Chris@16 2166 const_iterator2 &operator += (difference_type n) {
Chris@16 2167 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 2168 if (current_ == 0) {
Chris@16 2169 size_type d = (std::min) (n, it1_end_ - it1_);
Chris@16 2170 it1_ += d;
Chris@16 2171 n -= d;
Chris@16 2172 if (n > 0 || (end_ == 1 && it1_ == it1_end_)) {
Chris@16 2173 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
Chris@16 2174 d = (std::min) (n, it2_end_ - it2_begin_);
Chris@16 2175 it2_ = it2_begin_ + d;
Chris@16 2176 n -= d;
Chris@16 2177 current_ = 1;
Chris@16 2178 }
Chris@16 2179 } else /* if (current_ == 1) */ {
Chris@16 2180 size_type d = (std::min) (n, it2_end_ - it2_);
Chris@16 2181 it2_ += d;
Chris@16 2182 n -= d;
Chris@16 2183 if (n > 0 || (end_ == 0 && it2_ == it2_end_)) {
Chris@16 2184 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
Chris@16 2185 d = (std::min) (n, it1_end_ - it1_begin_);
Chris@16 2186 it1_ = it1_begin_ + d;
Chris@16 2187 n -= d;
Chris@16 2188 current_ = 0;
Chris@16 2189 }
Chris@16 2190 }
Chris@16 2191 BOOST_UBLAS_CHECK (n == 0, external_logic ());
Chris@16 2192 return *this;
Chris@16 2193 }
Chris@16 2194 BOOST_UBLAS_INLINE
Chris@16 2195 const_iterator2 &operator -= (difference_type n) {
Chris@16 2196 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 2197 if (current_ == 0) {
Chris@16 2198 size_type d = (std::min) (n, it1_ - it1_begin_);
Chris@16 2199 it1_ -= d;
Chris@16 2200 n -= d;
Chris@16 2201 if (n > 0) {
Chris@16 2202 BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
Chris@16 2203 d = (std::min) (n, it2_end_ - it2_begin_);
Chris@16 2204 it2_ = it2_end_ - d;
Chris@16 2205 n -= d;
Chris@16 2206 current_ = 1;
Chris@16 2207 }
Chris@16 2208 } else /* if (current_ == 1) */ {
Chris@16 2209 size_type d = (std::min) (n, it2_ - it2_begin_);
Chris@16 2210 it2_ -= d;
Chris@16 2211 n -= d;
Chris@16 2212 if (n > 0) {
Chris@16 2213 BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
Chris@16 2214 d = (std::min) (n, it1_end_ - it1_begin_);
Chris@16 2215 it1_ = it1_end_ - d;
Chris@16 2216 n -= d;
Chris@16 2217 current_ = 0;
Chris@16 2218 }
Chris@16 2219 }
Chris@16 2220 BOOST_UBLAS_CHECK (n == 0, external_logic ());
Chris@16 2221 return *this;
Chris@16 2222 }
Chris@16 2223 BOOST_UBLAS_INLINE
Chris@16 2224 difference_type operator - (const const_iterator2 &it) const {
Chris@16 2225 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2226 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 2227 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
Chris@16 2228 BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
Chris@16 2229 if (current_ == 0 && it.current_ == 0) {
Chris@16 2230 return it1_ - it.it1_;
Chris@16 2231 } else if (current_ == 0 && it.current_ == 1) {
Chris@16 2232 if (end_ == 1 && it.end_ == 1) {
Chris@16 2233 return (it1_ - it.it1_end_) + (it.it2_begin_ - it.it2_);
Chris@16 2234 } else /* if (end_ == 0 && it.end_ == 0) */ {
Chris@16 2235 return (it1_ - it.it1_begin_) + (it.it2_end_ - it.it2_);
Chris@16 2236 }
Chris@16 2237
Chris@16 2238 } else if (current_ == 1 && it.current_ == 0) {
Chris@16 2239 if (end_ == 1 && it.end_ == 1) {
Chris@16 2240 return (it2_ - it.it2_begin_) + (it.it1_end_ - it.it1_);
Chris@16 2241 } else /* if (end_ == 0 && it.end_ == 0) */ {
Chris@16 2242 return (it2_ - it.it2_end_) + (it.it1_begin_ - it.it1_);
Chris@16 2243 }
Chris@16 2244 } else /* if (current_ == 1 && it.current_ == 1) */ {
Chris@16 2245 return it2_ - it.it2_;
Chris@16 2246 }
Chris@16 2247 }
Chris@16 2248
Chris@16 2249 // Dereference
Chris@16 2250 BOOST_UBLAS_INLINE
Chris@16 2251 const_reference operator * () const {
Chris@16 2252 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 2253 if (current_ == 0) {
Chris@16 2254 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
Chris@16 2255 if (triangular_type::other (index1 (), index2 ()))
Chris@16 2256 return *it1_;
Chris@16 2257 else
Chris@16 2258 return type_traits<value_type>::conj (*it1_);
Chris@16 2259 } else /* if (current_ == 1) */ {
Chris@16 2260 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
Chris@16 2261 if (triangular_type::other (index1 (), index2 ()))
Chris@16 2262 return *it2_;
Chris@16 2263 else
Chris@16 2264 return type_traits<value_type>::conj (*it2_);
Chris@16 2265 }
Chris@16 2266 }
Chris@16 2267 BOOST_UBLAS_INLINE
Chris@16 2268 const_reference operator [] (difference_type n) const {
Chris@16 2269 return *(*this + n);
Chris@16 2270 }
Chris@16 2271
Chris@16 2272 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 2273 BOOST_UBLAS_INLINE
Chris@16 2274 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2275 typename self_type::
Chris@16 2276 #endif
Chris@16 2277 const_iterator1 begin () const {
Chris@16 2278 return (*this) ().find1 (1, 0, index2 ());
Chris@16 2279 }
Chris@16 2280 BOOST_UBLAS_INLINE
Chris@16 2281 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2282 typename self_type::
Chris@16 2283 #endif
Chris@101 2284 const_iterator1 cbegin () const {
Chris@101 2285 return begin ();
Chris@101 2286 }
Chris@101 2287 BOOST_UBLAS_INLINE
Chris@101 2288 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2289 typename self_type::
Chris@101 2290 #endif
Chris@16 2291 const_iterator1 end () const {
Chris@16 2292 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
Chris@16 2293 }
Chris@16 2294 BOOST_UBLAS_INLINE
Chris@16 2295 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2296 typename self_type::
Chris@16 2297 #endif
Chris@101 2298 const_iterator1 cend () const {
Chris@101 2299 return end ();
Chris@101 2300 }
Chris@101 2301 BOOST_UBLAS_INLINE
Chris@101 2302 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2303 typename self_type::
Chris@101 2304 #endif
Chris@16 2305 const_reverse_iterator1 rbegin () const {
Chris@16 2306 return const_reverse_iterator1 (end ());
Chris@16 2307 }
Chris@16 2308 BOOST_UBLAS_INLINE
Chris@16 2309 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2310 typename self_type::
Chris@16 2311 #endif
Chris@101 2312 const_reverse_iterator1 crbegin () const {
Chris@101 2313 return rbegin ();
Chris@101 2314 }
Chris@101 2315 BOOST_UBLAS_INLINE
Chris@101 2316 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2317 typename self_type::
Chris@101 2318 #endif
Chris@16 2319 const_reverse_iterator1 rend () const {
Chris@16 2320 return const_reverse_iterator1 (begin ());
Chris@16 2321 }
Chris@101 2322 BOOST_UBLAS_INLINE
Chris@101 2323 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2324 typename self_type::
Chris@101 2325 #endif
Chris@101 2326 const_reverse_iterator1 crend () const {
Chris@101 2327 return end ();
Chris@101 2328 }
Chris@16 2329 #endif
Chris@16 2330
Chris@16 2331 // Indices
Chris@16 2332 BOOST_UBLAS_INLINE
Chris@16 2333 size_type index1 () const {
Chris@16 2334 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 2335 if (current_ == 0) {
Chris@16 2336 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
Chris@16 2337 return it1_.index2 ();
Chris@16 2338 } else /* if (current_ == 1) */ {
Chris@16 2339 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
Chris@16 2340 return it2_.index1 ();
Chris@16 2341 }
Chris@16 2342 }
Chris@16 2343 BOOST_UBLAS_INLINE
Chris@16 2344 size_type index2 () const {
Chris@16 2345 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 2346 if (current_ == 0) {
Chris@16 2347 BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
Chris@16 2348 return it1_.index1 ();
Chris@16 2349 } else /* if (current_ == 1) */ {
Chris@16 2350 BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
Chris@16 2351 return it2_.index2 ();
Chris@16 2352 }
Chris@16 2353 }
Chris@16 2354
Chris@16 2355 // Assignment
Chris@16 2356 BOOST_UBLAS_INLINE
Chris@16 2357 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 2358 container_const_reference<self_type>::assign (&it ());
Chris@16 2359 begin_ = it.begin_;
Chris@16 2360 end_ = it.end_;
Chris@16 2361 current_ = it.current_;
Chris@16 2362 it1_begin_ = it.it1_begin_;
Chris@16 2363 it1_end_ = it.it1_end_;
Chris@16 2364 it1_ = it.it1_;
Chris@16 2365 it2_begin_ = it.it2_begin_;
Chris@16 2366 it2_end_ = it.it2_end_;
Chris@16 2367 it2_ = it.it2_;
Chris@16 2368 return *this;
Chris@16 2369 }
Chris@16 2370
Chris@16 2371 // Comparison
Chris@16 2372 BOOST_UBLAS_INLINE
Chris@16 2373 bool operator == (const const_iterator2 &it) const {
Chris@16 2374 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2375 BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
Chris@16 2376 BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
Chris@16 2377 BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
Chris@16 2378 return (current_ == 0 && it.current_ == 0 && it1_ == it.it1_) ||
Chris@16 2379 (current_ == 1 && it.current_ == 1 && it2_ == it.it2_);
Chris@16 2380 }
Chris@16 2381 BOOST_UBLAS_INLINE
Chris@16 2382 bool operator < (const const_iterator2 &it) const {
Chris@16 2383 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2384 return it - *this > 0;
Chris@16 2385 }
Chris@16 2386
Chris@16 2387 private:
Chris@16 2388 int begin_;
Chris@16 2389 int end_;
Chris@16 2390 int current_;
Chris@16 2391 const_subiterator1_type it1_begin_;
Chris@16 2392 const_subiterator1_type it1_end_;
Chris@16 2393 const_subiterator1_type it1_;
Chris@16 2394 const_subiterator2_type it2_begin_;
Chris@16 2395 const_subiterator2_type it2_end_;
Chris@16 2396 const_subiterator2_type it2_;
Chris@16 2397 };
Chris@16 2398 #endif
Chris@16 2399
Chris@16 2400 BOOST_UBLAS_INLINE
Chris@16 2401 const_iterator2 begin2 () const {
Chris@16 2402 return find2 (0, 0, 0);
Chris@16 2403 }
Chris@16 2404 BOOST_UBLAS_INLINE
Chris@101 2405 const_iterator2 cbegin2 () const {
Chris@101 2406 return begin2 ();
Chris@101 2407 }
Chris@101 2408 BOOST_UBLAS_INLINE
Chris@16 2409 const_iterator2 end2 () const {
Chris@16 2410 return find2 (0, 0, size2 ());
Chris@16 2411 }
Chris@101 2412 BOOST_UBLAS_INLINE
Chris@101 2413 const_iterator2 cend2 () const {
Chris@101 2414 return end2 ();
Chris@101 2415 }
Chris@16 2416
Chris@16 2417 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 2418 class iterator2:
Chris@16 2419 public container_reference<hermitian_adaptor>,
Chris@16 2420 public random_access_iterator_base<typename iterator_restrict_traits<
Chris@16 2421 typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
Chris@16 2422 iterator2, value_type> {
Chris@16 2423 public:
Chris@16 2424 typedef typename subiterator2_type::value_type value_type;
Chris@16 2425 typedef typename subiterator2_type::difference_type difference_type;
Chris@16 2426 typedef typename subiterator2_type::reference reference;
Chris@16 2427 typedef typename subiterator2_type::pointer pointer;
Chris@16 2428
Chris@16 2429 typedef iterator1 dual_iterator_type;
Chris@16 2430 typedef reverse_iterator1 dual_reverse_iterator_type;
Chris@16 2431
Chris@16 2432 // Construction and destruction
Chris@16 2433 BOOST_UBLAS_INLINE
Chris@16 2434 iterator2 ():
Chris@16 2435 container_reference<self_type> (), it2_ () {}
Chris@16 2436 BOOST_UBLAS_INLINE
Chris@16 2437 iterator2 (self_type &m, const subiterator2_type &it2):
Chris@16 2438 container_reference<self_type> (m), it2_ (it2) {}
Chris@16 2439
Chris@16 2440 // Arithmetic
Chris@16 2441 BOOST_UBLAS_INLINE
Chris@16 2442 iterator2 &operator ++ () {
Chris@16 2443 ++ it2_;
Chris@16 2444 return *this;
Chris@16 2445 }
Chris@16 2446 BOOST_UBLAS_INLINE
Chris@16 2447 iterator2 &operator -- () {
Chris@16 2448 -- it2_;
Chris@16 2449 return *this;
Chris@16 2450 }
Chris@16 2451 BOOST_UBLAS_INLINE
Chris@16 2452 iterator2 &operator += (difference_type n) {
Chris@16 2453 it2_ += n;
Chris@16 2454 return *this;
Chris@16 2455 }
Chris@16 2456 BOOST_UBLAS_INLINE
Chris@16 2457 iterator2 &operator -= (difference_type n) {
Chris@16 2458 it2_ -= n;
Chris@16 2459 return *this;
Chris@16 2460 }
Chris@16 2461 BOOST_UBLAS_INLINE
Chris@16 2462 difference_type operator - (const iterator2 &it) const {
Chris@16 2463 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2464 return it2_ - it.it2_;
Chris@16 2465 }
Chris@16 2466
Chris@16 2467 // Dereference
Chris@16 2468 BOOST_UBLAS_INLINE
Chris@16 2469 reference operator * () const {
Chris@16 2470 return *it2_;
Chris@16 2471 }
Chris@16 2472 BOOST_UBLAS_INLINE
Chris@16 2473 reference operator [] (difference_type n) const {
Chris@16 2474 return *(*this + n);
Chris@16 2475 }
Chris@16 2476
Chris@16 2477 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 2478 BOOST_UBLAS_INLINE
Chris@16 2479 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2480 typename self_type::
Chris@16 2481 #endif
Chris@16 2482 iterator1 begin () const {
Chris@16 2483 return (*this) ().find1 (1, 0, index2 ());
Chris@16 2484 }
Chris@16 2485 BOOST_UBLAS_INLINE
Chris@16 2486 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2487 typename self_type::
Chris@16 2488 #endif
Chris@16 2489 iterator1 end () const {
Chris@16 2490 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
Chris@16 2491 }
Chris@16 2492 BOOST_UBLAS_INLINE
Chris@16 2493 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2494 typename self_type::
Chris@16 2495 #endif
Chris@16 2496 reverse_iterator1 rbegin () const {
Chris@16 2497 return reverse_iterator1 (end ());
Chris@16 2498 }
Chris@16 2499 BOOST_UBLAS_INLINE
Chris@16 2500 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2501 typename self_type::
Chris@16 2502 #endif
Chris@16 2503 reverse_iterator1 rend () const {
Chris@16 2504 return reverse_iterator1 (begin ());
Chris@16 2505 }
Chris@16 2506 #endif
Chris@16 2507
Chris@16 2508 // Indices
Chris@16 2509 BOOST_UBLAS_INLINE
Chris@16 2510 size_type index1 () const {
Chris@16 2511 return it2_.index1 ();
Chris@16 2512 }
Chris@16 2513 BOOST_UBLAS_INLINE
Chris@16 2514 size_type index2 () const {
Chris@16 2515 return it2_.index2 ();
Chris@16 2516 }
Chris@16 2517
Chris@16 2518 // Assignment
Chris@16 2519 BOOST_UBLAS_INLINE
Chris@16 2520 iterator2 &operator = (const iterator2 &it) {
Chris@16 2521 container_reference<self_type>::assign (&it ());
Chris@16 2522 it2_ = it.it2_;
Chris@16 2523 return *this;
Chris@16 2524 }
Chris@16 2525
Chris@16 2526 // Comparison
Chris@16 2527 BOOST_UBLAS_INLINE
Chris@16 2528 bool operator == (const iterator2 &it) const {
Chris@16 2529 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2530 return it2_ == it.it2_;
Chris@16 2531 }
Chris@16 2532 BOOST_UBLAS_INLINE
Chris@16 2533 bool operator < (const iterator2 &it) const {
Chris@16 2534 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2535 return it2_ < it.it2_;
Chris@16 2536 }
Chris@16 2537
Chris@16 2538 private:
Chris@16 2539 subiterator2_type it2_;
Chris@16 2540
Chris@16 2541 friend class const_iterator2;
Chris@16 2542 };
Chris@16 2543 #endif
Chris@16 2544
Chris@16 2545 BOOST_UBLAS_INLINE
Chris@16 2546 iterator2 begin2 () {
Chris@16 2547 return find2 (0, 0, 0);
Chris@16 2548 }
Chris@16 2549 BOOST_UBLAS_INLINE
Chris@16 2550 iterator2 end2 () {
Chris@16 2551 return find2 (0, 0, size2 ());
Chris@16 2552 }
Chris@16 2553
Chris@16 2554 // Reverse iterators
Chris@16 2555
Chris@16 2556 BOOST_UBLAS_INLINE
Chris@16 2557 const_reverse_iterator1 rbegin1 () const {
Chris@16 2558 return const_reverse_iterator1 (end1 ());
Chris@16 2559 }
Chris@16 2560 BOOST_UBLAS_INLINE
Chris@101 2561 const_reverse_iterator1 crbegin1 () const {
Chris@101 2562 return rbegin1();
Chris@101 2563 }
Chris@101 2564 BOOST_UBLAS_INLINE
Chris@16 2565 const_reverse_iterator1 rend1 () const {
Chris@16 2566 return const_reverse_iterator1 (begin1 ());
Chris@16 2567 }
Chris@101 2568 BOOST_UBLAS_INLINE
Chris@101 2569 const_reverse_iterator1 crend1 () const {
Chris@101 2570 return rend1 ();
Chris@101 2571 }
Chris@16 2572
Chris@16 2573 BOOST_UBLAS_INLINE
Chris@16 2574 reverse_iterator1 rbegin1 () {
Chris@16 2575 return reverse_iterator1 (end1 ());
Chris@16 2576 }
Chris@16 2577 BOOST_UBLAS_INLINE
Chris@16 2578 reverse_iterator1 rend1 () {
Chris@16 2579 return reverse_iterator1 (begin1 ());
Chris@16 2580 }
Chris@16 2581
Chris@16 2582 BOOST_UBLAS_INLINE
Chris@16 2583 const_reverse_iterator2 rbegin2 () const {
Chris@16 2584 return const_reverse_iterator2 (end2 ());
Chris@16 2585 }
Chris@16 2586 BOOST_UBLAS_INLINE
Chris@101 2587 const_reverse_iterator2 crbegin2 () const {
Chris@101 2588 return rbegin2 ();
Chris@101 2589 }
Chris@101 2590 BOOST_UBLAS_INLINE
Chris@16 2591 const_reverse_iterator2 rend2 () const {
Chris@16 2592 return const_reverse_iterator2 (begin2 ());
Chris@16 2593 }
Chris@101 2594 BOOST_UBLAS_INLINE
Chris@101 2595 const_reverse_iterator2 crend2 () const {
Chris@101 2596 return rend2 ();
Chris@101 2597 }
Chris@16 2598
Chris@16 2599 BOOST_UBLAS_INLINE
Chris@16 2600 reverse_iterator2 rbegin2 () {
Chris@16 2601 return reverse_iterator2 (end2 ());
Chris@16 2602 }
Chris@16 2603 BOOST_UBLAS_INLINE
Chris@16 2604 reverse_iterator2 rend2 () {
Chris@16 2605 return reverse_iterator2 (begin2 ());
Chris@16 2606 }
Chris@16 2607
Chris@16 2608 private:
Chris@16 2609 matrix_closure_type data_;
Chris@16 2610 static value_type conj_;
Chris@16 2611 };
Chris@16 2612
Chris@16 2613 template<class M, class TRI>
Chris@16 2614 typename hermitian_adaptor<M, TRI>::value_type hermitian_adaptor<M, TRI>::conj_;
Chris@16 2615
Chris@16 2616 // Specialization for temporary_traits
Chris@16 2617 template <class M, class TRI>
Chris@16 2618 struct vector_temporary_traits< hermitian_adaptor<M, TRI> >
Chris@16 2619 : vector_temporary_traits< M > {} ;
Chris@16 2620 template <class M, class TRI>
Chris@16 2621 struct vector_temporary_traits< const hermitian_adaptor<M, TRI> >
Chris@16 2622 : vector_temporary_traits< M > {} ;
Chris@16 2623
Chris@16 2624 template <class M, class TRI>
Chris@16 2625 struct matrix_temporary_traits< hermitian_adaptor<M, TRI> >
Chris@16 2626 : matrix_temporary_traits< M > {} ;
Chris@16 2627 template <class M, class TRI>
Chris@16 2628 struct matrix_temporary_traits< const hermitian_adaptor<M, TRI> >
Chris@16 2629 : matrix_temporary_traits< M > {} ;
Chris@16 2630
Chris@16 2631 }}}
Chris@16 2632
Chris@16 2633 #endif