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