1
// -*- c++ -*- (enables emacs c++ mode)
2
//===========================================================================
4
// Copyright (C) 2000-2008 Yves Renard
6
// This file is a part of GETFEM++
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 2.1 of the License, or
11
// (at your option) any later version.
12
// This program is distributed in the hope that it will be useful, but
13
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
// License for more details.
16
// You should have received a copy of the GNU Lesser General Public License
17
// along with this program; if not, write to the Free Software Foundation,
18
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20
// As a special exception, you may use this file as part of a free software
21
// library without restriction. Specifically, if other files instantiate
22
// templates or use macros or inline functions from this file, or you compile
23
// this file and link it with other files to produce an executable, this
24
// file does not by itself cause the resulting executable to be covered by
25
// the GNU General Public License. This exception does not however
26
// invalidate any other reasons why the executable file might be covered by
27
// the GNU General Public License.
29
//===========================================================================
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.
37
#ifndef GMM_ALGOBASE_H__
38
#define GMM_ALGOBASE_H__
40
#include "gmm_except.h"
45
/* ********************************************************************* */
46
/* Definitition de classes de comparaison. */
47
/* retournant un int. */
48
/* ********************************************************************* */
51
struct less : public std::binary_function<T, T, int> {
52
inline int operator()(const T& x, const T& y) const
53
{ return (x < y) ? -1 : ((y < x) ? 1 : 0); }
56
template<> struct less<int> : public std::binary_function<int, int, int>
57
{ int operator()(int x, int y) const { return x-y; } };
58
template<> struct less<char> : public std::binary_function<char, char, int>
59
{ int operator()(char x, char y) const { return int(x-y); } };
60
template<> struct less<short> : public std::binary_function<short,short,int>
61
{ int operator()(short x, short y) const { return int(x-y); } };
62
template<> struct less<unsigned char>
63
: public std::binary_function<unsigned char, unsigned char, int> {
64
int operator()(unsigned char x, unsigned char y) const
65
{ return int(x)-int(y); }
70
struct greater : public std::binary_function<T, T, int> {
71
inline int operator()(const T& x, const T& y) const
72
{ return (y < x) ? -1 : ((x < y) ? 1 : 0); }
75
template<> struct greater<int> : public std::binary_function<int, int, int>
76
{ int operator()(int x, int y) const { return y-x; } };
77
template<> struct greater<char> : public std::binary_function<char,char,int>
78
{ int operator()(char x, char y) const { return int(y-x); } };
79
template<> struct greater<short>
80
: public std::binary_function<short, short, int>
81
{ int operator()(short x, short y) const { return int(y-x); } };
82
template<> struct greater<unsigned char>
83
: public std::binary_function<unsigned char, unsigned char, int> {
84
int operator()(unsigned char x, unsigned char y) const
85
{ return int(y)-int(x); }
88
template <typename T> inline T my_abs(T a) { return (a < T(0)) ? T(-a) : a; }
91
struct approx_less : public std::binary_function<T, T, int> {
93
inline int operator()(const T &x, const T &y) const
94
{ if (my_abs(x - y) <= eps) return 0; if (x < y) return -1; return 1; }
95
approx_less(double e = 1E-13) { eps = e; }
99
struct approx_greater : public std::binary_function<T, T, int> {
101
inline int operator()(const T &x, const T &y) const
102
{ if (my_abs(x - y) <= eps) return 0; if (x > y) return -1; return 1; }
103
approx_greater(double e = 1E-13) { eps = e; }
106
template<class ITER1, class ITER2, class COMP>
107
int lexicographical_compare(ITER1 b1, const ITER1 &e1,
108
ITER2 b2, const ITER2 &e2, const COMP &c) {
110
for ( ; b1 != e1 && b2 != e2; ++b1, ++b2)
111
if ((i = c(*b1, *b2)) != 0) return i;
112
if (b1 != e1) return 1; if (b2 != e2) return -1; return 0;
115
template<class CONT, class COMP = gmm::less<typename CONT::value_type> >
116
struct lexicographical_less : public std::binary_function<CONT, CONT, int>
119
int operator()(const CONT &x, const CONT &y) const {
120
return gmm::lexicographical_compare(x.begin(), x.end(),
121
y.begin(), y.end(), c);
123
lexicographical_less(const COMP &d = COMP()) { c = d; }
126
template<class CONT, class COMP = gmm::less<typename CONT::value_type> >
127
struct lexicographical_greater
128
: public std::binary_function<CONT, CONT, int> {
130
int operator()(const CONT &x, const CONT &y) const {
131
return -gmm::lexicographical_compare(x.begin(), x.end(),
132
y.begin(), y.end(), c);
134
lexicographical_greater(const COMP &d = COMP()) { c = d; }
138
/* ********************************************************************* */
139
/* "Virtual" iterators on sequences. */
140
/* The class T represent a class of sequence. */
141
/* ********************************************************************* */
143
template<class T> struct sequence_iterator {
145
typedef T value_type;
146
typedef value_type* pointer;
147
typedef value_type& reference;
148
typedef const value_type& const_reference;
149
typedef std::forward_iterator_tag iterator_category;
153
sequence_iterator(T U0 = T(0)) { Un = U0; }
155
sequence_iterator &operator ++()
156
{ ++Un; return *this; }
157
sequence_iterator operator ++(int)
158
{ sequence_iterator tmp = *this; (*this)++; return tmp; }
160
const_reference operator *() const { return Un; }
161
reference operator *() { return Un; }
163
bool operator ==(const sequence_iterator &i) const { return (i.Un==Un);}
164
bool operator !=(const sequence_iterator &i) const { return (i.Un!=Un);}
167
/* ********************************************************************* */
168
/* generic algorithms. */
169
/* ********************************************************************* */
171
template <class ITER1, class SIZE, class ITER2>
172
ITER2 copy_n(ITER1 first, SIZE count, ITER2 result) {
173
for ( ; count > 0; --count, ++first, ++result) *result = *first;
178
typename std::iterator_traits<ITER>::value_type
179
mean_value(ITER first, const ITER &last) {
180
GMM_ASSERT2(first != last, "mean value of empty container");
182
typename std::iterator_traits<ITER>::value_type res = *first++;
183
while (first != last) { res += *first; ++first; ++n; }
189
typename CONT::value_type
190
mean_value(const CONT &c) { return mean_value(c.begin(), c.end()); }
192
template<class ITER> /* hum ... */
193
void minmax_box(typename std::iterator_traits<ITER>::value_type &pmin,
194
typename std::iterator_traits<ITER>::value_type &pmax,
195
ITER first, const ITER &last) {
196
typedef typename std::iterator_traits<ITER>::value_type PT;
197
if (first != last) { pmin = pmax = *first; ++first; }
198
while (first != last) {
199
typename PT::const_iterator b = (*first).begin(), e = (*first).end();
200
typename PT::iterator b1 = pmin.begin(), b2 = pmax.begin();
202
{ *b1 = std::min(*b1, *b); *b2 = std::max(*b2, *b); ++b; ++b1; ++b2; }
206
template<typename VEC> struct sorted_indexes_aux {
209
sorted_indexes_aux(const VEC& v_) : v(v_) {}
210
template <typename IDX>
211
bool operator()(const IDX &ia, const IDX &ib) const
212
{ return v[ia] < v[ib]; }
215
template<typename VEC, typename IVEC>
216
void sorted_indexes(const VEC &v, IVEC &iv) {
217
iv.clear(); iv.resize(v.size());
218
for (size_t i=0; i < v.size(); ++i) iv[i] = i;
219
std::sort(iv.begin(), iv.end(), sorted_indexes_aux<VEC>(v));
225
#endif /* GMM_ALGOBASE_H__ */