GetFEM  5.4.3
gmm_scaled.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2002-2020 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 <[email protected]>
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  inline bool operator > (const scaled_const_iterator &i) const
92  { return (it > i.it); }
93  inline bool operator >=(const scaled_const_iterator &i) const
94  { return (it >= i.it); }
95  };
96 
97  template <typename V, typename S> struct scaled_vector_const_ref {
98  typedef scaled_vector_const_ref<V,S> this_type;
99  typedef typename linalg_traits<this_type>::value_type value_type;
100  typedef typename linalg_traits<V>::const_iterator iterator;
101  typedef typename linalg_traits<this_type>::reference reference;
102  typedef typename linalg_traits<this_type>::origin_type origin_type;
103 
104  iterator begin_, end_;
105  const origin_type *origin;
106  size_type size_;
107  S r;
108 
109  scaled_vector_const_ref(const V &v, S rr)
110  : begin_(vect_const_begin(v)), end_(vect_const_end(v)),
111  origin(linalg_origin(v)), size_(vect_size(v)), r(rr) {}
112 
113  reference operator[](size_type i) const
114  { return value_type(r) * linalg_traits<V>::access(origin, begin_, end_, i); }
115  };
116 
117 
118  template<typename V, typename S> std::ostream &operator <<
119  (std::ostream &o, const scaled_vector_const_ref<V,S>& m)
120  { gmm::write(o,m); return o; }
121 
122  /* ********************************************************************* */
123  /* Scaled references on matrices */
124  /* ********************************************************************* */
125 
126  template <typename M, typename S> struct scaled_row_const_iterator {
127  typedef scaled_row_const_iterator<M,S> iterator;
128  typedef typename linalg_traits<M>::const_row_iterator ITER;
129  typedef ptrdiff_t difference_type;
130  typedef size_t size_type;
131 
132  ITER it;
133  S r;
134 
135  inline iterator operator ++(int) { iterator tmp=*this; it++; return tmp; }
136  inline iterator operator --(int) { iterator tmp=*this; it--; return tmp; }
137  inline iterator &operator ++() { it++; return *this; }
138  inline iterator &operator --() { it--; return *this; }
139  iterator &operator +=(difference_type i) { it += i; return *this; }
140  iterator &operator -=(difference_type i) { it -= i; return *this; }
141  iterator operator +(difference_type i) const
142  { iterator itt = *this; return (itt += i); }
143  iterator operator -(difference_type i) const
144  { iterator itt = *this; return (itt -= i); }
145  difference_type operator -(const iterator &i) const
146  { return it - i.it; }
147 
148  inline ITER operator *() const { return it; }
149  inline ITER operator [](int i) { return it + i; }
150 
151  inline bool operator ==(const iterator &i) const { return (it == i.it); }
152  inline bool operator !=(const iterator &i) const { return !(i == *this); }
153  inline bool operator < (const iterator &i) const { return (it < i.it); }
154  inline bool operator >=(const iterator &i) const { return (it >= i.it); }
155  inline bool operator > (const iterator &i) const { return (it > i.it); }
156 
157  scaled_row_const_iterator(void) {}
158  scaled_row_const_iterator(const ITER &i, S rr)
159  : it(i), r(rr) { }
160 
161  };
162 
163  template <typename M, typename S> struct scaled_row_matrix_const_ref {
164 
165  typedef scaled_row_matrix_const_ref<M,S> this_type;
166  typedef typename linalg_traits<M>::const_row_iterator iterator;
167  typedef typename linalg_traits<this_type>::value_type value_type;
168  typedef typename linalg_traits<this_type>::origin_type origin_type;
169 
170  iterator begin_, end_;
171  const origin_type *origin;
172  S r;
173  size_type nr, nc;
174 
175  scaled_row_matrix_const_ref(const M &m, S rr)
176  : begin_(mat_row_begin(m)), end_(mat_row_end(m)),
177  origin(linalg_origin(m)), r(rr), nr(mat_nrows(m)), nc(mat_ncols(m)) {}
178 
179  value_type operator()(size_type i, size_type j) const
180  { return r * linalg_traits<M>::access(begin_+i, j); }
181  };
182 
183 
184  template<typename M, typename S> std::ostream &operator <<
185  (std::ostream &o, const scaled_row_matrix_const_ref<M,S>& m)
186  { gmm::write(o,m); return o; }
187 
188 
189  template <typename M, typename S> struct scaled_col_const_iterator {
190  typedef scaled_col_const_iterator<M,S> iterator;
191  typedef typename linalg_traits<M>::const_col_iterator ITER;
192  typedef ptrdiff_t difference_type;
193  typedef size_t size_type;
194 
195  ITER it;
196  S r;
197 
198  iterator operator ++(int) { iterator tmp = *this; it++; return tmp; }
199  iterator operator --(int) { iterator tmp = *this; it--; return tmp; }
200  iterator &operator ++() { it++; return *this; }
201  iterator &operator --() { it--; return *this; }
202  iterator &operator +=(difference_type i) { it += i; return *this; }
203  iterator &operator -=(difference_type i) { it -= i; return *this; }
204  iterator operator +(difference_type i) const
205  { iterator itt = *this; return (itt += i); }
206  iterator operator -(difference_type i) const
207  { iterator itt = *this; return (itt -= i); }
208  difference_type operator -(const iterator &i) const
209  { return it - i.it; }
210 
211  ITER operator *() const { return it; }
212  ITER operator [](int i) { return it + i; }
213 
214  bool operator ==(const iterator &i) const { return (it == i.it); }
215  bool operator !=(const iterator &i) const { return !(i == *this); }
216  bool operator < (const iterator &i) const { return (it < i.it); }
217  bool operator > (const iterator &i) const { return (it > i.it); }
218  bool operator >=(const iterator &i) const { return (it >= i.it); }
219 
220  scaled_col_const_iterator(void) {}
221  scaled_col_const_iterator(const ITER &i, S rr)
222  : it(i), r(rr) { }
223 
224  };
225 
226  template <typename M, typename S> struct scaled_col_matrix_const_ref {
227 
228  typedef scaled_col_matrix_const_ref<M,S> this_type;
229  typedef typename linalg_traits<M>::const_col_iterator iterator;
230  typedef typename linalg_traits<this_type>::value_type value_type;
231  typedef typename linalg_traits<this_type>::origin_type origin_type;
232 
233  iterator begin_, end_;
234  const origin_type *origin;
235  S r;
236  size_type nr, nc;
237 
238  scaled_col_matrix_const_ref(const M &m, S rr)
239  : begin_(mat_col_begin(m)), end_(mat_col_end(m)),
240  origin(linalg_origin(m)), r(rr), nr(mat_nrows(m)), nc(mat_ncols(m)) {}
241 
242  value_type operator()(size_type i, size_type j) const
243  { return r * linalg_traits<M>::access(begin_+j, i); }
244  };
245 
246 
247 
248  template<typename M, typename S> std::ostream &operator <<
249  (std::ostream &o, const scaled_col_matrix_const_ref<M,S>& m)
250  { gmm::write(o,m); return o; }
251 
252 
253  template <typename L, typename S, typename R> struct scaled_return__ {
254  typedef abstract_null_type return_type;
255  };
256  template <typename L, typename S> struct scaled_return__<L, S, row_major>
257  { typedef scaled_row_matrix_const_ref<L,S> return_type; };
258  template <typename L, typename S> struct scaled_return__<L, S, col_major>
259  { typedef scaled_col_matrix_const_ref<L,S> return_type; };
260 
261 
262  template <typename L, typename S, typename LT> struct scaled_return_ {
263  typedef abstract_null_type return_type;
264  };
265  template <typename L, typename S> struct scaled_return_<L, S, abstract_vector>
266  { typedef scaled_vector_const_ref<L,S> return_type; };
267  template <typename L, typename S> struct scaled_return_<L, S, abstract_matrix> {
268  typedef typename scaled_return__<L, S,
269  typename principal_orientation_type<typename
270  linalg_traits<L>::sub_orientation>::potype>::return_type return_type;
271  };
272 
273  template <typename L, typename S> struct scaled_return {
274  typedef typename scaled_return_<L, S, typename
275  linalg_traits<L>::linalg_type>::return_type return_type;
276  };
277 
278  template <typename L, typename S> inline
279  typename scaled_return<L,S>::return_type
280  scaled(const L &v, S x)
281  { return scaled(v, x, typename linalg_traits<L>::linalg_type()); }
282 
283  template <typename V, typename S> inline
284  typename scaled_return<V,S>::return_type
285  scaled(const V &v, S x, abstract_vector)
286  { return scaled_vector_const_ref<V,S>(v, x); }
287 
288  template <typename M, typename S> inline
289  typename scaled_return<M,S>::return_type
290  scaled(const M &m, S x,abstract_matrix) {
291  return scaled(m, x, typename principal_orientation_type<typename
292  linalg_traits<M>::sub_orientation>::potype());
293  }
294 
295  template <typename M, typename S> inline
296  typename scaled_return<M,S>::return_type
297  scaled(const M &m, S x, row_major) {
298  return scaled_row_matrix_const_ref<M,S>(m, x);
299  }
300 
301  template <typename M, typename S> inline
302  typename scaled_return<M,S>::return_type
303  scaled(const M &m, S x, col_major) {
304  return scaled_col_matrix_const_ref<M,S>(m, x);
305  }
306 
307 
308  /* ******************************************************************** */
309  /* matrix or vector scale */
310  /* ******************************************************************** */
311 
312  template <typename L> inline
313  void scale(L& l, typename linalg_traits<L>::value_type a)
314  { scale(l, a, typename linalg_traits<L>::linalg_type()); }
315 
316  template <typename L> inline
317  void scale(const L& l, typename linalg_traits<L>::value_type a)
318  { scale(linalg_const_cast(l), a); }
319 
320  template <typename L> inline
321  void scale(L& l, typename linalg_traits<L>::value_type a, abstract_vector) {
322  typename linalg_traits<L>::iterator it = vect_begin(l), ite = vect_end(l);
323  for ( ; it != ite; ++it) *it *= a;
324  }
325 
326  template <typename L>
327  void scale(L& l, typename linalg_traits<L>::value_type a, abstract_matrix) {
328  scale(l, a, typename principal_orientation_type<typename
329  linalg_traits<L>::sub_orientation>::potype());
330  }
331 
332  template <typename L>
333  void scale(L& l, typename linalg_traits<L>::value_type a, row_major) {
334  typename linalg_traits<L>::row_iterator it = mat_row_begin(l),
335  ite = mat_row_end(l);
336  for ( ; it != ite; ++it) scale(linalg_traits<L>::row(it), a);
337  }
338 
339  template <typename L>
340  void scale(L& l, typename linalg_traits<L>::value_type a, col_major) {
341  typename linalg_traits<L>::col_iterator it = mat_col_begin(l),
342  ite = mat_col_end(l);
343  for ( ; it != ite; ++it) scale(linalg_traits<L>::col(it), a);
344  }
345 
346  template <typename V, typename S> struct linalg_traits<scaled_vector_const_ref<V,S> > {
347  typedef scaled_vector_const_ref<V,S> this_type;
348  typedef linalg_const is_reference;
349  typedef abstract_vector linalg_type;
350  typedef typename strongest_numeric_type<S, typename linalg_traits<V>::value_type>::T value_type;
351  typedef typename linalg_traits<V>::origin_type origin_type;
352  typedef value_type reference;
353  typedef abstract_null_type iterator;
354  typedef scaled_const_iterator<typename linalg_traits<V>::const_iterator, S>
355  const_iterator;
356  typedef typename linalg_traits<V>::storage_type storage_type;
357  typedef typename linalg_traits<V>::index_sorted index_sorted;
358  static size_type size(const this_type &v) { return v.size_; }
359  static const_iterator begin(const this_type &v)
360  { return const_iterator(v.begin_, v.r); }
361  static const_iterator end(const this_type &v)
362  { return const_iterator(v.end_, v.r); }
363  static const origin_type* origin(const this_type &v) { return v.origin; }
364  static value_type access(const origin_type *o, const const_iterator &it,
365  const const_iterator &ite, size_type i)
366  { return it.r * (linalg_traits<V>::access(o, it.it, ite.it, i)); }
367 
368  };
369 
370 
371  template <typename M, typename S> struct linalg_traits<scaled_row_matrix_const_ref<M,S> > {
372  typedef scaled_row_matrix_const_ref<M,S> this_type;
373  typedef linalg_const is_reference;
374  typedef abstract_matrix linalg_type;
375  typedef typename linalg_traits<M>::origin_type origin_type;
376  typedef typename strongest_numeric_type<S, typename linalg_traits<M>::value_type>::T value_type;
377  typedef value_type reference;
378  typedef typename linalg_traits<M>::storage_type storage_type;
379  typedef typename org_type<typename linalg_traits<M>::const_sub_row_type>::t vector_type;
380  typedef scaled_vector_const_ref<vector_type,S> sub_row_type;
381  typedef scaled_vector_const_ref<vector_type,S> const_sub_row_type;
382  typedef scaled_row_const_iterator<M,S> row_iterator;
383  typedef scaled_row_const_iterator<M,S> const_row_iterator;
384  typedef abstract_null_type const_sub_col_type;
385  typedef abstract_null_type sub_col_type;
386  typedef abstract_null_type const_col_iterator;
387  typedef abstract_null_type col_iterator;
388  typedef row_major sub_orientation;
389  typedef typename linalg_traits<M>::index_sorted index_sorted;
390  static size_type nrows(const this_type &m)
391  { return m.nr; }
392  static size_type ncols(const this_type &m)
393  { return m.nc; }
394  static const_sub_row_type row(const const_row_iterator &it)
395  { return scaled(linalg_traits<M>::row(it.it), it.r); }
396  static const_row_iterator row_begin(const this_type &m)
397  { return const_row_iterator(m.begin_, m.r); }
398  static const_row_iterator row_end(const this_type &m)
399  { return const_row_iterator(m.end_, m.r); }
400  static const origin_type* origin(const this_type &m) { return m.origin; }
401  static value_type access(const const_row_iterator &it, size_type i)
402  { return it.r * (linalg_traits<M>::access(it.it, i)); }
403  };
404 
405  template <typename M, typename S> struct linalg_traits<scaled_col_matrix_const_ref<M,S> > {
406  typedef scaled_col_matrix_const_ref<M,S> this_type;
407  typedef linalg_const is_reference;
408  typedef abstract_matrix linalg_type;
409  typedef typename strongest_numeric_type<S, typename linalg_traits<M>::value_type>::T value_type;
410  typedef typename linalg_traits<M>::origin_type origin_type;
411  typedef value_type reference;
412  typedef typename linalg_traits<M>::storage_type storage_type;
413  typedef typename org_type<typename linalg_traits<M>::const_sub_col_type>::t vector_type;
414  typedef abstract_null_type sub_col_type;
415  typedef scaled_vector_const_ref<vector_type,S> const_sub_col_type;
416  typedef abstract_null_type col_iterator;
417  typedef scaled_col_const_iterator<M,S> const_col_iterator;
418  typedef abstract_null_type const_sub_row_type;
419  typedef abstract_null_type sub_row_type;
420  typedef abstract_null_type const_row_iterator;
421  typedef abstract_null_type row_iterator;
422  typedef col_major sub_orientation;
423  typedef typename linalg_traits<M>::index_sorted index_sorted;
424  static size_type ncols(const this_type &m)
425  { return m.nc; }
426  static size_type nrows(const this_type &m)
427  { return m.nr; }
428  static const_sub_col_type col(const const_col_iterator &it)
429  { return scaled(linalg_traits<M>::col(it.it), it.r); }
430  static const_col_iterator col_begin(const this_type &m)
431  { return const_col_iterator(m.begin_, m.r); }
432  static const_col_iterator col_end(const this_type &m)
433  { return const_col_iterator(m.end_, m.r); }
434  static const origin_type* origin(const this_type &m) { return m.origin; }
435  static value_type access(const const_col_iterator &it, size_type i)
436  { return it.r * (linalg_traits<M>::access(it.it, i)); }
437  };
438 
439 
440 }
441 
442 #endif // GMM_SCALED_H__
Basic definitions and tools of GMM.
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
Definition: bgeot_poly.h:756
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
Definition: bgeot_poly.h:749
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49