CppAD: A C++ Algorithmic Differentiation Package
20130102
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_STORE_OP_INCLUDED 00003 # define CPPAD_STORE_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 store_op_hpp store_op.hpp 00019 \{ 00020 \file store_op.hpp 00021 Changing the current value of a VecAD element. 00022 */ 00023 00024 /*! 00025 Zero order forward mode implementation of op = StppOp. 00026 00027 \copydetails forward_store_op_0 00028 */ 00029 template <class Base> 00030 inline void forward_store_pp_op_0( 00031 size_t i_z , 00032 const addr_t* arg , 00033 size_t num_par , 00034 size_t nc_taylor , 00035 Base* taylor , 00036 size_t nc_combined , 00037 bool* variable , 00038 size_t* combined ) 00039 { size_t i_vec = arg[1]; 00040 00041 // Because the index is a parameter, this indexing error should be 00042 // caught and reported to the user when the tape is recording. 00043 CPPAD_ASSERT_UNKNOWN( i_vec < combined[ arg[0] - 1 ] ); 00044 00045 CPPAD_ASSERT_UNKNOWN( variable != CPPAD_NULL ); 00046 CPPAD_ASSERT_UNKNOWN( combined != CPPAD_NULL ); 00047 CPPAD_ASSERT_UNKNOWN( NumArg(StppOp) == 3 ); 00048 CPPAD_ASSERT_UNKNOWN( NumRes(StppOp) == 0 ); 00049 CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); 00050 CPPAD_ASSERT_UNKNOWN( arg[0] + i_vec < nc_combined ); 00051 CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); 00052 00053 variable[ arg[0] + i_vec ] = false; 00054 combined[ arg[0] + i_vec ] = arg[2]; 00055 } 00056 00057 /*! 00058 Zero order forward mode implementation of op = StpvOp. 00059 00060 \copydetails forward_store_op_0 00061 */ 00062 template <class Base> 00063 inline void forward_store_pv_op_0( 00064 size_t i_z , 00065 const addr_t* arg , 00066 size_t num_par , 00067 size_t nc_taylor , 00068 Base* taylor , 00069 size_t nc_combined , 00070 bool* variable , 00071 size_t* combined ) 00072 { size_t i_vec = arg[1]; 00073 00074 // Because the index is a parameter, this indexing error should be 00075 // caught and reported to the user when the tape is recording. 00076 CPPAD_ASSERT_UNKNOWN( i_vec < combined[ arg[0] - 1 ] ); 00077 00078 CPPAD_ASSERT_UNKNOWN( variable != CPPAD_NULL ); 00079 CPPAD_ASSERT_UNKNOWN( combined != CPPAD_NULL ); 00080 CPPAD_ASSERT_UNKNOWN( NumArg(StpvOp) == 3 ); 00081 CPPAD_ASSERT_UNKNOWN( NumRes(StpvOp) == 0 ); 00082 CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); 00083 CPPAD_ASSERT_UNKNOWN( arg[0] + i_vec < nc_combined ); 00084 CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) <= i_z ); 00085 00086 variable[ arg[0] + i_vec ] = true; 00087 combined[ arg[0] + i_vec ] = arg[2]; 00088 } 00089 00090 /*! 00091 Zero order forward mode implementation of op = StvpOp. 00092 00093 \copydetails forward_store_op_0 00094 */ 00095 template <class Base> 00096 inline void forward_store_vp_op_0( 00097 size_t i_z , 00098 const addr_t* arg , 00099 size_t num_par , 00100 size_t nc_taylor , 00101 Base* taylor , 00102 size_t nc_combined , 00103 bool* variable , 00104 size_t* combined ) 00105 { 00106 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) <= i_z ); 00107 size_t i_vec = Integer( taylor[ arg[1] * nc_taylor + 0 ] ); 00108 CPPAD_ASSERT_KNOWN( 00109 i_vec < combined[ arg[0] - 1 ] , 00110 "VecAD: index during zero order forward sweep is out of range" 00111 ); 00112 00113 CPPAD_ASSERT_UNKNOWN( variable != CPPAD_NULL ); 00114 CPPAD_ASSERT_UNKNOWN( combined != CPPAD_NULL ); 00115 CPPAD_ASSERT_UNKNOWN( NumArg(StvpOp) == 3 ); 00116 CPPAD_ASSERT_UNKNOWN( NumRes(StvpOp) == 0 ); 00117 CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); 00118 CPPAD_ASSERT_UNKNOWN( arg[0] + i_vec < nc_combined ); 00119 CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); 00120 00121 variable[ arg[0] + i_vec ] = false; 00122 combined[ arg[0] + i_vec ] = arg[2]; 00123 } 00124 00125 /*! 00126 Zero order forward mode implementation of op = StvvOp. 00127 00128 \copydetails forward_store_op_0 00129 */ 00130 template <class Base> 00131 inline void forward_store_vv_op_0( 00132 size_t i_z , 00133 const addr_t* arg , 00134 size_t num_par , 00135 size_t nc_taylor , 00136 Base* taylor , 00137 size_t nc_combined , 00138 bool* variable , 00139 size_t* combined ) 00140 { 00141 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) <= i_z ); 00142 size_t i_vec = Integer( taylor[ arg[1] * nc_taylor + 0 ] ); 00143 CPPAD_ASSERT_KNOWN( 00144 i_vec < combined[ arg[0] - 1 ] , 00145 "VecAD: index during zero order forward sweep is out of range" 00146 ); 00147 00148 CPPAD_ASSERT_UNKNOWN( variable != CPPAD_NULL ); 00149 CPPAD_ASSERT_UNKNOWN( combined != CPPAD_NULL ); 00150 CPPAD_ASSERT_UNKNOWN( NumArg(StvpOp) == 3 ); 00151 CPPAD_ASSERT_UNKNOWN( NumRes(StvpOp) == 0 ); 00152 CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); 00153 CPPAD_ASSERT_UNKNOWN( arg[0] + i_vec < nc_combined ); 00154 CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) <= i_z ); 00155 00156 variable[ arg[0] + i_vec ] = true; 00157 combined[ arg[0] + i_vec ] = arg[2]; 00158 } 00159 00160 /*! 00161 Forward mode sparsity operations for StpvOp and StvvOp 00162 00163 \copydetails sparse_store_op 00164 */ 00165 template <class Vector_set> 00166 inline void forward_sparse_store_op( 00167 OpCode op , 00168 const addr_t* arg , 00169 size_t num_combined , 00170 const size_t* combined , 00171 Vector_set& var_sparsity , 00172 Vector_set& vecad_sparsity ) 00173 { 00174 CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); 00175 CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); 00176 CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); 00177 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined ); 00178 size_t i_v = combined[ arg[0] - 1 ]; 00179 CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() ); 00180 CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < var_sparsity.n_set() ); 00181 00182 vecad_sparsity.binary_union(i_v, i_v, arg[2], var_sparsity); 00183 00184 return; 00185 } 00186 00187 /*! 00188 Reverse mode sparsity operations for StpvOp and StvvOp 00189 00190 This routine is given the sparsity patterns for 00191 G(v[x], y , w , u ... ) and it uses them to compute the 00192 sparsity patterns for 00193 \verbatim 00194 H(y , w , u , ... ) = G[ v[x], y , w , u , ... ] 00195 \endverbatim 00196 00197 \copydetails sparse_store_op 00198 */ 00199 template <class Vector_set> 00200 inline void reverse_sparse_jacobian_store_op( 00201 OpCode op , 00202 const addr_t* arg , 00203 size_t num_combined , 00204 const size_t* combined , 00205 Vector_set& var_sparsity , 00206 Vector_set& vecad_sparsity ) 00207 { 00208 CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); 00209 CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); 00210 CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); 00211 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined ); 00212 size_t i_v = combined[ arg[0] - 1 ]; 00213 CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() ); 00214 CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < var_sparsity.n_set() ); 00215 00216 var_sparsity.binary_union(arg[2], arg[2], i_v, vecad_sparsity); 00217 00218 return; 00219 } 00220 00221 /*! 00222 Reverse mode sparsity operations for StpvOp and StvvOp 00223 00224 This routine is given the sparsity patterns for 00225 G(v[x], y , w , u ... ) 00226 and it uses them to compute the sparsity patterns for 00227 \verbatim 00228 H(y , w , u , ... ) = G[ v[x], y , w , u , ... ] 00229 \endverbatim 00230 00231 \copydetails sparse_store_op 00232 00233 \param var_jacobian 00234 \a var_jacobian[ \a arg[2] ] 00235 is false (true) if the Jacobian of G with respect to y is always zero 00236 (may be non-zero). 00237 00238 \param vecad_jacobian 00239 \a vecad_jacobian[i_v] 00240 is false (true) if the Jacobian with respect to x is always zero 00241 (may be non-zero). 00242 On input, it corresponds to the function G, 00243 and on output it corresponds to the function H. 00244 */ 00245 template <class Vector_set> 00246 inline void reverse_sparse_hessian_store_op( 00247 OpCode op , 00248 const addr_t* arg , 00249 size_t num_combined , 00250 const size_t* combined , 00251 Vector_set& var_sparsity , 00252 Vector_set& vecad_sparsity , 00253 bool* var_jacobian , 00254 bool* vecad_jacobian ) 00255 { 00256 CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); 00257 CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); 00258 CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); 00259 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined ); 00260 size_t i_v = combined[ arg[0] - 1 ]; 00261 CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() ); 00262 CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < var_sparsity.n_set() ); 00263 00264 var_sparsity.binary_union(arg[2], arg[2], i_v, vecad_sparsity); 00265 00266 var_jacobian[ arg[2] ] |= vecad_jacobian[i_v]; 00267 00268 return; 00269 } 00270 00271 /*! \} */ 00272 CPPAD_END_NAMESPACE 00273 # endif