static int xconvert(const char* x, pod_vector<T>& out, const char** errPos, int sep) { if (sep == 0) { sep = Potassco::def_sep; } typename pod_vector<T>::size_type sz = out.size(); std::size_t t = Potassco::convert_seq<T>(x, out.max_size() - sz, std::back_inserter(out), static_cast<char>(sep), errPos); if (!t) { out.resize(sz); } return static_cast<int>(t); }
void reverse_cskip( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op_ == op ); CPPAD_ASSERT_UNKNOWN( op_arg == op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_index == op_index_ ); CPPAD_ASSERT_UNKNOWN( var_index == var_index_ ); CPPAD_ASSERT_UNKNOWN( op == CSkipOp ); CPPAD_ASSERT_UNKNOWN( NumArg(CSkipOp) == 0 ); /* The variables that need fixing are op_arg_ and op_arg. Currently, op_arg points first arugment for the previous operator. */ --op_arg; op_arg = op_arg_ -= (op_arg[0] + 4); CPPAD_ASSERT_UNKNOWN( op_arg[1] + op_arg[2] == op_arg[ 3 + op_arg[1] + op_arg[2] ] ); CPPAD_ASSERT_UNKNOWN( op_index_ < op_rec_.size() ); CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_var_rec_ ); }
/// Approximate amount of memory used by the recording size_t Memory(void) const { return op_rec_.capacity() * sizeof(CPPAD_OP_CODE_TYPE) + vecad_ind_rec_.capacity() * sizeof(size_t) + op_arg_rec_.capacity() * sizeof(addr_t) + par_rec_.capacity() * sizeof(Base) + text_rec_.capacity() * sizeof(char); }
void reverse_csum( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op_ == op ); CPPAD_ASSERT_UNKNOWN( op_arg == op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_index == op_index_ ); CPPAD_ASSERT_UNKNOWN( var_index == var_index_ ); CPPAD_ASSERT_UNKNOWN( op == CSumOp ); CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 ); /* The variables that need fixing are op_arg_ and op_arg. Currently, op_arg points to the last argument for the previous operator. */ // last argument for this csum operation --op_arg; // first argument for this csum operation op_arg = op_arg_ -= (op_arg[0] + 4); // now op_arg points to the first argument for this csum operator CPPAD_ASSERT_UNKNOWN( op_arg[0] + op_arg[1] == op_arg[ 3 + op_arg[0] + op_arg[1] ] ); CPPAD_ASSERT_UNKNOWN( op_index_ < op_rec_.size() ); CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_var_rec_ ); }
/*! Fetch the next operator during a reverse sweep. Use reverse_start to initialize to reverse play back. The first call to reverse_next (after reverse_start) will give the last operator in the recording. We use the notation reverse_routine to denote the set reverse_start, reverse_next, reverse_csum, reverse_cskip. \param op [in,out] The input value of \c op must be its output value from the previous call to a reverse_routine. Its output value is the next operator in the recording (in reverse order). The last operator sets op equal to EndOp. \param op_arg [in,out] The input value of \c op_arg must be its output value from the previous call to a reverse_routine. Its output value is the beginning of the vector of argument indices for this operation. The last operator sets op_arg equal to the beginning of the argument indices for the entire recording. For speed, \c reverse_next does not check for the special cases <tt>op == CSumOp</tt> or <tt>op == CSkipOp</tt>. In these cases, the other return values from \c reverse_next must be corrected by a call to \c reverse_csum or \c reverse_cskip respectively. \param op_index [in,out] The input value of \c op_index must be its output value from the previous call to a reverse_routine. Its output value is the index of this operator in the recording. Thus the output value following the previous call to reverse_start is equal to the number of variables in the recording minus one. In addition, the output value decreases by one with each call to reverse_next. The last operator sets op_index equal to 0. \param var_index [in,out] The input value of \c var_index must be its output value from the previous call to a reverse_routine. Its output value is the index of the primary (last) result corresponding to the operator op. The last operator sets var_index equal to 0 (corresponding to BeginOp at beginning of operation sequence). */ void reverse_next( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op_ == op ); CPPAD_ASSERT_UNKNOWN( op_arg == op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_index == op_index_ ); CPPAD_ASSERT_UNKNOWN( var_index == var_index_ ); // index of the last result for the next operator CPPAD_ASSERT_UNKNOWN( var_index_ >= NumRes(op_) ); var_index = var_index_ -= NumRes(op_); // next operator CPPAD_ASSERT_UNKNOWN( op_index_ > 0 ); op_index = --op_index_; // index op = op_ = OpCode( op_rec_[ op_index_ ] ); // value // first argument for next operator op_arg = op_arg_ -= NumArg(op); CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= op_arg_rec_.data() + op_arg_rec_.size() ); }
/*! Correct \c forward_next return values when <tt>op == CSkipOp</tt>. \param op [in] The input value of op must be the return value from the previous call to \c forward_next and must be \c CSkipOp. It is not modified. \param op_arg [in,out] The input value of \c op_arg must be the return value from the previous call to \c forward_next. Its output value is the beginning of the vector of argument indices for the next operation. \param op_index [in] The input value of \c op_index does must be the return value from the previous call to \c forward_next. Its is not modified. \param var_index [in,out] The input value of \c var_index must be the return value from the previous call to \c forward_next. It is not modified. */ void forward_cskip( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op_ == op ); CPPAD_ASSERT_UNKNOWN( op_arg == op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_index == op_index_ ); CPPAD_ASSERT_UNKNOWN( var_index == var_index_ ); CPPAD_ASSERT_UNKNOWN( op == CSkipOp ); CPPAD_ASSERT_UNKNOWN( NumArg(CSkipOp) == 0 ); CPPAD_ASSERT_UNKNOWN( op_arg[4] + op_arg[5] == op_arg[ 6 + op_arg[4] + op_arg[5] ] ); /* The only thing that really needs fixing is op_arg_. Actual number of arugments for this operator is 7 + op_arg[4] + op_arg[5] We must change op_arg_ so that when you add NumArg(CSkipOp) you get first argument for next operator in sequence. */ op_arg = op_arg_ += 7 + op_arg[4] + op_arg[5]; CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= op_arg_rec_.data() + op_arg_rec_.size() ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_var_rec_ ); }
/// Approximate amount of memory used by the recording size_t Memory(void) const { return rec_op_.capacity() * sizeof(CPPAD_OP_CODE_TYPE) + rec_vecad_ind_.capacity() * sizeof(size_t) + rec_op_arg_.capacity() * sizeof(addr_t) + rec_par_.capacity() * sizeof(Base) + rec_text_.capacity() * sizeof(char); }
/*! Change number of sets, set end, and initialize all sets as empty If \c n_set_in is zero, any memory currently allocated for this object is freed. Otherwise, new memory may be allocated for the sets (if needed). \param n_set_in is the number of sets in this vector of sets. \param end_in is the maximum element plus one (the minimum element is 0). */ void resize(size_t n_set_in, size_t end_in) { n_set_ = n_set_in; end_ = end_in; if( n_set_ == 0 ) { data_.free(); return; } // now start a new vector with empty sets Pack zero(0); data_.erase(); n_pack_ = ( 1 + (end_ - 1) / n_bit_ ); size_t i = n_set_ * n_pack_; if( i > 0 ) { data_.extend(i); while(i--) data_[i] = zero; } // values that signify past end of list next_index_ = n_set_; next_element_ = end_; }
/*! Fetch the next operator during a forward sweep. Use forward_start to initialize to the first operator; i.e., the BeginOp at the beginning of the recording. We use the notation forward_routine to denote the set forward_start, forward_next, forward_csum, forward_cskip. \param op [in,out] The input value of \c op must be its output value from the previous call to a forward_routine. Its output value is the next operator in the recording. For speed, \c forward_next does not check for the special cases where <tt>op == CSumOp</tt> or <tt>op == CSkipOp</tt>. In these cases, the other return values from \c forward_next must be corrected by a call to \c forward_csum or \c forward_cskip respectively. \param op_arg [in,out] The input value of \c op_arg must be its output value form the previous call to a forward routine. Its output value is the beginning of the vector of argument indices for this operation. \param op_index [in,out] The input value of \c op_index must be its output value form the previous call to a forward routine. Its output value is the index of the next operator in the recording. Thus the ouput value following the previous call to forward_start is one. In addition, the output value increases by one with each call to forward_next. \param var_index [in,out] The input value of \c var_index must be its output value form the previous call to a forward routine. Its output value is the index of the primary (last) result corresponding to the operator op. */ void forward_next( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op_ == op ); CPPAD_ASSERT_UNKNOWN( op_arg == op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_index == op_index_ ); CPPAD_ASSERT_UNKNOWN( var_index == var_index_ ); // index for the next operator op_index = ++op_index_; // first argument for next operator op_arg = op_arg_ += NumArg(op_); // next operator op = op_ = OpCode( op_rec_[ op_index_ ] ); // index for last result for next operator var_index = var_index_ += NumRes(op); CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= op_arg_rec_.data() + op_arg_rec_.size() ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_var_rec_ ); }
/// Fetch a rough measure of amount of memory used to store recording /// (just lengths, not capacities). size_t Memory(void) const { return rec_op_.size() * sizeof(OpCode) + rec_op_arg_.size() * sizeof(addr_t) + rec_par_.size() * sizeof(Base) + rec_text_.size() * sizeof(char) + rec_vecad_ind_.size() * sizeof(addr_t) ; }
/// Fetch a rough measure of amount of memory used to store recording /// (just lengths, not capacities). size_t Memory(void) const { return op_rec_.size() * sizeof(OpCode) + op_arg_rec_.size() * sizeof(addr_t) + par_rec_.size() * sizeof(Base) + text_rec_.size() * sizeof(char) + vecad_ind_rec_.size() * sizeof(addr_t) ; }
/*! Frees all information in recording. Frees the operation sequence store in this recording (the operation sequence is empty after this operation). The buffers used to store the current recording are returned to the system (so as to conserve on memory). */ void free(void) { num_rec_var_ = 0; rec_op_.free(); rec_vecad_ind_.free(); rec_op_arg_.free(); rec_par_.free(); rec_text_.free(); }
/*! Frees all information in recording. Frees the operation sequence store in this recording (the operation sequence is empty after this operation). The buffers used to store the current recording are returned to the system (so as to conserve on memory). */ void free(void) { num_var_rec_ = 0; num_load_op_rec_ = 0; op_rec_.free(); vecad_ind_rec_.free(); op_arg_rec_.free(); par_rec_.free(); text_rec_.free(); }
void reverse_start( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { op_arg = op_arg_ = op_arg_rec_.data() + op_arg_rec_.size(); op_index = op_index_ = op_rec_.size() - 1; var_index = var_index_ = num_var_rec_ - 1; op = op_ = OpCode( op_rec_[ op_index_ ] ); CPPAD_ASSERT_UNKNOWN( op_ == EndOp ); CPPAD_ASSERT_NARG_NRES(op, 0, 0); return; }
/// Erase all information in an operation sequence player. void Erase(void) { num_rec_var_ = 0; num_rec_vecad_vec_ = 0; rec_op_.erase(); rec_vecad_ind_.erase(); rec_op_arg_.erase(); rec_par_.erase(); rec_text_.erase(); }
/// Erase all information in an operation sequence player. void Erase(void) { num_var_rec_ = 0; num_load_op_rec_ = 0; num_vecad_vec_rec_ = 0; op_rec_.erase(); vecad_ind_rec_.erase(); op_arg_rec_.erase(); par_rec_.erase(); text_rec_.erase(); }
void start_reverse( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { op_arg_ = rec_op_arg_.size(); // index op_arg = op_arg_ + rec_op_arg_.data(); // pointer op_index = op_index_ = rec_op_.size() - 1; var_index = var_index_ = num_rec_var_ - 1; op = op_ = OpCode( rec_op_[ op_index_ ] ); CPPAD_ASSERT_UNKNOWN( op_ == EndOp ); CPPAD_ASSERT_NARG_NRES(op, 0, 0); return; }
void get_internal_sparsity( bool transpose , const pod_vector<size_t>& internal_index , const InternalSparsity& internal_pattern , vector<bool>& pattern_out ) { typedef typename InternalSparsity::const_iterator iterator; // number variables size_t nr = internal_index.size(); // // column size of interanl sparstiy pattern size_t nc = internal_pattern.end(); // pattern_out.resize(nr * nc); for(size_t ij = 0; ij < nr * nc; ij++) pattern_out[ij] = false; // for(size_t i = 0; i < nr; i++) { CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() ); iterator itr(internal_pattern, internal_index[i]); size_t j = *itr; while( j < nc ) { if( transpose ) pattern_out[j * nr + i] = true; else pattern_out[i * nc + j] = true; j = *(++itr); } } return; }
void get_internal_sparsity( bool transpose , const pod_vector<size_t>& internal_index , const InternalSparsity& internal_pattern , vector< std::set<size_t> >& pattern_out ) { typedef typename InternalSparsity::const_iterator iterator; // number variables size_t nr = internal_index.size(); // // column size of interanl sparstiy pattern size_t nc = internal_pattern.end(); // if( transpose ) pattern_out.resize(nc); else pattern_out.resize(nr); for(size_t k = 0; k < pattern_out.size(); k++) pattern_out[k].clear(); // for(size_t i = 0; i < nr; i++) { CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() ); iterator itr(internal_pattern, internal_index[i]); size_t j = *itr; while( j < nc ) { if( transpose ) pattern_out[j].insert(i); else pattern_out[i].insert(j); j = *(++itr); } } return; }
/*! Moving an operation sequence from a recorder to a player \param rec the object that was used to record the operation sequence. After this operation, the state of the recording is no longer defined. For example, the \c pod_vector member variables in \c this have been swapped with \c rec . */ void get(recorder<Base>& rec) { size_t i; // just set size_t values num_var_rec_ = rec.num_var_rec_; num_load_op_rec_ = rec.num_load_op_rec_; // op_rec_ op_rec_.swap(rec.op_rec_); // vec_ind_rec_ vecad_ind_rec_.swap(rec.vecad_ind_rec_); // op_arg_rec_ op_arg_rec_.swap(rec.op_arg_rec_); // par_rec_ par_rec_.swap(rec.par_rec_); // text_rec_ text_rec_.swap(rec.text_rec_); // set the number of VecAD vectors num_vecad_vec_rec_ = 0; for(i = 0; i < vecad_ind_rec_.size(); i += vecad_ind_rec_[i] + 1) num_vecad_vec_rec_++; // vecad_ind_rec_ contains size of each VecAD followed by // the parameter indices used to iniialize it. CPPAD_ASSERT_UNKNOWN( i == vecad_ind_rec_.size() ); }
/*! Moving an operation sequence from a recorder to a player \param rec the object that was used to record the operation sequence. After this operation, the state of the recording is no longer defined. For example, the \c pod_vector member variables in \c this have been swapped with \c rec . */ void get(recorder<Base>& rec) { size_t i; // Var num_rec_var_ = rec.num_rec_var_; // Op rec_op_.swap(rec.rec_op_); // VecInd rec_vecad_ind_.swap(rec.rec_vecad_ind_); // Arg rec_op_arg_.swap(rec.rec_op_arg_); // Par rec_par_.swap(rec.rec_par_); // Txt rec_text_.swap(rec.rec_text_); // set the number of VecAD vectors num_rec_vecad_vec_ = 0; for(i = 0; i < rec_vecad_ind_.size(); i += rec_vecad_ind_[i] + 1) num_rec_vecad_vec_++; // rec_vecad_ind_ contains size of each VecAD followed by // the parameter indices used to iniialize it. CPPAD_ASSERT_UNKNOWN( i == rec_vecad_ind_.size() ); }
/*! Change number of sets, set end, and initialize all sets as empty Any memory currently allocated for this object is freed. If both \a n_set_in and \a end_in are non-zero new memory is allocated, otherwise no new memory is allocated for the object. \param n_set_in is the number of sets in this vector of sets. \param end_in is the maximum element plus one (the minimum element is 0). */ void resize(size_t n_set_in, size_t end_in) { Pack zero(0); data_.erase(); n_set_ = n_set_in; end_ = end_in; n_pack_ = ( 1 + (end_ - 1) / n_bit_ ); size_t i = n_set_ * n_pack_; if( i > 0 ) { data_.extend(i); while(i--) data_[i] = zero; } // values that signify past end of list next_index_ = n_set_; next_element_ = end_; }
void reverse_csum( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op == CSumOp ); CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 ); /* The things needs fixing are op_arg_ and op_arg. Currently, op_arg points first arugment for the previous operator. */ --op_arg; op_arg_ -= (op_arg[0] + 4); op_arg = op_arg_ + rec_op_arg_.data(); CPPAD_ASSERT_UNKNOWN( op_arg[0] + op_arg[1] == op_arg[ 3 + op_arg[0] + op_arg[1] ] ); CPPAD_ASSERT_UNKNOWN( op_index_ < rec_op_.size() ); CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= rec_op_arg_.size() ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_rec_var_ ); }
void next_forward( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; // index for the next operator op_index = ++op_index_; // first argument for next operator op_arg_ += NumArg(op_); // index op_arg = op_arg_ + rec_op_arg_.data(); // pointer // next operator op = op_ = OpCode( rec_op_[ op_index_ ] ); // index for last result for next operator var_index = var_index_ += NumRes(op); CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= rec_op_arg_.size() ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_rec_var_ ); }
void set_internal_sparsity( bool zero_empty , bool input_empty , bool transpose , const pod_vector<size_t>& internal_index , InternalSparsity& internal_pattern , const vector< std::set<size_t> >& pattern_in ) { size_t nr = internal_index.size(); size_t nc = internal_pattern.end(); # ifndef NDEBUG if( input_empty ) for(size_t i = 0; i < nr; i++) { size_t i_var = internal_index[i]; CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 ); } # endif if( transpose ) { CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nc ); for(size_t j = 0; j < nc; j++) { std::set<size_t>::const_iterator itr( pattern_in[j].begin() ); while( itr != pattern_in[j].end() ) { size_t i = *itr; size_t i_var = internal_index[i]; CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); CPPAD_ASSERT_UNKNOWN( j < nc ); bool ignore = zero_empty && i_var == 0; if( ! ignore ) internal_pattern.post_element( i_var, j); ++itr; } } } else { CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nr ); for(size_t i = 0; i < nr; i++) { std::set<size_t>::const_iterator itr( pattern_in[i].begin() ); while( itr != pattern_in[i].end() ) { size_t j = *itr; size_t i_var = internal_index[i]; CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); CPPAD_ASSERT_UNKNOWN( j < nc ); bool ignore = zero_empty && i_var == 0; if( ! ignore ) internal_pattern.post_element( i_var, j); ++itr; } } } // process posts for(size_t i = 0; i < nr; ++i) internal_pattern.process_post( internal_index[i] ); return; }
/*! Start a play back of the recording during a forward sweep. Use repeated calls to forward_next to play back one operator at a time. \param op [out] The input value of \c op does not matter. Its output value is the first operator in the recording; i.e., BeginOp. \param op_arg [out] The input value of \c op_arg does not matter. Its output value is the beginning of the vector of argument indices for the first operation; i.e., 0 \param op_index [out] The input value of \c op_index does not matter. Its output value is the index of the next first operator in the recording; i.e., 0. \param var_index [out] The input value of \c var_index does not matter. Its output value is the index of the primary (last) result corresponding to the the first operator (which must be a BeginOp); i.e., 0. */ void forward_start( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { op = op_ = OpCode( op_rec_[0] ); op_arg = op_arg_ = op_arg_rec_.data(); op_index = op_index_ = 0; var_index = var_index_ = 0; CPPAD_ASSERT_UNKNOWN( op_ == BeginOp ); CPPAD_ASSERT_NARG_NRES(op_, 1, 1); return; }
void get_internal_sparsity( bool transpose , const pod_vector<size_t>& internal_index , const InternalSparsity& internal_pattern , sparse_rc<SizeVector>& pattern_out ) { typedef typename InternalSparsity::const_iterator iterator; // number variables size_t nr = internal_index.size(); // column size of interanl sparstiy pattern size_t nc = internal_pattern.end(); // determine nnz, the number of possibly non-zero index pairs size_t nnz = 0; for(size_t i = 0; i < nr; i++) { CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() ); iterator itr(internal_pattern, internal_index[i]); size_t j = *itr; while( j < nc ) { ++nnz; j = *(++itr); } } // transposed if( transpose ) { pattern_out.resize(nc, nr, nnz); // size_t k = 0; for(size_t i = 0; i < nr; i++) { iterator itr(internal_pattern, internal_index[i]); size_t j = *itr; while( j < nc ) { pattern_out.set(k++, j, i); j = *(++itr); } } return; } // not transposed pattern_out.resize(nr, nc, nnz); // size_t k = 0; for(size_t i = 0; i < nr; i++) { iterator itr(internal_pattern, internal_index[i]); size_t j = *itr; while( j < nc ) { pattern_out.set(k++, i, j); j = *(++itr); } } return; }
void set_internal_sparsity( bool zero_empty , bool input_empty , bool transpose , const pod_vector<size_t>& internal_index , InternalSparsity& internal_pattern , const sparse_rc<SizeVector>& pattern_in ) { size_t nr = internal_index.size(); # ifndef NDEBUG size_t nc = internal_pattern.end(); if( transpose ) { CPPAD_ASSERT_UNKNOWN( pattern_in.nr() == nc ); CPPAD_ASSERT_UNKNOWN( pattern_in.nc() == nr ); } else { CPPAD_ASSERT_UNKNOWN( pattern_in.nr() == nr ); CPPAD_ASSERT_UNKNOWN( pattern_in.nc() == nc ); } if( input_empty ) for(size_t i = 0; i < nr; i++) { size_t i_var = internal_index[i]; CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 ); } # endif const SizeVector& row( pattern_in.row() ); const SizeVector& col( pattern_in.col() ); size_t nnz = row.size(); for(size_t k = 0; k < nnz; k++) { size_t r = row[k]; size_t c = col[k]; if( transpose ) std::swap(r, c); // size_t i_var = internal_index[r]; CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); CPPAD_ASSERT_UNKNOWN( c < nc ); bool ignore = zero_empty && i_var == 0; if( ! ignore ) internal_pattern.post_element( internal_index[r], c ); } // process posts for(size_t i = 0; i < nr; ++i) internal_pattern.process_post( internal_index[i] ); }
void next_reverse( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; // index of the last result for the next operator CPPAD_ASSERT_UNKNOWN( var_index_ >= NumRes(op_) ); var_index = var_index_ -= NumRes(op_); // next operator CPPAD_ASSERT_UNKNOWN( op_index_ > 0 ); op_index = --op_index_; // index op = op_ = OpCode( rec_op_[ op_index_ ] ); // value // first argument for next operator CPPAD_ASSERT_UNKNOWN( op_arg_ >= NumArg(op) ); op_arg_ -= NumArg(op); // index op_arg = op_arg_ + rec_op_arg_.data(); // pointer }
/*! Correct \c next_forward return values when <tt>op == CSumOp</tt>. \param op The input value of op must be the return value from the previous call to \c next_forward and must be \c CSumOp. \param op_arg The input value of *op_arg must be the return value from the previous call to \c next_forward. Its output value is the beginning of the vector of argument indices for this operation. \param op_index The input value of op_index does must be the return value from the previous call to \c next_forward. Its output value is the index of this operator in the recording. \param var_index The input value of var_index must be the return value from the previous call to \c next_forward. Its output value is the index of the primary (last) result corresponding to this. */ void forward_csum( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op == CSumOp ); CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 ); CPPAD_ASSERT_UNKNOWN( op_arg[0] + op_arg[1] == op_arg[ 3 + op_arg[0] + op_arg[1] ] ); /* The only thing that really needs fixing is op_arg_. Actual number of arugments for this operator is op_arg[0] + op_arg[1] + 4. We must change op_arg_ so that when you add NumArg(CSumOp) you get first argument for next operator in sequence. */ op_arg_ += op_arg[0] + op_arg[1] + 4; CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= rec_op_arg_.size() ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_rec_var_ ); }