CPPAD_INLINE AD<Base> CondExp( const AD<Base> &flag , const AD<Base> &exp_if_true , const AD<Base> &exp_if_false ) { return CondExpOp(CompareGt, flag, AD<Base>(0), exp_if_true, exp_if_false); }
inline void forward_cond_op_dir( size_t q , size_t r , size_t i_z , const addr_t* arg , size_t num_par , const Base* parameter , size_t cap_order , Base* taylor ) { Base y_0, y_1, y_2, y_3; Base zero(0); size_t num_taylor_per_var = (cap_order-1) * r + 1; Base* z = taylor + i_z * num_taylor_per_var; CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) ); CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); CPPAD_ASSERT_UNKNOWN( 0 < q ); CPPAD_ASSERT_UNKNOWN( q < cap_order ); if( arg[1] & 1 ) { y_0 = taylor[ arg[2] * num_taylor_per_var + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); y_0 = parameter[ arg[2] ]; } if( arg[1] & 2 ) { y_1 = taylor[ arg[3] * num_taylor_per_var + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); y_1 = parameter[ arg[3] ]; } size_t m = (q-1) * r + 1; for(size_t ell = 0; ell < r; ell++) { if( arg[1] & 4 ) { y_2 = taylor[ arg[4] * num_taylor_per_var + m + ell]; } else y_2 = zero; if( arg[1] & 8 ) { y_3 = taylor[ arg[5] * num_taylor_per_var + m + ell]; } else y_3 = zero; z[m+ell] = CondExpOp( CompareOp( arg[0] ), y_0, y_1, y_2, y_3 ); } return; }
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION AD<Base> CondExp( const AD<Base> &flag , const AD<Base> &if_true , const AD<Base> &if_false ) { return CondExpOp(CompareGt, flag, AD<Base>(0), if_true, if_false); }
inline void forward_cond_op_0( size_t i_z , const addr_t* arg , size_t num_par , const Base* parameter , size_t nc_taylor , Base* taylor ) { Base y_0, y_1, y_2, y_3; Base* z; CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) ); CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); if( arg[1] & 1 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z ); y_0 = taylor[ arg[2] * nc_taylor + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); y_0 = parameter[ arg[2] ]; } if( arg[1] & 2 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z ); y_1 = taylor[ arg[3] * nc_taylor + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); y_1 = parameter[ arg[3] ]; } if( arg[1] & 4 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z ); y_2 = taylor[ arg[4] * nc_taylor + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par ); y_2 = parameter[ arg[4] ]; } if( arg[1] & 8 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); y_3 = taylor[ arg[5] * nc_taylor + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par ); y_3 = parameter[ arg[5] ]; } z = taylor + i_z * nc_taylor; z[0] = CondExpOp( CompareOp( arg[0] ), y_0, y_1, y_2, y_3 ); return; }
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION AD<Base> CondExpOp( enum CompareOp cop , const AD<Base> &left , const AD<Base> &right , const AD<Base> &if_true , const AD<Base> &if_false ) { AD<Base> returnValue; CPPAD_ASSERT_UNKNOWN( Parameter(returnValue) ); // check first case where do not need to tape if( IdenticalPar(left) & IdenticalPar(right) ) { switch( cop ) { case CompareLt: if( left.value_ < right.value_ ) returnValue = if_true; else returnValue = if_false; break; case CompareLe: if( left.value_ <= right.value_ ) returnValue = if_true; else returnValue = if_false; break; case CompareEq: if( left.value_ == right.value_ ) returnValue = if_true; else returnValue = if_false; break; case CompareGe: if( left.value_ >= right.value_ ) returnValue = if_true; else returnValue = if_false; break; case CompareGt: if( left.value_ > right.value_ ) returnValue = if_true; else returnValue = if_false; break; default: CPPAD_ASSERT_UNKNOWN(0); returnValue = if_true; } return returnValue; } // must use CondExp incase Base is an AD type and recording returnValue.value_ = CondExpOp(cop, left.value_, right.value_, if_true.value_, if_false.value_); ADTape<Base> *tape = CPPAD_NULL; if( Variable(left) ) tape = left.tape_this(); if( Variable(right) ) tape = right.tape_this(); if( Variable(if_true) ) tape = if_true.tape_this(); if( Variable(if_false) ) tape = if_false.tape_this(); // add this operation to the tape if( tape != CPPAD_NULL ) tape->RecordCondExp(cop, returnValue, left, right, if_true, if_false); return returnValue; }
inline void reverse_cond_op( size_t d , size_t i_z , const addr_t* arg , size_t num_par , const Base* parameter , size_t nc_taylor , const Base* taylor , size_t nc_partial , Base* partial ) { Base y_0, y_1; Base zero(0); Base* pz; Base* py_2; Base* py_3; CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) ); CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); pz = partial + i_z * nc_partial + 0; if( arg[1] & 1 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z ); y_0 = taylor[ arg[2] * nc_taylor + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); y_0 = parameter[ arg[2] ]; } if( arg[1] & 2 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z ); y_1 = taylor[ arg[3] * nc_taylor + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); y_1 = parameter[ arg[3] ]; } if( arg[1] & 4 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z ); py_2 = partial + arg[4] * nc_partial; size_t j = d + 1; while(j--) { py_2[j] += CondExpOp( CompareOp( arg[0] ), y_0, y_1, pz[j], zero ); } } if( arg[1] & 8 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); py_3 = partial + arg[5] * nc_partial; size_t j = d + 1; while(j--) { py_3[j] += CondExpOp( CompareOp( arg[0] ), y_0, y_1, zero, pz[j] ); } } return; }
inline void forward_cond_op( size_t p , size_t q , size_t i_z , const addr_t* arg , size_t num_par , const Base* parameter , size_t cap_order , Base* taylor ) { Base y_0, y_1, y_2, y_3; Base zero(0); Base* z = taylor + i_z * cap_order; CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) ); CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); if( arg[1] & 1 ) { y_0 = taylor[ arg[2] * cap_order + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); y_0 = parameter[ arg[2] ]; } if( arg[1] & 2 ) { y_1 = taylor[ arg[3] * cap_order + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); y_1 = parameter[ arg[3] ]; } if( p == 0 ) { if( arg[1] & 4 ) { y_2 = taylor[ arg[4] * cap_order + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par ); y_2 = parameter[ arg[4] ]; } if( arg[1] & 8 ) { y_3 = taylor[ arg[5] * cap_order + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par ); y_3 = parameter[ arg[5] ]; } z[0] = CondExpOp( CompareOp( arg[0] ), y_0, y_1, y_2, y_3 ); p++; } for(size_t d = p; d <= q; d++) { if( arg[1] & 4 ) { y_2 = taylor[ arg[4] * cap_order + d]; } else y_2 = zero; if( arg[1] & 8 ) { y_3 = taylor[ arg[5] * cap_order + d]; } else y_3 = zero; z[d] = CondExpOp( CompareOp( arg[0] ), y_0, y_1, y_2, y_3 ); } return; }
inline void forward_cond_op( size_t d , size_t i_z , const addr_t* arg , size_t num_par , const Base* parameter , size_t nc_taylor , Base* taylor ) { Base y_0, y_1, y_2, y_3; Base zero(0); Base* z; CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) ); CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); if( arg[1] & 1 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < i_z ); y_0 = taylor[ arg[2] * nc_taylor + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); y_0 = parameter[ arg[2] ]; } if( arg[1] & 2 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < i_z ); y_1 = taylor[ arg[3] * nc_taylor + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); y_1 = parameter[ arg[3] ]; } # if CPPAD_USE_FORWARD0SWEEP CPPAD_ASSERT_UNKNOWN( d > 0 ); # else if( d == 0 ) { if( arg[1] & 4 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z ); y_2 = taylor[ arg[4] * nc_taylor + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par ); y_2 = parameter[ arg[4] ]; } if( arg[1] & 8 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); y_3 = taylor[ arg[5] * nc_taylor + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par ); y_3 = parameter[ arg[5] ]; } } else # endif { if( arg[1] & 4 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < i_z ); y_2 = taylor[ arg[4] * nc_taylor + d]; } else y_2 = zero; if( arg[1] & 8 ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < i_z ); y_3 = taylor[ arg[5] * nc_taylor + d]; } else y_3 = zero; } z = taylor + i_z * nc_taylor; z[d] = CondExpOp( CompareOp( arg[0] ), y_0, y_1, y_2, y_3 ); return; }