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_vector_to_matrix.h 32 @author Yves Renard <Yves.Renard@insa-lyon.fr> 33 @date December 6, 2003. 34 @brief View vectors as row or column matrices. */ 35 #ifndef GMM_VECTOR_TO_MATRIX_H__ 36 #define GMM_VECTOR_TO_MATRIX_H__ 37 38 #include "gmm_interface.h" 39 40 namespace gmm { 41 42 /* ********************************************************************* */ 43 /* row vector -> transform a vector in a (1, n) matrix. */ 44 /* ********************************************************************* */ 45 46 template <typename PT> struct gen_row_vector { 47 typedef gen_row_vector<PT> this_type; 48 typedef typename std::iterator_traits<PT>::value_type V; 49 typedef V * CPT; 50 typedef typename std::iterator_traits<PT>::reference ref_V; 51 typedef typename linalg_traits<this_type>::reference reference; 52 53 simple_vector_ref<PT> vec; 54 operatorgen_row_vector55 reference operator()(size_type, size_type j) const { return vec[j]; } 56 nrowsgen_row_vector57 size_type nrows(void) const { return 1; } ncolsgen_row_vector58 size_type ncols(void) const { return vect_size(vec); } 59 gen_row_vectorgen_row_vector60 gen_row_vector(ref_V v) : vec(v) {} gen_row_vectorgen_row_vector61 gen_row_vector() {} gen_row_vectorgen_row_vector62 gen_row_vector(const gen_row_vector<CPT> &cr) : vec(cr.vec) {} 63 }; 64 65 template <typename PT> 66 struct gen_row_vector_iterator { 67 typedef gen_row_vector<PT> this_type; 68 typedef typename modifiable_pointer<PT>::pointer MPT; 69 typedef typename std::iterator_traits<PT>::value_type V; 70 typedef simple_vector_ref<PT> value_type; 71 typedef const simple_vector_ref<PT> *pointer; 72 typedef const simple_vector_ref<PT> &reference; 73 typedef ptrdiff_t difference_type; 74 typedef size_t size_type; 75 typedef std::random_access_iterator_tag iterator_category; 76 typedef gen_row_vector_iterator<PT> iterator; 77 78 simple_vector_ref<PT> vec; 79 bool isend; 80 81 iterator &operator ++() { isend = true; return *this; } 82 iterator &operator --() { isend = false; return *this; } 83 iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } 84 iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } 85 iterator &operator +=(difference_type i) 86 { if (i) isend = false; return *this; } 87 iterator &operator -=(difference_type i) 88 { if (i) isend = true; return *this; } 89 iterator operator +(difference_type i) const 90 { iterator itt = *this; return (itt += i); } 91 iterator operator -(difference_type i) const 92 { iterator itt = *this; return (itt -= i); } 93 difference_type operator -(const iterator &i) const { 94 return (isend == true) ? ((i.isend == true) ? 0 : 1) 95 : ((i.isend == true) ? -1 : 0); 96 } 97 98 const simple_vector_ref<PT>& operator *() const { return vec; } 99 const simple_vector_ref<PT>& operator [](int i) { return vec; } 100 101 bool operator ==(const iterator &i) const { return (isend == i.isend); } 102 bool operator !=(const iterator &i) const { return !(i == *this); } 103 bool operator < (const iterator &i) const { return (*this - i < 0); } 104 gen_row_vector_iteratorgen_row_vector_iterator105 gen_row_vector_iterator(void) {} gen_row_vector_iteratorgen_row_vector_iterator106 gen_row_vector_iterator(const gen_row_vector_iterator<MPT> &itm) 107 : vec(itm.vec), isend(itm.isend) {} gen_row_vector_iteratorgen_row_vector_iterator108 gen_row_vector_iterator(const gen_row_vector<PT> &m, bool iis_end) 109 : vec(m.vec), isend(iis_end) { } 110 111 }; 112 113 template <typename PT> 114 struct linalg_traits<gen_row_vector<PT> > { 115 typedef gen_row_vector<PT> this_type; 116 typedef typename std::iterator_traits<PT>::value_type V; 117 typedef typename which_reference<PT>::is_reference is_reference; 118 typedef abstract_matrix linalg_type; 119 typedef typename linalg_traits<V>::origin_type origin_type; 120 typedef typename select_ref<const origin_type *, origin_type *, 121 PT>::ref_type porigin_type; 122 typedef typename linalg_traits<V>::value_type value_type; 123 typedef typename select_ref<value_type, 124 typename linalg_traits<V>::reference, PT>::ref_type reference; 125 typedef abstract_null_type sub_col_type; 126 typedef abstract_null_type col_iterator; 127 typedef abstract_null_type const_sub_col_type; 128 typedef abstract_null_type const_col_iterator; 129 typedef simple_vector_ref<const V *> const_sub_row_type; 130 typedef typename select_ref<abstract_null_type, 131 simple_vector_ref<V *>, PT>::ref_type sub_row_type; 132 typedef gen_row_vector_iterator<typename const_pointer<PT>::pointer> 133 const_row_iterator; 134 typedef typename select_ref<abstract_null_type, 135 gen_row_vector_iterator<PT>, PT>::ref_type row_iterator; 136 typedef typename linalg_traits<V>::storage_type storage_type; 137 typedef row_major sub_orientation; 138 typedef typename linalg_traits<V>::index_sorted index_sorted; 139 static size_type nrows(const this_type &) { return 1; } 140 static size_type ncols(const this_type &m) { return m.ncols(); } 141 static const_sub_row_type row(const const_row_iterator &it) { return *it; } 142 static sub_row_type row(const row_iterator &it) { return *it; } 143 static const_row_iterator row_begin(const this_type &m) 144 { return const_row_iterator(m, false); } 145 static row_iterator row_begin(this_type &m) 146 { return row_iterator(m, false); } 147 static const_row_iterator row_end(const this_type &m) 148 { return const_row_iterator(m, true); } 149 static row_iterator row_end(this_type &m) 150 { return row_iterator(m, true); } 151 static origin_type* origin(this_type &m) { return m.vec.origin; } 152 static const origin_type* origin(const this_type &m) 153 { return m.vec.origin; } 154 static void do_clear(this_type &m) 155 { clear(row(mat_row_begin(m))); } 156 static value_type access(const const_row_iterator &itrow, size_type i) 157 { return itrow.vec[i]; } 158 static reference access(const row_iterator &itrow, size_type i) 159 { return itrow.vec[i]; } 160 }; 161 162 template <typename PT> 163 std::ostream &operator <<(std::ostream &o, const gen_row_vector<PT>& m) 164 { gmm::write(o,m); return o; } 165 166 /* ********************************************************************* */ 167 /* col vector -> transform a vector in a (n, 1) matrix. */ 168 /* ********************************************************************* */ 169 170 template <typename PT> struct gen_col_vector { 171 typedef gen_col_vector<PT> this_type; 172 typedef typename std::iterator_traits<PT>::value_type V; 173 typedef V * CPT; 174 typedef typename std::iterator_traits<PT>::reference ref_V; 175 typedef typename linalg_traits<this_type>::reference reference; 176 177 simple_vector_ref<PT> vec; 178 179 reference operator()(size_type i, size_type) const { return vec[i]; } 180 181 size_type ncols(void) const { return 1; } 182 size_type nrows(void) const { return vect_size(vec); } 183 184 gen_col_vector(ref_V v) : vec(v) {} 185 gen_col_vector() {} 186 gen_col_vector(const gen_col_vector<CPT> &cr) : vec(cr.vec) {} 187 }; 188 189 template <typename PT> 190 struct gen_col_vector_iterator { 191 typedef gen_col_vector<PT> this_type; 192 typedef typename modifiable_pointer<PT>::pointer MPT; 193 typedef typename std::iterator_traits<PT>::value_type V; 194 typedef simple_vector_ref<PT> value_type; 195 typedef const simple_vector_ref<PT> *pointer; 196 typedef const simple_vector_ref<PT> &reference; 197 typedef ptrdiff_t difference_type; 198 typedef size_t size_type; 199 typedef std::random_access_iterator_tag iterator_category; 200 typedef gen_col_vector_iterator<PT> iterator; 201 202 simple_vector_ref<PT> vec; 203 bool isend; 204 205 iterator &operator ++() { isend = true; return *this; } 206 iterator &operator --() { isend = false; return *this; } 207 iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } 208 iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } 209 iterator &operator +=(difference_type i) 210 { if (i) isend = false; return *this; } 211 iterator &operator -=(difference_type i) 212 { if (i) isend = true; return *this; } 213 iterator operator +(difference_type i) const 214 { iterator itt = *this; return (itt += i); } 215 iterator operator -(difference_type i) const 216 { iterator itt = *this; return (itt -= i); } 217 difference_type operator -(const iterator &i) const { 218 return (isend == true) ? ((i.isend == true) ? 0 : 1) 219 : ((i.isend == true) ? -1 : 0); 220 } 221 222 const simple_vector_ref<PT>& operator *() const { return vec; } 223 const simple_vector_ref<PT>& operator [](int i) { return vec; } 224 225 bool operator ==(const iterator &i) const { return (isend == i.isend); } 226 bool operator !=(const iterator &i) const { return !(i == *this); } 227 bool operator < (const iterator &i) const { return (*this - i < 0); } 228 229 gen_col_vector_iterator(void) {} 230 gen_col_vector_iterator(const gen_col_vector_iterator<MPT> &itm) 231 : vec(itm.vec), isend(itm.isend) {} 232 gen_col_vector_iterator(const gen_col_vector<PT> &m, bool iis_end) 233 : vec(m.vec), isend(iis_end) { } 234 235 }; 236 237 template <typename PT> 238 struct linalg_traits<gen_col_vector<PT> > { 239 typedef gen_col_vector<PT> this_type; 240 typedef typename std::iterator_traits<PT>::value_type V; 241 typedef typename which_reference<PT>::is_reference is_reference; 242 typedef abstract_matrix linalg_type; 243 typedef typename linalg_traits<V>::origin_type origin_type; 244 typedef typename select_ref<const origin_type *, origin_type *, 245 PT>::ref_type porigin_type; 246 typedef typename linalg_traits<V>::value_type value_type; 247 typedef typename select_ref<value_type, 248 typename linalg_traits<V>::reference, PT>::ref_type reference; 249 typedef abstract_null_type sub_row_type; 250 typedef abstract_null_type row_iterator; 251 typedef abstract_null_type const_sub_row_type; 252 typedef abstract_null_type const_row_iterator; 253 typedef simple_vector_ref<const V *> const_sub_col_type; 254 typedef typename select_ref<abstract_null_type, 255 simple_vector_ref<V *>, PT>::ref_type sub_col_type; 256 typedef gen_col_vector_iterator<typename const_pointer<PT>::pointer> 257 const_col_iterator; 258 typedef typename select_ref<abstract_null_type, 259 gen_col_vector_iterator<PT>, PT>::ref_type col_iterator; 260 typedef typename linalg_traits<V>::storage_type storage_type; 261 typedef col_major sub_orientation; 262 typedef typename linalg_traits<V>::index_sorted index_sorted; 263 static size_type ncols(const this_type &) { return 1; } 264 static size_type nrows(const this_type &m) { return m.nrows(); } 265 static const_sub_col_type col(const const_col_iterator &it) { return *it; } 266 static sub_col_type col(const col_iterator &it) { return *it; } 267 static const_col_iterator col_begin(const this_type &m) 268 { return const_col_iterator(m, false); } 269 static col_iterator col_begin(this_type &m) 270 { return col_iterator(m, false); } 271 static const_col_iterator col_end(const this_type &m) 272 { return const_col_iterator(m, true); } 273 static col_iterator col_end(this_type &m) 274 { return col_iterator(m, true); } 275 static origin_type* origin(this_type &m) { return m.vec.origin; } 276 static const origin_type* origin(const this_type &m) 277 { return m.vec.origin; } 278 static void do_clear(this_type &m) 279 { clear(col(mat_col_begin(m))); } 280 static value_type access(const const_col_iterator &itcol, size_type i) 281 { return itcol.vec[i]; } 282 static reference access(const col_iterator &itcol, size_type i) 283 { return itcol.vec[i]; } 284 }; 285 286 template <typename PT> 287 std::ostream &operator <<(std::ostream &o, const gen_col_vector<PT>& m) 288 { gmm::write(o,m); return o; } 289 290 /* ******************************************************************** */ 291 /* col and row vectors */ 292 /* ******************************************************************** */ 293 294 295 template <class V> inline 296 typename select_return< gen_row_vector<const V *>, gen_row_vector<V *>, 297 const V *>::return_type 298 row_vector(const V& v) { 299 return typename select_return< gen_row_vector<const V *>, 300 gen_row_vector<V *>, const V *>::return_type(linalg_cast(v)); 301 } 302 303 template <class V> inline 304 typename select_return< gen_row_vector<const V *>, gen_row_vector<V *>, 305 V *>::return_type 306 row_vector(V& v) { 307 return typename select_return< gen_row_vector<const V *>, 308 gen_row_vector<V *>, V *>::return_type(linalg_cast(v)); 309 } 310 311 template <class V> inline gen_row_vector<const V *> 312 const_row_vector(V& v) 313 { return gen_row_vector<const V *>(v); } 314 315 316 template <class V> inline 317 typename select_return< gen_col_vector<const V *>, gen_col_vector<V *>, 318 const V *>::return_type 319 col_vector(const V& v) { 320 return typename select_return< gen_col_vector<const V *>, 321 gen_col_vector<V *>, const V *>::return_type(linalg_cast(v)); 322 } 323 324 template <class V> inline 325 typename select_return< gen_col_vector<const V *>, gen_col_vector<V *>, 326 V *>::return_type 327 col_vector(V& v) { 328 return typename select_return< gen_col_vector<const V *>, 329 gen_col_vector<V *>, V *>::return_type(linalg_cast(v)); 330 } 331 332 template <class V> inline gen_col_vector<const V *> 333 const_col_vector(V& v) 334 { return gen_col_vector<const V *>(v); } 335 336 337 } 338 339 #endif // GMM_VECTOR_TO_MATRIX_H__ 340