size_t forward0sweep( std::ostream& s_out, bool print, size_t n, size_t numvar, player<Base> *Rec, size_t J, Base *Taylor, CppAD::vector<bool>& cskip_op ) { CPPAD_ASSERT_UNKNOWN( J >= 1 ); // op code for current instruction OpCode op; // index for current instruction size_t i_op; // next variables size_t i_var; // constant and non-constant version of the operation argument indices addr_t* non_const_arg; const addr_t* arg = CPPAD_NULL; // initialize the comparision operator (ComOp) counter size_t compareCount = 0; // This is an order zero calculation, initialize vector indices pod_vector<size_t> VectorInd; // address for each element pod_vector<bool> VectorVar; // is element a variable size_t i = Rec->num_rec_vecad_ind(); if( i > 0 ) { VectorInd.extend(i); VectorVar.extend(i); while(i--) { VectorInd[i] = Rec->GetVecInd(i); VectorVar[i] = false; } } // zero order, so initialize conditional skip flags for(i = 0; i < Rec->num_rec_op(); i++) cskip_op[i] = false; // work space used by UserOp. const size_t user_q = 0; // lowest order const size_t user_p = 0; // highest order vector<bool> user_vx; // empty vecotor vector<bool> user_vy; // empty vecotor vector<Base> user_tx; // argument vector Taylor coefficients vector<Base> user_ty; // result vector Taylor coefficients size_t user_index = 0; // indentifier for this atomic operation size_t user_id = 0; // user identifier for this call to operator size_t user_i = 0; // index in result vector size_t user_j = 0; // index in argument vector size_t user_m = 0; // size of result vector size_t user_n = 0; // size of arugment vector // atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator # ifndef NDEBUG bool user_ok = false; // atomic op return value # endif // // next expected operator in a UserOp sequence enum { user_start, user_arg, user_ret, user_end } user_state = user_start; // check numvar argument CPPAD_ASSERT_UNKNOWN( Rec->num_rec_var() == numvar ); // length of the parameter vector (used by CppAD assert macros) const size_t num_par = Rec->num_rec_par(); // length of the text vector (used by CppAD assert macros) const size_t num_text = Rec->num_rec_text(); // pointer to the beginning of the parameter vector const Base* parameter = CPPAD_NULL; if( num_par > 0 ) parameter = Rec->GetPar(); // pointer to the beginning of the text vector const char* text = CPPAD_NULL; if( num_text > 0 ) text = Rec->GetTxt(0); // skip the BeginOp at the beginning of the recording Rec->start_forward(op, arg, i_op, i_var); CPPAD_ASSERT_UNKNOWN( op == BeginOp ); # if CPPAD_FORWARD0SWEEP_TRACE std::cout << std::endl; # endif bool more_operators = true; while(more_operators) { // this op Rec->next_forward(op, arg, i_op, i_var); CPPAD_ASSERT_UNKNOWN( (i_op > n) | (op == InvOp) ); CPPAD_ASSERT_UNKNOWN( (i_op <= n) | (op != InvOp) ); // check if we are skipping this operation while( cskip_op[i_op] ) { if( op == CSumOp ) { // CSumOp has a variable number of arguments Rec->forward_csum(op, arg, i_op, i_var); } Rec->next_forward(op, arg, i_op, i_var); } // action to take depends on the case switch( op ) { case AbsOp: forward_abs_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case AddvvOp: forward_addvv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case AddpvOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); forward_addpv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case AcosOp: // sqrt(1 - x * x), acos(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_acos_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case AsinOp: // sqrt(1 - x * x), asin(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_asin_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case AtanOp: // 1 + x * x, atan(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_atan_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case CExpOp: // Use the general case with d == 0 // (could create an optimzied verison for this case) forward_cond_op_0( i_var, arg, num_par, parameter, J, Taylor ); break; // --------------------------------------------------- case ComOp: forward_comp_op_0( compareCount, arg, num_par, parameter, J, Taylor ); break; // --------------------------------------------------- case CosOp: // sin(x), cos(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_cos_op_0(i_var, arg[0], J, Taylor); break; // --------------------------------------------------- case CoshOp: // sinh(x), cosh(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_cosh_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case CSkipOp: // CSkipOp has a variable number of arguments and // next_forward thinks it one has one argument. // we must inform next_forward of this special case. Rec->forward_cskip(op, arg, i_op, i_var); forward_cskip_op_0( i_var, arg, num_par, parameter, J, Taylor, cskip_op ); break; // ------------------------------------------------- case CSumOp: // CSumOp has a variable number of arguments and // next_forward thinks it one has one argument. // we must inform next_forward of this special case. Rec->forward_csum(op, arg, i_op, i_var); forward_csum_op( 0, 0, i_var, arg, num_par, parameter, J, Taylor ); break; // ------------------------------------------------- case DisOp: forward_dis_op_0(i_var, arg, J, Taylor); break; // ------------------------------------------------- case DivvvOp: forward_divvv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case DivpvOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); forward_divpv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case DivvpOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); forward_divvp_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case EndOp: CPPAD_ASSERT_NARG_NRES(op, 0, 0); more_operators = false; break; // ------------------------------------------------- case ExpOp: forward_exp_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case InvOp: break; // ------------------------------------------------- case LdpOp: CPPAD_ASSERT_UNKNOWN( VectorInd.size() != 0 ); CPPAD_ASSERT_UNKNOWN( VectorVar.size() != 0 ); non_const_arg = Rec->forward_non_const_arg(); forward_load_p_op_0( i_var, non_const_arg, num_par, parameter, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar.data(), VectorInd.data() ); break; // ------------------------------------------------- case LdvOp: CPPAD_ASSERT_UNKNOWN( VectorInd.size() != 0 ); CPPAD_ASSERT_UNKNOWN( VectorVar.size() != 0 ); non_const_arg = Rec->forward_non_const_arg(); forward_load_v_op_0( i_var, non_const_arg, num_par, parameter, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar.data(), VectorInd.data() ); break; // ------------------------------------------------- case LogOp: forward_log_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case MulvvOp: forward_mulvv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case MulpvOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); forward_mulpv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case ParOp: forward_par_op_0( i_var, arg, num_par, parameter, J, Taylor ); break; // ------------------------------------------------- case PowvpOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); forward_powvp_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case PowpvOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); forward_powpv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case PowvvOp: forward_powvv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case PriOp: if( print ) forward_pri_0(s_out, i_var, arg, num_text, text, num_par, parameter, J, Taylor ); break; // ------------------------------------------------- case SignOp: // cos(x), sin(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_sign_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case SinOp: // cos(x), sin(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_sin_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case SinhOp: // cosh(x), sinh(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_sinh_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case SqrtOp: forward_sqrt_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case StppOp: forward_store_pp_op_0( i_var, arg, num_par, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar.data(), VectorInd.data() ); break; // ------------------------------------------------- case StpvOp: forward_store_pv_op_0( i_var, arg, num_par, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar.data(), VectorInd.data() ); break; // ------------------------------------------------- case StvpOp: forward_store_vp_op_0( i_var, arg, num_par, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar.data(), VectorInd.data() ); break; // ------------------------------------------------- case StvvOp: forward_store_vv_op_0( i_var, arg, num_par, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar.data(), VectorInd.data() ); break; // ------------------------------------------------- case SubvvOp: forward_subvv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case SubpvOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); forward_subpv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case SubvpOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); forward_subvp_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case TanOp: // tan(x)^2, tan(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_tan_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case TanhOp: // tanh(x)^2, tanh(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_tanh_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case UserOp: // start or end an atomic operation sequence CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 ); CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 ); if( user_state == user_start ) { user_index = arg[0]; user_id = arg[1]; user_n = arg[2]; user_m = arg[3]; user_atom = atomic_base<Base>::class_object(user_index); # ifndef NDEBUG if( user_atom == CPPAD_NULL ) { std::string msg = atomic_base<Base>::class_name(user_index) + ": atomic_base function has been deleted"; CPPAD_ASSERT_KNOWN(false, msg.c_str() ); } # endif if(user_tx.size() != user_n) user_tx.resize(user_n); if(user_ty.size() != user_m) user_ty.resize(user_m); user_j = 0; user_i = 0; user_state = user_arg; } else { CPPAD_ASSERT_UNKNOWN( user_state == user_end ); CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) ); CPPAD_ASSERT_UNKNOWN( user_id == size_t(arg[1]) ); CPPAD_ASSERT_UNKNOWN( user_n == size_t(arg[2]) ); CPPAD_ASSERT_UNKNOWN( user_m == size_t(arg[3]) ); # ifndef NDEBUG if( ! user_ok ) { std::string msg = atomic_base<Base>::class_name(user_index) + ": atomic_base.forward: returned false"; CPPAD_ASSERT_KNOWN(false, msg.c_str() ); } # endif user_state = user_start; } break; case UsrapOp: // parameter argument in an atomic operation sequence CPPAD_ASSERT_UNKNOWN( user_state == user_arg ); CPPAD_ASSERT_UNKNOWN( user_j < user_n ); CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); user_tx[user_j++] = parameter[ arg[0] ]; if( user_j == user_n ) { // call users function for this operation user_atom->set_id(user_id); CPPAD_ATOMIC_CALL(user_q, user_p, user_vx, user_vy, user_tx, user_ty ); user_state = user_ret; } break; case UsravOp: // variable argument in an atomic operation sequence CPPAD_ASSERT_UNKNOWN( user_state == user_arg ); CPPAD_ASSERT_UNKNOWN( user_j < user_n ); CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var ); user_tx[user_j++] = Taylor[ arg[0] * J + 0 ]; if( user_j == user_n ) { // call users function for this operation user_atom->set_id(user_id); CPPAD_ATOMIC_CALL(user_q, user_p, user_vx, user_vy, user_tx, user_ty ); user_state = user_ret; } break; case UsrrpOp: // parameter result in an atomic operation sequence CPPAD_ASSERT_UNKNOWN( user_state == user_ret ); CPPAD_ASSERT_UNKNOWN( user_i < user_m ); user_i++; if( user_i == user_m ) user_state = user_end; break; case UsrrvOp: // variable result in an atomic operation sequence CPPAD_ASSERT_UNKNOWN( user_state == user_ret ); CPPAD_ASSERT_UNKNOWN( user_i < user_m ); Taylor[ i_var * J + 0 ] = user_ty[user_i++]; if( user_i == user_m ) user_state = user_end; break; // ------------------------------------------------- default: CPPAD_ASSERT_UNKNOWN(false); } # if CPPAD_FORWARD0SWEEP_TRACE size_t d = 0; size_t i_tmp = i_var; Base* Z_tmp = Taylor + i_var * J; printOp( std::cout, Rec, i_op, i_tmp, op, arg, d + 1, Z_tmp, 0, (Base *) CPPAD_NULL ); } std::cout << std::endl; # else }
void forward0sweep( std::ostream& s_out, bool print, size_t n, size_t numvar, local::player<Base>* play, size_t J, Base* taylor, bool* cskip_op, pod_vector<addr_t>& var_by_load_op, size_t compare_change_count, size_t& compare_change_number, size_t& compare_change_op_index ) { CPPAD_ASSERT_UNKNOWN( J >= 1 ); CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar ); // use p, q, r so other forward sweeps can use code defined here size_t p = 0; size_t q = 0; size_t r = 1; /* <!-- define forward0sweep_code_define --> */ // op code for current instruction OpCode op; // index for current instruction size_t i_op; // next variables size_t i_var; // operation argument indices const addr_t* arg = CPPAD_NULL; // initialize the comparision operator counter if( p == 0 ) { compare_change_number = 0; compare_change_op_index = 0; } // If this includes a zero calculation, initialize this information pod_vector<bool> isvar_by_ind; pod_vector<size_t> index_by_ind; if( p == 0 ) { size_t i; // this includes order zero calculation, initialize vector indices size_t num = play->num_vec_ind_rec(); if( num > 0 ) { isvar_by_ind.extend(num); index_by_ind.extend(num); for(i = 0; i < num; i++) { index_by_ind[i] = play->GetVecInd(i); isvar_by_ind[i] = false; } } // includes zero order, so initialize conditional skip flags num = play->num_op_rec(); for(i = 0; i < num; i++) cskip_op[i] = false; } // work space used by UserOp. vector<bool> user_vx; // empty vecotor vector<bool> user_vy; // empty vecotor vector<Base> user_tx; // argument vector Taylor coefficients vector<Base> user_ty; // result vector Taylor coefficients // atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator # ifndef NDEBUG bool user_ok = false; // atomic op return value # endif // // information defined by forward_user size_t user_old=0, user_m=0, user_n=0, user_i=0, user_j=0; enum_user_state user_state = start_user; // proper initialization // length of the parameter vector (used by CppAD assert macros) const size_t num_par = play->num_par_rec(); // pointer to the beginning of the parameter vector const Base* parameter = CPPAD_NULL; if( num_par > 0 ) parameter = play->GetPar(); // length of the text vector (used by CppAD assert macros) const size_t num_text = play->num_text_rec(); // pointer to the beginning of the text vector const char* text = CPPAD_NULL; if( num_text > 0 ) text = play->GetTxt(0); /* <!-- end forward0sweep_code_define --> */ # if CPPAD_FORWARD0SWEEP_TRACE // flag as to when to trace user function values bool user_trace = false; // variable indices for results vector // (done differently for order zero). vector<size_t> user_iy; # endif // skip the BeginOp at the beginning of the recording play->forward_start(op, arg, i_op, i_var); CPPAD_ASSERT_UNKNOWN( op == BeginOp ); # if CPPAD_FORWARD0SWEEP_TRACE std::cout << std::endl; # endif bool flag; // a temporary flag to use in switch cases bool more_operators = true; while(more_operators) { // this op play->forward_next(op, arg, i_op, i_var); CPPAD_ASSERT_UNKNOWN( (i_op > n) | (op == InvOp) ); CPPAD_ASSERT_UNKNOWN( (i_op <= n) | (op != InvOp) ); CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() ); CPPAD_ASSERT_ARG_BEFORE_RESULT(op, arg, i_var); // check if we are skipping this operation while( cskip_op[i_op] ) { switch(op) { case CSumOp: // CSumOp has a variable number of arguments play->forward_csum(op, arg, i_op, i_var); break; case CSkipOp: // CSkip has a variable number of arguments play->forward_cskip(op, arg, i_op, i_var); break; case UserOp: { // skip all operations in this user atomic call CPPAD_ASSERT_UNKNOWN( user_state == start_user ); play->forward_user(op, user_state, user_old, user_m, user_n, user_i, user_j ); size_t n_skip = user_m + user_n + 1; for(size_t i = 0; i < n_skip; i++) { play->forward_next(op, arg, i_op, i_var); play->forward_user(op, user_state, user_old, user_m, user_n, user_i, user_j ); } CPPAD_ASSERT_UNKNOWN( user_state == start_user ); } break; default: break; } play->forward_next(op, arg, i_op, i_var); CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() ); } // action to take depends on the case switch( op ) { case AbsOp: forward_abs_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- case AddvvOp: forward_addvv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case AddpvOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); forward_addpv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case AcosOp: // sqrt(1 - x * x), acos(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_acos_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- # if CPPAD_USE_CPLUSPLUS_2011 case AcoshOp: // sqrt(x * x - 1), acosh(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_acosh_op_0(i_var, arg[0], J, taylor); break; # endif // ------------------------------------------------- case AsinOp: // sqrt(1 - x * x), asin(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_asin_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- # if CPPAD_USE_CPLUSPLUS_2011 case AsinhOp: // sqrt(1 + x * x), asinh(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_asinh_op_0(i_var, arg[0], J, taylor); break; # endif // ------------------------------------------------- case AtanOp: // 1 + x * x, atan(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_atan_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- # if CPPAD_USE_CPLUSPLUS_2011 case AtanhOp: // 1 - x * x, atanh(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_atanh_op_0(i_var, arg[0], J, taylor); break; # endif // ------------------------------------------------- case CExpOp: // Use the general case with d == 0 // (could create an optimzied verison for this case) forward_cond_op_0( i_var, arg, num_par, parameter, J, taylor ); break; // --------------------------------------------------- case CosOp: // sin(x), cos(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_cos_op_0(i_var, arg[0], J, taylor); break; // --------------------------------------------------- case CoshOp: // sinh(x), cosh(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_cosh_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- case CSkipOp: // CSkipOp has a variable number of arguments and // forward_next thinks it has no arguments. // we must inform forward_next of this special case. forward_cskip_op_0( i_var, arg, num_par, parameter, J, taylor, cskip_op ); play->forward_cskip(op, arg, i_op, i_var); break; // ------------------------------------------------- case CSumOp: // CSumOp has a variable number of arguments and // forward_next thinks it has no arguments. // we must inform forward_next of this special case. forward_csum_op( 0, 0, i_var, arg, num_par, parameter, J, taylor ); play->forward_csum(op, arg, i_op, i_var); break; // ------------------------------------------------- case DisOp: forward_dis_op(p, q, r, i_var, arg, J, taylor); break; // ------------------------------------------------- case DivvvOp: forward_divvv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case DivpvOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); forward_divpv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case DivvpOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); forward_divvp_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case EndOp: CPPAD_ASSERT_NARG_NRES(op, 0, 0); more_operators = false; break; // ------------------------------------------------- case EqpvOp: if( compare_change_count ) { forward_eqpv_op_0( compare_change_number, arg, parameter, J, taylor ); { if( compare_change_count == compare_change_number ) compare_change_op_index = i_op; } } break; // ------------------------------------------------- case EqvvOp: if( compare_change_count ) { forward_eqvv_op_0( compare_change_number, arg, parameter, J, taylor ); { if( compare_change_count == compare_change_number ) compare_change_op_index = i_op; } } break; // ------------------------------------------------- # if CPPAD_USE_CPLUSPLUS_2011 case ErfOp: forward_erf_op_0(i_var, arg, parameter, J, taylor); break; # endif // ------------------------------------------------- case ExpOp: forward_exp_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- # if CPPAD_USE_CPLUSPLUS_2011 case Expm1Op: forward_expm1_op_0(i_var, arg[0], J, taylor); break; # endif // ------------------------------------------------- case InvOp: CPPAD_ASSERT_NARG_NRES(op, 0, 1); break; // --------------------------------------------------- case LdpOp: forward_load_p_op_0( play, i_var, arg, parameter, J, taylor, isvar_by_ind.data(), index_by_ind.data(), var_by_load_op.data() ); break; // ------------------------------------------------- case LdvOp: forward_load_v_op_0( play, i_var, arg, parameter, J, taylor, isvar_by_ind.data(), index_by_ind.data(), var_by_load_op.data() ); break; // ------------------------------------------------- case LepvOp: if( compare_change_count ) { forward_lepv_op_0( compare_change_number, arg, parameter, J, taylor ); { if( compare_change_count == compare_change_number ) compare_change_op_index = i_op; } } break; // ------------------------------------------------- case LevpOp: if( compare_change_count ) { forward_levp_op_0( compare_change_number, arg, parameter, J, taylor ); { if( compare_change_count == compare_change_number ) compare_change_op_index = i_op; } } break; // ------------------------------------------------- case LevvOp: if( compare_change_count ) { forward_levv_op_0( compare_change_number, arg, parameter, J, taylor ); { if( compare_change_count == compare_change_number ) compare_change_op_index = i_op; } } break; // ------------------------------------------------- case LogOp: forward_log_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- # if CPPAD_USE_CPLUSPLUS_2011 case Log1pOp: forward_log1p_op_0(i_var, arg[0], J, taylor); break; # endif // ------------------------------------------------- case LtpvOp: if( compare_change_count ) { forward_ltpv_op_0( compare_change_number, arg, parameter, J, taylor ); { if( compare_change_count == compare_change_number ) compare_change_op_index = i_op; } } break; // ------------------------------------------------- case LtvpOp: if( compare_change_count ) { forward_ltvp_op_0( compare_change_number, arg, parameter, J, taylor ); { if( compare_change_count == compare_change_number ) compare_change_op_index = i_op; } } break; // ------------------------------------------------- case LtvvOp: if( compare_change_count ) { forward_ltvv_op_0( compare_change_number, arg, parameter, J, taylor ); { if( compare_change_count == compare_change_number ) compare_change_op_index = i_op; } } break; // ------------------------------------------------- case MulpvOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); forward_mulpv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case MulvvOp: forward_mulvv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case NepvOp: if( compare_change_count ) { forward_nepv_op_0( compare_change_number, arg, parameter, J, taylor ); { if( compare_change_count == compare_change_number ) compare_change_op_index = i_op; } } break; // ------------------------------------------------- case NevvOp: if( compare_change_count ) { forward_nevv_op_0( compare_change_number, arg, parameter, J, taylor ); { if( compare_change_count == compare_change_number ) compare_change_op_index = i_op; } } break; // ------------------------------------------------- case ParOp: forward_par_op_0( i_var, arg, num_par, parameter, J, taylor ); break; // ------------------------------------------------- case PowvpOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); forward_powvp_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case PowpvOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); forward_powpv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case PowvvOp: forward_powvv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case PriOp: if( print ) forward_pri_0(s_out, arg, num_text, text, num_par, parameter, J, taylor ); break; // ------------------------------------------------- case SignOp: // cos(x), sin(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_sign_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- case SinOp: // cos(x), sin(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_sin_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- case SinhOp: // cosh(x), sinh(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_sinh_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- case SqrtOp: forward_sqrt_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- case StppOp: forward_store_pp_op_0( i_var, arg, num_par, J, taylor, isvar_by_ind.data(), index_by_ind.data() ); break; // ------------------------------------------------- case StpvOp: forward_store_pv_op_0( i_var, arg, num_par, J, taylor, isvar_by_ind.data(), index_by_ind.data() ); break; // ------------------------------------------------- case StvpOp: forward_store_vp_op_0( i_var, arg, num_par, J, taylor, isvar_by_ind.data(), index_by_ind.data() ); break; // ------------------------------------------------- case StvvOp: forward_store_vv_op_0( i_var, arg, num_par, J, taylor, isvar_by_ind.data(), index_by_ind.data() ); break; // ------------------------------------------------- case SubvvOp: forward_subvv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case SubpvOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); forward_subpv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case SubvpOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); forward_subvp_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case TanOp: // tan(x)^2, tan(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_tan_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- case TanhOp: // tanh(x)^2, tanh(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_tanh_op_0(i_var, arg[0], J, taylor); break; // ------------------------------------------------- case UserOp: // start or end an atomic operation sequence flag = user_state == start_user; user_atom = play->forward_user(op, user_state, user_old, user_m, user_n, user_i, user_j ); if( flag ) { user_tx.resize(user_n); user_ty.resize(user_m); # if CPPAD_FORWARD0SWEEP_TRACE user_iy.resize(user_m); # endif } else { # ifndef NDEBUG if( ! user_ok ) { std::string msg = user_atom->afun_name() + ": atomic_base.forward: returned false"; CPPAD_ASSERT_KNOWN(false, msg.c_str() ); } # endif # if CPPAD_FORWARD0SWEEP_TRACE user_trace = true; # endif } break; case UsrapOp: // parameter argument in an atomic operation sequence CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); user_tx[user_j] = parameter[ arg[0] ]; play->forward_user(op, user_state, user_old, user_m, user_n, user_i, user_j ); if( user_j == user_n ) { // call users function for this operation user_atom->set_old(user_old); CPPAD_ATOMIC_CALL(p, q, user_vx, user_vy, user_tx, user_ty ); } break; case UsravOp: // variable argument in an atomic operation sequence CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var ); user_tx[user_j] = taylor[ arg[0] * J + 0 ]; play->forward_user(op, user_state, user_old, user_m, user_n, user_i, user_j ); if( user_j == user_n ) { // call users function for this operation user_atom->set_old(user_old); CPPAD_ATOMIC_CALL(p, q, user_vx, user_vy, user_tx, user_ty ); } break; case UsrrpOp: // parameter result in an atomic operation sequence # if CPPAD_FORWARD0SWEEP_TRACE user_iy[user_i] = 0; # endif play->forward_user(op, user_state, user_old, user_m, user_n, user_i, user_j ); break; case UsrrvOp: // variable result in an atomic operation sequence # if CPPAD_FORWARD0SWEEP_TRACE user_iy[user_i] = i_var; # endif taylor[ i_var * J + 0 ] = user_ty[user_i]; play->forward_user(op, user_state, user_old, user_m, user_n, user_i, user_j ); break; // ------------------------------------------------- case ZmulpvOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); forward_zmulpv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case ZmulvpOp: CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); forward_zmulvp_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- case ZmulvvOp: forward_zmulvv_op_0(i_var, arg, parameter, J, taylor); break; // ------------------------------------------------- default: CPPAD_ASSERT_UNKNOWN(false); } # if CPPAD_FORWARD0SWEEP_TRACE size_t d = 0; if( user_trace ) { user_trace = false; CPPAD_ASSERT_UNKNOWN( op == UserOp ); CPPAD_ASSERT_UNKNOWN( NumArg(UsrrvOp) == 0 ); for(size_t i = 0; i < user_m; i++) if( user_iy[i] > 0 ) { size_t i_tmp = (i_op + i) - user_m; printOp( std::cout, play, i_tmp, user_iy[i], UsrrvOp, CPPAD_NULL ); Base* Z_tmp = taylor + user_iy[i] * J; printOpResult( std::cout, d + 1, Z_tmp, 0, (Base *) CPPAD_NULL ); std::cout << std::endl; } } Base* Z_tmp = taylor + i_var * J; const addr_t* arg_tmp = arg; if( op == CSumOp ) arg_tmp = arg - arg[-1] - 4; if( op == CSkipOp ) arg_tmp = arg - arg[-1] - 7; if( op != UsrrvOp ) { printOp( std::cout, play, i_op, i_var, op, arg_tmp ); if( NumRes(op) > 0 ) printOpResult( std::cout, d + 1, Z_tmp, 0, (Base *) CPPAD_NULL ); std::cout << std::endl; } } std::cout << std::endl; # else }
size_t forward0sweep( bool print, size_t n, size_t numvar, player<Base> *Rec, size_t J, Base *Taylor ) { CPPAD_ASSERT_UNKNOWN( J >= 1 ); // op code for current instruction OpCode op; // index for current instruction size_t i_op; // next variables size_t i_var; // constant and non-constant version of the operation argument indices size_t* non_const_arg; const size_t *arg = 0; // initialize the comparision operator (ComOp) counter size_t compareCount = 0; // This is an order zero calculation, initialize vector indices size_t *VectorInd = CPPAD_NULL; // address for each element bool *VectorVar = CPPAD_NULL; // is element a variable size_t i = Rec->num_rec_vecad_ind(); if( i > 0 ) { VectorInd = CPPAD_TRACK_NEW_VEC(i, VectorInd); VectorVar = CPPAD_TRACK_NEW_VEC(i, VectorVar); while(i--) { VectorInd[i] = Rec->GetVecInd(i); VectorVar[i] = false; } } // check numvar argument CPPAD_ASSERT_UNKNOWN( Rec->num_rec_var() == numvar ); // length of the parameter vector (used by CppAD assert macros) const size_t num_par = Rec->num_rec_par(); // length of the text vector (used by CppAD assert macros) const size_t num_text = Rec->num_rec_text(); // pointer to the beginning of the parameter vector const Base* parameter = CPPAD_NULL; if( num_par > 0 ) parameter = Rec->GetPar(); // pointer to the beginning of the text vector const char* text = CPPAD_NULL; if( num_text > 0 ) text = Rec->GetTxt(0); // skip the BeginOp at the beginning of the recording Rec->start_forward(op, arg, i_op, i_var); CPPAD_ASSERT_UNKNOWN( op == BeginOp ); # if CPPAD_FORWARD0SWEEP_TRACE std::cout << std::endl; # endif while(op != EndOp) { // this op Rec->next_forward(op, arg, i_op, i_var); # ifndef NDEBUG if( i_op <= n ) { CPPAD_ASSERT_UNKNOWN((op == InvOp) | (op == BeginOp)); } else CPPAD_ASSERT_UNKNOWN((op != InvOp) & (op != BeginOp)); # endif // action to take depends on the case switch( op ) { case AbsOp: forward_abs_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case AddvvOp: forward_addvv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case AddpvOp: CPPAD_ASSERT_UNKNOWN( arg[0] < num_par ); forward_addpv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case AcosOp: // results: sqrt(1 - x * x), acos(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_acos_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case AsinOp: // results: sqrt(1 - x * x), asin(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_asin_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case AtanOp: // results: 1 + x * x, atan(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_atan_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case CSumOp: // CSumOp has a variable number of arguments and // next_forward thinks it one has one argument. // we must inform next_forward of this special case. Rec->forward_csum(op, arg, i_op, i_var); forward_csum_op( 0, i_var, arg, num_par, parameter, J, Taylor ); break; // ------------------------------------------------- case CExpOp: // Use the general case with d == 0 // (could create an optimzied verison for this case) forward_cond_op_0( i_var, arg, num_par, parameter, J, Taylor ); break; // --------------------------------------------------- case ComOp: forward_comp_op_0( compareCount, arg, num_par, parameter, J, Taylor ); break; // --------------------------------------------------- case CosOp: // results: sin(x), cos(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_cos_op_0(i_var, arg[0], J, Taylor); break; // --------------------------------------------------- case CoshOp: // variables: sinh(x), cosh(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_cosh_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case DisOp: forward_dis_op_0(i_var, arg, J, Taylor); break; // ------------------------------------------------- case DivvvOp: forward_divvv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case DivpvOp: CPPAD_ASSERT_UNKNOWN( arg[0] < num_par ); forward_divpv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case DivvpOp: CPPAD_ASSERT_UNKNOWN( arg[1] < num_par ); forward_divvp_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case EndOp: CPPAD_ASSERT_NARG_NRES(op, 0, 0); break; // ------------------------------------------------- case ExpOp: forward_exp_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case InvOp: break; // ------------------------------------------------- case LdpOp: CPPAD_ASSERT_UNKNOWN( VectorInd != CPPAD_NULL ); CPPAD_ASSERT_UNKNOWN( VectorVar != CPPAD_NULL ); non_const_arg = Rec->forward_non_const_arg(); forward_load_p_op_0( i_var, non_const_arg, num_par, parameter, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar, VectorInd ); break; // ------------------------------------------------- case LdvOp: CPPAD_ASSERT_UNKNOWN( VectorInd != CPPAD_NULL ); CPPAD_ASSERT_UNKNOWN( VectorVar != CPPAD_NULL ); non_const_arg = Rec->forward_non_const_arg(); forward_load_v_op_0( i_var, non_const_arg, num_par, parameter, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar, VectorInd ); break; // ------------------------------------------------- case LogOp: forward_log_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case MulvvOp: forward_mulvv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case MulpvOp: CPPAD_ASSERT_UNKNOWN( arg[0] < num_par ); forward_mulpv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case ParOp: forward_par_op_0( i_var, arg, num_par, parameter, J, Taylor ); break; // ------------------------------------------------- case PowvpOp: CPPAD_ASSERT_UNKNOWN( arg[1] < num_par ); forward_powvp_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case PowpvOp: CPPAD_ASSERT_UNKNOWN( arg[0] < num_par ); forward_powpv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case PowvvOp: forward_powvv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case PripOp: if( print ) forward_prip_0( arg, num_text, text, num_par, parameter ); break; // ------------------------------------------------- case PrivOp: if( print ) forward_priv_0( i_var, arg, num_text, text, J, Taylor ); break; // ------------------------------------------------- case SinOp: // variables: cos(x), sin(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_sin_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case SinhOp: // variables: cosh(x), sinh(x) CPPAD_ASSERT_UNKNOWN( i_var < numvar ); forward_sinh_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case SqrtOp: forward_sqrt_op_0(i_var, arg[0], J, Taylor); break; // ------------------------------------------------- case StppOp: forward_store_pp_op_0( i_var, arg, num_par, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar, VectorInd ); break; // ------------------------------------------------- case StpvOp: forward_store_pv_op_0( i_var, arg, num_par, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar, VectorInd ); break; // ------------------------------------------------- case StvpOp: forward_store_vp_op_0( i_var, arg, num_par, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar, VectorInd ); break; // ------------------------------------------------- case StvvOp: forward_store_vv_op_0( i_var, arg, num_par, J, Taylor, Rec->num_rec_vecad_ind(), VectorVar, VectorInd ); break; // ------------------------------------------------- case SubvvOp: forward_subvv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case SubpvOp: CPPAD_ASSERT_UNKNOWN( arg[0] < num_par ); forward_subpv_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- case SubvpOp: CPPAD_ASSERT_UNKNOWN( arg[1] < num_par ); forward_subvp_op_0(i_var, arg, parameter, J, Taylor); break; // ------------------------------------------------- default: CPPAD_ASSERT_UNKNOWN(0); } # if CPPAD_FORWARD0SWEEP_TRACE size_t d = 0; size_t i_tmp = i_var; Base* Z_tmp = Taylor + i_var * J; printOp( std::cout, Rec, i_tmp, op, arg, d + 1, Z_tmp, 0, (Base *) CPPAD_NULL ); } std::cout << std::endl; # else }