CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_EXP_OP_INCLUDED 00003 # define CPPAD_EXP_OP_INCLUDED 00004 00005 /* -------------------------------------------------------------------------- 00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 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 namespace CppAD { // BEGIN_CPPAD_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 p , 00037 size_t q , 00038 size_t i_z , 00039 size_t i_x , 00040 size_t nc_taylor , 00041 Base* taylor ) 00042 { 00043 // check assumptions 00044 CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 ); 00045 CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 ); 00046 CPPAD_ASSERT_UNKNOWN( i_x < i_z ); 00047 CPPAD_ASSERT_UNKNOWN( q < nc_taylor ); 00048 CPPAD_ASSERT_UNKNOWN( p <= q ); 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( p == 0 ) 00056 { z[0] = exp( x[0] ); 00057 p++; 00058 } 00059 for(size_t j = p; j <= q; j++) 00060 { 00061 z[j] = x[1] * z[j-1]; 00062 for(k = 2; k <= j; k++) 00063 z[j] += Base(k) * x[k] * z[j-k]; 00064 z[j] /= Base(j); 00065 } 00066 } 00067 00068 /*! 00069 Zero order forward mode Taylor coefficient for result of op = ExpOp. 00070 00071 The C++ source code corresponding to this operation is 00072 \verbatim 00073 z = exp(x) 00074 \endverbatim 00075 00076 \copydetails forward_unary1_op_0 00077 */ 00078 template <class Base> 00079 inline void forward_exp_op_0( 00080 size_t i_z , 00081 size_t i_x , 00082 size_t nc_taylor , 00083 Base* taylor ) 00084 { 00085 // check assumptions 00086 CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 ); 00087 CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 ); 00088 CPPAD_ASSERT_UNKNOWN( i_x < i_z ); 00089 CPPAD_ASSERT_UNKNOWN( 0 < nc_taylor ); 00090 00091 // Taylor coefficients corresponding to argument and result 00092 Base* x = taylor + i_x * nc_taylor; 00093 Base* z = taylor + i_z * nc_taylor; 00094 00095 z[0] = exp( x[0] ); 00096 } 00097 /*! 00098 Reverse mode partial derivatives for result of op = ExpOp. 00099 00100 The C++ source code corresponding to this operation is 00101 \verbatim 00102 z = exp(x) 00103 \endverbatim 00104 00105 \copydetails reverse_unary1_op 00106 */ 00107 00108 template <class Base> 00109 inline void reverse_exp_op( 00110 size_t d , 00111 size_t i_z , 00112 size_t i_x , 00113 size_t nc_taylor , 00114 const Base* taylor , 00115 size_t nc_partial , 00116 Base* partial ) 00117 { 00118 // check assumptions 00119 CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 ); 00120 CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 ); 00121 CPPAD_ASSERT_UNKNOWN( i_x < i_z ); 00122 CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); 00123 CPPAD_ASSERT_UNKNOWN( d < nc_partial ); 00124 00125 // Taylor coefficients and partials corresponding to argument 00126 const Base* x = taylor + i_x * nc_taylor; 00127 Base* px = partial + i_x * nc_partial; 00128 00129 // Taylor coefficients and partials corresponding to result 00130 const Base* z = taylor + i_z * nc_taylor; 00131 Base* pz = partial + i_z * nc_partial; 00132 00133 // loop through orders in reverse 00134 size_t j, k; 00135 j = d; 00136 while(j) 00137 { // scale partial w.r.t z[j] 00138 pz[j] /= Base(j); 00139 00140 for(k = 1; k <= j; k++) 00141 { px[k] += pz[j] * Base(k) * z[j-k]; 00142 pz[j-k] += pz[j] * Base(k) * x[k]; 00143 } 00144 --j; 00145 } 00146 px[0] += pz[0] * z[0]; 00147 } 00148 00149 } // END_CPPAD_NAMESPACE 00150 # endif