Cantera  2.5.1
utilities.h
Go to the documentation of this file.
1 /**
2  * @file utilities.h
3  * Various templated functions that carry out common vector
4  * operations (see \ref utils).
5  */
6 
7 // This file is part of Cantera. See License.txt in the top-level directory or
8 // at https://cantera.org/license.txt for license and copyright information.
9 
10 /**
11  * @defgroup utils Templated Utility Functions
12  *
13  * These are templates to perform various simple operations on arrays. Note that
14  * the compiler will inline these, so using them carries no performance penalty.
15  */
16 
17 #ifndef CT_UTILITIES_H
18 #define CT_UTILITIES_H
19 
20 #include "ct_defs.h"
21 #include "global.h"
22 #include <stdexcept>
23 
24 #include <numeric>
25 
26 namespace Cantera
27 {
28 //! Unary operator to multiply the argument by a constant.
29 /*!
30  * The form of this operator is designed for use by std::transform.
31  * @see @ref scale().
32  *
33  * @deprecated To be removed after Cantera 2.5. Replaceable with C++11 lambda.
34  */
35 template<class T> struct timesConstant : public std::unary_function<T, double> {
36  //! Constructor
37  /*!
38  * @param c Constant of templated type T that will be stored internally
39  * within the object and used in the multiplication operation
40  */
41  timesConstant(T c) : m_c(c) {
42  warn_deprecated("class timesConstant",
43  "To be removed after Cantera 2.5. Replaceable with C++11 lambda.");
44  }
45 
46  //! Parenthesis operator returning a double
47  /*!
48  * @param x Variable of templated type T that will be used in the
49  * multiplication operator
50  * @returns a value of type double from the internal multiplication
51  */
52  double operator()(T x) {
53  return m_c * x;
54  }
55 
56  //! Stored constant value of time T
57  T m_c;
58 };
59 
60 //! Templated Inner product of two vectors of length 4.
61 /*!
62  * If either \a x or \a y has length greater than 4, only the first 4 elements
63  * will be used.
64  *
65  * @param x first reference to the templated class V
66  * @param y second reference to the templated class V
67  * @return This class returns a hard-coded type, doublereal.
68  */
69 template<class V>
70 inline doublereal dot4(const V& x, const V& y)
71 {
72  return x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3];
73 }
74 
75 //! Templated Inner product of two vectors of length 5
76 /*!
77  * If either \a x or \a y has length greater than 4, only the first 4 elements
78  * will be used.
79  *
80  * @param x first reference to the templated class V
81  * @param y second reference to the templated class V
82  * @return This class returns a hard-coded type, doublereal.
83  */
84 template<class V>
85 inline doublereal dot5(const V& x, const V& y)
86 {
87  return x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3] +
88  x[4]*y[4];
89 }
90 
91 //! Function that calculates a templated inner product.
92 /*!
93  * This inner product is templated twice. The output variable is hard coded
94  * to return a doublereal.
95  *
96  * template<class InputIter, class InputIter2>
97  *
98  * @code
99  * double x[8], y[8];
100  * doublereal dsum = dot<double *,double *>(x, &x+7, y);
101  * @endcode
102  *
103  * @param x_begin Iterator pointing to the beginning, belonging to the
104  * iterator class InputIter.
105  * @param x_end Iterator pointing to the end, belonging to the
106  * iterator class InputIter.
107  * @param y_begin Iterator pointing to the beginning of y, belonging to the
108  * iterator class InputIter2.
109  * @return The return is hard-coded to return a double.
110  */
111 template<class InputIter, class InputIter2>
112 inline doublereal dot(InputIter x_begin, InputIter x_end,
113  InputIter2 y_begin)
114 {
115  return std::inner_product(x_begin, x_end, y_begin, 0.0);
116 }
117 
118 //! Multiply elements of an array by a scale factor.
119 /*!
120  * \code
121  * vector_fp in(8, 1.0), out(8);
122  * scale(in.begin(), in.end(), out.begin(), factor);
123  * \endcode
124  *
125  * @param begin Iterator pointing to the beginning, belonging to the
126  * iterator class InputIter.
127  * @param end Iterator pointing to the end, belonging to the
128  * iterator class InputIter.
129  * @param out Iterator pointing to the beginning of out, belonging to the
130  * iterator class OutputIter. This is the output variable
131  * for this routine.
132  * @param scale_factor input scale factor belonging to the class S.
133  */
134 template<class InputIter, class OutputIter, class S>
135 inline void scale(InputIter begin, InputIter end,
136  OutputIter out, S scale_factor)
137 {
138  std::transform(begin, end, out,
139  [scale_factor](double x) { return x * scale_factor; });
140 }
141 
142 //! Multiply each entry in x by the corresponding entry in y.
143 /*!
144  * The template arguments are: template<class InputIter, class OutputIter>
145  *
146  * Simple code Equivalent:
147  * \code
148  * double x[10], y[10]
149  * for (n = 0; n < 10; n++) {
150  * x[n] *= y[n];
151  * }
152  * \endcode
153  * Example of function call usage to implement the simple code example:
154  * \code
155  * double x[10], y[10]
156  * multiply_each(x, x+10, y);
157  * \endcode
158  *
159  * @param x_begin Iterator pointing to the beginning of the vector x,
160  * belonging to the iterator class InputIter.
161  * @param x_end Iterator pointing to the end of the vector x, belonging to
162  * the iterator class InputIter. The difference between end and
163  * begin determines the loop length
164  * @param y_begin Iterator pointing to the beginning of the vector y,
165  * belonging to the iterator class outputIter.
166  * @deprecated Unused. To be removed after Cantera 2.5.
167  */
168 template<class InputIter, class OutputIter>
169 inline void multiply_each(OutputIter x_begin, OutputIter x_end,
170  InputIter y_begin)
171 {
172  warn_deprecated("multiply_each", "To be removed after Cantera 2.5.");
173  for (; x_begin != x_end; ++x_begin, ++y_begin) {
174  *x_begin *= *y_begin;
175  }
176 }
177 
178 //! The maximum absolute value (templated version)
179 /*!
180  * The template arguments are: template<class InputIter>
181  *
182  * Simple code Equivalent:
183  * \code
184  * double x[10] amax = 0.0;
185  * for (int n = 0; n < 10; n++) {
186  * if (fabs(x[n]) > amax) amax = fabs(x[10]);
187  * }
188  * return amax;
189  * \endcode
190  * Example of function call usage to implement the simple code example:
191  * \code
192  * double x[10]
193  * double amax = absmax(x, x+10);
194  * \endcode
195  *
196  * @param begin Iterator pointing to the beginning of the x vector,
197  * belonging to the iterator class InputIter.
198  * @param end Iterator pointing to the end of the x vector, belonging to
199  * the iterator class InputIter. The difference between end and
200  * begin determines the loop length
201  * @deprecated Unused. To be removed after Cantera 2.5.
202  */
203 template<class InputIter>
204 inline doublereal absmax(InputIter begin, InputIter end)
205 {
206  warn_deprecated("absmax", "To be removed after Cantera 2.5.");
207  doublereal amax = 0.0;
208  for (; begin != end; ++begin) {
209  amax = std::max(fabs(*begin), amax);
210  }
211  return amax;
212 }
213 
214 //! Normalize the values in a sequence, such that they sum to 1.0 (templated
215 //! version)
216 /*!
217  * The template arguments are: template<class InputIter, class OutputIter>
218  *
219  * Simple Equivalent:
220  * \code
221  * double x[10], y[10], sum = 0.0;
222  * for (int n = 0; n < 10; n++) {
223  * sum += x[10];
224  * }
225  * for (int n = 0; n < 10; n++) {
226  * y[n] = x[n]/sum;
227  * }
228  * \endcode
229  * Example of function call usage:
230  * \code
231  * double x[10], y[10];
232  * normalize(x, x+10, y);
233  * \endcode
234  *
235  * @param begin Iterator pointing to the beginning of the x vector,
236  * belonging to the iterator class InputIter.
237  * @param end Iterator pointing to the end of the x vector, belonging to
238  * the iterator class InputIter. The difference between end and
239  * begin determines the loop length
240  * @param out Iterator pointing to the beginning of the output vector,
241  * belonging to the iterator class OutputIter.
242  * @deprecated Unused. To be removed after Cantera 2.5.
243  */
244 template<class InputIter, class OutputIter>
245 inline void normalize(InputIter begin, InputIter end,
246  OutputIter out)
247 {
248  warn_deprecated("normalize", "To be removed after Cantera 2.5.");
249  doublereal sum = std::accumulate(begin, end, 0.0);
250  for (; begin != end; ++begin, ++out) {
251  *out = *begin/sum;
252  }
253 }
254 
255 //! Templated divide of each element of \a x by the corresponding element of \a y.
256 /*!
257  * The template arguments are: template<class InputIter, class OutputIter>
258  *
259  * Simple Equivalent:
260  * \code
261  * double x[10], y[10];
262  * for (n = 0; n < 10; n++) {
263  * x[n] /= y[n];
264  * }
265  * \endcode
266  * Example of code usage:
267  * \code
268  * double x[10], y[10];
269  * divide_each(x, x+10, y);
270  * \endcode
271  *
272  * @param x_begin Iterator pointing to the beginning of the x vector,
273  * belonging to the iterator class OutputIter.
274  * @param x_end Iterator pointing to the end of the x vector, belonging to
275  * the iterator class OutputIter. The difference between end
276  * and begin determines the number of inner iterations.
277  * @param y_begin Iterator pointing to the beginning of the yvector, belonging
278  * to the iterator class InputIter.
279  * @deprecated Unused. To be removed after Cantera 2.5.
280  */
281 template<class InputIter, class OutputIter>
282 inline void divide_each(OutputIter x_begin, OutputIter x_end,
283  InputIter y_begin)
284 {
285  warn_deprecated("divide_each", "To be removed after Cantera 2.5.");
286  for (; x_begin != x_end; ++x_begin, ++y_begin) {
287  *x_begin /= *y_begin;
288  }
289 }
290 
291 //! Increment each entry in \a x by the corresponding entry in \a y.
292 /*!
293  * The template arguments are: template<class InputIter, class OutputIter>
294  *
295  * @param x_begin Iterator pointing to the beginning of the x vector,
296  * belonging to the iterator class OutputIter.
297  * @param x_end Iterator pointing to the end of the x vector, belonging to
298  * the iterator class OutputIter. The difference between end
299  * and begin determines the number of inner iterations.
300  * @param y_begin Iterator pointing to the beginning of the yvector, belonging
301  * to the iterator class InputIter.
302  * @deprecated Unused. To be removed after Cantera 2.5.
303  */
304 template<class InputIter, class OutputIter>
305 inline void sum_each(OutputIter x_begin, OutputIter x_end,
306  InputIter y_begin)
307 {
308  warn_deprecated("sum_each", "To be removed after Cantera 2.5.");
309  for (; x_begin != x_end; ++x_begin, ++y_begin) {
310  *x_begin += *y_begin;
311  }
312 }
313 
314 //! Copies a contiguous range in a sequence to indexed
315 //! positions in another sequence.
316 /*!
317  * The template arguments are: template<class InputIter, class OutputIter, class IndexIter>
318  *
319  * Example:
320  *
321  * \code
322  * vector_fp x(3), y(20);
323  * vector_int index(3);
324  * index[0] = 9;
325  * index[1] = 2;
326  * index[3] = 16;
327  * scatter_copy(x.begin(), x.end(), y.begin(), index.begin());
328  * \endcode
329  *
330  * This routine is templated 3 times.
331  * InputIter is an iterator for the source vector
332  * OutputIter is an iterator for the destination vector
333  * IndexIter is an iterator for the index into the destination vector.
334  *
335  * @param begin Iterator pointing to the beginning of the source vector,
336  * belonging to the iterator class InputIter.
337  * @param end Iterator pointing to the end of the source vector, belonging
338  * to the iterator class InputIter. The difference between end
339  * and begin determines the number of inner iterations.
340  * @param result Iterator pointing to the beginning of the output vector,
341  * belonging to the iterator class outputIter.
342  * @param index Iterator pointing to the beginning of the index vector, belonging to the
343  * iterator class IndexIter.
344  * @deprecated Unused. To be removed after Cantera 2.5.
345  */
346 template<class InputIter, class OutputIter, class IndexIter>
347 inline void scatter_copy(InputIter begin, InputIter end,
348  OutputIter result, IndexIter index)
349 {
350  warn_deprecated("scatter_copy", "To be removed after Cantera 2.5.");
351  for (; begin != end; ++begin, ++index) {
352  *(result + *index) = *begin;
353  }
354 }
355 
356 //! Multiply selected elements in an array by a contiguous sequence of
357 //! multipliers.
358 /*!
359  * The template arguments are: template<class InputIter, class RandAccessIter, class IndexIter>
360  *
361  * Example:
362  * \code
363  * double multipliers[] = {8.9, -2.0, 5.6};
364  * int index[] = {7, 4, 13};
365  * vector_fp data(20);
366  * ...
367  * // Multiply elements 7, 4, and 13 in data by multipliers[0], multipliers[1],and multipliers[2],
368  * // respectively
369  * scatter_mult(multipliers, multipliers + 3, data.begin(), index);
370  * \endcode
371  *
372  * @param mult_begin Iterator pointing to the beginning of the multiplier
373  * vector, belonging to the iterator class InputIter.
374  * @param mult_end Iterator pointing to the end of the multiplier vector,
375  * belonging to the iterator class InputIter. The difference
376  * between end and begin determines the number of inner
377  * iterations.
378  * @param data Iterator pointing to the beginning of the output vector,
379  * belonging to the iterator class RandAccessIter, that will
380  * be selectively multiplied.
381  * @param index Iterator pointing to the beginning of the index vector,
382  * belonging to the iterator class IndexIter.
383  * @deprecated Unused. To be removed after Cantera 2.5.
384  */
385 template<class InputIter, class RandAccessIter, class IndexIter>
386 inline void scatter_mult(InputIter mult_begin, InputIter mult_end,
387  RandAccessIter data, IndexIter index)
388 {
389  warn_deprecated("scatter_mult", "To be removed after Cantera 2.5.");
390  for (; mult_begin != mult_end; ++mult_begin, ++index) {
391  *(data + *index) *= *mult_begin;
392  }
393 }
394 
395 //! Compute \f[ \sum_k x_k \log x_k. \f].
396 /*!
397  * The template arguments are: template<class InputIter>
398  *
399  * A small number (1.0E-20) is added before taking the log. This templated
400  * class does the indicated sum. The template must be an iterator.
401  *
402  * @param begin Iterator pointing to the beginning, belonging to the
403  * iterator class InputIter.
404  * @param end Iterator pointing to the end, belonging to the
405  * iterator class InputIter.
406  * @return The return from this class is a double.
407  * @deprecated Unused. To be removed after Cantera 2.5.
408  */
409 template<class InputIter>
410 inline doublereal sum_xlogx(InputIter begin, InputIter end)
411 {
412  warn_deprecated("sum_xlogx", "To be removed after Cantera 2.5.");
413  doublereal sum = 0.0;
414  for (; begin != end; ++begin) {
415  sum += (*begin) * std::log(*begin + Tiny);
416  }
417  return sum;
418 }
419 
420 //! Compute \f[ \sum_k x_k \log Q_k. \f].
421 /*!
422  * The template arguments are: template<class InputIter1, class InputIter2>
423  *
424  * This class is templated twice. The first template, InputIter1 is the iterator
425  * that points to $x_k$. The second iterator InputIter2, point to $Q_k$. A small
426  * number (1.0E-20) is added before taking the log.
427  *
428  * @param begin Iterator pointing to the beginning, belonging to the
429  * iterator class InputIter1.
430  * @param end Iterator pointing to the end, belonging to the
431  * iterator class InputIter1.
432  * @param Q_begin Iterator pointing to the beginning of Q_k, belonging to the
433  * iterator class InputIter2.
434  * @return The return from this class is hard coded to a doublereal.
435  * @deprecated Unused. To be removed after Cantera 2.5.
436  */
437 template<class InputIter1, class InputIter2>
438 inline doublereal sum_xlogQ(InputIter1 begin, InputIter1 end,
439  InputIter2 Q_begin)
440 {
441  warn_deprecated("sum_xlogQ", "To be removed after Cantera 2.5.");
442  doublereal sum = 0.0;
443  for (; begin != end; ++begin, ++Q_begin) {
444  sum += (*begin) * std::log(*Q_begin + Tiny);
445  }
446  return sum;
447 }
448 
449 //! Templated evaluation of a polynomial of order 6
450 /*!
451  * @param x Value of the independent variable - First template parameter
452  * @param c Pointer to the polynomial - Second template parameter
453  */
454 template<class D, class R>
455 R poly6(D x, R* c)
456 {
457  return ((((((c[6]*x + c[5])*x + c[4])*x + c[3])*x +
458  c[2])*x + c[1])*x + c[0]);
459 }
460 
461 //! Templated evaluation of a polynomial of order 8
462 /*!
463  * @param x Value of the independent variable - First template parameter
464  * @param c Pointer to the polynomial - Second template parameter
465  */
466 template<class D, class R>
467 R poly8(D x, R* c)
468 {
469  return ((((((((c[8]*x + c[7])*x + c[6])*x + c[5])*x + c[4])*x + c[3])*x +
470  c[2])*x + c[1])*x + c[0]);
471 }
472 
473 //! Templated evaluation of a polynomial of order 5
474 /*!
475  * @param x Value of the independent variable - First template parameter
476  * @param c Pointer to the polynomial - Second template parameter
477  */
478 template<class D, class R>
479 R poly5(D x, R* c)
480 {
481  return (((((c[5]*x + c[4])*x + c[3])*x +
482  c[2])*x + c[1])*x + c[0]);
483 }
484 
485 //! Evaluates a polynomial of order 4.
486 /*!
487  * @param x Value of the independent variable.
488  * @param c Pointer to the polynomial coefficient array.
489  */
490 template<class D, class R>
491 R poly4(D x, R* c)
492 {
493  return ((((c[4]*x + c[3])*x +
494  c[2])*x + c[1])*x + c[0]);
495 }
496 
497 //! Templated evaluation of a polynomial of order 3
498 /*!
499  * @param x Value of the independent variable - First template parameter
500  * @param c Pointer to the polynomial - Second template parameter
501  */
502 template<class D, class R>
503 R poly3(D x, R* c)
504 {
505  return (((c[3]*x + c[2])*x + c[1])*x + c[0]);
506 }
507 
508 //@}
509 
510 //! Check to see that a number is finite (not NaN, +Inf or -Inf)
511 void checkFinite(const double tmp);
512 
513 //! Check to see that all elements in an array are finite
514 /*!
515  * Throws an exception if any element is NaN, +Inf, or -Inf
516  * @param name Name to be used in the exception message if the check fails
517  * @param values Array of *N* values to be checked
518  * @param N Number of elements in *values*
519  */
520 void checkFinite(const std::string& name, double* values, size_t N);
521 
522 //! Const accessor for a value in a std::map.
523 /*
524  * Similar to std::map.at(key), but returns *default_val* if the key is not
525  * found instead of throwing an exception.
526  */
527 template <class T, class U>
528 const U& getValue(const std::map<T, U>& m, const T& key, const U& default_val) {
529  typename std::map<T,U>::const_iterator iter = m.find(key);
530  return (iter == m.end()) ? default_val : iter->second;
531 }
532 
533 }
534 
535 #endif
This file contains definitions of terms that are used in internal routines and are unlikely to need m...
This file contains definitions for utility functions and text for modules, inputfiles,...
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:54
const double Tiny
Small number to compare differences of mole fractions against.
Definition: ct_defs.h:166
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264
const U & getValue(const std::map< T, U > &m, const T &key, const U &default_val)
Const accessor for a value in a std::map.
Definition: utilities.h:528
void checkFinite(const double tmp)
Check to see that a number is finite (not NaN, +Inf or -Inf)
Definition: checkFinite.cpp:15
void divide_each(OutputIter x_begin, OutputIter x_end, InputIter y_begin)
Templated divide of each element of x by the corresponding element of y.
Definition: utilities.h:282
doublereal dot(InputIter x_begin, InputIter x_end, InputIter2 y_begin)
Function that calculates a templated inner product.
Definition: utilities.h:112
doublereal sum_xlogQ(InputIter1 begin, InputIter1 end, InputIter2 Q_begin)
Compute.
Definition: utilities.h:438
doublereal absmax(InputIter begin, InputIter end)
The maximum absolute value (templated version)
Definition: utilities.h:204
void multiply_each(OutputIter x_begin, OutputIter x_end, InputIter y_begin)
Multiply each entry in x by the corresponding entry in y.
Definition: utilities.h:169
doublereal sum_xlogx(InputIter begin, InputIter end)
Compute.
Definition: utilities.h:410
doublereal dot4(const V &x, const V &y)
Templated Inner product of two vectors of length 4.
Definition: utilities.h:70
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
Definition: utilities.h:135
R poly5(D x, R *c)
Templated evaluation of a polynomial of order 5.
Definition: utilities.h:479
doublereal dot5(const V &x, const V &y)
Templated Inner product of two vectors of length 5.
Definition: utilities.h:85
void scatter_copy(InputIter begin, InputIter end, OutputIter result, IndexIter index)
Copies a contiguous range in a sequence to indexed positions in another sequence.
Definition: utilities.h:347
void scatter_mult(InputIter mult_begin, InputIter mult_end, RandAccessIter data, IndexIter index)
Multiply selected elements in an array by a contiguous sequence of multipliers.
Definition: utilities.h:386
void sum_each(OutputIter x_begin, OutputIter x_end, InputIter y_begin)
Increment each entry in x by the corresponding entry in y.
Definition: utilities.h:305
void normalize(InputIter begin, InputIter end, OutputIter out)
Normalize the values in a sequence, such that they sum to 1.0 (templated version)
Definition: utilities.h:245
R poly8(D x, R *c)
Templated evaluation of a polynomial of order 8.
Definition: utilities.h:467
R poly3(D x, R *c)
Templated evaluation of a polynomial of order 3.
Definition: utilities.h:503
R poly4(D x, R *c)
Evaluates a polynomial of order 4.
Definition: utilities.h:491
R poly6(D x, R *c)
Templated evaluation of a polynomial of order 6.
Definition: utilities.h:455
Unary operator to multiply the argument by a constant.
Definition: utilities.h:35
timesConstant(T c)
Constructor.
Definition: utilities.h:41
T m_c
Stored constant value of time T.
Definition: utilities.h:57
double operator()(T x)
Parenthesis operator returning a double.
Definition: utilities.h:52