libMesh
utility.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 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  while (first != last)
60  {
61  *first = value++;
62  ++first;
63  }
64 }
65 
66 
73 template<class InputIterator >
74 bool is_sorted(InputIterator first, InputIterator last)
75 {
76  if (first == last)
77  return true;
78 
79  // "prev" always points to the entry just to the left of "first"
80  // [- - - - - -]
81  // ^ ^
82  // prev first
83  //
84  // [- - - - - -]
85  // ^ ^
86  // prev first
87  //
88  // [- - - - - -]
89  // ^ ^
90  // prev first
91  InputIterator prev( first );
92  for (++first; first != last; ++prev, ++first)
93  if (*first < *prev) // Note: this is the same as *prev > *first,
94  return false; // but we only require op< to be defined.
95 
96  // If we haven't returned yet, it's sorted!
97  return true;
98 
99 
100  // A one-liner version using adjacent_find. This doesn't work for
101  // C-style arrays, since their pointers do not have a value_type.
102  //
103  // Works by checking to see if adjacent entries satisfy *i >
104  // *(i+1) and returns the first one which does. If "last" is
105  // returned, no such pair was found, and therefore the range must
106  // be in non-decreasing order.
107  //
108  // return (last ==
109  // std::adjacent_find(first, last,
110  // std::greater<typename InputIterator::value_type >()));
111 
112  // A second one-linear attempt. This one checks for a **strictly
113  // increasing** (no duplicate entries) range. Also doesn't work
114  // with C-style arrays.
115  //
116  // return (last ==
117  // std::adjacent_find(first, last,
118  // std::not2(std::less<typename InputIterator::value_type>())));
119 }
120 
121 
131 template<class ForwardIterator, class T>
132 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T & value)
133 {
134  ForwardIterator it = std::lower_bound(first, last, value);
135  return (it == last || value < *it) ? last : it;
136 }
137 
141 template<class ForwardIterator, class T, class Compare>
142 ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T & value, Compare comp)
143 {
144  ForwardIterator it = std::lower_bound(first, last, value, comp);
145  return (it == last || comp(value,*it)) ? last : it;
146 }
147 
148 
153 template <int N, typename T>
154 struct do_pow {
155  static inline T apply (const T & x)
156  {
157  libmesh_assert(N>1);
158 
159  if (N%2) // odd exponent
160  return x * do_pow<N-1,T>::apply(x);
161 
162  const T xNover2 = do_pow<N/2,T>::apply(x);
163 
164  return xNover2*xNover2;
165  }
166 };
167 
168 // An efficient compiler would distill N=6 down to 3
169 // multiplications, but an inefficient one (or a complicated
170 // T::operator*) might do worse, so we'll specialize here.
171 template <typename T>
172 struct do_pow<6,T> {
173  static inline T apply (const T & x)
174  {
175  const T x2 = x*x,
176  x4 = x2*x2;
177 
178  return x4*x2;
179  }
180 };
181 
182 template <typename T>
183 struct do_pow<1,T> {
184  static inline T apply (const T & x) { return x; }
185 };
186 
187 template <typename T>
188 struct do_pow<0,T> {
189  static inline T apply (const T &) { return 1; }
190 };
191 
192 
193 template <int N, typename T>
194 inline
195 T pow(const T & x)
196 {
197  return do_pow<N,T>::apply(x);
198 }
199 
203 inline
204 unsigned int factorial(unsigned int n)
205 {
206 
207  unsigned int factorial_n = 1;
208 
209  if (n==0)
210  return factorial_n;
211 
212  for (unsigned int i=1; i<n; i++)
213  factorial_n *= i+1;
214 
215  return factorial_n;
216 }
217 
218 
219 // Simple function to compute "n choose k", aka the binomial coefficient.
220 template <typename T>
221 T binomial(T n, T k)
222 {
223  T ret = 1;
224 
225  // Binomial function is "symmetric" in k, C(n, k) = C(n, n-k).
226  if (k > n - k)
227  k = n - k;
228 
229  // Compute n * (n-1) * ... * (n-k+1) / (k * (k-1) * ... * 1)
230  for (T i = 0; i < k; ++i)
231  {
232  ret *= (n - i);
233  ret /= (i + 1);
234  }
235 
236  return ret;
237 }
238 
239 
243 template <typename T>
244 void deallocate (std::vector<T> & vec)
245 {
246  std::vector<T>().swap(vec);
247 }
248 
249 
250 // Utility functions useful when dealing with complex numbers.
251 
252 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
253 
259 std::string complex_filename (const std::string & basename,
260  unsigned int r_o_c=0);
261 
265 void prepare_complex_data (const std::vector<Complex> & source,
266  std::vector<Real> & real_part,
267  std::vector<Real> & imag_part);
268 
269 #endif // #ifdef LIBMESH_USE_COMPLEX_NUMBERS
270 
271 
275 int mkdir(const char* pathname);
276 
277 
287 {
288 public:
289 
294  explicit
295  ReverseBytes (const bool dr);
296 
301  template <typename T>
302  T operator () (T & data) const;
303 
304 private:
305 
309  bool reverse () const { return _do_reverse; }
310 
314  const bool _do_reverse;
315 };
316 
317 
318 
319 // ReverseBytes inline members
320 inline
321 ReverseBytes::ReverseBytes (const bool rb) :
322  _do_reverse (rb)
323 {}
324 
325 
326 template <typename T>
327 inline
329 {
330  // Possibly reverse the byte ordering
331  if (this->reverse())
332  {
333  unsigned char * b = (unsigned char *) &data;
334 
335  int i=0;
336  int j=(sizeof(T) - 1);
337 
338  while (i < j)
339  {
340  std::swap (b[i], b[j]);
341  i++; j--;
342  }
343  }
344 
345  return data;
346 }
347 
348 
349 }
350 
351 } // namespace libMesh
352 
353 #endif // LIBMESH_UTILITY_H
This Functor simply takes an object and reverses its byte representation.
Definition: utility.h:286
const bool _do_reverse
flag
Definition: utility.h:314
std::string complex_filename(const std::string &basename, unsigned int r_o_c=0)
Definition: utility.C:105
void deallocate(std::vector< T > &vec)
A convenient method to truly empty a vector using the "swap trick".
Definition: utility.h:244
static const unsigned int prev[3]
A lookup table for the decrement modulo 3 operation, for iterating through the three nodes per elemen...
int mkdir(const char *pathname)
Create a directory.
Definition: utility.C:140
The libMesh namespace provides an interface to certain functionality in the library.
std::string system_info()
Definition: utility.C:57
void iota(ForwardIter first, ForwardIter last, T value)
Utility::iota is a duplication of the SGI STL extension std::iota.
Definition: utility.h:57
T operator()(T &data) const
Functor.
Definition: utility.h:328
libmesh_assert(j)
static T apply(const T &)
Definition: utility.h:189
static T apply(const T &x)
Definition: utility.h:184
T pow(const T &x)
Definition: utility.h:195
PetscErrorCode Vec x
void prepare_complex_data(const std::vector< Complex > &source, std::vector< Real > &real_part, std::vector< Real > &imag_part)
Prepare complex data for writing.
Definition: utility.C:121
An efficient template instantiation for raising to an arbitrary integer power.
Definition: utility.h:154
static T apply(const T &x)
Definition: utility.h:155
static T apply(const T &x)
Definition: utility.h:173
X_input swap(X_system)
void swap(Iterator &lhs, Iterator &rhs)
swap, used to implement op=
unsigned int factorial(unsigned int n)
A simple implementation of the factorial.
Definition: utility.h:204
static const bool value
Definition: xdr_io.C:108
bool is_sorted(InputIterator first, InputIterator last)
Utility::is_sorted mimics the behavior of the SGI STL extension std::is_sorted.
Definition: utility.h:74
ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T &value)
The STL provides std::binary_search() which returns true or false depending on whether the searched-f...
Definition: utility.h:132
IterBase * data
Ideally this private member data should have protected access.
ReverseBytes(const bool dr)
Constructor.
Definition: utility.h:321
T binomial(T n, T k)
Definition: utility.h:221