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