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