inline void forward_abs_op( size_t j , size_t i_z , size_t i_x , size_t nc_taylor , Base* taylor ) { size_t k; static Base zero(0); // check assumptions CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 ); CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 ); CPPAD_ASSERT_UNKNOWN( i_x < i_z ); CPPAD_ASSERT_UNKNOWN( j < nc_taylor ); // Taylor coefficients corresponding to argument and result Base* x = taylor + i_x * nc_taylor; Base* z = taylor + i_z * nc_taylor; // order that decides positive, negative or zero k = 0; while( (k < j) & (x[k] == zero) ) k++; if( GreaterThanZero(x[k]) ) z[j] = x[j]; else if( LessThanZero(x[k]) ) z[j] = -x[j]; else z[j] = zero; }
inline void ForAbsOp(size_t j, Base *z, const Base *x) { size_t k; // order that decides positive, negative or zero k = 0; while( (k < j) & (x[k] == Base(0)) ) k++; if( GreaterThanZero(x[k]) ) z[j] = x[j]; else if( LessThanZero(x[k]) ) z[j] = -x[j]; else z[j] = Base(0); }
inline void reverse_abs_op( size_t d , size_t i_z , size_t i_x , size_t nc_taylor , const Base* taylor , size_t nc_partial , Base* partial ) { size_t j, k; static Base zero(0); // check assumptions CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 ); CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 ); CPPAD_ASSERT_UNKNOWN( i_x < i_z ); CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); CPPAD_ASSERT_UNKNOWN( d < nc_partial ); // Taylor coefficients and partials corresponding to argument const Base* x = taylor + i_x * nc_taylor; Base* px = partial + i_x * nc_partial; // Taylor coefficients and partials corresponding to result Base* pz = partial + i_z * nc_partial; // order that decides positive, negative or zero k = 0; while( (k < d) & (x[k] == zero) ) k++; if( GreaterThanZero(x[k]) ) { // partial of z w.r.t y is +1 for(j = k; j <= d; j++) px[j] += pz[j]; } else if( LessThanZero(x[k]) ) { // partial of z w.r.t y is -1 for(j = k; j <= d; j++) px[j] -= pz[j]; } }
inline void RevAbsOp(size_t d, const Base *z, const Base *x, Base *pz, Base *px) { size_t j, k; // order that decides positive, negative or zero k = 0; while( (k < d) & (x[k] == Base(0)) ) k++; if( GreaterThanZero(x[k]) ) { for(j = k; j <= d; j++) px[j] += pz[j]; } else if( LessThanZero(x[k]) ) { for(j = k; j <= d; j++) px[j] -= pz[j]; } }
inline void forward_abs_op_0( size_t i_z , size_t i_x , size_t nc_taylor , Base* taylor ) { // check assumptions CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 ); CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 ); CPPAD_ASSERT_UNKNOWN( i_x < i_z ); CPPAD_ASSERT_UNKNOWN( 0 < nc_taylor ); // Taylor coefficients corresponding to argument and result Base y0 = *(taylor + i_x * nc_taylor); Base* z = taylor + i_z * nc_taylor; if( LessThanZero(y0) ) z[0] = - y0; else z[0] = y0; }
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION bool LessThanZero(const AD<Base> &x) { return LessThanZero(x.value_); }
void forward_cskip_op_0( size_t i_z , const addr_t* arg , size_t num_par , const Base* parameter , size_t cap_order , Base* taylor , bool* cskip_op ) { CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < size_t(CompareNe) ); CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); Base left, right; if( arg[1] & 1 ) { // If variable arg[2] <= i_z, it has already been computed, // but it will be skipped for higher orders. CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) <= i_z ); left = taylor[ size_t(arg[2]) * cap_order + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); left = parameter[ arg[2] ]; } if( arg[1] & 2 ) { // If variable arg[3] <= i_z, it has already been computed, // but it will be skipped for higher orders. CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) <= i_z ); right = taylor[ size_t(arg[3]) * cap_order + 0 ]; } else { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); right = parameter[ arg[3] ]; } bool ok_to_skip = IdenticalCon(left) & IdenticalCon(right); if( ! ok_to_skip ) return; // initialize to avoid compiler warning bool true_case = false; Base diff = left - right; switch( CompareOp( arg[0] ) ) { case CompareLt: true_case = LessThanZero(diff); break; case CompareLe: true_case = LessThanOrZero(diff); break; case CompareEq: true_case = IdenticalZero(diff); break; case CompareGe: true_case = GreaterThanOrZero(diff); break; case CompareGt: true_case = GreaterThanZero(diff); break; case CompareNe: true_case = ! IdenticalZero(diff); break; default: CPPAD_ASSERT_UNKNOWN(false); } if( true_case ) { for(addr_t i = 0; i < arg[4]; i++) cskip_op[ arg[6+i] ] = true; } else { for(addr_t i = 0; i < arg[5]; i++) cskip_op[ arg[6+arg[4]+i] ] = true; } return; }