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