GetFEM  5.4.3
gmm_algobase.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2000-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_algobase.h
33  @author Yves Renard <[email protected]>
34  @date September 28, 2000.
35  @brief Miscelleanous algorithms on containers.
36 */
37 
38 #ifndef GMM_ALGOBASE_H__
39 #define GMM_ALGOBASE_H__
40 #include "gmm_std.h"
41 #include "gmm_except.h"
42 #include <functional>
43 
44 namespace gmm {
45 
46  /* ********************************************************************* */
47  /* Definitition de classes de comparaison. */
48  /* retournant un int. */
49  /* ********************************************************************* */
50 
51  template <class T>
52  struct less {
53  inline int operator()(const T& x, const T& y) const
54  { return (x < y) ? -1 : ((y < x) ? 1 : 0); }
55  };
56 
57  template<> struct less<int> {
58  int operator()(int x, int y) const { return x-y; } };
59  template<> struct less<char> {
60  int operator()(char x, char y) const { return int(x-y); } };
61  template<> struct less<short> {
62  int operator()(short x, short y) const { return int(x-y); } };
63  template<> struct less<unsigned char> {
64  int operator()(unsigned char x, unsigned char y) const
65  { return int(x)-int(y); }
66  };
67 
68 
69  template <class T>
70  struct greater {
71  inline int operator()(const T& x, const T& y) const
72  { return (y < x) ? -1 : ((x < y) ? 1 : 0); }
73  };
74 
75  template<> struct greater<int> {
76  int operator()(int x, int y) const { return y-x; } };
77  template<> struct greater<char> {
78  int operator()(char x, char y) const { return int(y-x); } };
79  template<> struct greater<short> {
80  int operator()(short x, short y) const { return int(y-x); } };
81  template<> struct greater<unsigned char> {
82  int operator()(unsigned char x, unsigned char y) const
83  { return int(y)-int(x); }
84  };
85 
86  template <typename T> inline T my_abs(T a) { return (a < T(0)) ? T(-a) : a; }
87 
88  template <class T>
89  struct approx_less {
90  double eps;
91  inline int operator()(const T &x, const T &y) const
92  { if (my_abs(x - y) <= eps) return 0; if (x < y) return -1; return 1; }
93  approx_less(double e = 1E-13) { eps = e; }
94  };
95 
96  template <class T>
97  struct approx_greater {
98  double eps;
99  inline int operator()(const T &x, const T &y) const
100  { if (my_abs(x - y) <= eps) return 0; if (x > y) return -1; return 1; }
101  approx_greater(double e = 1E-13) { eps = e; }
102  };
103 
104  template<class ITER1, class ITER2, class COMP>
105  int lexicographical_compare(ITER1 b1, const ITER1 &e1,
106  ITER2 b2, const ITER2 &e2, const COMP &c) {
107  int i;
108  for ( ; b1 != e1 && b2 != e2; ++b1, ++b2)
109  if ((i = c(*b1, *b2)) != 0) return i;
110  if (b1 != e1) return 1;
111  if (b2 != e2) return -1;
112  return 0;
113  }
114 
115  template<class CONT, class COMP = gmm::less<typename CONT::value_type> >
116  struct lexicographical_less {
117  COMP c;
118  int operator()(const CONT &x, const CONT &y) const {
119  return gmm::lexicographical_compare(x.begin(), x.end(),
120  y.begin(), y.end(), c);
121  }
122  lexicographical_less(const COMP &d = COMP()) { c = d; }
123  };
124 
125  template<class CONT, class COMP = gmm::less<typename CONT::value_type> >
126  struct lexicographical_greater {
127  COMP c;
128  int operator()(const CONT &x, const CONT &y) const {
129  return -gmm::lexicographical_compare(x.begin(), x.end(),
130  y.begin(), y.end(), c);
131  }
132  lexicographical_greater(const COMP &d = COMP()) { c = d; }
133  };
134 
135 
136  /* ********************************************************************* */
137  /* "Virtual" iterators on sequences. */
138  /* The class T represent a class of sequence. */
139  /* ********************************************************************* */
140 
141  template<class T> struct sequence_iterator {
142 
143  typedef T value_type;
144  typedef value_type* pointer;
145  typedef value_type& reference;
146  typedef const value_type& const_reference;
147  typedef std::forward_iterator_tag iterator_category;
148 
149  T Un;
150 
151  sequence_iterator(T U0 = T(0)) { Un = U0; }
152 
153  sequence_iterator &operator ++()
154  { ++Un; return *this; }
155  sequence_iterator operator ++(int)
156  { sequence_iterator tmp = *this; (*this)++; return tmp; }
157 
158  const_reference operator *() const { return Un; }
159  reference operator *() { return Un; }
160 
161  bool operator ==(const sequence_iterator &i) const { return (i.Un==Un);}
162  bool operator !=(const sequence_iterator &i) const { return (i.Un!=Un);}
163  };
164 
165  /* ********************************************************************* */
166  /* generic algorithms. */
167  /* ********************************************************************* */
168 
169  template <class ITER1, class SIZE, class ITER2>
170  ITER2 copy_n(ITER1 first, SIZE count, ITER2 result) {
171  for ( ; count > 0; --count, ++first, ++result) *result = *first;
172  return result;
173  }
174 
175  template<class ITER>
176  typename std::iterator_traits<ITER>::value_type
177  mean_value(ITER first, const ITER &last) {
178  GMM_ASSERT2(first != last, "mean value of empty container");
179  size_t n = 1;
180  typename std::iterator_traits<ITER>::value_type res = *first++;
181  while (first != last) { res += *first; ++first; ++n; }
182  res /= float(n);
183  return res;
184  }
185 
186  template<class CONT>
187  typename CONT::value_type
188  mean_value(const CONT &c) { return mean_value(c.begin(), c.end()); }
189 
190  template<class ITER> /* hum ... */
191  void minmax_box(typename std::iterator_traits<ITER>::value_type &pmin,
192  typename std::iterator_traits<ITER>::value_type &pmax,
193  ITER first, const ITER &last) {
194  typedef typename std::iterator_traits<ITER>::value_type PT;
195  if (first != last) { pmin = pmax = *first; ++first; }
196  while (first != last) {
197  typename PT::const_iterator b = (*first).begin(), e = (*first).end();
198  typename PT::iterator b1 = pmin.begin(), b2 = pmax.begin();
199  while (b != e)
200  { *b1 = std::min(*b1, *b); *b2 = std::max(*b2, *b); ++b; ++b1; ++b2; }
201  }
202  }
203 
204  template<typename VEC> struct sorted_indexes_aux {
205  const VEC &v;
206  public:
207  sorted_indexes_aux(const VEC& v_) : v(v_) {}
208  template <typename IDX>
209  bool operator()(const IDX &ia, const IDX &ib) const
210  { return v[ia] < v[ib]; }
211  };
212 
213  template<typename VEC, typename IVEC>
214  void sorted_indexes(const VEC &v, IVEC &iv) {
215  iv.clear(); iv.resize(v.size());
216  for (size_t i=0; i < v.size(); ++i) iv[i] = i;
217  std::sort(iv.begin(), iv.end(), sorted_indexes_aux<VEC>(v));
218  }
219 
220 }
221 
222 
223 #endif /* GMM_ALGOBASE_H__ */
Definition of basic exceptions.
basic setup for gmm (includes, typedefs etc.)