1 // -*- c++ -*- (enables emacs c++ mode) 2 //=========================================================================== 3 // 4 // Copyright (C) 2003-2008 Yves Renard 5 // 6 // This file is a part of GETFEM++ 7 // 8 // Getfem++ is free software; you can redistribute it and/or modify it 9 // under the terms of the GNU Lesser General Public License as published 10 // by the Free Software Foundation; either version 2.1 of the License, or 11 // (at your option) any later version. 12 // This program is distributed in the hope that it will be useful, but 13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 // License for more details. 16 // You should have received a copy of the GNU Lesser General Public License 17 // along with this program; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 19 // 20 // As a special exception, you may use this file as part of a free software 21 // library without restriction. Specifically, if other files instantiate 22 // templates or use macros or inline functions from this file, or you compile 23 // this file and link it with other files to produce an executable, this 24 // file does not by itself cause the resulting executable to be covered by 25 // the GNU General Public License. This exception does not however 26 // invalidate any other reasons why the executable file might be covered by 27 // the GNU General Public License. 28 // 29 //=========================================================================== 30 31 /**@file gmm_conjugated.h 32 @author Yves Renard <Yves.Renard@insa-lyon.fr> 33 @date September 18, 2003. 34 @brief handle conjugation of complex matrices/vectors. 35 */ 36 #ifndef GMM_CONJUGATED_H__ 37 #define GMM_CONJUGATED_H__ 38 39 #include "gmm_def.h" 40 41 namespace gmm { 42 ///@cond DOXY_SHOW_ALL_FUNCTIONS 43 44 /* ********************************************************************* */ 45 /* Conjugated references on vectors */ 46 /* ********************************************************************* */ 47 48 template <typename IT> struct conjugated_const_iterator { 49 typedef typename std::iterator_traits<IT>::value_type value_type; 50 typedef typename std::iterator_traits<IT>::pointer pointer; 51 typedef typename std::iterator_traits<IT>::reference reference; 52 typedef typename std::iterator_traits<IT>::difference_type difference_type; 53 typedef typename std::iterator_traits<IT>::iterator_category 54 iterator_category; 55 56 IT it; 57 conjugated_const_iteratorconjugated_const_iterator58 conjugated_const_iterator(void) {} conjugated_const_iteratorconjugated_const_iterator59 conjugated_const_iterator(const IT &i) : it(i) {} 60 indexconjugated_const_iterator61 inline size_type index(void) const { return it.index(); } 62 conjugated_const_iterator operator ++(int) 63 { conjugated_const_iterator tmp = *this; ++it; return tmp; } 64 conjugated_const_iterator operator --(int) 65 { conjugated_const_iterator tmp = *this; --it; return tmp; } 66 conjugated_const_iterator &operator ++() { ++it; return *this; } 67 conjugated_const_iterator &operator --() { --it; return *this; } 68 conjugated_const_iterator &operator +=(difference_type i) 69 { it += i; return *this; } 70 conjugated_const_iterator &operator -=(difference_type i) 71 { it -= i; return *this; } 72 conjugated_const_iterator operator +(difference_type i) const 73 { conjugated_const_iterator itb = *this; return (itb += i); } 74 conjugated_const_iterator operator -(difference_type i) const 75 { conjugated_const_iterator itb = *this; return (itb -= i); } 76 difference_type operator -(const conjugated_const_iterator &i) const 77 { return difference_type(it - i.it); } 78 79 value_type operator *() const { return gmm::conj(*it); } 80 value_type operator [](size_type ii) const { return gmm::conj(it[ii]); } 81 82 bool operator ==(const conjugated_const_iterator &i) const 83 { return (i.it == it); } 84 bool operator !=(const conjugated_const_iterator &i) const 85 { return (i.it != it); } 86 bool operator < (const conjugated_const_iterator &i) const 87 { return (it < i.it); } 88 }; 89 90 template <typename V> struct conjugated_vector_const_ref { 91 typedef conjugated_vector_const_ref<V> this_type; 92 typedef typename linalg_traits<V>::value_type value_type; 93 typedef typename linalg_traits<V>::const_iterator iterator; 94 typedef typename linalg_traits<this_type>::reference reference; 95 typedef typename linalg_traits<this_type>::origin_type origin_type; 96 97 iterator begin_, end_; 98 const origin_type *origin; 99 size_type size_; 100 conjugated_vector_const_refconjugated_vector_const_ref101 conjugated_vector_const_ref(const V &v) 102 : begin_(vect_const_begin(v)), end_(vect_const_end(v)), 103 origin(linalg_origin(v)), 104 size_(vect_size(v)) {} 105 106 reference operator[](size_type i) const 107 { return gmm::conj(linalg_traits<V>::access(origin, begin_, end_, i)); } 108 }; 109 110 template <typename V> struct linalg_traits<conjugated_vector_const_ref<V> > { 111 typedef conjugated_vector_const_ref<V> this_type; 112 typedef typename linalg_traits<V>::origin_type origin_type; 113 typedef linalg_const is_reference; 114 typedef abstract_vector linalg_type; 115 typedef typename linalg_traits<V>::value_type value_type; 116 typedef value_type reference; 117 typedef abstract_null_type iterator; 118 typedef conjugated_const_iterator<typename 119 linalg_traits<V>::const_iterator> const_iterator; 120 typedef typename linalg_traits<V>::storage_type storage_type; 121 typedef typename linalg_traits<V>::index_sorted index_sorted; 122 static size_type size(const this_type &v) { return v.size_; } 123 static iterator begin(this_type &v) { return iterator(v.begin_); } 124 static const_iterator begin(const this_type &v) 125 { return const_iterator(v.begin_); } 126 static iterator end(this_type &v) 127 { return iterator(v.end_); } 128 static const_iterator end(const this_type &v) 129 { return const_iterator(v.end_); } 130 static value_type access(const origin_type *o, const const_iterator &it, 131 const const_iterator &ite, size_type i) 132 { return gmm::conj(linalg_traits<V>::access(o, it.it, ite.it, i)); } 133 static const origin_type* origin(const this_type &v) { return v.origin; } 134 }; 135 136 template<typename V> std::ostream &operator << 137 (std::ostream &o, const conjugated_vector_const_ref<V>& m) 138 { gmm::write(o,m); return o; } 139 140 /* ********************************************************************* */ 141 /* Conjugated references on matrices */ 142 /* ********************************************************************* */ 143 144 template <typename M> struct conjugated_row_const_iterator { 145 typedef conjugated_row_const_iterator<M> iterator; 146 typedef typename linalg_traits<M>::const_row_iterator ITER; 147 typedef typename linalg_traits<M>::value_type value_type; 148 typedef ptrdiff_t difference_type; 149 typedef size_t size_type; 150 151 ITER it; 152 153 iterator operator ++(int) { iterator tmp = *this; it++; return tmp; } 154 iterator operator --(int) { iterator tmp = *this; it--; return tmp; } 155 iterator &operator ++() { it++; return *this; } 156 iterator &operator --() { it--; return *this; } 157 iterator &operator +=(difference_type i) { it += i; return *this; } 158 iterator &operator -=(difference_type i) { it -= i; return *this; } 159 iterator operator +(difference_type i) const 160 { iterator itt = *this; return (itt += i); } 161 iterator operator -(difference_type i) const 162 { iterator itt = *this; return (itt -= i); } 163 difference_type operator -(const iterator &i) const 164 { return it - i.it; } 165 166 ITER operator *() const { return it; } 167 ITER operator [](int i) { return it + i; } 168 169 bool operator ==(const iterator &i) const { return (it == i.it); } 170 bool operator !=(const iterator &i) const { return !(i == *this); } 171 bool operator < (const iterator &i) const { return (it < i.it); } 172 173 conjugated_row_const_iterator(void) {} 174 conjugated_row_const_iterator(const ITER &i) : it(i) { } 175 176 }; 177 178 template <typename M> struct conjugated_row_matrix_const_ref { 179 180 typedef conjugated_row_matrix_const_ref<M> this_type; 181 typedef typename linalg_traits<M>::const_row_iterator iterator; 182 typedef typename linalg_traits<M>::value_type value_type; 183 typedef typename linalg_traits<this_type>::origin_type origin_type; 184 185 iterator begin_, end_; 186 const origin_type *origin; 187 size_type nr, nc; 188 189 conjugated_row_matrix_const_ref(const M &m) 190 : begin_(mat_row_begin(m)), end_(mat_row_end(m)), 191 origin(linalg_origin(m)), nr(mat_ncols(m)), nc(mat_nrows(m)) {} 192 193 value_type operator()(size_type i, size_type j) const 194 { return gmm::conj(linalg_traits<M>::access(begin_+j, i)); } 195 }; 196 197 template <typename M> 198 struct linalg_traits<conjugated_row_matrix_const_ref<M> > { 199 typedef conjugated_row_matrix_const_ref<M> this_type; 200 typedef typename linalg_traits<M>::origin_type origin_type; 201 typedef linalg_const is_reference; 202 typedef abstract_matrix linalg_type; 203 typedef typename linalg_traits<M>::value_type value_type; 204 typedef value_type reference; 205 typedef typename linalg_traits<M>::storage_type storage_type; 206 typedef typename linalg_traits<M>::const_sub_row_type vector_type; 207 typedef conjugated_vector_const_ref<vector_type> sub_col_type; 208 typedef conjugated_vector_const_ref<vector_type> const_sub_col_type; 209 typedef conjugated_row_const_iterator<M> col_iterator; 210 typedef conjugated_row_const_iterator<M> const_col_iterator; 211 typedef abstract_null_type const_sub_row_type; 212 typedef abstract_null_type sub_row_type; 213 typedef abstract_null_type const_row_iterator; 214 typedef abstract_null_type row_iterator; 215 typedef col_major sub_orientation; 216 typedef typename linalg_traits<M>::index_sorted index_sorted; 217 static inline size_type ncols(const this_type &m) { return m.nc; } 218 static inline size_type nrows(const this_type &m) { return m.nr; } 219 static inline const_sub_col_type col(const const_col_iterator &it) 220 { return conjugated(linalg_traits<M>::row(it.it)); } 221 static inline const_col_iterator col_begin(const this_type &m) 222 { return const_col_iterator(m.begin_); } 223 static inline const_col_iterator col_end(const this_type &m) 224 { return const_col_iterator(m.end_); } 225 static inline const origin_type* origin(const this_type &m) 226 { return m.origin; } 227 static value_type access(const const_col_iterator &it, size_type i) 228 { return gmm::conj(linalg_traits<M>::access(it.it, i)); } 229 }; 230 231 template<typename M> std::ostream &operator << 232 (std::ostream &o, const conjugated_row_matrix_const_ref<M>& m) 233 { gmm::write(o,m); return o; } 234 235 236 template <typename M> struct conjugated_col_const_iterator { 237 typedef conjugated_col_const_iterator<M> iterator; 238 typedef typename linalg_traits<M>::const_col_iterator ITER; 239 typedef typename linalg_traits<M>::value_type value_type; 240 typedef ptrdiff_t difference_type; 241 typedef size_t size_type; 242 243 ITER it; 244 245 iterator operator ++(int) { iterator tmp = *this; it++; return tmp; } 246 iterator operator --(int) { iterator tmp = *this; it--; return tmp; } 247 iterator &operator ++() { it++; return *this; } 248 iterator &operator --() { it--; return *this; } 249 iterator &operator +=(difference_type i) { it += i; return *this; } 250 iterator &operator -=(difference_type i) { it -= i; return *this; } 251 iterator operator +(difference_type i) const 252 { iterator itt = *this; return (itt += i); } 253 iterator operator -(difference_type i) const 254 { iterator itt = *this; return (itt -= i); } 255 difference_type operator -(const iterator &i) const 256 { return it - i.it; } 257 258 ITER operator *() const { return it; } 259 ITER operator [](int i) { return it + i; } 260 261 bool operator ==(const iterator &i) const { return (it == i.it); } 262 bool operator !=(const iterator &i) const { return !(i == *this); } 263 bool operator < (const iterator &i) const { return (it < i.it); } 264 265 conjugated_col_const_iterator(void) {} 266 conjugated_col_const_iterator(const ITER &i) : it(i) { } 267 268 }; 269 270 template <typename M> struct conjugated_col_matrix_const_ref { 271 272 typedef conjugated_col_matrix_const_ref<M> this_type; 273 typedef typename linalg_traits<M>::const_col_iterator iterator; 274 typedef typename linalg_traits<M>::value_type value_type; 275 typedef typename linalg_traits<this_type>::origin_type origin_type; 276 277 iterator begin_, end_; 278 const origin_type *origin; 279 size_type nr, nc; 280 281 conjugated_col_matrix_const_ref(const M &m) 282 : begin_(mat_col_begin(m)), end_(mat_col_end(m)), 283 origin(linalg_origin(m)), nr(mat_ncols(m)), nc(mat_nrows(m)) {} 284 285 value_type operator()(size_type i, size_type j) const 286 { return gmm::conj(linalg_traits<M>::access(begin_+i, j)); } 287 }; 288 289 template <typename M> 290 struct linalg_traits<conjugated_col_matrix_const_ref<M> > { 291 typedef conjugated_col_matrix_const_ref<M> this_type; 292 typedef typename linalg_traits<M>::origin_type origin_type; 293 typedef linalg_const is_reference; 294 typedef abstract_matrix linalg_type; 295 typedef typename linalg_traits<M>::value_type value_type; 296 typedef value_type reference; 297 typedef typename linalg_traits<M>::storage_type storage_type; 298 typedef typename linalg_traits<M>::const_sub_col_type vector_type; 299 typedef conjugated_vector_const_ref<vector_type> sub_row_type; 300 typedef conjugated_vector_const_ref<vector_type> const_sub_row_type; 301 typedef conjugated_col_const_iterator<M> row_iterator; 302 typedef conjugated_col_const_iterator<M> const_row_iterator; 303 typedef abstract_null_type const_sub_col_type; 304 typedef abstract_null_type sub_col_type; 305 typedef abstract_null_type const_col_iterator; 306 typedef abstract_null_type col_iterator; 307 typedef row_major sub_orientation; 308 typedef typename linalg_traits<M>::index_sorted index_sorted; 309 static inline size_type nrows(const this_type &m) { return m.nr; } 310 static inline size_type ncols(const this_type &m) { return m.nc; } 311 static inline const_sub_row_type row(const const_row_iterator &it) 312 { return conjugated(linalg_traits<M>::col(it.it)); } 313 static inline const_row_iterator row_begin(const this_type &m) 314 { return const_row_iterator(m.begin_); } 315 static inline const_row_iterator row_end(const this_type &m) 316 { return const_row_iterator(m.end_); } 317 static inline const origin_type* origin(const this_type &m) 318 { return m.origin; } 319 static value_type access(const const_row_iterator &it, size_type i) 320 { return gmm::conj(linalg_traits<M>::access(it.it, i)); } 321 }; 322 323 template<typename M> std::ostream &operator << 324 (std::ostream &o, const conjugated_col_matrix_const_ref<M>& m) 325 { gmm::write(o,m); return o; } 326 327 328 template <typename L, typename SO> struct conjugated_return__ { 329 typedef conjugated_row_matrix_const_ref<L> return_type; 330 }; 331 template <typename L> struct conjugated_return__<L, col_major> { 332 typedef conjugated_col_matrix_const_ref<L> return_type; 333 }; 334 template <typename L, typename T, typename LT> struct conjugated_return_ { 335 typedef const L & return_type; 336 }; 337 template <typename L, typename T> 338 struct conjugated_return_<L, std::complex<T>, abstract_vector> { 339 typedef conjugated_vector_const_ref<L> return_type; 340 }; 341 template <typename L, typename T> 342 struct conjugated_return_<L, T, abstract_matrix> { 343 typedef typename conjugated_return__<L, 344 typename principal_orientation_type<typename 345 linalg_traits<L>::sub_orientation>::potype 346 >::return_type return_type; 347 }; 348 template <typename L> struct conjugated_return { 349 typedef typename 350 conjugated_return_<L, typename linalg_traits<L>::value_type, 351 typename linalg_traits<L>::linalg_type 352 >::return_type return_type; 353 }; 354 355 ///@endcond 356 /** return a conjugated view of the input matrix or vector. */ 357 template <typename L> inline 358 typename conjugated_return<L>::return_type 359 conjugated(const L &v) { 360 return conjugated(v, typename linalg_traits<L>::value_type(), 361 typename linalg_traits<L>::linalg_type()); 362 } 363 ///@cond DOXY_SHOW_ALL_FUNCTIONS 364 365 template <typename L, typename T, typename LT> inline 366 const L & conjugated(const L &v, T, LT) { return v; } 367 368 template <typename L, typename T> inline 369 conjugated_vector_const_ref<L> conjugated(const L &v, std::complex<T>, 370 abstract_vector) 371 { return conjugated_vector_const_ref<L>(v); } 372 373 template <typename L, typename T> inline 374 typename conjugated_return__<L, 375 typename principal_orientation_type<typename 376 linalg_traits<L>::sub_orientation>::potype>::return_type 377 conjugated(const L &v, T, abstract_matrix) { 378 return conjugated(v, typename principal_orientation_type<typename 379 linalg_traits<L>::sub_orientation>::potype()); 380 } 381 382 template <typename L> inline 383 conjugated_row_matrix_const_ref<L> conjugated(const L &v, row_major) 384 { return conjugated_row_matrix_const_ref<L>(v); } 385 386 template <typename L> inline 387 conjugated_col_matrix_const_ref<L> conjugated(const L &v, col_major) 388 { return conjugated_col_matrix_const_ref<L>(v); } 389 390 ///@endcond 391 392 393 } 394 395 #endif // GMM_CONJUGATED_H__ 396