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