Cantera  2.0
vec_functions.h
Go to the documentation of this file.
1 /**
2  * @file vec_functions.h
3  * Templates for operations on vector-like objects.
4  */
5 /*
6  * Copyright 2001 California Institute of Technology
7  */
8 
9 #ifndef CT_VEC_FUNCTIONS_H
10 #define CT_VEC_FUNCTIONS_H
11 
12 #include "ct_defs.h"
13 #include "utilities.h"
14 #include <numeric>
15 #include <functional>
16 #include <algorithm>
17 #include <iostream>
18 #include <cstring>
19 
20 namespace Cantera
21 {
22 
23 
24 //! Templated function that copies the first n entries from x to y.
25 /*!
26  *
27  *
28  * The templated type is the type of x and y
29  *
30  * @param n Number of elements to copy from x to y
31  * @param x The object x, of templated type const T&
32  * @param y The object y, of templated type T&
33  */
34 template<class T>
35 inline void copyn(size_t n, const T& x, T& y)
36 {
37  std::copy(x.begin(), x.begin() + n, y.begin());
38 }
39 
40 //! Divide each element of x by the corresponding element of y.
41 /*!
42  * This function replaces x[n] by x[n]/y[n], for 0 <= n < x.size()
43  *
44  * @param x Numerator object of the division operation with template type T
45  * At the end of the calculation, it contains the result.
46  * @param y Denominator object of the division template type T
47  */
48 template<class T>
49 inline void divide_each(T& x, const T& y)
50 {
51  std::transform(x.begin(), x.end(), y.begin(),
52  x.begin(), std::divides<typename T::value_type>());
53 }
54 
55 //! Multiply each element of x by the corresponding element of y.
56 /*!
57  * This function replaces x[n] by x[n]*y[n], for 0 <= n < x.size()
58  * This is a templated function with just one template type.
59  *
60  * @param x First object of the multiplication with template type T
61  * At the end of the calculation, it contains the result.
62  * @param y Second object of the multiplication with template type T
63  *
64  */
65 template<class T>
66 inline void multiply_each(T& x, const T& y)
67 {
68  std::transform(x.begin(), x.end(), y.begin(),
69  x.begin(), std::multiplies<typename T::value_type>());
70 }
71 
72 //! Multiply each element of x by scale_factor.
73 /*!
74  * This function replaces x[n] by x[n]*scale_factor, for 0 <= n < x.size()
75  *
76  * @param x First object of the multiplication with template type T
77  * At the end of the calculation, it contains the result.
78  * @param scale_factor scale factor with template type S
79  */
80 template<class T, class S>
81 inline void scale(T& x, S scale_factor)
82 {
83  scale(x.begin(), x.end(), x.begin(), scale_factor);
84 }
85 
86 //! Return the templated dot product of two objects
87 /*!
88  * Returns the sum of x[n]*y[n], for 0 <= n < x.size().
89  *
90  * @param x First object of the dot product with template type T
91  * At the end of the calculation, it contains the result.
92  * @param y Second object of the dot product with template type T
93  */
94 template<class T>
95 inline doublereal dot_product(const T& x, const T& y)
96 {
97  return std::inner_product(x.begin(), x.end(), y.begin(), 0.0);
98 }
99 
100 //! Returns the templated dot ratio of two objects
101 /**
102  * Returns the sum of x[n]/y[n], for 0 <= n < x.size().
103  *
104  * @param x First object of the dot product with template type T
105  * At the end of the calculation, it contains the result.
106  * @param y Second object of the dot product with template type T
107  */
108 template<class T>
109 inline doublereal dot_ratio(const T& x, const T& y)
110 {
111  return _dot_ratio(x.begin(), x.end(), y.begin(), 0.0);
112 }
113 
114 //! Returns a templated addition operation of two objects
115 /**
116  * Replaces x[n] by x[n] + y[n] for 0 <= n < x.size()
117  *
118  * @param x First object of the addition with template type T
119  * At the end of the calculation, it contains the result.
120  * @param y Second object of the addition with template type T
121  */
122 template<class T>
123 inline void add_each(T& x, const T& y)
124 {
125  std::transform(x.begin(), x.end(), y.begin(),
126  x.begin(), std::plus<typename T::value_type>());
127 }
128 
129 
130 //! Templated dot ratio class
131 /*!
132  * Calculates the quantity:
133  *
134  * S += x[n]/y[n]
135  *
136  * The first templated type is the iterator type for x[] and y[].
137  * The second templated type is the type of S.
138  *
139  * @param x_begin InputIter type, indicating the address of the
140  * first element of x
141  * @param x_end InputIter type, indicating the address of the
142  * last element of x
143  * @param y_begin InputIter type, indicating the address of the
144  * first element of y
145  * @param start_value S type, indicating the type of the
146  * accumulation result.
147  */
148 template<class InputIter, class S>
149 inline doublereal _dot_ratio(InputIter x_begin, InputIter x_end,
150  InputIter y_begin, S start_value)
151 {
152  for (; x_begin != x_end; ++x_begin, ++y_begin) {
153  start_value += *x_begin / *y_begin;
154  }
155  return start_value;
156 }
157 
158 
159 //! Finds the entry in a vector with maximum absolute
160 //! value, and return this value.
161 /*!
162  * @param v Vector to be queried for maximum value, with template type T
163  *
164  * @return Returns an object of type T that is the maximum value,
165  */
166 template<class T>
167 inline T absmax(const std::vector<T>& v)
168 {
169  int n = v.size();
170  T val;
171  T maxval = 0.0;
172  for (int i = 0; i < n; i++) {
173  val = v[i];
174  if (val < 0) {
175  val = -val;
176  }
177  if (val > maxval) {
178  maxval = val;
179  }
180  }
181  return maxval;
182 }
183 
184 //! Write a vector to a stream
185 template <class T>
186 inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
187 {
188  size_t n = v.size();
189  for (size_t i = 0; i < n; i++) {
190  os << v[i];
191  if (i != n-1) {
192  os << ", ";
193  }
194  }
195  return os;
196 }
197 
198 }
199 
200 #endif