CppAD: A C++ Algorithmic Differentiation Package
20130102
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_SPARSE_BINARY_OP_INCLUDED 00003 # define CPPAD_SPARSE_BINARY_OP_INCLUDED 00004 /* -------------------------------------------------------------------------- 00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell 00006 00007 CppAD is distributed under multiple licenses. This distribution is under 00008 the terms of the 00009 Eclipse Public License Version 1.0. 00010 00011 A copy of this license is included in the COPYING file of this distribution. 00012 Please visit http://www.coin-or.org/CppAD/ for information on other licenses. 00013 -------------------------------------------------------------------------- */ 00014 00015 CPPAD_BEGIN_NAMESPACE 00016 /*! 00017 \defgroup sparse_binary_op_hpp sparse_binary_op.hpp 00018 \{ 00019 \file sparse_binary_op.hpp 00020 Forward and reverse mode sparsity patterns for binary operators. 00021 */ 00022 00023 00024 /*! 00025 Forward mode Jacobian sparsity pattern for all binary operators. 00026 00027 The C++ source code corresponding to a binary operation has the form 00028 \verbatim 00029 z = fun(x, y) 00030 \endverbatim 00031 where fun is a C++ binary function and both x and y are variables, 00032 or it has the form 00033 \verbatim 00034 z = x op y 00035 \endverbatim 00036 where op is a C++ binary unary operator and both x and y are variables. 00037 00038 \tparam Vector_set 00039 is the type used for vectors of sets. It can be either 00040 \c sparse_pack, \c sparse_set, or \c sparse_list. 00041 00042 \param i_z 00043 variable index corresponding to the result for this operation; 00044 i.e., z. 00045 00046 \param arg 00047 \a arg[0] 00048 variable index corresponding to the left operand for this operator; 00049 i.e., x. 00050 \n 00051 \n arg[1] 00052 variable index corresponding to the right operand for this operator; 00053 i.e., y. 00054 00055 \param sparsity 00056 \b Input: 00057 The set with index \a arg[0] in \a sparsity 00058 is the sparsity bit pattern for x. 00059 This identifies which of the independent variables the variable x 00060 depends on. 00061 \n 00062 \n 00063 \b Input: 00064 The set with index \a arg[1] in \a sparsity 00065 is the sparsity bit pattern for y. 00066 This identifies which of the independent variables the variable y 00067 depends on. 00068 \n 00069 \n 00070 \b Output: 00071 The set with index \a i_z in \a sparsity 00072 is the sparsity bit pattern for z. 00073 This identifies which of the independent variables the variable z 00074 depends on. 00075 00076 \par Checked Assertions: 00077 \li \a arg[0] < \a i_z 00078 \li \a arg[1] < \a i_z 00079 */ 00080 00081 template <class Vector_set> 00082 inline void forward_sparse_jacobian_binary_op( 00083 size_t i_z , 00084 const addr_t* arg , 00085 Vector_set& sparsity ) 00086 { 00087 // check assumptions 00088 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); 00089 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); 00090 00091 sparsity.binary_union(i_z, arg[0], arg[1], sparsity); 00092 00093 return; 00094 } 00095 00096 /*! 00097 Reverse mode Jacobian sparsity pattern for all binary operators. 00098 00099 The C++ source code corresponding to a unary operation has the form 00100 \verbatim 00101 z = fun(x, y) 00102 \endverbatim 00103 where fun is a C++ unary function and x and y are variables, 00104 or it has the form 00105 \verbatim 00106 z = x op y 00107 \endverbatim 00108 where op is a C++ bianry operator and x and y are variables. 00109 00110 This routine is given the sparsity patterns 00111 for a function G(z, y, x, ... ) 00112 and it uses them to compute the sparsity patterns for 00113 \verbatim 00114 H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ] 00115 \endverbatim 00116 00117 \tparam Vector_set 00118 is the type used for vectors of sets. It can be either 00119 \c sparse_pack, \c sparse_set, or \c sparse_list. 00120 00121 \param i_z 00122 variable index corresponding to the result for this operation; 00123 i.e., z. 00124 00125 \param arg 00126 \a arg[0] 00127 variable index corresponding to the left operand for this operator; 00128 i.e., x. 00129 00130 \n 00131 \n arg[1] 00132 variable index corresponding to the right operand for this operator; 00133 i.e., y. 00134 00135 \param sparsity 00136 The set with index \a i_z in \a sparsity 00137 is the sparsity pattern for z corresponding ot the function G. 00138 \n 00139 \n 00140 The set with index \a arg[0] in \a sparsity 00141 is the sparsity pattern for x. 00142 On input, it corresponds to the function G, 00143 and on output it corresponds to H. 00144 \n 00145 \n 00146 The set with index \a arg[1] in \a sparsity 00147 is the sparsity pattern for y. 00148 On input, it corresponds to the function G, 00149 and on output it corresponds to H. 00150 \n 00151 \n 00152 00153 \par Checked Assertions: 00154 \li \a arg[0] < \a i_z 00155 \li \a arg[1] < \a i_z 00156 */ 00157 template <class Vector_set> 00158 inline void reverse_sparse_jacobian_binary_op( 00159 size_t i_z , 00160 const addr_t* arg , 00161 Vector_set& sparsity ) 00162 { 00163 // check assumptions 00164 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); 00165 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); 00166 00167 sparsity.binary_union(arg[0], arg[0], i_z, sparsity); 00168 sparsity.binary_union(arg[1], arg[1], i_z, sparsity); 00169 00170 return; 00171 } 00172 00173 /*! 00174 Reverse mode Hessian sparsity pattern for add and subtract operators. 00175 00176 The C++ source code corresponding to a unary operation has the form 00177 \verbatim 00178 z = x op y 00179 \endverbatim 00180 where op is + or - and x, y are variables. 00181 00182 \copydetails reverse_sparse_hessian_binary_op 00183 */ 00184 template <class Vector_set> 00185 inline void reverse_sparse_hessian_addsub_op( 00186 size_t i_z , 00187 const addr_t* arg , 00188 bool* jac_reverse , 00189 Vector_set& for_jac_sparsity , 00190 Vector_set& rev_hes_sparsity ) 00191 { 00192 // check assumptions 00193 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); 00194 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); 00195 00196 rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity); 00197 rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity); 00198 00199 jac_reverse[arg[0]] |= jac_reverse[i_z]; 00200 jac_reverse[arg[1]] |= jac_reverse[i_z]; 00201 00202 return; 00203 } 00204 00205 /*! 00206 Reverse mode Hessian sparsity pattern for multiplication operator. 00207 00208 The C++ source code corresponding to a unary operation has the form 00209 \verbatim 00210 z = x * y 00211 \endverbatim 00212 where x and y are variables. 00213 00214 \copydetails reverse_sparse_hessian_binary_op 00215 */ 00216 template <class Vector_set> 00217 inline void reverse_sparse_hessian_mul_op( 00218 size_t i_z , 00219 const addr_t* arg , 00220 bool* jac_reverse , 00221 Vector_set& for_jac_sparsity , 00222 Vector_set& rev_hes_sparsity ) 00223 { 00224 // check assumptions 00225 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); 00226 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); 00227 00228 rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity); 00229 rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity); 00230 00231 if( jac_reverse[i_z] ) 00232 { rev_hes_sparsity.binary_union( 00233 arg[0], arg[0], arg[1], for_jac_sparsity); 00234 rev_hes_sparsity.binary_union( 00235 arg[1], arg[1], arg[0], for_jac_sparsity); 00236 } 00237 00238 jac_reverse[arg[0]] |= jac_reverse[i_z]; 00239 jac_reverse[arg[1]] |= jac_reverse[i_z]; 00240 return; 00241 } 00242 00243 /*! 00244 Reverse mode Hessian sparsity pattern for division operator. 00245 00246 The C++ source code corresponding to a unary operation has the form 00247 \verbatim 00248 z = x / y 00249 \endverbatim 00250 where x and y are variables. 00251 00252 \copydetails reverse_sparse_hessian_binary_op 00253 */ 00254 template <class Vector_set> 00255 inline void reverse_sparse_hessian_div_op( 00256 size_t i_z , 00257 const addr_t* arg , 00258 bool* jac_reverse , 00259 Vector_set& for_jac_sparsity , 00260 Vector_set& rev_hes_sparsity ) 00261 { 00262 // check assumptions 00263 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); 00264 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); 00265 00266 rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity); 00267 rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity); 00268 00269 if( jac_reverse[i_z] ) 00270 { rev_hes_sparsity.binary_union( 00271 arg[0], arg[0], arg[1], for_jac_sparsity); 00272 rev_hes_sparsity.binary_union( 00273 arg[1], arg[1], arg[0], for_jac_sparsity); 00274 rev_hes_sparsity.binary_union( 00275 arg[1], arg[1], arg[1], for_jac_sparsity); 00276 } 00277 00278 jac_reverse[arg[0]] |= jac_reverse[i_z]; 00279 jac_reverse[arg[1]] |= jac_reverse[i_z]; 00280 return; 00281 } 00282 00283 /*! 00284 Reverse mode Hessian sparsity pattern for power function. 00285 00286 The C++ source code corresponding to a unary operation has the form 00287 \verbatim 00288 z = pow(x, y) 00289 \endverbatim 00290 where x and y are variables. 00291 00292 \copydetails reverse_sparse_hessian_binary_op 00293 */ 00294 template <class Vector_set> 00295 inline void reverse_sparse_hessian_pow_op( 00296 size_t i_z , 00297 const addr_t* arg , 00298 bool* jac_reverse , 00299 Vector_set& for_jac_sparsity , 00300 Vector_set& rev_hes_sparsity ) 00301 { 00302 // check assumptions 00303 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); 00304 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); 00305 00306 rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity); 00307 rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity); 00308 00309 if( jac_reverse[i_z] ) 00310 { 00311 rev_hes_sparsity.binary_union( 00312 arg[0], arg[0], arg[0], for_jac_sparsity); 00313 rev_hes_sparsity.binary_union( 00314 arg[0], arg[0], arg[1], for_jac_sparsity); 00315 00316 rev_hes_sparsity.binary_union( 00317 arg[1], arg[1], arg[0], for_jac_sparsity); 00318 rev_hes_sparsity.binary_union( 00319 arg[1], arg[1], arg[1], for_jac_sparsity); 00320 } 00321 00322 // I cannot think of a case where this is necessary, but it including 00323 // it makes it like the other cases. 00324 jac_reverse[arg[0]] |= jac_reverse[i_z]; 00325 jac_reverse[arg[1]] |= jac_reverse[i_z]; 00326 return; 00327 } 00328 00329 /*! \} */ 00330 CPPAD_END_NAMESPACE 00331 # endif