/*! Change number of sets, set end, and initialize all sets as empty Any memory currently allocated for this object is freed. If \a n_set is zero, no new memory is allocated for the set. Otherwise, new memory may be allocated for the sets. \param n_set is the number of sets in this vector of sets. \param end is the maximum element plus one (the minimum element is 0). */ void resize(size_t n_set, size_t end) { n_set_ = n_set; end_ = end; // free all memory connected with data_ data_.resize(0); // now start a new vector with empty sets data_.resize(n_set_); // value that signfies past end of list next_index_ = n_set; }
/*! 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 ) { // free all memory connected with data_ data_.clear(); return; } // now start a new vector with empty sets data_.resize(n_set_); // value that signfies past end of list next_index_ = n_set_; }
/*! Create a two vector sparsity representation from a vector of maps. \param sparse Is a vector of maps representation of sparsity as well as the index in the two vector representation. To be specific; \verbatim for(i = 0; i < sparse.size(); i++) { for(itr = sparse[i].begin(); itr != sparse[i].end(); itr++) { j = itr->first; // (i, j) is a possibly non-zero entry in sparsity pattern // k == itr->second, is corresponding index in i_row and j_col k++; } } \endverbatim \param n_nz is the total number of possibly non-zero entries. \param i_row The input size and element values for \c i_row do not matter. On output, it has size \c n_nz and <tt>i_row[k]</tt> contains the row index corresponding to the \c k-th possibly non-zero entry. \param j_col The input size and element values for \c j_col do not matter. On output, it has size \c n_nz and <tt>j_col[k]</tt> contains the column index corresponding to the \c k-th possibly non-zero entry. */ void sparse_map2vec( const CppAD::vector< std::map<size_t, size_t> > sparse, size_t& n_nz , CppAD::vector<size_t>& i_row , CppAD::vector<size_t>& j_col ) { size_t i, j, k, m; // number of rows in sparse m = sparse.size(); // itererator for one row std::map<size_t, size_t>::const_iterator itr; // count the number of possibly non-zeros in sparse n_nz = 0; for(i = 0; i < m; i++) for(itr = sparse[i].begin(); itr != sparse[i].end(); itr++) ++n_nz; // resize the return vectors to accomidate n_nz entries i_row.resize(n_nz); j_col.resize(n_nz); // set the row and column indices and check assumptions on sparse k = 0; for(i = 0; i < m; i++) { for(itr = sparse[i].begin(); itr != sparse[i].end(); itr++) { j = itr->first; CPPAD_ASSERT_UNKNOWN( k == itr->second ); i_row[k] = i; j_col[k] = j; ++k; } } return; }
void do_init(vector<double> x){ UserFunctor<double> f; n=x.size(); m=f(x).size(); UserFunctor<AD<double> > f0; UserFunctor<AD<AD<double> > > f1; UserFunctor<AD<AD<AD<double> > > > f2; UserFunctor<AD<AD<AD<AD<double> > > > > f3; vpf.resize(NTHREADS); for(int thread=0;thread<NTHREADS;thread++){ vpf[thread].resize(4); } cpyADfunPointer(tape_symbol(f0,x), 0); cpyADfunPointer(tape_symbol(f1,x), 1); cpyADfunPointer(tape_symbol(f2,x), 2); cpyADfunPointer(tape_symbol(f3,x), 3); }
void color_general_cppad( const VectorSet& pattern , const VectorSize& row , const VectorSize& col , CppAD::vector<size_t>& color ) { size_t i, j, k, ell, r; size_t K = row.size(); size_t m = pattern.n_set(); size_t n = pattern.end(); CPPAD_ASSERT_UNKNOWN( size_t( col.size() ) == K ); CPPAD_ASSERT_UNKNOWN( size_t( color.size() ) == m ); // We define the set of rows, columns, and pairs that appear // by the set ( row[k], col[k] ) for k = 0, ... , K-1. // initialize rows that appear CppAD::vector<bool> row_appear(m); for(i = 0; i < m; i++) row_appear[i] = false; // rows and columns that appear VectorSet c2r_appear, r2c_appear; c2r_appear.resize(n, m); r2c_appear.resize(m, n); for(k = 0; k < K; k++) { CPPAD_ASSERT_UNKNOWN( pattern.is_element(row[k], col[k]) ); row_appear[ row[k] ] = true; c2r_appear.add_element(col[k], row[k]); r2c_appear.add_element(row[k], col[k]); } // for each column, which rows are non-zero and do not appear VectorSet not_appear; not_appear.resize(n, m); for(i = 0; i < m; i++) { typename VectorSet::const_iterator pattern_itr(pattern, i); j = *pattern_itr; while( j != pattern.end() ) { if( ! c2r_appear.is_element(j , i) ) not_appear.add_element(j, i); j = *(++pattern_itr); } } // initial coloring color.resize(m); ell = 0; for(i = 0; i < m; i++) { if( row_appear[i] ) color[i] = ell++; else color[i] = m; } /* See GreedyPartialD2Coloring Algorithm Section 3.6.2 of Graph Coloring in Optimization Revisited by Assefaw Gebremedhin, Fredrik Maane, Alex Pothen The algorithm above was modified (by Brad Bell) to take advantage of the fact that only the entries (subset of the sparsity pattern) specified by row and col need to be computed. */ CppAD::vector<bool> forbidden(m); for(i = 1; i < m; i++) // for each row that appears if( color[i] < m ) { // initial all colors as ok for this row // (value of forbidden for ell > initial color[i] does not matter) for(ell = 0; ell <= color[i]; ell++) forbidden[ell] = false; // ----------------------------------------------------- // Forbid colors for which this row would destroy results: // // for each column that is non-zero for this row typename VectorSet::const_iterator pattern_itr(pattern, i); j = *pattern_itr; while( j != pattern.end() ) { // for each row that appears with this column typename VectorSet::const_iterator c2r_itr(c2r_appear, j); r = *c2r_itr; while( r != c2r_appear.end() ) { // if this is not the same row, forbid its color if( (r < i) & (color[r] < m) ) forbidden[ color[r] ] = true; r = *(++c2r_itr); } j = *(++pattern_itr); } // ----------------------------------------------------- // Forbid colors that destroy results needed for this row. // // for each column that appears with this row typename VectorSet::const_iterator r2c_itr(r2c_appear, i); j = *r2c_itr; while( j != r2c_appear.end() ) { // For each row that is non-zero for this column // (the appear rows have already been checked above). typename VectorSet::const_iterator not_itr(not_appear, j); r = *not_itr; while( r != not_appear.end() ) { // if this is not the same row, forbid its color if( (r < i) & (color[r] < m) ) forbidden[ color[r] ] = true; r = *(++not_itr); } j = *(++r2c_itr); } // pick the color with smallest index ell = 0; while( forbidden[ell] ) { ell++; CPPAD_ASSERT_UNKNOWN( ell <= color[i] ); } color[i] = ell; } return; }
// ----------------------------------------------------------------------- // get the result of the work bool multi_newton_combine(CppAD::vector<double>& xout) { // number of threads in the calculation size_t num_threads = std::max(num_threads_, size_t(1)); // remove duplicates and points that are not solutions xout.resize(0); bool ok = true; size_t thread_num; // initialize as more that sub_lenght_ / 2 from any possible solution double xlast = - sub_length_; for(thread_num = 0; thread_num < num_threads; thread_num++) { vector<double>& x = work_all_[thread_num]->x; size_t i; for(i = 0; i < x.size(); i++) { // check for case where this point is lower limit for this // thread and upper limit for previous thread if( fabs(x[i] - xlast) >= sub_length_ ) { xout.push_back( x[i] ); xlast = x[i]; } else { double fcur, flast, df; fun_(x[i], fcur, df); fun_(xlast, flast, df); if( fabs(fcur) < fabs(flast) ) { xout[ xout.size() - 1] = x[i]; xlast = x[i]; } } } ok &= work_all_[thread_num]->ok; } // go down so free memory for other threads before memory for master thread_num = num_threads; while(thread_num--) { # if USE_THREAD_ALLOC_FOR_WORK_ALL // call the destructor for CppAD::vector destructor work_all_[thread_num]->x.~vector<double>(); // delete the raw memory allocation void* v_ptr = static_cast<void*>( work_all_[thread_num] ); thread_alloc::return_memory( v_ptr ); # else delete work_all_[thread_num]; # endif // Note that xout corresponds to memroy that is inuse by master // (so we can only chech have freed all their memory). if( thread_num > 0 ) { // check that there is no longer any memory inuse by this thread ok &= thread_alloc::inuse(thread_num) == 0; // return all memory being held for future use by this thread thread_alloc::free_available(thread_num); } } // now we are done with the work_all_ vector so free its memory // (becasue it is a static variable) work_all_.clear(); return ok; }
void my_init(vector<bool> keepcol){ Partial.extend(num_var_tape_ * 1); arg_mark_.resize(play_.op_arg_rec_.size()); for(size_t i=0;i<arg_mark_.size();i++)arg_mark_[i]=false; /* Run a reverse test-sweep to store pointers once */ tape_point tp; play_.reverse_start(tp.op, tp.op_arg, tp.op_index, tp.var_index); tp_.resize(tp.op_index+1); var2op_.resize(tp.var_index+1); op_mark_.resize(tp.op_index+1); for(size_t i=0;i<op_mark_.size();i++)op_mark_[i]=0; user_region_mark_.resize(tp.op_index+1); for(size_t i=0;i<user_region_mark_.size();i++)user_region_mark_[i]=0; tp_[tp.op_index]=tp; /* 1. We need to be able to find out, for a given variable, what operator created the variable. This is easiest done by looping through the _operators_ because for a given op we have access to all the resulting variables it creates. 2. We precompute the a vector of "tape_points" so that instead of calling "reverse_next", we simply get the next tape entry by tp_[i-1]. */ while(tp.op != BeginOp ){ /* tp.op_index is decremented by one in each iteration ... */ // printTP(tp); /* For debugging */ play_.reverse_next(tp.op, tp.op_arg, tp.op_index, tp.var_index); /* Csum is special case - see remarks in player.hpp and reverse_sweep.hpp */ if(tp.op == CSumOp)play_.reverse_csum(tp.op, tp.op_arg, tp.op_index, tp.var_index); for(size_t i=0;i<NumRes(tp.op);i++)var2op_[tp.var_index-i]=tp.op_index; tp_[tp.op_index]=tp; markArgs(tp); } /* Lookup table: is tape_point within a UserOp region? */ bool user_within=false; user_region_.resize(tp_.size()); for(size_t i=0;i<tp_.size();i++){ if(tp_[i].op==UserOp){ user_region_[i]=true; user_within=!user_within; } else { user_region_[i]=user_within; } } /* Lookup table: is tape_point a constant (=only fixed effect dependent) ? */ constant_tape_point_.resize(tp_.size()); int indep_var_number=0; for(size_t i=0;i<tp_.size();i++){ if(tp_[i].op==InvOp){ /* All independent variables are marked according to being random or fixed effect */ constant_tape_point_[i]=!keepcol[indep_var_number]; indep_var_number++; } else { /* Mark operator as constant if _all_ arguments are constant */ constant_tape_point_[i] = is_tape_point_constant(i); } //std::cout << constant_tape_point_[i] << " "; printTP(tp_[i]); } // std::cout << "Total: " << constant_tape_point_.size() << "\n"; // int sum=0; for(int i=0;i<constant_tape_point_.size();i++)sum+=constant_tape_point_[i]; // std::cout << "Constant:" << sum << "\n"; // Calculate pattern int m=Range(); colpattern.resize(m); for(int i=0;i<m;i++)my_pattern(i); for(size_t i=0;i<op_mark_.size();i++)op_mark_[i]=0; /* remember to reset marks */ for(size_t i=0;i<user_region_mark_.size();i++)user_region_mark_[i]=0; /* remember to reset marks */ }