CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_COND_OP_INCLUDED 00003 # define CPPAD_COND_OP_INCLUDED 00004 /* -------------------------------------------------------------------------- 00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 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 namespace CppAD { // BEGIN_CPPAD_NAMESPACE 00016 /*! 00017 \file cond_op.hpp 00018 Forward, reverse, and sparse operations for conditional expressions. 00019 */ 00020 00021 /*! 00022 Shared documentation for conditional expressions (not called). 00023 00024 <!-- define conditional_exp_op --> 00025 The C++ source code coresponding to this operation is 00026 \verbatim 00027 z = CondExpRel(y_0, y_1, y_2, y_3) 00028 \endverbatim 00029 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 00030 00031 \tparam Base 00032 base type for the operator; i.e., this operation was recorded 00033 using AD< \a Base > and computations by this routine are done using type 00034 \a Base. 00035 00036 \param i_z 00037 is the AD variable index corresponding to the variable z. 00038 00039 \param arg 00040 \n 00041 \a arg[0] 00042 is static cast to size_t from the enum type 00043 \verbatim 00044 enum CompareOp { 00045 CompareLt, 00046 CompareLe, 00047 CompareEq, 00048 CompareGe, 00049 CompareGt, 00050 CompareNe 00051 } 00052 \endverbatim 00053 for this operation. 00054 Note that arg[0] cannot be equal to CompareNe. 00055 \n 00056 \n 00057 \a arg[1] & 1 00058 \n 00059 If this is zero, y_0 is a parameter. Otherwise it is a variable. 00060 \n 00061 \n 00062 \a arg[1] & 2 00063 \n 00064 If this is zero, y_1 is a parameter. Otherwise it is a variable. 00065 \n 00066 \n 00067 \a arg[1] & 4 00068 \n 00069 If this is zero, y_2 is a parameter. Otherwise it is a variable. 00070 \n 00071 \n 00072 \a arg[1] & 8 00073 \n 00074 If this is zero, y_3 is a parameter. Otherwise it is a variable. 00075 \n 00076 \n 00077 \a arg[2 + j ] for j = 0, 1, 2, 3 00078 \n 00079 is the index corresponding to y_j. 00080 00081 \param num_par 00082 is the total number of values in the vector \a parameter. 00083 00084 \param parameter 00085 For j = 0, 1, 2, 3, 00086 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value. 00087 00088 \param nc_taylor 00089 number of columns in the matrix containing the Taylor coefficients. 00090 00091 \par Checked Assertions 00092 \li NumArg(CExpOp) == 6 00093 \li NumRes(CExpOp) == 1 00094 \li arg[0] < static_cast<size_t> ( CompareNe ) 00095 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. 00096 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. 00097 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz. 00098 <!-- end conditional_exp_op --> 00099 */ 00100 template <class Base> 00101 inline void conditional_exp_op( 00102 size_t i_z , 00103 const addr_t* arg , 00104 size_t num_par , 00105 const Base* parameter , 00106 size_t nc_taylor ) 00107 { // This routine is only for documentation, it should never be used 00108 CPPAD_ASSERT_UNKNOWN( false ); 00109 } 00110 00111 /*! 00112 Shared documentation for conditional expression sparse operations (not called). 00113 00114 <!-- define sparse_conditional_exp_op --> 00115 The C++ source code coresponding to this operation is 00116 \verbatim 00117 z = CondExpRel(y_0, y_1, y_2, y_3) 00118 \endverbatim 00119 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 00120 00121 \tparam Vector_set 00122 is the type used for vectors of sets. It can be either 00123 \c sparse_pack, \c sparse_set, or \c sparse_list. 00124 00125 \param i_z 00126 is the AD variable index corresponding to the variable z. 00127 00128 \param arg 00129 \n 00130 \a arg[0] 00131 is static cast to size_t from the enum type 00132 \verbatim 00133 enum CompareOp { 00134 CompareLt, 00135 CompareLe, 00136 CompareEq, 00137 CompareGe, 00138 CompareGt, 00139 CompareNe 00140 } 00141 \endverbatim 00142 for this operation. 00143 Note that arg[0] cannot be equal to CompareNe. 00144 \n 00145 \n 00146 \a arg[1] & 1 00147 \n 00148 If this is zero, y_0 is a parameter. Otherwise it is a variable. 00149 \n 00150 \n 00151 \a arg[1] & 2 00152 \n 00153 If this is zero, y_1 is a parameter. Otherwise it is a variable. 00154 \n 00155 \n 00156 \a arg[1] & 4 00157 \n 00158 If this is zero, y_2 is a parameter. Otherwise it is a variable. 00159 \n 00160 \n 00161 \a arg[1] & 8 00162 \n 00163 If this is zero, y_3 is a parameter. Otherwise it is a variable. 00164 \n 00165 \n 00166 \a arg[2 + j ] for j = 0, 1, 2, 3 00167 \n 00168 is the index corresponding to y_j. 00169 00170 \param num_par 00171 is the total number of values in the vector \a parameter. 00172 00173 \par Checked Assertions 00174 \li NumArg(CExpOp) == 6 00175 \li NumRes(CExpOp) == 1 00176 \li arg[0] < static_cast<size_t> ( CompareNe ) 00177 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. 00178 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. 00179 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz. 00180 <!-- end sparse_conditional_exp_op --> 00181 */ 00182 template <class Vector_set> 00183 inline void sparse_conditional_exp_op( 00184 size_t i_z , 00185 const addr_t* arg , 00186 size_t num_par ) 00187 { // This routine is only for documentation, it should never be used 00188 CPPAD_ASSERT_UNKNOWN( false ); 00189 } 00190 00191 /*! 00192 Compute forward mode Taylor coefficients for op = CExpOp. 00193 00194 <!-- replace conditional_exp_op --> 00195 The C++ source code coresponding to this operation is 00196 \verbatim 00197 z = CondExpRel(y_0, y_1, y_2, y_3) 00198 \endverbatim 00199 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 00200 00201 \tparam Base 00202 base type for the operator; i.e., this operation was recorded 00203 using AD< \a Base > and computations by this routine are done using type 00204 \a Base. 00205 00206 \param i_z 00207 is the AD variable index corresponding to the variable z. 00208 00209 \param arg 00210 \n 00211 \a arg[0] 00212 is static cast to size_t from the enum type 00213 \verbatim 00214 enum CompareOp { 00215 CompareLt, 00216 CompareLe, 00217 CompareEq, 00218 CompareGe, 00219 CompareGt, 00220 CompareNe 00221 } 00222 \endverbatim 00223 for this operation. 00224 Note that arg[0] cannot be equal to CompareNe. 00225 \n 00226 \n 00227 \a arg[1] & 1 00228 \n 00229 If this is zero, y_0 is a parameter. Otherwise it is a variable. 00230 \n 00231 \n 00232 \a arg[1] & 2 00233 \n 00234 If this is zero, y_1 is a parameter. Otherwise it is a variable. 00235 \n 00236 \n 00237 \a arg[1] & 4 00238 \n 00239 If this is zero, y_2 is a parameter. Otherwise it is a variable. 00240 \n 00241 \n 00242 \a arg[1] & 8 00243 \n 00244 If this is zero, y_3 is a parameter. Otherwise it is a variable. 00245 \n 00246 \n 00247 \a arg[2 + j ] for j = 0, 1, 2, 3 00248 \n 00249 is the index corresponding to y_j. 00250 00251 \param num_par 00252 is the total number of values in the vector \a parameter. 00253 00254 \param parameter 00255 For j = 0, 1, 2, 3, 00256 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value. 00257 00258 \param nc_taylor 00259 number of columns in the matrix containing the Taylor coefficients. 00260 00261 \par Checked Assertions 00262 \li NumArg(CExpOp) == 6 00263 \li NumRes(CExpOp) == 1 00264 \li arg[0] < static_cast<size_t> ( CompareNe ) 00265 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. 00266 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. 00267 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz. 00268 <!-- end conditional_exp_op --> 00269 00270 \param p 00271 is the lowest order of the Taylor coefficient of z that we are computing. 00272 00273 \param q 00274 is the highest order of the Taylor coefficient of z that we are computing. 00275 00276 \param taylor 00277 \b Input: 00278 For j = 0, 1, 2, 3 and k = 0 , ... , q, 00279 if y_j is a variable then 00280 <code>taylor [ arg[2+j] * nc_taylor + k ]</code> 00281 is the k-th order Taylor coefficient corresponding to y_j. 00282 \n 00283 \b Input: <code>taylor [ i_z * nc_taylor + k ]</code> 00284 for k = 0 , ... , p-1, 00285 is the k-th order Taylor coefficient corresponding to z. 00286 \n 00287 \b Output: <code>taylor [ i_z * nc_taylor + k ]</code> 00288 for k = p , ... , q, 00289 is the k-th order Taylor coefficient corresponding to z. 00290 00291 */ 00292 template <class Base> 00293 inline void forward_cond_op( 00294 size_t p , 00295 size_t q , 00296 size_t i_z , 00297 const addr_t* arg , 00298 size_t num_par , 00299 const Base* parameter , 00300 size_t nc_taylor , 00301 Base* taylor ) 00302 { Base y_0, y_1, y_2, y_3; 00303 Base zero(0); 00304 Base* z = taylor + i_z * nc_taylor; 00305 00306 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) ); 00307 CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); 00308 CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); 00309 CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); 00310 00311 if( arg[1] & 1 ) 00312 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z ); 00313 y_0 = taylor[ arg[2] * nc_taylor + 0 ]; 00314 } 00315 else 00316 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); 00317 y_0 = parameter[ arg[2] ]; 00318 } 00319 if( arg[1] & 2 ) 00320 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z ); 00321 y_1 = taylor[ arg[3] * nc_taylor + 0 ]; 00322 } 00323 else 00324 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); 00325 y_1 = parameter[ arg[3] ]; 00326 } 00327 if( p == 0 ) 00328 { if( arg[1] & 4 ) 00329 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z ); 00330 y_2 = taylor[ arg[4] * nc_taylor + 0 ]; 00331 } 00332 else 00333 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par ); 00334 y_2 = parameter[ arg[4] ]; 00335 } 00336 if( arg[1] & 8 ) 00337 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); 00338 y_3 = taylor[ arg[5] * nc_taylor + 0 ]; 00339 } 00340 else 00341 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par ); 00342 y_3 = parameter[ arg[5] ]; 00343 } 00344 z[0] = CondExpOp( 00345 CompareOp( arg[0] ), 00346 y_0, 00347 y_1, 00348 y_2, 00349 y_3 00350 ); 00351 p++; 00352 } 00353 for(size_t d = p; d <= q; d++) 00354 { if( arg[1] & 4 ) 00355 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z ); 00356 y_2 = taylor[ arg[4] * nc_taylor + d]; 00357 } 00358 else y_2 = zero; 00359 if( arg[1] & 8 ) 00360 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); 00361 y_3 = taylor[ arg[5] * nc_taylor + d]; 00362 } 00363 else y_3 = zero; 00364 z[d] = CondExpOp( 00365 CompareOp( arg[0] ), 00366 y_0, 00367 y_1, 00368 y_2, 00369 y_3 00370 ); 00371 } 00372 return; 00373 } 00374 00375 /*! 00376 Compute zero order forward mode Taylor coefficients for op = CExpOp. 00377 00378 <!-- replace conditional_exp_op --> 00379 The C++ source code coresponding to this operation is 00380 \verbatim 00381 z = CondExpRel(y_0, y_1, y_2, y_3) 00382 \endverbatim 00383 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 00384 00385 \tparam Base 00386 base type for the operator; i.e., this operation was recorded 00387 using AD< \a Base > and computations by this routine are done using type 00388 \a Base. 00389 00390 \param i_z 00391 is the AD variable index corresponding to the variable z. 00392 00393 \param arg 00394 \n 00395 \a arg[0] 00396 is static cast to size_t from the enum type 00397 \verbatim 00398 enum CompareOp { 00399 CompareLt, 00400 CompareLe, 00401 CompareEq, 00402 CompareGe, 00403 CompareGt, 00404 CompareNe 00405 } 00406 \endverbatim 00407 for this operation. 00408 Note that arg[0] cannot be equal to CompareNe. 00409 \n 00410 \n 00411 \a arg[1] & 1 00412 \n 00413 If this is zero, y_0 is a parameter. Otherwise it is a variable. 00414 \n 00415 \n 00416 \a arg[1] & 2 00417 \n 00418 If this is zero, y_1 is a parameter. Otherwise it is a variable. 00419 \n 00420 \n 00421 \a arg[1] & 4 00422 \n 00423 If this is zero, y_2 is a parameter. Otherwise it is a variable. 00424 \n 00425 \n 00426 \a arg[1] & 8 00427 \n 00428 If this is zero, y_3 is a parameter. Otherwise it is a variable. 00429 \n 00430 \n 00431 \a arg[2 + j ] for j = 0, 1, 2, 3 00432 \n 00433 is the index corresponding to y_j. 00434 00435 \param num_par 00436 is the total number of values in the vector \a parameter. 00437 00438 \param parameter 00439 For j = 0, 1, 2, 3, 00440 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value. 00441 00442 \param nc_taylor 00443 number of columns in the matrix containing the Taylor coefficients. 00444 00445 \par Checked Assertions 00446 \li NumArg(CExpOp) == 6 00447 \li NumRes(CExpOp) == 1 00448 \li arg[0] < static_cast<size_t> ( CompareNe ) 00449 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. 00450 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. 00451 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz. 00452 <!-- end conditional_exp_op --> 00453 00454 \param taylor 00455 \b Input: 00456 For j = 0, 1, 2, 3, 00457 if y_j is a variable then 00458 \a taylor [ \a arg[2+j] * nc_taylor + 0 ] 00459 is the zero order Taylor coefficient corresponding to y_j. 00460 \n 00461 \b Output: \a taylor [ \a i_z * \a nc_taylor + 0 ] 00462 is the zero order Taylor coefficient corresponding to z. 00463 */ 00464 template <class Base> 00465 inline void forward_cond_op_0( 00466 size_t i_z , 00467 const addr_t* arg , 00468 size_t num_par , 00469 const Base* parameter , 00470 size_t nc_taylor , 00471 Base* taylor ) 00472 { Base y_0, y_1, y_2, y_3; 00473 Base* z; 00474 00475 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) ); 00476 CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); 00477 CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); 00478 CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); 00479 00480 if( arg[1] & 1 ) 00481 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z ); 00482 y_0 = taylor[ arg[2] * nc_taylor + 0 ]; 00483 } 00484 else 00485 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); 00486 y_0 = parameter[ arg[2] ]; 00487 } 00488 if( arg[1] & 2 ) 00489 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z ); 00490 y_1 = taylor[ arg[3] * nc_taylor + 0 ]; 00491 } 00492 else 00493 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); 00494 y_1 = parameter[ arg[3] ]; 00495 } 00496 if( arg[1] & 4 ) 00497 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z ); 00498 y_2 = taylor[ arg[4] * nc_taylor + 0 ]; 00499 } 00500 else 00501 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par ); 00502 y_2 = parameter[ arg[4] ]; 00503 } 00504 if( arg[1] & 8 ) 00505 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); 00506 y_3 = taylor[ arg[5] * nc_taylor + 0 ]; 00507 } 00508 else 00509 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par ); 00510 y_3 = parameter[ arg[5] ]; 00511 } 00512 z = taylor + i_z * nc_taylor; 00513 z[0] = CondExpOp( 00514 CompareOp( arg[0] ), 00515 y_0, 00516 y_1, 00517 y_2, 00518 y_3 00519 ); 00520 return; 00521 } 00522 00523 /*! 00524 Compute reverse mode Taylor coefficients for op = CExpOp. 00525 00526 This routine is given the partial derivatives of a function 00527 G( z , y , x , w , ... ) 00528 and it uses them to compute the partial derivatives of 00529 \verbatim 00530 H( y , x , w , u , ... ) = G[ z(y) , y , x , w , u , ... ] 00531 \endverbatim 00532 where y above represents y_0, y_1, y_2, y_3. 00533 00534 <!-- replace conditional_exp_op --> 00535 The C++ source code coresponding to this operation is 00536 \verbatim 00537 z = CondExpRel(y_0, y_1, y_2, y_3) 00538 \endverbatim 00539 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 00540 00541 \tparam Base 00542 base type for the operator; i.e., this operation was recorded 00543 using AD< \a Base > and computations by this routine are done using type 00544 \a Base. 00545 00546 \param i_z 00547 is the AD variable index corresponding to the variable z. 00548 00549 \param arg 00550 \n 00551 \a arg[0] 00552 is static cast to size_t from the enum type 00553 \verbatim 00554 enum CompareOp { 00555 CompareLt, 00556 CompareLe, 00557 CompareEq, 00558 CompareGe, 00559 CompareGt, 00560 CompareNe 00561 } 00562 \endverbatim 00563 for this operation. 00564 Note that arg[0] cannot be equal to CompareNe. 00565 \n 00566 \n 00567 \a arg[1] & 1 00568 \n 00569 If this is zero, y_0 is a parameter. Otherwise it is a variable. 00570 \n 00571 \n 00572 \a arg[1] & 2 00573 \n 00574 If this is zero, y_1 is a parameter. Otherwise it is a variable. 00575 \n 00576 \n 00577 \a arg[1] & 4 00578 \n 00579 If this is zero, y_2 is a parameter. Otherwise it is a variable. 00580 \n 00581 \n 00582 \a arg[1] & 8 00583 \n 00584 If this is zero, y_3 is a parameter. Otherwise it is a variable. 00585 \n 00586 \n 00587 \a arg[2 + j ] for j = 0, 1, 2, 3 00588 \n 00589 is the index corresponding to y_j. 00590 00591 \param num_par 00592 is the total number of values in the vector \a parameter. 00593 00594 \param parameter 00595 For j = 0, 1, 2, 3, 00596 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value. 00597 00598 \param nc_taylor 00599 number of columns in the matrix containing the Taylor coefficients. 00600 00601 \par Checked Assertions 00602 \li NumArg(CExpOp) == 6 00603 \li NumRes(CExpOp) == 1 00604 \li arg[0] < static_cast<size_t> ( CompareNe ) 00605 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. 00606 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. 00607 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz. 00608 <!-- end conditional_exp_op --> 00609 00610 \param d 00611 is the order of the Taylor coefficient of z that we are computing. 00612 00613 \param taylor 00614 \b Input: 00615 For j = 0, 1, 2, 3 and k = 0 , ... , \a d, 00616 if y_j is a variable then 00617 \a taylor [ \a arg[2+j] * nc_taylor + k ] 00618 is the k-th order Taylor coefficient corresponding to y_j. 00619 \n 00620 \a taylor [ \a i_z * \a nc_taylor + k ] 00621 for k = 0 , ... , \a d 00622 is the k-th order Taylor coefficient corresponding to z. 00623 00624 \param nc_partial 00625 number of columns in the matrix containing the Taylor coefficients. 00626 00627 \param partial 00628 \b Input: 00629 For j = 0, 1, 2, 3 and k = 0 , ... , \a d, 00630 if y_j is a variable then 00631 \a partial [ \a arg[2+j] * nc_partial + k ] 00632 is the partial derivative of G( z , y , x , w , u , ... ) 00633 with respect to the k-th order Taylor coefficient corresponding to y_j. 00634 \n 00635 \b Input: \a partial [ \a i_z * \a nc_taylor + k ] 00636 for k = 0 , ... , \a d 00637 is the partial derivative of G( z , y , x , w , u , ... ) 00638 with respect to the k-th order Taylor coefficient corresponding to z. 00639 \n 00640 \b Output: 00641 For j = 0, 1, 2, 3 and k = 0 , ... , \a d, 00642 if y_j is a variable then 00643 \a partial [ \a arg[2+j] * nc_partial + k ] 00644 is the partial derivative of H( y , x , w , u , ... ) 00645 with respect to the k-th order Taylor coefficient corresponding to y_j. 00646 00647 */ 00648 template <class Base> 00649 inline void reverse_cond_op( 00650 size_t d , 00651 size_t i_z , 00652 const addr_t* arg , 00653 size_t num_par , 00654 const Base* parameter , 00655 size_t nc_taylor , 00656 const Base* taylor , 00657 size_t nc_partial , 00658 Base* partial ) 00659 { Base y_0, y_1; 00660 Base zero(0); 00661 Base* pz; 00662 Base* py_2; 00663 Base* py_3; 00664 00665 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) ); 00666 CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); 00667 CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); 00668 CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); 00669 00670 pz = partial + i_z * nc_partial + 0; 00671 if( arg[1] & 1 ) 00672 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z ); 00673 y_0 = taylor[ arg[2] * nc_taylor + 0 ]; 00674 } 00675 else 00676 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); 00677 y_0 = parameter[ arg[2] ]; 00678 } 00679 if( arg[1] & 2 ) 00680 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z ); 00681 y_1 = taylor[ arg[3] * nc_taylor + 0 ]; 00682 } 00683 else 00684 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); 00685 y_1 = parameter[ arg[3] ]; 00686 } 00687 if( arg[1] & 4 ) 00688 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z ); 00689 py_2 = partial + arg[4] * nc_partial; 00690 size_t j = d + 1; 00691 while(j--) 00692 { py_2[j] += CondExpOp( 00693 CompareOp( arg[0] ), 00694 y_0, 00695 y_1, 00696 pz[j], 00697 zero 00698 ); 00699 } 00700 } 00701 if( arg[1] & 8 ) 00702 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); 00703 py_3 = partial + arg[5] * nc_partial; 00704 size_t j = d + 1; 00705 while(j--) 00706 { py_3[j] += CondExpOp( 00707 CompareOp( arg[0] ), 00708 y_0, 00709 y_1, 00710 zero, 00711 pz[j] 00712 ); 00713 } 00714 } 00715 return; 00716 } 00717 00718 /*! 00719 Compute forward Jacobian sparsity patterns for op = CExpOp. 00720 00721 <!-- replace sparse_conditional_exp_op --> 00722 The C++ source code coresponding to this operation is 00723 \verbatim 00724 z = CondExpRel(y_0, y_1, y_2, y_3) 00725 \endverbatim 00726 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 00727 00728 \tparam Vector_set 00729 is the type used for vectors of sets. It can be either 00730 \c sparse_pack, \c sparse_set, or \c sparse_list. 00731 00732 \param i_z 00733 is the AD variable index corresponding to the variable z. 00734 00735 \param arg 00736 \n 00737 \a arg[0] 00738 is static cast to size_t from the enum type 00739 \verbatim 00740 enum CompareOp { 00741 CompareLt, 00742 CompareLe, 00743 CompareEq, 00744 CompareGe, 00745 CompareGt, 00746 CompareNe 00747 } 00748 \endverbatim 00749 for this operation. 00750 Note that arg[0] cannot be equal to CompareNe. 00751 \n 00752 \n 00753 \a arg[1] & 1 00754 \n 00755 If this is zero, y_0 is a parameter. Otherwise it is a variable. 00756 \n 00757 \n 00758 \a arg[1] & 2 00759 \n 00760 If this is zero, y_1 is a parameter. Otherwise it is a variable. 00761 \n 00762 \n 00763 \a arg[1] & 4 00764 \n 00765 If this is zero, y_2 is a parameter. Otherwise it is a variable. 00766 \n 00767 \n 00768 \a arg[1] & 8 00769 \n 00770 If this is zero, y_3 is a parameter. Otherwise it is a variable. 00771 \n 00772 \n 00773 \a arg[2 + j ] for j = 0, 1, 2, 3 00774 \n 00775 is the index corresponding to y_j. 00776 00777 \param num_par 00778 is the total number of values in the vector \a parameter. 00779 00780 \par Checked Assertions 00781 \li NumArg(CExpOp) == 6 00782 \li NumRes(CExpOp) == 1 00783 \li arg[0] < static_cast<size_t> ( CompareNe ) 00784 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. 00785 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. 00786 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz. 00787 <!-- end sparse_conditional_exp_op --> 00788 00789 \param sparsity 00790 \b Input: 00791 if y_2 is a variable, the set with index t is 00792 the sparsity pattern corresponding to y_2. 00793 This identifies which of the independent variables the variable y_2 00794 depends on. 00795 \n 00796 \b Input: 00797 if y_3 is a variable, the set with index t is 00798 the sparsity pattern corresponding to y_3. 00799 This identifies which of the independent variables the variable y_3 00800 depends on. 00801 \n 00802 \b Output: 00803 The set with index T is 00804 the sparsity pattern corresponding to z. 00805 This identifies which of the independent variables the variable z 00806 depends on. 00807 */ 00808 template <class Vector_set> 00809 inline void forward_sparse_jacobian_cond_op( 00810 size_t i_z , 00811 const addr_t* arg , 00812 size_t num_par , 00813 Vector_set& sparsity ) 00814 { 00815 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) ); 00816 CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); 00817 CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); 00818 CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); 00819 00820 # ifndef NDEBUG 00821 if( arg[1] & 1 ) 00822 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z ); 00823 } 00824 else 00825 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); 00826 } 00827 if( arg[1] & 2 ) 00828 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z ); 00829 } 00830 else 00831 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); 00832 } 00833 # endif 00834 if( arg[1] & 4 ) 00835 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z ); 00836 if( arg[1] & 8 ) 00837 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); 00838 sparsity.binary_union(i_z, arg[4], arg[5], sparsity); 00839 } 00840 else 00841 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par ); 00842 sparsity.assignment(i_z, arg[4], sparsity); 00843 } 00844 } 00845 else 00846 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par ); 00847 if( arg[1] & 8 ) 00848 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); 00849 sparsity.assignment(i_z, arg[5], sparsity); 00850 } 00851 else 00852 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par ); 00853 sparsity.clear(i_z); 00854 } 00855 } 00856 return; 00857 } 00858 00859 /*! 00860 Compute reverse Jacobian sparsity patterns for op = CExpOp. 00861 00862 This routine is given the sparsity patterns 00863 for a function G(z, y, x, ... ) 00864 and it uses them to compute the sparsity patterns for 00865 \verbatim 00866 H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ] 00867 \endverbatim 00868 where y represents the combination of y_0, y_1, y_2, and y_3. 00869 00870 <!-- replace sparse_conditional_exp_op --> 00871 The C++ source code coresponding to this operation is 00872 \verbatim 00873 z = CondExpRel(y_0, y_1, y_2, y_3) 00874 \endverbatim 00875 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 00876 00877 \tparam Vector_set 00878 is the type used for vectors of sets. It can be either 00879 \c sparse_pack, \c sparse_set, or \c sparse_list. 00880 00881 \param i_z 00882 is the AD variable index corresponding to the variable z. 00883 00884 \param arg 00885 \n 00886 \a arg[0] 00887 is static cast to size_t from the enum type 00888 \verbatim 00889 enum CompareOp { 00890 CompareLt, 00891 CompareLe, 00892 CompareEq, 00893 CompareGe, 00894 CompareGt, 00895 CompareNe 00896 } 00897 \endverbatim 00898 for this operation. 00899 Note that arg[0] cannot be equal to CompareNe. 00900 \n 00901 \n 00902 \a arg[1] & 1 00903 \n 00904 If this is zero, y_0 is a parameter. Otherwise it is a variable. 00905 \n 00906 \n 00907 \a arg[1] & 2 00908 \n 00909 If this is zero, y_1 is a parameter. Otherwise it is a variable. 00910 \n 00911 \n 00912 \a arg[1] & 4 00913 \n 00914 If this is zero, y_2 is a parameter. Otherwise it is a variable. 00915 \n 00916 \n 00917 \a arg[1] & 8 00918 \n 00919 If this is zero, y_3 is a parameter. Otherwise it is a variable. 00920 \n 00921 \n 00922 \a arg[2 + j ] for j = 0, 1, 2, 3 00923 \n 00924 is the index corresponding to y_j. 00925 00926 \param num_par 00927 is the total number of values in the vector \a parameter. 00928 00929 \par Checked Assertions 00930 \li NumArg(CExpOp) == 6 00931 \li NumRes(CExpOp) == 1 00932 \li arg[0] < static_cast<size_t> ( CompareNe ) 00933 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. 00934 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. 00935 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz. 00936 <!-- end sparse_conditional_exp_op --> 00937 00938 \param nz_compare 00939 Are the derivatives with respect to left and right of the expression below 00940 considered to be non-zero: 00941 \code 00942 CondExpRel(left, right, if_true, if_false) 00943 \endcode 00944 This is used by the optimizer to obtain the correct dependency relations. 00945 00946 00947 \param sparsity 00948 if y_2 is a variable, the set with index t is 00949 the sparsity pattern corresponding to y_2. 00950 This identifies which of the dependent variables depend on the variable y_2. 00951 On input, this pattern corresponds to the function G. 00952 On ouput, it corresponds to the function H. 00953 \n 00954 \n 00955 if y_3 is a variable, the set with index t is 00956 the sparsity pattern corresponding to y_3. 00957 This identifies which of the dependent variables depeond on the variable y_3. 00958 On input, this pattern corresponds to the function G. 00959 On ouput, it corresponds to the function H. 00960 \n 00961 \b Output: 00962 The set with index T is 00963 the sparsity pattern corresponding to z. 00964 This identifies which of the dependent variables depend on the variable z. 00965 On input and output, this pattern corresponds to the function G. 00966 */ 00967 template <class Vector_set> 00968 inline void reverse_sparse_jacobian_cond_op( 00969 bool nz_compare , 00970 size_t i_z , 00971 const addr_t* arg , 00972 size_t num_par , 00973 Vector_set& sparsity ) 00974 { 00975 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) ); 00976 CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); 00977 CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); 00978 CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); 00979 00980 # ifndef NDEBUG 00981 if( arg[1] & 1 ) 00982 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z ); 00983 } 00984 else 00985 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); 00986 } 00987 if( arg[1] & 2 ) 00988 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z ); 00989 } 00990 else 00991 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); 00992 } 00993 if( ! ( arg[1] & 4 ) ) 00994 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par ); 00995 } 00996 if( ! ( arg[1] & 8 ) ) 00997 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par ); 00998 } 00999 # endif 01000 if( nz_compare ) 01001 { if( arg[1] & 1 ) 01002 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z ); 01003 sparsity.binary_union(arg[2], arg[2], i_z, sparsity); 01004 } 01005 if( arg[1] & 2 ) 01006 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z ); 01007 sparsity.binary_union(arg[3], arg[3], i_z, sparsity); 01008 } 01009 } 01010 // -------------------------------------------------------------------- 01011 if( arg[1] & 4 ) 01012 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z ); 01013 sparsity.binary_union(arg[4], arg[4], i_z, sparsity); 01014 } 01015 if( arg[1] & 8 ) 01016 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); 01017 sparsity.binary_union(arg[5], arg[5], i_z, sparsity); 01018 } 01019 return; 01020 } 01021 01022 /*! 01023 Compute reverse Hessian sparsity patterns for op = CExpOp. 01024 01025 This routine is given the sparsity patterns 01026 for a function G(z, y, x, ... ) 01027 and it uses them to compute the sparsity patterns for 01028 \verbatim 01029 H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ] 01030 \endverbatim 01031 where y represents the combination of y_0, y_1, y_2, and y_3. 01032 01033 <!-- replace sparse_conditional_exp_op --> 01034 The C++ source code coresponding to this operation is 01035 \verbatim 01036 z = CondExpRel(y_0, y_1, y_2, y_3) 01037 \endverbatim 01038 where Rel is one of the following: Lt, Le, Eq, Ge, Gt. 01039 01040 \tparam Vector_set 01041 is the type used for vectors of sets. It can be either 01042 \c sparse_pack, \c sparse_set, or \c sparse_list. 01043 01044 \param i_z 01045 is the AD variable index corresponding to the variable z. 01046 01047 \param arg 01048 \n 01049 \a arg[0] 01050 is static cast to size_t from the enum type 01051 \verbatim 01052 enum CompareOp { 01053 CompareLt, 01054 CompareLe, 01055 CompareEq, 01056 CompareGe, 01057 CompareGt, 01058 CompareNe 01059 } 01060 \endverbatim 01061 for this operation. 01062 Note that arg[0] cannot be equal to CompareNe. 01063 \n 01064 \n 01065 \a arg[1] & 1 01066 \n 01067 If this is zero, y_0 is a parameter. Otherwise it is a variable. 01068 \n 01069 \n 01070 \a arg[1] & 2 01071 \n 01072 If this is zero, y_1 is a parameter. Otherwise it is a variable. 01073 \n 01074 \n 01075 \a arg[1] & 4 01076 \n 01077 If this is zero, y_2 is a parameter. Otherwise it is a variable. 01078 \n 01079 \n 01080 \a arg[1] & 8 01081 \n 01082 If this is zero, y_3 is a parameter. Otherwise it is a variable. 01083 \n 01084 \n 01085 \a arg[2 + j ] for j = 0, 1, 2, 3 01086 \n 01087 is the index corresponding to y_j. 01088 01089 \param num_par 01090 is the total number of values in the vector \a parameter. 01091 01092 \par Checked Assertions 01093 \li NumArg(CExpOp) == 6 01094 \li NumRes(CExpOp) == 1 01095 \li arg[0] < static_cast<size_t> ( CompareNe ) 01096 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. 01097 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. 01098 \li For j = 0, 1, 2, 3 if y_j is a variable, arg[2+j] < iz. 01099 <!-- end sparse_conditional_exp_op --> 01100 01101 01102 \param jac_reverse 01103 \a jac_reverse[i_z] 01104 is false (true) if the Jacobian of G with respect to z is always zero 01105 (may be non-zero). 01106 \n 01107 \n 01108 \a jac_reverse[ arg[4] ] 01109 If y_2 is a variable, 01110 \a jac_reverse[ arg[4] ] 01111 is false (true) if the Jacobian with respect to y_2 is always zero 01112 (may be non-zero). 01113 On input, it corresponds to the function G, 01114 and on output it corresponds to the function H. 01115 \n 01116 \n 01117 \a jac_reverse[ arg[5] ] 01118 If y_3 is a variable, 01119 \a jac_reverse[ arg[5] ] 01120 is false (true) if the Jacobian with respect to y_3 is always zero 01121 (may be non-zero). 01122 On input, it corresponds to the function G, 01123 and on output it corresponds to the function H. 01124 01125 \param hes_sparsity 01126 The set with index \a i_z in \a hes_sparsity 01127 is the Hessian sparsity pattern for the function G 01128 where one of the partials is with respect to z. 01129 \n 01130 \n 01131 If y_2 is a variable, 01132 the set with index \a arg[4] in \a hes_sparsity 01133 is the Hessian sparsity pattern 01134 where one of the partials is with respect to y_2. 01135 On input, this pattern corresponds to the function G. 01136 On output, this pattern corresponds to the function H. 01137 \n 01138 \n 01139 If y_3 is a variable, 01140 the set with index \a arg[5] in \a hes_sparsity 01141 is the Hessian sparsity pattern 01142 where one of the partials is with respect to y_3. 01143 On input, this pattern corresponds to the function G. 01144 On output, this pattern corresponds to the function H. 01145 */ 01146 template <class Vector_set> 01147 inline void reverse_sparse_hessian_cond_op( 01148 size_t i_z , 01149 const addr_t* arg , 01150 size_t num_par , 01151 bool* jac_reverse , 01152 Vector_set& hes_sparsity ) 01153 { 01154 01155 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) ); 01156 CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); 01157 CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); 01158 CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); 01159 01160 # ifndef NDEBUG 01161 if( arg[1] & 1 ) 01162 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z ); 01163 } 01164 else 01165 { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); 01166 } 01167 if( arg[1] & 2 ) 01168 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z ); 01169 } 01170 else 01171 { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); 01172 } 01173 if( ! ( arg[1] & 4 ) ) 01174 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par ); 01175 } 01176 if( ! ( arg[1] & 8 ) ) 01177 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par ); 01178 } 01179 # endif 01180 if( arg[1] & 4 ) 01181 { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z ); 01182 01183 hes_sparsity.binary_union(arg[4], arg[4], i_z, hes_sparsity); 01184 jac_reverse[ arg[4] ] |= jac_reverse[i_z]; 01185 } 01186 if( arg[1] & 8 ) 01187 { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); 01188 01189 hes_sparsity.binary_union(arg[5], arg[5], i_z, hes_sparsity); 01190 jac_reverse[ arg[5] ] |= jac_reverse[i_z]; 01191 } 01192 return; 01193 } 01194 01195 } // END_CPPAD_NAMESPACE 01196 # endif