CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_POLY_INCLUDED 00003 # define CPPAD_POLY_INCLUDED 00004 00005 /* -------------------------------------------------------------------------- 00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell 00007 00008 CppAD is distributed under multiple licenses. This distribution is under 00009 the terms of the 00010 Eclipse Public License Version 1.0. 00011 00012 A copy of this license is included in the COPYING file of this distribution. 00013 Please visit http://www.coin-or.org/CppAD/ for information on other licenses. 00014 -------------------------------------------------------------------------- */ 00015 /* 00016 $begin Poly$$ 00017 $spell 00018 cppad.hpp 00019 CppAD 00020 namespace 00021 cstddef 00022 ifndef 00023 endif 00024 deg 00025 const 00026 std 00027 da 00028 $$ 00029 00030 $index Poly$$ 00031 $index polynomial$$ 00032 $index derivative, polynomial template$$ 00033 $index template, polynomial derivative$$ 00034 00035 $section Evaluate a Polynomial or its Derivative$$ 00036 00037 $head Syntax$$ 00038 $code # include <cppad/poly.hpp>$$ 00039 $pre 00040 $$ 00041 $icode%p% = Poly(%k%, %a%, %z%)%$$ 00042 00043 00044 $head Description$$ 00045 Computes the $th k$$ derivative of the polynomial 00046 $latex \[ 00047 P(z) = a_0 + a_1 z^1 + \cdots + a_d z^d 00048 \] $$ 00049 If $icode k$$ is equal to zero, the return value is $latex P(z)$$. 00050 00051 $head Include$$ 00052 The file $code cppad/poly.hpp$$ is included by $code cppad/cppad.hpp$$ 00053 but it can also be included separately with out the rest of 00054 the $code CppAD$$ routines. 00055 Including this file defines 00056 $code Poly$$ within the $code CppAD$$ namespace. 00057 00058 $head k$$ 00059 The argument $icode k$$ has prototype 00060 $codei% 00061 size_t %k% 00062 %$$ 00063 It specifies the order of the derivative to calculate. 00064 00065 $head a$$ 00066 The argument $icode a$$ has prototype 00067 $codei% 00068 const %Vector% &%a% 00069 %$$ 00070 (see $cref/Vector/Poly/Vector/$$ below). 00071 It specifies the vector corresponding to the polynomial $latex P(z)$$. 00072 00073 $head z$$ 00074 The argument $icode z$$ has prototype 00075 $codei% 00076 const %Type% &%z% 00077 %$$ 00078 (see $icode Type$$ below). 00079 It specifies the point at which to evaluate the polynomial 00080 00081 $head p$$ 00082 The result $icode p$$ has prototype 00083 $codei% 00084 %Type% %p% 00085 %$$ 00086 (see $cref/Type/Poly/Type/$$ below) 00087 and it is equal to the $th k$$ derivative of $latex P(z)$$; i.e., 00088 $latex \[ 00089 p = \frac{k !}{0 !} a_k 00090 + \frac{(k+1) !}{1 !} a_{k+1} z^1 00091 + \ldots 00092 + \frac{d !}{(d - k) !} a_d z^{d - k} 00093 \] 00094 $$ 00095 If $latex k > d$$, $icode%p% = %Type%(0)%$$. 00096 00097 $head Type$$ 00098 The type $icode Type$$ is determined by the argument $icode z$$. 00099 It is assumed that 00100 multiplication and addition of $icode Type$$ objects 00101 are commutative. 00102 00103 $subhead Operations$$ 00104 The following operations must be supported where 00105 $icode x$$ and $icode y$$ are objects of type $icode Type$$ 00106 and $icode i$$ is an $code int$$: 00107 $table 00108 $icode%x% = %i%$$ $cnext assignment $rnext 00109 $icode%x% = %y%$$ $cnext assignment $rnext 00110 $icode%x% *= %y%$$ $cnext multiplication computed assignment $rnext 00111 $icode%x% += %y%$$ $cnext addition computed assignment 00112 00113 $tend 00114 00115 00116 $head Vector$$ 00117 The type $icode Vector$$ must be a $cref SimpleVector$$ class with 00118 $cref/elements of type/SimpleVector/Elements of Specified Type/$$ 00119 $icode Type$$. 00120 The routine $cref CheckSimpleVector$$ will generate an error message 00121 if this is not the case. 00122 00123 $head Operation Sequence$$ 00124 The $icode Type$$ operation sequence used to calculate $icode p$$ is 00125 $cref/independent/glossary/Operation/Independent/$$ 00126 of $icode z$$ and the elements of $icode a$$ 00127 (it does depend on the size of the vector $icode a$$). 00128 00129 00130 $children% 00131 example/poly.cpp% 00132 omh/poly_hpp.omh 00133 %$$ 00134 00135 $head Example$$ 00136 The file 00137 $cref poly.cpp$$ 00138 contains an example and test of this routine. 00139 It returns true if it succeeds and false otherwise. 00140 00141 $head Source$$ 00142 The file $cref poly.hpp$$ contains the 00143 current source code that implements these specifications. 00144 00145 $end 00146 ------------------------------------------------------------------------------ 00147 */ 00148 // BEGIN C++ 00149 # include <cstddef> // used to defined size_t 00150 # include <cppad/check_simple_vector.hpp> 00151 00152 namespace CppAD { // BEGIN CppAD namespace 00153 00154 template <class Type, class Vector> 00155 Type Poly(size_t k, const Vector &a, const Type &z) 00156 { size_t i; 00157 size_t d = a.size() - 1; 00158 00159 Type tmp; 00160 00161 // check Vector is Simple Vector class with Type elements 00162 CheckSimpleVector<Type, Vector>(); 00163 00164 // case where derivative order greater than degree of polynomial 00165 if( k > d ) 00166 { tmp = 0; 00167 return tmp; 00168 } 00169 // case where we are evaluating a derivative 00170 if( k > 0 ) 00171 { // initialize factor as (k-1) ! 00172 size_t factor = 1; 00173 for(i = 2; i < k; i++) 00174 factor *= i; 00175 00176 // set b to coefficient vector corresponding to derivative 00177 Vector b(d - k + 1); 00178 for(i = k; i <= d; i++) 00179 { factor *= i; 00180 tmp = factor; 00181 b[i - k] = a[i] * tmp; 00182 factor /= (i - k + 1); 00183 } 00184 // value of derivative polynomial 00185 return Poly(0, b, z); 00186 } 00187 // case where we are evaluating the original polynomial 00188 Type sum = a[d]; 00189 i = d; 00190 while(i > 0) 00191 { sum *= z; 00192 sum += a[--i]; 00193 } 00194 return sum; 00195 } 00196 } // END CppAD namespace 00197 // END C++ 00198 # endif