void ADTape<Base>::Independent(VectorAD &x) { // check VectorAD is Simple Vector class with AD<Base> elements CheckSimpleVector< AD<Base>, VectorAD>(); // dimension of the domain space size_t n = x.size(); CPPAD_ASSERT_KNOWN( n > 0, "Indepdendent: the argument vector x has zero size" ); CPPAD_ASSERT_UNKNOWN( Rec_.num_rec_var() == 0 ); // mark the beginning of the tape and skip the first variable index // (zero) because parameters use taddr zero CPPAD_ASSERT_NARG_NRES(BeginOp, 0, 1); Rec_.PutOp(BeginOp); // place each of the independent variables in the tape CPPAD_ASSERT_NARG_NRES(InvOp, 0, 1); size_t j; for(j = 0; j < n; j++) { // tape address for this independent variable x[j].taddr_ = Rec_.PutOp(InvOp); x[j].tape_id_ = id_; CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == j+1 ); CPPAD_ASSERT_UNKNOWN( Variable(x[j] ) ); } // done specifying all of the independent variables size_independent_ = n; }
ADFun<Base>::ADFun(const VectorAD &x, const VectorAD &y) { CPPAD_ASSERT_KNOWN( x.size() > 0, "ADFun<Base>: independent variable vector has size zero." ); CPPAD_ASSERT_KNOWN( Variable(x[0]), "ADFun<Base>: independent variable vector has been changed." ); ADTape<Base>* tape = AD<Base>::tape_ptr(x[0].tape_id_); CPPAD_ASSERT_KNOWN( tape->size_independent_ == size_t ( x.size() ), "ADFun<Base>: independent variable vector has been changed." ); size_t j, n = x.size(); # ifndef NDEBUG size_t i, m = y.size(); for(j = 0; j < n; j++) { CPPAD_ASSERT_KNOWN( size_t(x[j].taddr_) == (j+1), "ADFun<Base>: independent variable vector has been changed." ); CPPAD_ASSERT_KNOWN( x[j].tape_id_ == x[0].tape_id_, "ADFun<Base>: independent variable vector has been changed." ); } for(i = 0; i < m; i++) { CPPAD_ASSERT_KNOWN( CppAD::Parameter( y[i] ) | (y[i].tape_id_ == x[0].tape_id_) , "ADFun<Base>: dependent vector contains variables for" "\na different tape than the independent variables." ); } # endif // stop the tape and store the operation sequence Dependent(tape, y); // ad_fun.hpp member values not set by dependent check_for_nan_ = true; // allocate memory for one zero order taylor_ coefficient CPPAD_ASSERT_UNKNOWN( num_order_taylor_ == 0 ); CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == 0 ); size_t c = 1; size_t r = 1; capacity_order(c, r); CPPAD_ASSERT_UNKNOWN( cap_order_taylor_ == c ); CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == r ); // set zero order coefficients corresponding to indpendent variables CPPAD_ASSERT_UNKNOWN( n == ind_taddr_.size() ); for(j = 0; j < n; j++) { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) ); CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == (j+1) ); taylor_[ ind_taddr_[j] ] = x[j].value_; } // use independent variable values to fill in values for others CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() ); CPPAD_ASSERT_UNKNOWN( load_op_.size() == play_.num_load_op_rec() ); forward0sweep(std::cout, false, n, num_var_tape_, &play_, cap_order_taylor_, taylor_.data(), cskip_op_.data(), load_op_, compare_change_count_, compare_change_number_, compare_change_op_index_ ); CPPAD_ASSERT_UNKNOWN( compare_change_count_ == 1 ); CPPAD_ASSERT_UNKNOWN( compare_change_number_ == 0 ); CPPAD_ASSERT_UNKNOWN( compare_change_op_index_ == 0 ); // now set the number of orders stored num_order_taylor_ = 1; # ifndef NDEBUG // on MS Visual Studio 2012, CppAD required in front of isnan ? for(i = 0; i < m; i++) if( taylor_[dep_taddr_[i]] != y[i].value_ || CppAD::isnan( y[i].value_ ) ) { using std::endl; std::ostringstream buf; buf << "A dependent variable value is not equal to " << "its tape evaluation value," << endl << "perhaps it is nan." << endl << "Dependent variable value = " << y[i].value_ << endl << "Tape evaluation value = " << taylor_[dep_taddr_[i]] << endl << "Difference = " << y[i].value_ - taylor_[dep_taddr_[i]] << endl ; CPPAD_ASSERT_KNOWN( 0, buf.str().c_str() ); } # endif }
ADFun<Base>::ADFun(const VectorAD &x, const VectorAD &y) : total_num_var_(0), taylor_(CPPAD_NULL) { CPPAD_ASSERT_KNOWN( x.size() > 0, "ADFun<Base>: independent variable vector has size zero." ); CPPAD_ASSERT_KNOWN( Variable(x[0]), "ADFun<Base>: independent variable vector has been changed." ); ADTape<Base> *tape = AD<Base>::tape_ptr(x[0].id_); CPPAD_ASSERT_KNOWN( tape->size_independent_ == x.size(), "ADFun<Base>: independent variable vector has been changed." ); size_t j, n = x.size(); # ifndef NDEBUG size_t i, m = y.size(); for(j = 0; j < n; j++) { CPPAD_ASSERT_KNOWN( x[j].taddr_ == (j+1), "ADFun<Base>: independent variable vector has been changed." ); CPPAD_ASSERT_KNOWN( x[j].id_ == x[0].id_, "ADFun<Base>: independent variable vector has been changed." ); } for(i = 0; i < m; i++) { CPPAD_ASSERT_KNOWN( CppAD::Parameter( y[i] ) | (y[i].id_ == x[0].id_) , "ADFun<Base>: dependent vector contains variables for" "\na different tape than the independent variables." ); } # endif // stop the tape and store the operation sequence Dependent(tape, y); // allocate memory for one zero order taylor_ coefficient taylor_per_var_ = 1; taylor_col_dim_ = 1; taylor_ = CPPAD_TRACK_NEW_VEC(total_num_var_, taylor_); // set zero order coefficients corresponding to indpendent variables CPPAD_ASSERT_UNKNOWN( n == ind_taddr_.size() ); for(j = 0; j < n; j++) { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) ); CPPAD_ASSERT_UNKNOWN( x[j].taddr_ == (j+1) ); taylor_[ ind_taddr_[j] ] = x[j].value_; } // use independent variable values to fill in values for others # if CPPAD_USE_FORWARD0SWEEP compare_change_ = forward0sweep( false, n, total_num_var_, &play_, taylor_col_dim_, taylor_ ); # else size_t p = 0; compare_change_ = forward_sweep( false, p, n, total_num_var_, &play_, taylor_col_dim_, taylor_ ); # endif CPPAD_ASSERT_UNKNOWN( compare_change_ == 0 ); # ifndef NDEBUG for(i = 0; i < m; i++) if( taylor_[dep_taddr_[i]] != y[i].value_ ) { using std::endl; std::ostringstream buf; buf << "A dependent variable value is not equal to " << "its tape evaluation value," << endl << "perhaps it is nan." << endl << "Dependent variable value = " << y[i].value_ << endl << "Tape evaluation value = " << taylor_[dep_taddr_[i]] << endl << "Difference = " << y[i].value_ - taylor_[dep_taddr_[i]] << endl ; CPPAD_ASSERT_KNOWN( 0, buf.str().c_str() ); } # endif }