CppAD: A C++ Algorithmic Differentiation Package 20110419
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_EXP_OP_INCLUDED 00003 # define CPPAD_EXP_OP_INCLUDED 00004 00005 /* -------------------------------------------------------------------------- 00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-10 Bradley M. Bell 00007 00008 CppAD is distributed under multiple licenses. This distribution is under 00009 the terms of the 00010 Common 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 00017 CPPAD_BEGIN_NAMESPACE 00018 /*! 00019 \file exp_op.hpp 00020 Forward and reverse mode calculations for z = exp(x). 00021 */ 00022 00023 00024 /*! 00025 Forward mode Taylor coefficient for result of op = ExpOp. 00026 00027 The C++ source code corresponding to this operation is 00028 \verbatim 00029 z = exp(x) 00030 \endverbatim 00031 00032 \copydetails forward_unary1_op 00033 */ 00034 template <class Base> 00035 inline void forward_exp_op( 00036 size_t j , 00037 size_t i_z , 00038 size_t i_x , 00039 size_t nc_taylor , 00040 Base* taylor ) 00041 { 00042 // check assumptions 00043 CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 ); 00044 CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 ); 00045 CPPAD_ASSERT_UNKNOWN( i_x < i_z ); 00046 CPPAD_ASSERT_UNKNOWN( j < nc_taylor ); 00047 00048 // Taylor coefficients corresponding to argument and result 00049 Base* x = taylor + i_x * nc_taylor; 00050 Base* z = taylor + i_z * nc_taylor; 00051 00052 size_t k; 00053 if( j == 0 ) 00054 z[0] = exp( x[0] ); 00055 else 00056 { 00057 z[j] = x[1] * z[j-1]; 00058 for(k = 2; k <= j; k++) 00059 z[j] += Base(k) * x[k] * z[j-k]; 00060 z[j] /= Base(j); 00061 } 00062 } 00063 00064 /*! 00065 Zero order forward mode Taylor coefficient for result of op = ExpOp. 00066 00067 The C++ source code corresponding to this operation is 00068 \verbatim 00069 z = exp(x) 00070 \endverbatim 00071 00072 \copydetails forward_unary1_op_0 00073 */ 00074 template <class Base> 00075 inline void forward_exp_op_0( 00076 size_t i_z , 00077 size_t i_x , 00078 size_t nc_taylor , 00079 Base* taylor ) 00080 { 00081 // check assumptions 00082 CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 ); 00083 CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 ); 00084 CPPAD_ASSERT_UNKNOWN( i_x < i_z ); 00085 CPPAD_ASSERT_UNKNOWN( 0 < nc_taylor ); 00086 00087 // Taylor coefficients corresponding to argument and result 00088 Base* x = taylor + i_x * nc_taylor; 00089 Base* z = taylor + i_z * nc_taylor; 00090 00091 z[0] = exp( x[0] ); 00092 } 00093 /*! 00094 Reverse mode partial derivatives for result of op = ExpOp. 00095 00096 The C++ source code corresponding to this operation is 00097 \verbatim 00098 z = exp(x) 00099 \endverbatim 00100 00101 \copydetails reverse_unary1_op 00102 */ 00103 00104 template <class Base> 00105 inline void reverse_exp_op( 00106 size_t d , 00107 size_t i_z , 00108 size_t i_x , 00109 size_t nc_taylor , 00110 const Base* taylor , 00111 size_t nc_partial , 00112 Base* partial ) 00113 { 00114 // check assumptions 00115 CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 ); 00116 CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 ); 00117 CPPAD_ASSERT_UNKNOWN( i_x < i_z ); 00118 CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); 00119 CPPAD_ASSERT_UNKNOWN( d < nc_partial ); 00120 00121 // Taylor coefficients and partials corresponding to argument 00122 const Base* x = taylor + i_x * nc_taylor; 00123 Base* px = partial + i_x * nc_partial; 00124 00125 // Taylor coefficients and partials corresponding to result 00126 const Base* z = taylor + i_z * nc_taylor; 00127 Base* pz = partial + i_z * nc_partial; 00128 00129 // lopp through orders in reverse 00130 size_t j, k; 00131 j = d; 00132 while(j) 00133 { // scale partial w.r.t z[j] 00134 pz[j] /= Base(j); 00135 00136 for(k = 1; k <= j; k++) 00137 { px[k] += pz[j] * Base(k) * z[j-k]; 00138 pz[j-k] += pz[j] * Base(k) * x[k]; 00139 } 00140 --j; 00141 } 00142 px[0] += pz[0] * z[0]; 00143 } 00144 00145 CPPAD_END_NAMESPACE 00146 # endif