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