00001 /** 00002 * @file vec_functions.h 00003 * Templates for operations on vector-like objects. 00004 */ 00005 /* 00006 * $Date: 2010-01-03 19:46:26 -0500 (Sun, 03 Jan 2010) $ 00007 * $Revision: 368 $ 00008 * 00009 * Copyright 2001 California Institute of Technology 00010 * 00011 */ 00012 00013 #ifndef CT_VEC_FUNCTIONS_H 00014 #define CT_VEC_FUNCTIONS_H 00015 00016 #include "ct_defs.h" 00017 #include "utilities.h" 00018 #include <numeric> 00019 #include <functional> 00020 #include <algorithm> 00021 00022 #include <cstring> 00023 00024 namespace Cantera { 00025 00026 00027 //! Templated function that copies the first n entries from x to y. 00028 /*! 00029 * 00030 * 00031 * The templated type is the type of x and y 00032 * 00033 * @param n Number of elements to copy from x to y 00034 * @param x The object x, of templated type const T& 00035 * @param y The object y, of templated type T& 00036 */ 00037 template<class T> 00038 inline void copyn(size_t n, const T& x, T& y) { 00039 std::copy(x.begin(), x.begin() + n, y.begin()); 00040 } 00041 00042 //! Divide each element of x by the corresponding element of y. 00043 /*! 00044 * This function replaces x[n] by x[n]/y[n], for 0 <= n < x.size() 00045 * 00046 * @param x Numerator object of the division operation with template type T 00047 * At the end of the calculation, it contains the result. 00048 * @param y Denominator object of the division template type T 00049 */ 00050 template<class T> 00051 inline void divide_each(T& x, const T& y) { 00052 std::transform(x.begin(), x.end(), y.begin(), 00053 x.begin(), std::divides<TYPENAME_KEYWORD T::value_type>()); 00054 } 00055 00056 //! Multiply each element of x by the corresponding element of y. 00057 /*! 00058 * This function replaces x[n] by x[n]*y[n], for 0 <= n < x.size() 00059 * This is a templated function with just one template type. 00060 * 00061 * @param x First object of the multiplication with template type T 00062 * At the end of the calculation, it contains the result. 00063 * @param y Second object of the multiplication with template type T 00064 * 00065 */ 00066 template<class T> 00067 inline void multiply_each(T& x, const T& y) { 00068 std::transform(x.begin(), x.end(), y.begin(), 00069 x.begin(), std::multiplies<TYPENAME_KEYWORD T::value_type>()); 00070 } 00071 00072 //! Multiply each element of x by scale_factor. 00073 /*! 00074 * This function replaces x[n] by x[n]*scale_factor, for 0 <= n < x.size() 00075 * 00076 * @param x First object of the multiplication with template type T 00077 * At the end of the calculation, it contains the result. 00078 * @param scale_factor scale factor with template type S 00079 */ 00080 template<class T, class S> 00081 inline void scale(T& x, S scale_factor) { 00082 scale(x.begin(), x.end(), x.begin(), scale_factor); 00083 } 00084 00085 //! Return the templated dot product of two objects 00086 /*! 00087 * Returns the sum of x[n]*y[n], for 0 <= n < x.size(). 00088 * 00089 * @param x First object of the dot product with template type T 00090 * At the end of the calculation, it contains the result. 00091 * @param y Second object of the dot product with template type T 00092 */ 00093 template<class T> 00094 inline doublereal dot_product(const T& x, const T& y) { 00095 return std::inner_product(x.begin(), x.end(), y.begin(), 0.0); 00096 } 00097 00098 //! Returns the templated dot ratio of two objects 00099 /** 00100 * Returns the sum of x[n]/y[n], for 0 <= n < x.size(). 00101 * 00102 * @param x First object of the dot product with template type T 00103 * At the end of the calculation, it contains the result. 00104 * @param y Second object of the dot product with template type T 00105 */ 00106 template<class T> 00107 inline doublereal dot_ratio(const T& x, const T& y) { 00108 return _dot_ratio(x.begin(), x.end(), y.begin(), 0.0); 00109 } 00110 00111 //! Returns a templated addition operation of two objects 00112 /** 00113 * Replaces x[n] by x[n] + y[n] for 0 <= n < x.size() 00114 * 00115 * @param x First object of the addition with template type T 00116 * At the end of the calculation, it contains the result. 00117 * @param y Second object of the addition with template type T 00118 */ 00119 template<class T> 00120 inline void add_each(T& x, const T& y) { 00121 std::transform(x.begin(), x.end(), y.begin(), 00122 x.begin(), std::plus<TYPENAME_KEYWORD T::value_type>()); 00123 } 00124 00125 00126 //! Templated dot ratio class 00127 /*! 00128 * Calculates the quantity: 00129 * 00130 * S += x[n]/y[n] 00131 * 00132 * The first templated type is the iterator type for x[] and y[]. 00133 * The second templated type is the type of S. 00134 * 00135 * @param x_begin InputIter type, indicating the address of the 00136 * first element of x 00137 * @param x_end InputIter type, indicating the address of the 00138 * last element of x 00139 * @param y_begin InputIter type, indicating the address of the 00140 * first element of y 00141 * @param start_value S type, indicating the type of the 00142 * accumulation result. 00143 */ 00144 template<class InputIter, class S> 00145 inline doublereal _dot_ratio(InputIter x_begin, InputIter x_end, 00146 InputIter y_begin, S start_value) { 00147 for (; x_begin != x_end; ++x_begin, ++y_begin) 00148 start_value += *x_begin / *y_begin; 00149 return start_value; 00150 } 00151 00152 00153 //! Finds the entry in a vector with maximum absolute 00154 //! value, and return this value. 00155 /*! 00156 * @param v Vector to be queried for maximum value, with template type T 00157 * 00158 * @return Returns an object of type T that is the maximum value, 00159 */ 00160 template<class T> 00161 inline T absmax(const std::vector<T>& v) { 00162 int n = v.size(); 00163 T val; 00164 T maxval = 0.0; 00165 for (int i = 0; i < n; i++) { 00166 val = v[i]; 00167 if (val < 0) val = -val; 00168 if (val > maxval) maxval = val; 00169 } 00170 return maxval; 00171 } 00172 00173 //! Copy a vector of doubles in an efficient, fast manner. 00174 /*! 00175 * No checking is done other that to check that len is greater than 0 00176 * 00177 * @param copyTo Vector to receive the copy 00178 * @param copyFrom Vector from which the copy is coming 00179 * @param len Length of the copy 00180 */ 00181 inline void fbo_copy_dbl_1(doublereal * const copyTo, const doublereal * const copyFrom, 00182 const int len) { 00183 if (len > 0) { 00184 (void) memcpy((void *)copyTo, (const void *)copyFrom, len * sizeof(doublereal)); 00185 } 00186 } 00187 00188 //! Copy a vector<doubles> in an efficient, fast manner. 00189 /*! 00190 * No checking is done other that to check that len is greater than 0 00191 * 00192 * @param copyTo Vector to receive the copy 00193 * @param copyFrom Vector from which the copy is coming 00194 * @param len Length of the copy 00195 */ 00196 inline void fvo_copy_dbl_1(std::vector<doublereal> ©To, const std::vector<doublereal> ©From, 00197 const int len) { 00198 if (len > 0) { 00199 (void) memcpy((void *)(©To[0]), (const void *)(©From[0]), len * sizeof(doublereal)); 00200 } 00201 } 00202 00203 //! Zero a double vector in an efficient, fast manner. 00204 /*! 00205 * No checking is done other that to check that len is greater than 0 00206 * 00207 * @param v Vector to be zeroed 00208 * @param len Length of the copy 00209 */ 00210 inline void fbo_zero_dbl_1(doublereal * const v, const int len) { 00211 if (len > 0) { 00212 (void) memset((void *)v, 0, len * sizeof(doublereal)); 00213 } 00214 } 00215 00216 //! Zero a vector<doubles> in an efficient, fast manner. 00217 /*! 00218 * No checking is done other that to check that len is greater than 0 00219 * 00220 * @param v Vector to be zeroed 00221 * @param len Length of the copy 00222 */ 00223 inline void fvo_zero_dbl_1(std::vector<doublereal> &v, const int len) { 00224 if (len > 0) { 00225 (void) memset((void *)(&v[0]), 0, len * sizeof(doublereal)); 00226 } 00227 } 00228 00229 00230 } 00231 00232 #endif