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