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
|