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
Cantera::divide_each
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
global.h
Cantera::checkFinite
void checkFinite(const double tmp)
Check to see that a number is finite (not NaN, +Inf or -Inf)
Definition: checkFinite.cpp:15
ct_defs.h
Cantera::poly3
R poly3(D x, R *c)
Templated evaluation of a polynomial of order 3.
Definition: utilities.h:503
Cantera::warn_deprecated
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:54
Cantera::Tiny
const double Tiny
Small number to compare differences of mole fractions against.
Definition: ct_defs.h:166
Cantera::timesConstant::m_c
T m_c
Stored constant value of time T.
Definition: utilities.h:57
Cantera::poly5
R poly5(D x, R *c)
Templated evaluation of a polynomial of order 5.
Definition: utilities.h:479
Cantera::dot4
doublereal dot4(const V &x, const V &y)
Templated Inner product of two vectors of length 4.
Definition: utilities.h:70
Cantera::multiply_each
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
Cantera::timesConstant::timesConstant
timesConstant(T c)
Constructor.
Definition: utilities.h:41
Cantera::normalize
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
Cantera::poly4
R poly4(D x, R *c)
Evaluates a polynomial of order 4.
Definition: utilities.h:491
Cantera::timesConstant::operator()
double operator()(T x)
Parenthesis operator returning a double.
Definition: utilities.h:52
Cantera::poly6
R poly6(D x, R *c)
Templated evaluation of a polynomial of order 6.
Definition: utilities.h:455
Cantera::poly8
R poly8(D x, R *c)
Templated evaluation of a polynomial of order 8.
Definition: utilities.h:467
Cantera::getValue
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
Cantera::scatter_mult
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
Cantera::sum_xlogQ
doublereal sum_xlogQ(InputIter1 begin, InputIter1 end, InputIter2 Q_begin)
Compute.
Definition: utilities.h:438
Cantera::sum_xlogx
doublereal sum_xlogx(InputIter begin, InputIter end)
Compute.
Definition: utilities.h:410
Cantera::absmax
doublereal absmax(InputIter begin, InputIter end)
The maximum absolute value (templated version)
Definition: utilities.h:204
Cantera::dot
doublereal dot(InputIter x_begin, InputIter x_end, InputIter2 y_begin)
Function that calculates a templated inner product.
Definition: utilities.h:112
Cantera::dot5
doublereal dot5(const V &x, const V &y)
Templated Inner product of two vectors of length 5.
Definition: utilities.h:85
Cantera::scale
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
Definition: utilities.h:135
Cantera::scatter_copy
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
Cantera::sum_each
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
Cantera::timesConstant
Unary operator to multiply the argument by a constant.
Definition: utilities.h:35
Cantera
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:263