utilities.h

Go to the documentation of this file.
00001 /**
00002  *  @file utilities.h
00003  *  Various templated functions that carry out common vector
00004  *  operations (see \ref globalUtilFuncs).
00005  */
00006 
00007 // Copyright 2001  California Institute of Technology
00008 /*
00009  * $Id: utilities.h 387 2010-01-17 18:17:55Z hkmoffa $
00010 
00011  */
00012 /**
00013  * @defgroup utils Templated Utility Functions
00014  *
00015  * These are templates to perform various simple operations on arrays.
00016  * Note that the compiler will inline these, so using them carries no
00017  * performnce penalty.
00018  */
00019 
00020 #ifndef CT_UTILITIES_H
00021 #define CT_UTILITIES_H
00022 
00023 #include "ct_defs.h"
00024 
00025 #ifdef WIN32
00026 #pragma warning(disable:4996)
00027 #endif
00028 
00029 //! Unary operator to multiply the argument by a constant. 
00030 /*!
00031  *  The form of this operator is designed for use by std::transform. 
00032  *  @see @ref  scale().
00033  */
00034 template<class T> struct timesConstant : public std::unary_function<T, double>
00035 {
00036   //! Constructor
00037   /*!
00038    * @param c  Constant of templated type T
00039    *           that will be storred internally within the object
00040    *           and used in the multiplication operation
00041    */
00042   timesConstant(T c) : m_c(c) {}
00043 
00044   //! Parenthesis operator returning a double
00045   /*!
00046    * @param x  Variable of templated type T that will be 
00047    *           used in the mulitplication operator
00048    *
00049    * @return Returns a value of type double from the internal 
00050    *         multiplication
00051    */
00052   double operator()(T x) {return m_c * x;}
00053 
00054   //! Storred constant value of time T
00055   T m_c;
00056 };
00057 
00058 
00059 namespace Cantera {
00060 
00061   /*!
00062    * @defgroup globalUtilFuncs Global Utility Functions
00063    *
00064    */
00065   //@{
00066     
00067   //! Maximum of two templated quantities, i and j.
00068   /*!
00069    * If \a i and \a j have different types, \a j
00070    * is converted to the type of \a i before the comparison.
00071    *
00072    * @param i   first argument, instance of templated class T
00073    * @param j   Second argument, instance of templated class S
00074    * @return  
00075    *       This function returns the maximum of the two values 
00076    *       as an instance of templated type T.
00077    */
00078   template<class T, class S>
00079   inline T max(T i, S j) {
00080     return (i > T(j) ? i : T(j));
00081   }
00082 
00083   //! Minimum of two templated quantities, i and j.
00084   /*!
00085    * If \a i and \a j have different types, \a j
00086    * is converted to the type of \a i before the comparison.
00087    *
00088    * @param i   first argument, instance of templated class T
00089    * @param j   Second argument, instance of templated class S
00090    * @return  
00091    *       This function returns the minimum of the two values 
00092    *       as an instance of templated type T.
00093    */
00094   template<class T, class S>
00095   inline T min(T i, S j) {
00096     return (i < T(j) ? i : T(j));
00097   }
00098 
00099     
00100   //!  Templated Inner product of two vectors of length 4. 
00101   /*!
00102    * If either \a x
00103    * or \a y has length greater than 4, only the first 4 elements
00104    * will be used.
00105    *
00106    * @param x   first reference to the templated class V
00107    * @param y   second reference to the templated class V
00108    * @return
00109    *      This class returns a hard-coded type, doublereal.
00110    */
00111   template<class V>
00112   inline doublereal dot4(const V& x, const V& y) {
00113     return x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3];
00114   }
00115   
00116   
00117   //!  Tempalted Inner product of two vectors of length 5 
00118   /*!
00119    * If either \a x
00120    * or \a y has length greater than 4, only the first 4 elements
00121    * will be used.
00122    *
00123    * @param x   first reference to the templated class V
00124    * @param y   second reference to the templated class V
00125    * @return
00126    *      This class returns a hard-coded type, doublereal.
00127    */
00128   template<class V>
00129   inline doublereal dot5(const V& x, const V& y) {
00130     return x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3] +
00131       x[4]*y[4];
00132   }
00133   
00134   //!  Tempalted Inner product of two vectors of length 6
00135   /*!
00136    * If either \a x
00137    * or \a y has length greater than 4, only the first 4 elements
00138    * will be used.
00139    *
00140    * @param x   first reference to the templated class V
00141    * @param y   second reference to the templated class V
00142    * @return
00143    *      This class returns a hard-coded type, doublereal.
00144    */
00145   template<class V>
00146   inline doublereal dot6(const V& x, const V& y) {
00147     return x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3] +
00148       x[4]*y[4] + x[5]*y[5];
00149   }
00150     
00151   //! Function that calculates a templated inner product.
00152   /*!
00153    * This inner product is templated twice. The output variable is hard coded
00154    * to return a doublereal.
00155    *
00156    * template<class InputIter, class InputIter2>
00157    *
00158    * @code
00159    *     double x[8], y[8];
00160    *     doublereal dsum = dot<double *,double *>(x, &x+7, y);
00161    * @endcode
00162    *
00163    * @param x_begin  Iterator pointing to the beginning, belonging to the
00164    *                 iterator class InputIter. 
00165    * @param x_end    Iterator pointing to the end, belonging to the
00166    *                 iterator class InputIter.
00167    * @param y_begin Iterator pointing to the beginning of y, belonging to the
00168    *               iterator class InputIter2. 
00169    * @return
00170    *     The return is hard-coded to return a double.
00171    */
00172   template<class InputIter, class InputIter2>
00173   inline doublereal dot(InputIter x_begin, InputIter x_end, 
00174                         InputIter2 y_begin) {
00175       return inner_product(x_begin, x_end, y_begin, 0.0);
00176   }
00177   
00178   //!   Multiply elements of an array by a scale factor.
00179   /*!
00180    * \code
00181    * vector_fp in(8, 1.0), out(8);
00182    * scale(in.begin(), in.end(), out.begin(), factor);
00183    * \endcode 
00184    *
00185    * @param begin  Iterator pointing to the beginning, belonging to the
00186    *               iterator class InputIter. 
00187    * @param end    Iterator pointing to the end, belonging to the
00188    *               iterator class InputIter.
00189    * @param out    Iterator pointing to the beginning of out, belonging to the
00190    *               iterator class OutputIter. This is the output variable
00191    *               for this routine.
00192    * @param scale_factor  input scale factor belonging to the class S.
00193    */ 
00194   template<class InputIter, class OutputIter, class S>
00195   inline void scale(InputIter begin, InputIter end, 
00196                     OutputIter out, S scale_factor) {
00197       std::transform(begin, end, out, timesConstant<S>(scale_factor));
00198   }
00199   
00200   /*!
00201    * Multiply elements of an array, y, by a scale factor, f and add the
00202    * result to an existing array, x. This is essentially a templated daxpy_
00203    * operation. 
00204    * 
00205    * The template arguments are:  template<class InputIter, 
00206    * class OutputIter, class S>  
00207    *
00208    *  Simple Code Example of the functionality;
00209    * @code
00210    *       double x[10], y[10], f;
00211    *       for (i = 0; i < n; i++) {
00212    *         y[i] += f * x[i]
00213    *       }
00214    * @endcode
00215    *  Example of the function call to implement the simple code example
00216    *   @code
00217    *      double x[10], y[10], f;
00218    *      increment_scale(x, x+10, y, f); 
00219    *   @endcode
00220    *
00221    * It is templated with three parameters. The first template
00222    * is the iterator, InputIter, which controls access to y[].
00223    * The second template is the iterator OutputIter, which controls
00224    * access to y[]. The third iterator is S, which is f.
00225    *
00226    * @param begin InputIter Iterator for beginning of y[]
00227    * @param end   inputIter Iterator for end of y[]  
00228    * @param out   OutputIter Iterator for beginning of x[]
00229    * @param scale_factor Scale Factor to multiply y[i] by
00230    */ 
00231   template<class InputIter, class OutputIter, class S>
00232   inline void increment_scale(InputIter begin, InputIter end, 
00233                               OutputIter out, S scale_factor) {
00234     for (; begin != end; ++begin, ++out) 
00235       *out += scale_factor * *begin;
00236   }
00237   
00238     
00239   //! Multiply each entry in x by the corresponding entry in y.
00240   /*!
00241    * The template arguments are:  template<class InputIter, class OutputIter>  
00242    *
00243    * Simple code Equivalent:
00244    *  \code
00245    *   double x[10], y[10]
00246    *   for (n = 0; n < 10; n++) {
00247    *     x[n] *= y[n];
00248    *   }
00249    * \endcode
00250    * Example of function call usage to implement the simple code example:
00251    *  \code
00252    *     double x[10], y[10]
00253    *     multiply_each(x, x+10, y);
00254    *  \endcode
00255    *
00256    * @param x_begin   Iterator pointing to the beginning of the vector x, belonging to the
00257    *                  iterator class InputIter.
00258    * @param x_end     Iterator pointing to the end of the vector x, belonging to the
00259    *                  iterator class InputIter. The difference between end and begin
00260    *                  determines the loop length
00261    * @param y_begin   Iterator pointing to the beginning of the vector y, belonging to the
00262    *                  iterator class outputIter.
00263    */    
00264   template<class InputIter, class OutputIter>   
00265   inline void multiply_each(OutputIter x_begin, OutputIter x_end, 
00266                             InputIter y_begin) {
00267     for(; x_begin != x_end; ++x_begin, ++y_begin) *x_begin *= *y_begin;
00268   }
00269 
00270   //! Invoke method 'resize' with argument \a m for a sequence of objects (templated version)
00271   /*!
00272    * The template arguments are:  template<class InputIter>  
00273    *
00274    * Simple code Equivalent:
00275    *  \code
00276    *   vector<vector<double> *> VV;
00277    *   for (n = 0; n < 20; n++) {
00278    *     vector<double> *vp = VV[n];
00279    *     vp->resize(m);
00280    *   }
00281    * \endcode
00282    * Example of function call usage to implement the simple code example:
00283    *  \code
00284    *    vector<vector<double> *> VV;
00285    *    resize_each(m, &VV[0], &VV[20]);
00286    *  \endcode
00287    *
00288    * @param m         Integer specifying the size that each object should be resized to.
00289    * @param begin     Iterator pointing to the beginning of the sequence of object, belonging to the
00290    *                  iterator class InputIter.
00291    * @param end       Iterator pointing to the end of the sequence of objects, belonging to the
00292    *                  iterator class InputIter. The difference between end and begin
00293    *                  determines the loop length
00294    *
00295    * @note This is currently unused.
00296    */
00297   template<class InputIter>
00298   inline void resize_each(int m, InputIter begin, InputIter end) {
00299     for(; begin != end; ++begin) begin->resize(m);
00300   }
00301 
00302   //! The maximum absolute value (templated version)
00303   /*!
00304    * The template arguments are:  template<class InputIter>  
00305    *
00306    * Simple code Equivalent:
00307    *  \code
00308    *   double x[10] amax = 0.0;
00309    *   for (int n = 0; n < 10; n++) {
00310    *    if (fabs(x[n]) > amax) amax = fabs(x[10]);
00311    *   }
00312    *   return amax;
00313    * \endcode
00314    * Example of function call usage to implement the simple code example:
00315    *  \code
00316    *   double x[10]
00317    *   double amax = absmax(x, x+10);
00318    *  \endcode
00319    *
00320    * @param begin     Iterator pointing to the beginning of the x vector, belonging to the
00321    *                  iterator class InputIter.
00322    * @param end       Iterator pointing to the end of the x vector, belonging to the
00323    *                  iterator class InputIter. The difference between end and begin
00324    *                  determines the loop length
00325    */
00326   template<class InputIter>
00327   inline doublereal absmax(InputIter begin, InputIter end) {
00328     doublereal amax = 0.0;
00329     for(; begin != end; ++begin) 
00330       if (fabs(*begin) > amax) amax = fabs(*begin);
00331     return amax;
00332   }
00333     
00334   //! Normalize the values in a sequence, such that they sum to 1.0 (templated version)
00335   /*!
00336    * The template arguments are:  template<class InputIter, class OutputIter>  
00337    *
00338    * Simple Equivalent:
00339    *  \code
00340    *   double x[10], y[10], sum = 0.0;
00341    *   for (int n = 0; n < 10; n++) {
00342    *    sum += x[10];
00343    *   }
00344    *   for (int n = 0; n < 10; n++) {
00345    *    y[n] = x[n]/sum;
00346    *   }
00347    * \endcode
00348    * Example of function call usage:
00349    *  \code
00350    *   double x[10], y[10]; 
00351    *   normalize(x, x+10, y);
00352    *  \endcode
00353    *
00354    * @param begin     Iterator pointing to the beginning of the x vector, belonging to the
00355    *                  iterator class InputIter.
00356    * @param end       Iterator pointing to the end of the x vector, belonging to the
00357    *                  iterator class InputIter. The difference between end and begin
00358    *                  determines the loop length
00359    * @param out       Iterator pointing to the beginning of the output vector, belonging to the
00360    *                  iterator class OutputIter.
00361    */
00362   template<class InputIter, class OutputIter>
00363   inline void normalize(InputIter begin, InputIter end, 
00364                         OutputIter out) {
00365     doublereal sum = accumulate(begin, end, 0.0);
00366     for (; begin != end; ++begin, ++out) *out = *begin/sum;
00367   }
00368 
00369   //! Templated divide of each element of \a x by the corresponding element of \a y.
00370   /*!
00371    * The template arguments are:  template<class InputIter, class OutputIter>  
00372    *
00373    * Simple Equivalent:
00374    *  \code
00375    *   double x[10], y[10];
00376    *   for (n = 0; n < 10; n++) {
00377    *     x[n] /= y[n];
00378    *   }
00379    * \endcode
00380    * Example of code usage:
00381    *  \code
00382    *   double x[10], y[10];
00383    *   divide_each(x, x+10, y);
00384    *  \endcode
00385    *
00386    * @param x_begin   Iterator pointing to the beginning of the x vector, belonging to the
00387    *                  iterator class OutputIter.
00388    * @param x_end     Iterator pointing to the end of the x vector, belonging to the
00389    *                  iterator class OutputIter. The difference between end and begin
00390    *                  determines the number of inner iterations.
00391    * @param y_begin   Iterator pointing to the beginning of the yvector, belonging to the
00392    *                  iterator class InputIter.
00393    */
00394   template<class InputIter, class OutputIter>   
00395   inline void divide_each(OutputIter x_begin, OutputIter x_end, 
00396                           InputIter y_begin) {
00397     for(; x_begin != x_end; ++x_begin, ++y_begin) *x_begin /= *y_begin;
00398   }
00399  
00400   //!  Increment each entry in \a x by the corresponding entry in \a y.
00401   /*!
00402    * The template arguments are:  template<class InputIter, class OutputIter>  
00403    *
00404    * @param x_begin   Iterator pointing to the beginning of the x vector, belonging to the
00405    *                  iterator class OutputIter.
00406    * @param x_end     Iterator pointing to the end of the x vector, belonging to the
00407    *                  iterator class OutputIter. The difference between end and begin
00408    *                  determines the number of inner iterations.
00409    * @param y_begin   Iterator pointing to the beginning of the yvector, belonging to the
00410    *                  iterator class InputIter.
00411    */
00412   template<class InputIter, class OutputIter>   
00413   inline void sum_each(OutputIter x_begin, OutputIter x_end, 
00414                        InputIter y_begin) {
00415     for(; x_begin != x_end; ++x_begin, ++y_begin) *x_begin += *y_begin;
00416   }
00417 
00418   //!   Copies a contiguous range in a sequence to indexed
00419   //!   positions in another sequence. 
00420   /*!
00421    * The template arguments are:  template<class InputIter, class OutputIter, class IndexIter>  
00422    *
00423    *  Example:
00424    *
00425    *  \code
00426    *  vector<double> x(3), y(20), ;
00427    *  vector<int> index(3);
00428    *  index[0] = 9;
00429    *  index[1] = 2;
00430    *  index[3] = 16; 
00431    *  scatter_copy(x.begin(), x.end(), y.begin(), index.begin());
00432    *  \endcode
00433    *
00434    *  This routine is templated 3 times. 
00435    *      InputIter is an iterator for the source vector
00436    *      OutputIter is an iterator for the destination vector
00437    *      IndexIter is an iterator for the index into the destination vector.
00438    *
00439    * @param begin   Iterator pointing to the beginning of the source vector, belonging to the
00440    *                iterator class InputIter.
00441    * @param end     Iterator pointing to the end of the source vector, belonging to the
00442    *                iterator class InputIter. The difference between end and begin
00443    *                determines the number of inner iterations.
00444    * @param result  Iterator pointing to the beginning of the output vector, belonging to the
00445    *                iterator class outputIter.
00446    * @param index   Iterator pointing to the beginning of the index vector, belonging to the
00447    *                iterator class IndexIter.
00448    */
00449   template<class InputIter, class OutputIter, class IndexIter>
00450   inline void scatter_copy(InputIter begin, InputIter end, 
00451                            OutputIter result, IndexIter index) {
00452     for (; begin != end; ++begin, ++index) {
00453       *(result + *index) = *begin;
00454     }
00455   }
00456   
00457  
00458   //! Multiply selected elements in an array by a contiguous 
00459   //! sequence of multipliers. 
00460   /*!
00461    * The template arguments are:  template<class InputIter, class RandAccessIter, class IndexIter>  
00462    *
00463    * Example:
00464    * \code
00465    * double multipliers[] = {8.9, -2.0, 5.6};
00466    * int index[] = {7, 4, 13};
00467    * vector_fp data(20);
00468    * ...
00469    * // Multiply elements 7, 4, and 13 in data by multipliers[0], multipliers[1],and multipliers[2],
00470    * // respectively
00471    * scatter_mult(multipliers, multipliers + 3, data.begin(), index);
00472    * \endcode
00473    *
00474    * @param mult_begin   Iterator pointing to the beginning of the multiplier vector, belonging to the
00475    *                     iterator class InputIter.
00476    * @param mult_end     Iterator pointing to the end of the multiplier vector, belonging to the
00477    *                     iterator class InputIter. The difference between end and begin
00478    *                     determines the number of inner iterations.
00479    * @param data         Iterator pointing to the beginning of the output vector, belonging to the
00480    *                     iterator class RandAccessIter, that will be selectively multipied.
00481    * @param index        Iterator pointing to the beginning of the index vector, belonging to the
00482    *                     iterator class IndexIter.
00483    */
00484   template<class InputIter, class RandAccessIter, class IndexIter>
00485   inline void scatter_mult(InputIter mult_begin, InputIter mult_end, 
00486                            RandAccessIter data, IndexIter index) {
00487     for (; mult_begin != mult_end; ++mult_begin, ++index) {
00488       *(data + *index) *= *mult_begin;
00489     }
00490   }
00491 
00492     
00493   //! Divide selected elements in an array by a contiguous sequence of divisors.
00494   /*!
00495    * The template arguments are:  template<class InputIter, class OutputIter, class IndexIter>  
00496    *
00497    * Example: 
00498    * \code
00499    * double divisors[] = {8.9, -2.0, 5.6};
00500    * int index[] = {7, 4, 13};
00501    * vector_fp data(20);
00502    * ...
00503    * // divide elements 7, 4, and 13 in data by divisors[7] divisors[4], and divisors[13]
00504    * // respectively
00505    * scatter_divide(divisors, divisors + 3, data.begin(), index);
00506    * \endcode
00507    *
00508    * @param begin   Iterator pointing to the beginning of the source vector, belonging to the
00509    *                iterator class InputIter.
00510    * @param end     Iterator pointing to the end of the source vector, belonging to the
00511    *                iterator class InputIter. The difference between end and begin
00512    *                determines the number of inner iterations.
00513    * @param result  Iterator pointing to the beginning of the output vector, belonging to the
00514    *                iterator class outputIter.
00515    * @param index   Iterator pointing to the beginning of the index vector, belonging to the
00516    *                iterator class IndexIter.
00517    */
00518   template<class InputIter, class OutputIter, class IndexIter>
00519   inline void scatter_divide(InputIter begin, InputIter end,
00520                              OutputIter result, IndexIter index) {
00521     for (; begin != end; ++begin, ++index) {
00522       *(result + *index) /= *begin;
00523     }
00524   }
00525   
00526   //!  Compute \f[ \sum_k x_k \log x_k. \f]. 
00527   /*!
00528    * The template arguments are:  template<class InputIter>
00529    *
00530    *  A small number (1.0E-20) is added before taking the log. This templated
00531    *  class does the indicated sun. The template must be an iterator.
00532    *
00533    * @param begin  Iterator pointing to the beginning, belonging to the
00534    *               iterator class InputIter. 
00535    * @param end    Iterator pointing to the end, belonging to the
00536    *               iterator class InputIter.
00537    * @return 
00538    *      The return from this class is a double.
00539    */ 
00540   template<class InputIter>  
00541   inline doublereal sum_xlogx(InputIter begin, InputIter end) {
00542     doublereal sum = 0.0;
00543     for (; begin != end; ++begin) {
00544       sum += (*begin) * std::log(*begin + Tiny);
00545     }
00546     return sum;
00547   }
00548 
00549   //! Compute \f[ \sum_k x_k \log Q_k. \f]. 
00550   /*!
00551    * The template arguments are:  template<class InputIter1, class InputIter2>
00552    *
00553    * This class is templated twice. The first template, InputIter1
00554    * is the iterator that points to $x_k$. The second iterator
00555    * InputIter2, point to $Q_k$.
00556    *  A small number (1.0E-20) is added before taking the log.
00557    * 
00558    * @param begin  Iterator pointing to the beginning, belonging to the
00559    *               iterator class InputIter1. 
00560    * @param end    Iterator pointing to the end, belonging to the
00561    *               iterator class InputIter1.
00562    * @param Q_begin Iterator pointing to the beginning of Q_k, belonging to the
00563    *               iterator class InputIter2. 
00564    * @return 
00565    *      The return from this class is hard coded to a doublereal.
00566    */ 
00567   template<class InputIter1, class InputIter2>  
00568   inline doublereal sum_xlogQ(InputIter1 begin, InputIter1 end,
00569                               InputIter2 Q_begin) {
00570     doublereal sum = 0.0;
00571     for (; begin != end; ++begin, ++Q_begin) {
00572       sum += (*begin) * std::log(*Q_begin + Tiny);
00573     }
00574     return sum;
00575   }
00576 
00577   //!   Scale a templated vector by a constant factor.
00578   /*!
00579    *   The template arguments are:  template<class OutputIter>
00580    *
00581    * This function is essentially a wrapper around the stl
00582    * function %scale(). The function is has one template
00583    * parameter, OutputIter. OutputIter is a templated iterator
00584    * that points to the vector to be scaled.
00585    *
00586    * @param N       Length of the vector
00587    * @param alpha   scale factor - double
00588    * @param x       Templated Iterator to the start of the vector
00589    *                to be scaled. 
00590    */
00591   template<class OutputIter>
00592   inline void scale(int N, double alpha, OutputIter x) {
00593     scale(x, x+N, x, alpha);
00594   }
00595   
00596 
00597   //! Templated evaluation of a polynomial of order 6
00598   /*!
00599    *  @param x   Value of the independent variable - First template parameter
00600    *  @param c   Pointer to the polynomial - Second template parameter 
00601    */
00602   template<class D, class R>
00603   R poly6(D x, R* c) {
00604     return ((((((c[6]*x + c[5])*x + c[4])*x + c[3])*x + 
00605               c[2])*x + c[1])*x + c[0]);
00606   }
00607 
00608   //! Templated evaluation of a polynomial of order 8
00609   /*!
00610    *  @param x   Value of the independent variable - First template parameter
00611    *  @param c   Pointer to the polynomial - Second template parameter 
00612    */
00613   template<class D, class R>
00614   R poly8(D x, R* c) {
00615     return ((((((((c[8]*x + c[7])*x + c[6])*x + c[5])*x + c[4])*x + c[3])*x + 
00616               c[2])*x + c[1])*x + c[0]);
00617   }
00618 
00619   //! Templated evaluation of a polynomial of order 10
00620   /*!
00621    *  @param x   Value of the independent variable - First template parameter
00622    *  @param c   Pointer to the polynomial - Second template parameter 
00623    */
00624   template<class D, class R>
00625   R poly10(D x, R* c) {
00626     return ((((((((((c[10]*x + c[9])*x + c[8])*x + c[7])*x 
00627                   + c[6])*x + c[5])*x + c[4])*x + c[3])*x 
00628               + c[2])*x + c[1])*x + c[0]);
00629   }
00630 
00631   //! Templated evaluation of a polynomial of order 5
00632   /*!
00633    *  @param x   Value of the independent variable - First template parameter
00634    *  @param c   Pointer to the polynomial - Second template parameter 
00635    */ 
00636   template<class D, class R>
00637   R poly5(D x, R* c) {
00638     return (((((c[5]*x + c[4])*x + c[3])*x + 
00639               c[2])*x + c[1])*x + c[0]);
00640   }
00641 
00642   //! Evaluates a polynomial of order 4.
00643   /*!
00644    *  @param x   Value of the independent variable.
00645    *  @param c   Pointer to the polynomial coefficient array.
00646    */
00647   template<class D, class R>
00648   R poly4(D x, R* c) {
00649     return ((((c[4]*x + c[3])*x + 
00650               c[2])*x + c[1])*x + c[0]);
00651   }
00652     
00653   //! Templated evaluation of a polynomial of order 3
00654   /*!
00655    *  @param x   Value of the independent variable - First template parameter
00656    *  @param c   Pointer to the polynomial - Second template parameter 
00657    */
00658   template<class D, class R>
00659   R poly3(D x, R* c) {
00660     return (((c[3]*x + c[2])*x + c[1])*x + c[0]);
00661   }
00662 
00663   //@}
00664 }
00665 
00666 
00667 #endif
00668 
00669 
00670 
00671 
00672 
00673 
00674 
00675 
00676 
00677 
00678 
00679 
00680 
00681 
00682 
00683 
00684 
Generated by  doxygen 1.6.3