1 // -*- c++ -*- (enables emacs c++ mode) 2 //=========================================================================== 3 // 4 // Copyright (C) 2002-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_transposed.h 32 @author Yves Renard <Yves.Renard@insa-lyon.fr> 33 @date November 10, 2002. 34 @brief Generic transposed matrices 35 */ 36 #ifndef GMM_TRANSPOSED_H__ 37 #define GMM_TRANSPOSED_H__ 38 39 #include "gmm_def.h" 40 41 namespace gmm { 42 43 /* ********************************************************************* */ 44 /* transposed reference */ 45 /* ********************************************************************* */ 46 47 template <typename PT> struct transposed_row_ref { 48 49 typedef transposed_row_ref<PT> this_type; 50 typedef typename std::iterator_traits<PT>::value_type M; 51 typedef M * CPT; 52 typedef typename std::iterator_traits<PT>::reference ref_M; 53 typedef typename select_ref<typename linalg_traits<this_type> 54 ::const_col_iterator, typename linalg_traits<this_type> 55 ::col_iterator, PT>::ref_type iterator; 56 typedef typename linalg_traits<this_type>::reference reference; 57 typedef typename linalg_traits<this_type>::porigin_type porigin_type; 58 59 iterator begin_, end_; 60 porigin_type origin; 61 size_type nr, nc; 62 transposed_row_reftransposed_row_ref63 transposed_row_ref(ref_M m) 64 : begin_(mat_row_begin(m)), end_(mat_row_end(m)), 65 origin(linalg_origin(m)), nr(mat_ncols(m)), nc(mat_nrows(m)) {} 66 transposed_row_reftransposed_row_ref67 transposed_row_ref(const transposed_row_ref<CPT> &cr) : 68 begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {} 69 operatortransposed_row_ref70 reference operator()(size_type i, size_type j) const 71 { return linalg_traits<M>::access(begin_+j, i); } 72 }; 73 74 template <typename PT> struct linalg_traits<transposed_row_ref<PT> > { 75 typedef transposed_row_ref<PT> this_type; 76 typedef typename std::iterator_traits<PT>::value_type M; 77 typedef typename linalg_traits<M>::origin_type origin_type; 78 typedef typename select_ref<const origin_type *, origin_type *, 79 PT>::ref_type porigin_type; 80 typedef typename which_reference<PT>::is_reference is_reference; 81 typedef abstract_matrix linalg_type; 82 typedef typename linalg_traits<M>::value_type value_type; 83 typedef typename select_ref<value_type, 84 typename linalg_traits<M>::reference, PT>::ref_type reference; 85 typedef typename linalg_traits<M>::storage_type storage_type; 86 typedef abstract_null_type sub_row_type; 87 typedef abstract_null_type const_sub_row_type; 88 typedef abstract_null_type row_iterator; 89 typedef abstract_null_type const_row_iterator; 90 typedef typename linalg_traits<M>::const_sub_row_type const_sub_col_type; 91 typedef typename select_ref<abstract_null_type, typename 92 linalg_traits<M>::sub_row_type, PT>::ref_type sub_col_type; 93 typedef typename linalg_traits<M>::const_row_iterator const_col_iterator; 94 typedef typename select_ref<abstract_null_type, typename 95 linalg_traits<M>::row_iterator, PT>::ref_type col_iterator; 96 typedef col_major sub_orientation; 97 typedef typename linalg_traits<M>::index_sorted index_sorted; 98 static size_type ncols(const this_type &v) { return v.nc; } 99 static size_type nrows(const this_type &v) { return v.nr; } 100 static const_sub_col_type col(const const_col_iterator &it) 101 { return linalg_traits<M>::row(it); } 102 static sub_col_type col(const col_iterator &it) 103 { return linalg_traits<M>::row(it); } 104 static col_iterator col_begin(this_type &m) { return m.begin_; } 105 static col_iterator col_end(this_type &m) { return m.end_; } 106 static const_col_iterator col_begin(const this_type &m) 107 { return m.begin_; } 108 static const_col_iterator col_end(const this_type &m) { return m.end_; } 109 static origin_type* origin(this_type &v) { return v.origin; } 110 static const origin_type* origin(const this_type &v) { return v.origin; } 111 static void do_clear(this_type &v); 112 static value_type access(const const_col_iterator &itcol, size_type i) 113 { return linalg_traits<M>::access(itcol, i); } 114 static reference access(const col_iterator &itcol, size_type i) 115 { return linalg_traits<M>::access(itcol, i); } 116 }; 117 118 template <typename PT> 119 void linalg_traits<transposed_row_ref<PT> >::do_clear(this_type &v) { 120 col_iterator it = mat_col_begin(v), ite = mat_col_end(v); 121 for (; it != ite; ++it) clear(col(it)); 122 } 123 124 template<typename PT> std::ostream &operator << 125 (std::ostream &o, const transposed_row_ref<PT>& m) 126 { gmm::write(o,m); return o; } 127 128 template <typename PT> struct transposed_col_ref { 129 130 typedef transposed_col_ref<PT> this_type; 131 typedef typename std::iterator_traits<PT>::value_type M; 132 typedef M * CPT; 133 typedef typename std::iterator_traits<PT>::reference ref_M; 134 typedef typename select_ref<typename linalg_traits<this_type> 135 ::const_row_iterator, typename linalg_traits<this_type> 136 ::row_iterator, PT>::ref_type iterator; 137 typedef typename linalg_traits<this_type>::reference reference; 138 typedef typename linalg_traits<this_type>::porigin_type porigin_type; 139 140 iterator begin_, end_; 141 porigin_type origin; 142 size_type nr, nc; 143 144 transposed_col_ref(ref_M m) 145 : begin_(mat_col_begin(m)), end_(mat_col_end(m)), 146 origin(linalg_origin(m)), nr(mat_ncols(m)), nc(mat_nrows(m)) {} 147 148 transposed_col_ref(const transposed_col_ref<CPT> &cr) : 149 begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {} 150 151 reference operator()(size_type i, size_type j) const 152 { return linalg_traits<M>::access(begin_+i, j); } 153 }; 154 155 template <typename PT> struct linalg_traits<transposed_col_ref<PT> > { 156 typedef transposed_col_ref<PT> this_type; 157 typedef typename std::iterator_traits<PT>::value_type M; 158 typedef typename linalg_traits<M>::origin_type origin_type; 159 typedef typename select_ref<const origin_type *, origin_type *, 160 PT>::ref_type porigin_type; 161 typedef typename which_reference<PT>::is_reference is_reference; 162 typedef abstract_matrix linalg_type; 163 typedef typename linalg_traits<M>::value_type value_type; 164 typedef typename select_ref<value_type, 165 typename linalg_traits<M>::reference, PT>::ref_type reference; 166 typedef typename linalg_traits<M>::storage_type storage_type; 167 typedef abstract_null_type sub_col_type; 168 typedef abstract_null_type const_sub_col_type; 169 typedef abstract_null_type col_iterator; 170 typedef abstract_null_type const_col_iterator; 171 typedef typename linalg_traits<M>::const_sub_col_type const_sub_row_type; 172 typedef typename select_ref<abstract_null_type, typename 173 linalg_traits<M>::sub_col_type, PT>::ref_type sub_row_type; 174 typedef typename linalg_traits<M>::const_col_iterator const_row_iterator; 175 typedef typename select_ref<abstract_null_type, typename 176 linalg_traits<M>::col_iterator, PT>::ref_type row_iterator; 177 typedef row_major sub_orientation; 178 typedef typename linalg_traits<M>::index_sorted index_sorted; 179 static size_type nrows(const this_type &v) 180 { return v.nr; } 181 static size_type ncols(const this_type &v) 182 { return v.nc; } 183 static const_sub_row_type row(const const_row_iterator &it) 184 { return linalg_traits<M>::col(it); } 185 static sub_row_type row(const row_iterator &it) 186 { return linalg_traits<M>::col(it); } 187 static row_iterator row_begin(this_type &m) { return m.begin_; } 188 static row_iterator row_end(this_type &m) { return m.end_; } 189 static const_row_iterator row_begin(const this_type &m) 190 { return m.begin_; } 191 static const_row_iterator row_end(const this_type &m) { return m.end_; } 192 static origin_type* origin(this_type &v) { return v.origin; } 193 static const origin_type* origin(const this_type &v) { return v.origin; } 194 static void do_clear(this_type &m); 195 static value_type access(const const_row_iterator &itrow, size_type i) 196 { return linalg_traits<M>::access(itrow, i); } 197 static reference access(const row_iterator &itrow, size_type i) 198 { return linalg_traits<M>::access(itrow, i); } 199 }; 200 201 template <typename PT> 202 void linalg_traits<transposed_col_ref<PT> >::do_clear(this_type &v) { 203 row_iterator it = mat_row_begin(v), ite = mat_row_end(v); 204 for (; it != ite; ++it) clear(row(it)); 205 } 206 207 template<typename PT> std::ostream &operator << 208 (std::ostream &o, const transposed_col_ref<PT>& m) 209 { gmm::write(o,m); return o; } 210 211 template <typename TYPE, typename PT> struct transposed_return_ { 212 typedef abstract_null_type return_type; 213 }; 214 template <typename PT> struct transposed_return_<row_major, PT> { 215 typedef typename std::iterator_traits<PT>::value_type L; 216 typedef typename select_return<transposed_row_ref<const L *>, 217 transposed_row_ref< L *>, PT>::return_type return_type; 218 }; 219 template <typename PT> struct transposed_return_<col_major, PT> { 220 typedef typename std::iterator_traits<PT>::value_type L; 221 typedef typename select_return<transposed_col_ref<const L *>, 222 transposed_col_ref< L *>, PT>::return_type return_type; 223 }; 224 template <typename PT> struct transposed_return { 225 typedef typename std::iterator_traits<PT>::value_type L; 226 typedef typename transposed_return_<typename principal_orientation_type< 227 typename linalg_traits<L>::sub_orientation>::potype, 228 PT>::return_type return_type; 229 }; 230 231 template <typename L> inline 232 typename transposed_return<const L *>::return_type transposed(const L &l) { 233 return typename transposed_return<const L *>::return_type 234 (linalg_cast(const_cast<L &>(l))); 235 } 236 237 template <typename L> inline 238 typename transposed_return<L *>::return_type transposed(L &l) 239 { return typename transposed_return<L *>::return_type(linalg_cast(l)); } 240 241 } 242 243 #endif // GMM_TRANSPOSED_H__ 244