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