CppAD: A C++ Algorithmic Differentiation Package 20110419
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_ADD_OP_INCLUDED 00003 # define CPPAD_ADD_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 CPPAD_BEGIN_NAMESPACE 00017 /*! 00018 \file add_op.hpp 00019 Forward and reverse mode calculations for z = x + y. 00020 */ 00021 00022 // --------------------------- Addvv ----------------------------------------- 00023 /*! 00024 Compute forward mode Taylor coefficients for result of op = AddvvOp. 00025 00026 The C++ source code corresponding to this operation is 00027 \verbatim 00028 z = x + y 00029 \endverbatim 00030 In the documentation below, 00031 this operations is for the case where both x and y are variables 00032 and the argument \a parameter is not used. 00033 00034 \copydetails forward_binary_op 00035 */ 00036 00037 template <class Base> 00038 inline void forward_addvv_op( 00039 size_t d , 00040 size_t i_z , 00041 const size_t* arg , 00042 const Base* parameter , 00043 size_t nc_taylor , 00044 Base* taylor ) 00045 { 00046 // check assumptions 00047 CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 ); 00048 CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 ); 00049 CPPAD_ASSERT_UNKNOWN( arg[0] < i_z ); 00050 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00051 CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); 00052 00053 // Taylor coefficients corresponding to arguments and result 00054 Base* x = taylor + arg[0] * nc_taylor; 00055 Base* y = taylor + arg[1] * nc_taylor; 00056 Base* z = taylor + i_z * nc_taylor; 00057 00058 z[d] = x[d] + y[d]; 00059 } 00060 00061 /*! 00062 Compute zero order forward mode Taylor coefficients for result of op = AddvvOp. 00063 00064 The C++ source code corresponding to this operation is 00065 \verbatim 00066 z = x + y 00067 \endverbatim 00068 In the documentation below, 00069 this operations is for the case where both x and y are variables 00070 and the argument \a parameter is not used. 00071 00072 \copydetails forward_binary_op_0 00073 */ 00074 00075 template <class Base> 00076 inline void forward_addvv_op_0( 00077 size_t i_z , 00078 const size_t* arg , 00079 const Base* parameter , 00080 size_t nc_taylor , 00081 Base* taylor ) 00082 { 00083 // check assumptions 00084 CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 ); 00085 CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 ); 00086 CPPAD_ASSERT_UNKNOWN( arg[0] < i_z ); 00087 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00088 00089 // Taylor coefficients corresponding to arguments and result 00090 Base* x = taylor + arg[0] * nc_taylor; 00091 Base* y = taylor + arg[1] * nc_taylor; 00092 Base* z = taylor + i_z * nc_taylor; 00093 00094 z[0] = x[0] + y[0]; 00095 } 00096 00097 /*! 00098 Compute reverse mode partial derivatives for result of op = AddvvOp. 00099 00100 The C++ source code corresponding to this operation is 00101 \verbatim 00102 z = x + y 00103 \endverbatim 00104 In the documentation below, 00105 this operations is for the case where both x and y are variables 00106 and the argument \a parameter is not used. 00107 00108 \copydetails reverse_binary_op 00109 */ 00110 00111 template <class Base> 00112 inline void reverse_addvv_op( 00113 size_t d , 00114 size_t i_z , 00115 const size_t* arg , 00116 const Base* parameter , 00117 size_t nc_taylor , 00118 const Base* taylor , 00119 size_t nc_partial , 00120 Base* partial ) 00121 { 00122 // check assumptions 00123 CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 ); 00124 CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 ); 00125 CPPAD_ASSERT_UNKNOWN( arg[0] < i_z ); 00126 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00127 CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); 00128 CPPAD_ASSERT_UNKNOWN( d < nc_partial ); 00129 00130 // Partial derivatives corresponding to arguments and result 00131 Base* px = partial + arg[0] * nc_partial; 00132 Base* py = partial + arg[1] * nc_partial; 00133 Base* pz = partial + i_z * nc_partial; 00134 00135 // number of indices to access 00136 size_t i = d + 1; 00137 while(i) 00138 { --i; 00139 px[i] += pz[i]; 00140 py[i] += pz[i]; 00141 } 00142 } 00143 00144 // --------------------------- Addpv ----------------------------------------- 00145 /*! 00146 Compute forward mode Taylor coefficients for result of op = AddpvOp. 00147 00148 The C++ source code corresponding to this operation is 00149 \verbatim 00150 z = x + y 00151 \endverbatim 00152 In the documentation below, 00153 this operations is for the case where x is a parameter and y is a variable. 00154 00155 \copydetails forward_binary_op 00156 */ 00157 00158 template <class Base> 00159 inline void forward_addpv_op( 00160 size_t d , 00161 size_t i_z , 00162 const size_t* arg , 00163 const Base* parameter , 00164 size_t nc_taylor , 00165 Base* taylor ) 00166 { 00167 // check assumptions 00168 CPPAD_ASSERT_UNKNOWN( NumArg(AddpvOp) == 2 ); 00169 CPPAD_ASSERT_UNKNOWN( NumRes(AddpvOp) == 1 ); 00170 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00171 CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); 00172 00173 // Taylor coefficients corresponding to arguments and result 00174 Base* y = taylor + arg[1] * nc_taylor; 00175 Base* z = taylor + i_z * nc_taylor; 00176 00177 # if CPPAD_USE_FORWARD0SWEEP 00178 CPPAD_ASSERT_UNKNOWN( d > 0 ); 00179 z[d] = y[d]; 00180 # else 00181 // Paraemter value 00182 Base x = parameter[ arg[0] ]; 00183 if( d == 0 ) 00184 z[d] = x + y[d]; 00185 else z[d] = y[d]; 00186 # endif 00187 } 00188 /*! 00189 Compute zero order forward mode Taylor coefficient for result of op = AddpvOp. 00190 00191 The C++ source code corresponding to this operation is 00192 \verbatim 00193 z = x + y 00194 \endverbatim 00195 In the documentation below, 00196 this operations is for the case where x is a parameter and y is a variable. 00197 00198 \copydetails forward_binary_op_0 00199 */ 00200 00201 template <class Base> 00202 inline void forward_addpv_op_0( 00203 size_t i_z , 00204 const size_t* arg , 00205 const Base* parameter , 00206 size_t nc_taylor , 00207 Base* taylor ) 00208 { 00209 // check assumptions 00210 CPPAD_ASSERT_UNKNOWN( NumArg(AddpvOp) == 2 ); 00211 CPPAD_ASSERT_UNKNOWN( NumRes(AddpvOp) == 1 ); 00212 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00213 00214 // Paraemter value 00215 Base x = parameter[ arg[0] ]; 00216 00217 // Taylor coefficients corresponding to arguments and result 00218 Base* y = taylor + arg[1] * nc_taylor; 00219 Base* z = taylor + i_z * nc_taylor; 00220 00221 z[0] = x + y[0]; 00222 } 00223 00224 /*! 00225 Compute reverse mode partial derivative for result of op = AddpvOp. 00226 00227 The C++ source code corresponding to this operation is 00228 \verbatim 00229 z = x + y 00230 \endverbatim 00231 In the documentation below, 00232 this operations is for the case where x is a parameter and y is a variable. 00233 00234 \copydetails reverse_binary_op 00235 */ 00236 00237 template <class Base> 00238 inline void reverse_addpv_op( 00239 size_t d , 00240 size_t i_z , 00241 const size_t* arg , 00242 const Base* parameter , 00243 size_t nc_taylor , 00244 const Base* taylor , 00245 size_t nc_partial , 00246 Base* partial ) 00247 { 00248 // check assumptions 00249 CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 ); 00250 CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 ); 00251 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00252 CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); 00253 CPPAD_ASSERT_UNKNOWN( d < nc_partial ); 00254 00255 // Partial derivatives corresponding to arguments and result 00256 Base* py = partial + arg[1] * nc_partial; 00257 Base* pz = partial + i_z * nc_partial; 00258 00259 // number of indices to access 00260 size_t i = d + 1; 00261 while(i) 00262 { --i; 00263 py[i] += pz[i]; 00264 } 00265 } 00266 00267 00268 CPPAD_END_NAMESPACE 00269 # endif