utility.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 #ifndef LIBMESH_UTILITY_H
20 #define LIBMESH_UTILITY_H
21 
22 // Local includes
23 #include "libmesh/libmesh_common.h" // for Real
24 
25 // System includes
26 #include <string>
27 #include <vector>
28 #include <algorithm> // for std::lower_bound
29 
30 namespace libMesh
31 {
32 
33 
34 // ------------------------------------------------------------
35 // The Utility namespace is for functions
36 // which are useful but don't necessarily belong anywhere else.
37 
38 namespace Utility
39 {
40 
45 std::string system_info();
46 
47 
48 
56 template <typename ForwardIter, typename T>
57 void iota (ForwardIter first, ForwardIter last, T value)
58 {
59  // Use std::iota instead!
60  libmesh_deprecated();
61 
62  while (first != last)
63  {
64  *first = value++;
65  ++first;
66  }
67 }
68 
69 
76 template<class InputIterator >
77 bool is_sorted(InputIterator first, InputIterator last)
78 {
79  if (first == last)
80  return true;
81 
82  // "prev" always points to the entry just to the left of "first"
83  // [- - - - - -]
84  // ^ ^
85  // prev first
86  //
87  // [- - - - - -]
88  // ^ ^
89  // prev first
90  //
91  // [- - - - - -]
92  // ^ ^
93  // prev first
94  InputIterator prev( first );
95  for (++first; first != last; ++prev, ++first)
96  if (*first < *prev) // Note: this is the same as *prev > *first,
97  return false; // but we only require op< to be defined.
98 
99  // If we haven't returned yet, it's sorted!
100  return true;
101 
102 
103  // A one-liner version using adjacent_find. This doesn't work for
104  // C-style arrays, since their pointers do not have a value_type.
105  //
106  // Works by checking to see if adjacent entries satisfy *i >
107  // *(i+1) and returns the first one which does. If "last" is
108  // returned, no such pair was found, and therefore the range must
109  // be in non-decreasing order.
110  //
111  // return (last ==
112  // std::adjacent_find(first, last,
113  // std::greater<typename InputIterator::value_type >()));
114 
115  // A second one-linear attempt. This one checks for a **strictly
116  // increasing** (no duplicate entries) range. Also doesn't work
117  // with C-style arrays.
118  //
119  // return (last ==
120  // std::adjacent_find(first, last,
121  // std::not2(std::less<typename InputIterator::value_type>())));
122 }
123 
124 
134 template<class ForwardIterator, class T>
135 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T & value)
136 {
137  ForwardIterator it = std::lower_bound(first, last, value);
138  return (it == last || value < *it) ? last : it;
139 }
140 
144 template<class ForwardIterator, class T, class Compare>
145 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T & value, Compare comp)
146 {
147  ForwardIterator it = std::lower_bound(first, last, value, comp);
148  return (it == last || comp(value,*it)) ? last : it;
149 }
150 
151 
156 template <int N, typename T>
157 struct do_pow {
158  static inline T apply (const T & x)
159  {
160  libmesh_assert(N>1);
161 
162  if (N%2) // odd exponent
163  return x * do_pow<N-1,T>::apply(x);
164 
165  const T xNover2 = do_pow<N/2,T>::apply(x);
166 
167  return xNover2*xNover2;
168  }
169 };
170 
171 // An efficient compiler would distill N=6 down to 3
172 // multiplications, but an inefficient one (or a complicated
173 // T::operator*) might do worse, so we'll specialize here.
174 template <typename T>
175 struct do_pow<6,T> {
176  static inline T apply (const T & x)
177  {
178  const T x2 = x*x,
179  x4 = x2*x2;
180 
181  return x4*x2;
182  }
183 };
184 
185 template <typename T>
186 struct do_pow<1,T> {
187  static inline T apply (const T & x) { return x; }
188 };
189 
190 template <typename T>
191 struct do_pow<0,T> {
192  static inline T apply (const T &) { return 1; }
193 };
194 
195 
196 template <int N, typename T>
197 inline
198 T pow(const T & x)
199 {
200  return do_pow<N,T>::apply(x);
201 }
202 
206 inline
207 unsigned int factorial(unsigned int n)
208 {
209 
210  unsigned int factorial_n = 1;
211 
212  if (n==0)
213  return factorial_n;
214 
215  for (unsigned int i=1; i<n; i++)
216  factorial_n *= i+1;
217 
218  return factorial_n;
219 }
220 
221 
222 // Simple function to compute "n choose k", aka the binomial coefficient.
223 template <typename T>
224 T binomial(T n, T k)
225 {
226  T ret = 1;
227 
228  // Binomial function is "symmetric" in k, C(n, k) = C(n, n-k).
229  if (k > n - k)
230  k = n - k;
231 
232  // Compute n * (n-1) * ... * (n-k+1) / (k * (k-1) * ... * 1)
233  for (T i = 0; i < k; ++i)
234  {
235  ret *= (n - i);
236  ret /= (i + 1);
237  }
238 
239  return ret;
240 }
241 
242 
246 template <typename T>
247 void deallocate (std::vector<T> & vec)
248 {
249  std::vector<T>().swap(vec);
250 }
251 
252 
253 // Utility functions useful when dealing with complex numbers.
254 
255 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
256 
262 std::string complex_filename (const std::string & basename,
263  unsigned int r_o_c=0);
264 
268 void prepare_complex_data (const std::vector<Complex> & source,
269  std::vector<Real> & real_part,
270  std::vector<Real> & imag_part);
271 
272 #endif // #ifdef LIBMESH_USE_COMPLEX_NUMBERS
273 
274 
278 int mkdir(const char* pathname);
279 
280 
290 {
291 public:
292 
297  explicit
298  ReverseBytes (const bool dr);
299 
304  template <typename T>
305  T operator () (T & data) const;
306 
307 private:
308 
312  bool reverse () const { return _do_reverse; }
313 
317  const bool _do_reverse;
318 };
319 
320 
321 
322 // ReverseBytes inline members
323 inline
324 ReverseBytes::ReverseBytes (const bool rb) :
325  _do_reverse (rb)
326 {}
327 
328 
329 template <typename T>
330 inline
332 {
333  // Possibly reverse the byte ordering
334  if (this->reverse())
335  {
336  unsigned char * b = (unsigned char *) &data;
337 
338  int i=0;
339  int j=(sizeof(T) - 1);
340 
341  while (i < j)
342  {
343  std::swap (b[i], b[j]);
344  i++; j--;
345  }
346  }
347 
348  return data;
349 }
350 
351 
352 }
353 
354 } // namespace libMesh
355 
356 #endif // LIBMESH_UTILITY_H
std::string complex_filename(const std::string &basename, unsigned int r_o_c=0)
Definition: utility.C:105
void deallocate(std::vector< T > &vec)
Definition: utility.h:247
static const unsigned int prev[3]
int mkdir(const char *pathname)
Definition: utility.C:140
std::string system_info()
Definition: utility.C:57
void iota(ForwardIter first, ForwardIter last, T value)
Definition: utility.h:57
static T apply(const T &)
Definition: utility.h:192
static T apply(const T &x)
Definition: utility.h:187
T pow(const T &x)
Definition: utility.h:198
T operator()(T &data) const
Definition: utility.h:331
void prepare_complex_data(const std::vector< Complex > &source, std::vector< Real > &real_part, std::vector< Real > &imag_part)
Definition: utility.C:121
static T apply(const T &x)
Definition: utility.h:158
static T apply(const T &x)
Definition: utility.h:176
void swap(Iterator &lhs, Iterator &rhs)
unsigned int factorial(unsigned int n)
Definition: utility.h:207
static const bool value
Definition: xdr_io.C:109
bool is_sorted(InputIterator first, InputIterator last)
Definition: utility.h:77
ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T &value)
Definition: utility.h:135
IterBase * data
ReverseBytes(const bool dr)
Definition: utility.h:324
T binomial(T n, T k)
Definition: utility.h:224