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