templates.h
1/***************************************************************************
2 *
3 * Copyright (C) 2000 by Willem van Straten
4 * Licensed under the Academic Free License version 2.1
5 *
6 ***************************************************************************/
7
8#ifndef _Util_genutil_templates_h
9#define _Util_genutil_templates_h
10
11#include <algorithm>
12#include <functional>
13#include <iterator>
14#include <vector>
15
16#include <assert.h>
17#include <string.h>
18
20template<typename C, typename M>
21void foreach (C& container, M method)
22{
23 std::for_each (container.begin(), container.end(),
24 std::mem_fun(method));
25}
26
28template<typename C, typename M, typename A>
29void foreach (C& container, M method, const A& a)
30{
31 std::for_each (container.begin(), container.end(),
32 std::bind2nd( std::mem_fun(method), a ));
33}
34
35template <class T>
36void scrunch (std::vector<T>& vals, unsigned factor, bool mean = true)
37{
38 typename std::vector<T>::iterator into = vals.begin();
39 typename std::vector<T>::iterator val;
40
41 unsigned fi = 0;
42
43 for (val = vals.begin(); val != vals.end(); into++) {
44 *into = *val; val++;
45 for (fi=1; fi<factor && val != vals.end(); (val++, fi++))
46 *into += *val;
47 if (mean)
48 *into /= fi;
49 }
50 vals.resize (vals.size()/factor);
51}
52
54template<typename T>
55void shift (unsigned size, unsigned shift, T* array)
56{
57 T* temp = new T[shift];
58 memcpy (temp, array, shift*sizeof(T));
59 memmove (array, array+shift, (size-shift)*sizeof(T));
60 memcpy (array+size-shift, temp, shift*sizeof(T));
61 delete [] temp;
62}
63
65template<typename T>
66void shift (unsigned size, unsigned shift, T* result, const T* input)
67{
68 memcpy (result, input+shift, (size-shift)*sizeof(T));
69 memcpy (result+size-shift, input, shift*sizeof(T));
70}
71
72// returns the mean "bin" of a histogram
73template <class T>
74T histomean (const std::vector<T>& vals)
75{
76 T valcount = 0.0;
77 T totcount = 0.0;
78
79 T total = vals.size();
80 T bin = 0.0;
81
82 typename std::vector<T>::const_iterator val;
83
84 for (val = vals.begin(); val != vals.end(); val++) {
85 valcount += *val * bin;
86 totcount += *val * total;
87
88 bin += 1.0;
89 }
90 return valcount/totcount;
91}
92
93template <class T>
94T sqr (const T& x)
95{
96 return x * x;
97}
98
100
102template <class I, class T>
103T sum (const I& it1, const I& it2, T& the_sum)
104{
105 the_sum = 0.0;
106
107 for (I it=it1; it != it2; it++)
108 the_sum += T(*it);
109
110 return the_sum;
111}
112
114template <class I> typename std::iterator_traits<I>::value_type
115sum (const I& it1, const I& it2)
116{
117 typename std::iterator_traits<I>::value_type t;
118 return sum (it1, it2, t);
119}
120
121// return the sum of all elements in an STL container
122template <class C> typename C::value_type
123sum (const C& x)
124{
125 return sum (x.begin(), x.end());
126}
127
129
131template <class I, class T> T
132mean (const I& it1, const I& it2, T& the_mean)
133{
134 the_mean = sum(it1, it2, the_mean) / (it2 - it1);
135 return the_mean;
136}
137
139template <class I> typename std::iterator_traits<I>::value_type
140mean (const I& it1, const I& it2)
141{
142 typename std::iterator_traits<I>::value_type t;
143 return mean (it1, it2, t);
144}
145
146// return the mean of all elements in an STL container
147template <class C> typename C::value_type
148mean (const C& x)
149{
150 return mean (x.begin(), x.end());
151}
152
154
156template <class I, class T> T
157variance (const I& it1, const I& it2, T& the_variance)
158{
159 T the_mean = mean (it1, it2, the_mean);
160 the_variance = 0.0;
161
162 for (I it=it1; it != it2; it++)
163 the_variance += sqr( T(*it) - the_mean );
164
165 the_variance /= (it2 - it1 - 1);
166
167 return the_variance;
168}
169
171template <class I> typename std::iterator_traits<I>::value_type
172variance (const I& it1, const I& it2)
173{
174 typename std::iterator_traits<I>::value_type t;
175 return variance (it1, it2, t);
176}
177
178// return the variance of all elements in an STL container
179template <class C> typename C::value_type
180variance (const C& x)
181{
182 return variance (x.begin(), x.end());
183}
184
185// normalize each element of a vector by the sum of all elements in it
186template <class T>
187void normalize (std::vector<T>& x)
188{
189 T the_sum = sum (x);
190 assert( the_sum != 0 );
191 for (unsigned i=0; i<x.size(); i++)
192 x[i] /= the_sum;
193}
194
196template <class T, class I>
197void minmax (const I& it1, const I& it2, T& min, T& max, bool follow = false)
198{
199 if (!follow && (it1 != it2))
200 max = min = *it1;
201
202 for (I it=it1; it != it2; it++) {
203 if (*it > max)
204 max = *it;
205 if (*it < min)
206 min = *it;
207 }
208}
209
211template <class T, class C>
212void minmax (const C& c, T& min, T& max, bool follow = false)
213{
214 minmax (c.begin(), c.end(), min, max, follow);
215}
216
218template <class T, class C>
219 void cyclic_minmax (const C& c, unsigned i1, unsigned i2, T& min, T& max,
220 bool follow = false)
221{
222 if (i2 < c.size())
223 minmax (c.begin()+i1, c.begin()+i2, min, max, follow);
224 else {
225 i2 -= c.size();
226 minmax (c.begin()+i1, c.end(), min, max, follow);
227 minmax (c.begin(), c.begin()+i2, min, max, true);
228 }
229}
230
232template <class T, class C>
233bool found (const T& x, const C& c)
234{
235 return std::find (c.begin(), c.end(), x) != c.end();
236}
237
239template<class T, class C>
240int index (const T& x, const C& c)
241{
242 typename C::const_iterator f = std::find (c.begin(), c.end(), x);
243 if (f == c.end())
244 return -1;
245
246 return f - c.begin();
247}
248
250template<class T, class C>
251bool remove (const T& x, C& c)
252{
253 typename C::iterator f = std::find (c.begin(), c.end(), x);
254 if (f != c.end()) {
255 c.erase(f);
256 return true;
257 }
258 return false;
259}
260
262
273template<typename C>
274void remove (C& c, unsigned first, unsigned last)
275{
276 c.erase (c.begin()+first, c.begin()+last+1);
277}
278
280template<typename Big, typename Small>
281inline Big multiple_greater (Big big, Small small)
282{
283 Big divides = big / small;
284 if (big % small)
285 divides ++;
286
287 return divides * small;
288}
289
290// set B to the set-theoretic difference of B and A
291// also known as the relative complement of A in B
292template<typename C1, typename C2>
293void set_difference (C1& B, const C2& A)
294{
295 typename C1::iterator newlast = B.end();
296 for (typename C2::const_iterator it=A.begin(); it != A.end(); it++)
297 newlast = std::remove (B.begin(), newlast, *it);
298 B.erase (newlast, B.end());
299}
300
301#endif
302

Generated using doxygen 1.14.0