void ForSparseJacSet( bool transpose , size_t q , const VectorSet& r , VectorSet& s , size_t total_num_var , CppAD::vector<size_t>& dep_taddr , CppAD::vector<size_t>& ind_taddr , CppAD::player<Base>& play , CPPAD_INTERNAL_SPARSE_SET& for_jac_sparsity ) { // temporary indices size_t i, j; std::set<size_t>::const_iterator itr; // range and domain dimensions for F size_t m = dep_taddr.size(); size_t n = ind_taddr.size(); CPPAD_ASSERT_KNOWN( q > 0, "RevSparseJac: q is not greater than zero" ); CPPAD_ASSERT_KNOWN( size_t(r.size()) == n || transpose, "RevSparseJac: size of r is not equal to n and transpose is false." ); CPPAD_ASSERT_KNOWN( size_t(r.size()) == q || ! transpose, "RevSparseJac: size of r is not equal to q and transpose is true." ); // allocate memory for the requested sparsity calculation for_jac_sparsity.resize(total_num_var, q); // set values corresponding to independent variables if( transpose ) { for(i = 0; i < q; i++) { // add the elements that are present itr = r[i].begin(); while( itr != r[i].end() ) { j = *itr++; CPPAD_ASSERT_KNOWN( j < n, "ForSparseJac: transpose is true and element of the set\n" "r[j] has value greater than or equal n." ); CPPAD_ASSERT_UNKNOWN( ind_taddr[j] < total_num_var ); // operator for j-th independent variable CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[j] ) == InvOp ); for_jac_sparsity.add_element( ind_taddr[j], i); } } } else { for(i = 0; i < n; i++) { CPPAD_ASSERT_UNKNOWN( ind_taddr[i] < total_num_var ); // ind_taddr[i] is operator taddr for i-th independent variable CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[i] ) == InvOp ); // add the elements that are present itr = r[i].begin(); while( itr != r[i].end() ) { j = *itr++; CPPAD_ASSERT_KNOWN( j < q, "ForSparseJac: an element of the set r[i] " "has value greater than or equal q." ); for_jac_sparsity.add_element( ind_taddr[i], j); } } } // evaluate the sparsity patterns ForJacSweep( n, total_num_var, &play, for_jac_sparsity ); // return values corresponding to dependent variables CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == m || transpose ); CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q || ! transpose ); for(i = 0; i < m; i++) { CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < total_num_var ); // extract results from for_jac_sparsity // and add corresponding elements to sets in s CPPAD_ASSERT_UNKNOWN( for_jac_sparsity.end() == q ); for_jac_sparsity.begin( dep_taddr[i] ); j = for_jac_sparsity.next_element(); while( j < q ) { if( transpose ) s[j].insert(i); else s[i].insert(j); j = for_jac_sparsity.next_element(); } } }
void ForSparseJacBool( bool transpose , size_t q , const VectorSet& r , VectorSet& s , size_t total_num_var , CppAD::vector<size_t>& dep_taddr , CppAD::vector<size_t>& ind_taddr , CppAD::player<Base>& play , sparse_pack& for_jac_sparsity ) { // temporary indices size_t i, j; // range and domain dimensions for F size_t m = dep_taddr.size(); size_t n = ind_taddr.size(); CPPAD_ASSERT_KNOWN( q > 0, "ForSparseJac: q is not greater than zero" ); CPPAD_ASSERT_KNOWN( size_t(r.size()) == n * q, "ForSparseJac: size of r is not equal to\n" "q times domain dimension for ADFun object." ); // allocate memory for the requested sparsity calculation result for_jac_sparsity.resize(total_num_var, q); // set values corresponding to independent variables for(i = 0; i < n; i++) { CPPAD_ASSERT_UNKNOWN( ind_taddr[i] < total_num_var ); // ind_taddr[i] is operator taddr for i-th independent variable CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[i] ) == InvOp ); // set bits that are true if( transpose ) { for(j = 0; j < q; j++) if( r[ j * n + i ] ) for_jac_sparsity.add_element( ind_taddr[i], j); } else { for(j = 0; j < q; j++) if( r[ i * q + j ] ) for_jac_sparsity.add_element( ind_taddr[i], j); } } // evaluate the sparsity patterns ForJacSweep( n, total_num_var, &play, for_jac_sparsity ); // return values corresponding to dependent variables CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == m * q ); for(i = 0; i < m; i++) { CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < total_num_var ); // extract the result from for_jac_sparsity if( transpose ) { for(j = 0; j < q; j++) s[ j * m + i ] = false; } else { for(j = 0; j < q; j++) s[ i * q + j ] = false; } CPPAD_ASSERT_UNKNOWN( for_jac_sparsity.end() == q ); for_jac_sparsity.begin( dep_taddr[i] ); j = for_jac_sparsity.next_element(); while( j < q ) { if( transpose ) s[j * m + i] = true; else s[i * q + j] = true; j = for_jac_sparsity.next_element(); } } }
/** * Accessor to vertices. * @return pointer to vertices collection. */ VectorSet* getVertices() { VectorSet* newVertices = new VectorSet(); for(unsigned i = 0; i < vertices.size(); i++) newVertices->push_back(vertices[i]); return newVertices; }
/** * Method is used to rotate solid by vectors and angle. * @param a is rotate vector. * @param b is rotate vector. * @param angle is rotate angle value. */ void Rotate(const Vector& a, const Vector& b, float angle) { for(unsigned i = 0; i < vertices.size(); i++) { Vector v = vertices[i]; v = VectorRotate(v, a, b, angle); vertices[i] = v; } }
/** * Method is used to translate solid by vector. * @param t is translate vector. */ void Translate(const Vector& t) { for(unsigned i = 0; i < vertices.size(); i++) { Vector v = vertices[i]; v = v + t; vertices[i] = v; } }
/** * Method is used to scale solid by vector. * @param s id scale vector. */ void Scale(const Vector& s) { for(unsigned i = 0; i < vertices.size(); i++) { Vector v = vertices[i]; v = VectorScale(v, s); vertices[i] = v; } }
void sparsity_user2internal( sparse_set& internal , const VectorSet& user , size_t n_row , size_t n_col , bool transpose ) { CPPAD_ASSERT_UNKNOWN( n_row == size_t(user.size()) ); CPPAD_ASSERT_KNOWN( size_t( user.size() ) == n_row, "Size of this vector of sets sparsity pattern is not equal " "the range dimension for the corresponding function." ); size_t i, j; std::set<size_t>::const_iterator itr; // transposed pattern case if( transpose ) { internal.resize(n_col, n_row); for(i = 0; i < n_row; i++) { itr = user[i].begin(); while(itr != user[i].end()) { j = *itr++; CPPAD_ASSERT_UNKNOWN( j < n_col ); internal.add_element(j, i); } } return; } // same pattern case internal.resize(n_row, n_col); for(i = 0; i < n_row; i++) { itr = user[i].begin(); while(itr != user[i].end()) { j = *itr++; CPPAD_ASSERT_UNKNOWN( j < n_col ); internal.add_element(i, j); } } return; }
void solve() { borderSquares[xFace]->clear(); borderSquares[yFace]->clear(); borderSquares[zFace]->clear(); for (vector<Face*>::iterator iter = faces.begin(); iter != faces.end(); iter++) { // derive all Squares of this face Face* f = *iter; // unsigned int startTime = getMicroSecs(); // cout << "deriveSquares: "; f->deriveSquares(); // cout << (getMicroSecs() - startTime) << endl; // put all squares of faces with the same orientation together VectorSet* squares = borderSquares[f->orientation]; for(VectorSet::iterator iter = f->squares.begin(); iter != f->squares.end(); iter++) { Vertex v = *iter; squares->insert(v); } } VectorSet::iterator iter = borderSquares[zFace]->begin(); Vertex min = *iter; while(iter != borderSquares[zFace]->end()) { if(*iter < min) min = *iter; iter++; } blocks.clear(); blocks.insert(min); // unsigned int startTime = getMicroSecs(); // cout << "collectBlocks: "; collectBlocks(min); // cout << (getMicroSecs() - startTime) << endl; cout << "The bulk is composed of " << blocks.size() << " units.\n"; }
void RevSparseHesSet( bool transpose , size_t q , const VectorSet& s , VectorSet& h , size_t num_var , CppAD::vector<size_t>& dep_taddr , CppAD::vector<size_t>& ind_taddr , CppAD::player<Base>& play , CPPAD_INTERNAL_SPARSE_SET& for_jac_sparsity ) { // temporary indices size_t i, j; std::set<size_t>::const_iterator itr; // check VectorSet is Simple Vector class with sets for elements CheckSimpleVector<std::set<size_t>, VectorSet>( one_element_std_set<size_t>(), two_element_std_set<size_t>() ); // range and domain dimensions for F # ifndef NDEBUG size_t m = dep_taddr.size(); # endif size_t n = ind_taddr.size(); CPPAD_ASSERT_KNOWN( q == for_jac_sparsity.end(), "RevSparseHes: q is not equal to its value\n" "in the previous call to ForSparseJac with this ADFun object." ); CPPAD_ASSERT_KNOWN( s.size() == 1, "RevSparseHes: size of s is not equal to one." ); // Array that will hold reverse Jacobian dependency flag. // Initialize as true for the dependent variables. pod_vector<bool> RevJac; RevJac.extend(num_var); for(i = 0; i < num_var; i++) RevJac[i] = false; itr = s[0].begin(); while( itr != s[0].end() ) { i = *itr++; CPPAD_ASSERT_KNOWN( i < m, "RevSparseHes: an element of the set s[0] has value " "greater than or equal m" ); CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < num_var ); RevJac[ dep_taddr[i] ] = true; } // vector of sets that will hold reverse Hessain values CPPAD_INTERNAL_SPARSE_SET rev_hes_sparsity; rev_hes_sparsity.resize(num_var, q); // compute the Hessian sparsity patterns RevHesSweep( n, num_var, &play, for_jac_sparsity, RevJac.data(), rev_hes_sparsity ); // return values corresponding to independent variables // j is index corresponding to reverse mode partial CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == q || transpose ); CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == n || ! transpose ); for(j = 0; j < n; j++) { CPPAD_ASSERT_UNKNOWN( ind_taddr[j] < num_var ); CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == j + 1 ); CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[j] ) == InvOp ); // extract the result from rev_hes_sparsity // and add corresponding elements to result sets in h CPPAD_ASSERT_UNKNOWN( rev_hes_sparsity.end() == q ); rev_hes_sparsity.begin(j+1); i = rev_hes_sparsity.next_element(); while( i < q ) { if( transpose ) h[j].insert(i); else h[i].insert(j); i = rev_hes_sparsity.next_element(); } } return; }
void RevSparseHesBool( bool transpose , size_t q , const VectorSet& s , VectorSet& h , size_t num_var , CppAD::vector<size_t>& dep_taddr , CppAD::vector<size_t>& ind_taddr , CppAD::player<Base>& play , sparse_pack& for_jac_sparsity ) { // temporary indices size_t i, j; // check Vector is Simple VectorSet class with bool elements CheckSimpleVector<bool, VectorSet>(); // range and domain dimensions for F size_t m = dep_taddr.size(); size_t n = ind_taddr.size(); CPPAD_ASSERT_KNOWN( q == for_jac_sparsity.end(), "RevSparseHes: q is not equal to its value\n" "in the previous call to ForSparseJac with this ADFun object." ); CPPAD_ASSERT_KNOWN( size_t(s.size()) == m, "RevSparseHes: size of s is not equal to\n" "range dimension for ADFun object." ); // Array that will hold reverse Jacobian dependency flag. // Initialize as true for the dependent variables. pod_vector<bool> RevJac; RevJac.extend(num_var); for(i = 0; i < num_var; i++) RevJac[i] = false; for(i = 0; i < m; i++) { CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < num_var ); RevJac[ dep_taddr[i] ] = s[i]; } // vector of sets that will hold reverse Hessain values sparse_pack rev_hes_sparsity; rev_hes_sparsity.resize(num_var, q); // compute the Hessian sparsity patterns RevHesSweep( n, num_var, &play, for_jac_sparsity, RevJac.data(), rev_hes_sparsity ); // return values corresponding to independent variables CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == n * q ); for(j = 0; j < n; j++) { for(i = 0; i < q; i++) { if( transpose ) h[ j * q + i ] = false; else h[ i * n + j ] = false; } } // j is index corresponding to reverse mode partial for(j = 0; j < n; j++) { CPPAD_ASSERT_UNKNOWN( ind_taddr[j] < num_var ); // ind_taddr[j] is operator taddr for j-th independent variable CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == j + 1 ); CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[j] ) == InvOp ); // extract the result from rev_hes_sparsity CPPAD_ASSERT_UNKNOWN( rev_hes_sparsity.end() == q ); rev_hes_sparsity.begin(j + 1); i = rev_hes_sparsity.next_element(); while( i < q ) { if( transpose ) h[ j * q + i ] = true; else h[ i * n + j ] = true; i = rev_hes_sparsity.next_element(); } } return; }
void ADFun<Base>::SparseJacobianCase( const std::set<size_t>& set_type , const VectorBase& x , const VectorSet& p , VectorBase& jac ) { typedef CppAD::vector<size_t> SizeVector; typedef CppAD::vectorBool VectorBool; size_t i, j, k; size_t m = Range(); size_t n = Domain(); // some values const Base zero(0); const Base one(1); // check VectorSet is Simple Vector class with sets for elements CheckSimpleVector<std::set<size_t>, VectorSet>( one_element_std_set<size_t>(), two_element_std_set<size_t>() ); // check VectorBase is Simple Vector class with Base type elements CheckSimpleVector<Base, VectorBase>(); CPPAD_ASSERT_KNOWN( x.size() == n, "SparseJacobian: size of x not equal domain dimension for f" ); CPPAD_ASSERT_KNOWN( p.size() == m, "SparseJacobian: using sets and size of p " "not equal range dimension for f" ); CPPAD_ASSERT_UNKNOWN(jac.size() == m * n); // point at which we are evaluating the Jacobian Forward(0, x); // initialize the return value for(i = 0; i < m; i++) for(j = 0; j < n; j++) jac[i * n + j] = zero; // create a copy of the transpose sparsity pattern VectorSet q(n); std::set<size_t>::const_iterator itr_i, itr_j; for(i = 0; i < m; i++) { itr_j = p[i].begin(); while( itr_j != p[i].end() ) { j = *itr_j++; q[j].insert(i); } } if( n <= m ) { // use forward mode ---------------------------------------- // initial coloring SizeVector color(n); for(j = 0; j < n; j++) color[j] = j; // See GreedyPartialD2Coloring Algorithm Section 3.6.2 of // Graph Coloring in Optimization Revisited by // Assefaw Gebremedhin, Fredrik Maane, Alex Pothen VectorBool forbidden(n); for(j = 0; j < n; j++) { // initial all colors as ok for this column for(k = 0; k < n; k++) forbidden[k] = false; // for each row connected to column j itr_i = q[j].begin(); while( itr_i != q[j].end() ) { i = *itr_i++; // for each column connected to row i itr_j = p[i].begin(); while( itr_j != p[i].end() ) { // if this is not j, forbid it k = *itr_j++; forbidden[ color[k] ] = (k != j); } } k = 0; while( forbidden[k] && k < n ) { k++; CPPAD_ASSERT_UNKNOWN( k < n ); } color[j] = k; } size_t n_color = 1; for(k = 0; k < n; k++) n_color = std::max(n_color, color[k] + 1); // direction vector for calls to forward VectorBase dx(n); // location for return values from Reverse VectorBase dy(m); // loop over colors size_t c; for(c = 0; c < n_color; c++) { // determine all the colums with this color for(j = 0; j < n; j++) { if( color[j] == c ) dx[j] = one; else dx[j] = zero; } // call forward mode for all these columns at once dy = Forward(1, dx); // set the corresponding components of the result for(j = 0; j < n; j++) if( color[j] == c ) { itr_i = q[j].begin(); while( itr_i != q[j].end() ) { i = *itr_i++; jac[i * n + j] = dy[i]; } } } } else { // use reverse mode ---------------------------------------- // initial coloring SizeVector color(m); for(i = 0; i < m; i++) color[i] = i; // See GreedyPartialD2Coloring Algorithm Section 3.6.2 of // Graph Coloring in Optimization Revisited by // Assefaw Gebremedhin, Fredrik Maane, Alex Pothen VectorBool forbidden(m); for(i = 0; i < m; i++) { // initial all colors as ok for this row for(k = 0; k < m; k++) forbidden[k] = false; // for each column connected to row i itr_j = p[i].begin(); while( itr_j != p[i].end() ) { j = *itr_j++; // for each row connected to column j itr_i = q[j].begin(); while( itr_i != q[j].end() ) { // if this is not i, forbid it k = *itr_i++; forbidden[ color[k] ] = (k != i); } } k = 0; while( forbidden[k] && k < m ) { k++; CPPAD_ASSERT_UNKNOWN( k < n ); } color[i] = k; } size_t n_color = 1; for(k = 0; k < m; k++) n_color = std::max(n_color, color[k] + 1); // weight vector for calls to reverse VectorBase w(m); // location for return values from Reverse VectorBase dw(n); // loop over colors size_t c; for(c = 0; c < n_color; c++) { // determine all the rows with this color for(i = 0; i < m; i++) { if( color[i] == c ) w[i] = one; else w[i] = zero; } // call reverse mode for all these rows at once dw = Reverse(1, w); // set the corresponding components of the result for(i = 0; i < m; i++) if( color[i] == c ) { itr_j = p[i].begin(); while( itr_j != p[i].end() ) { j = *itr_j++; jac[i * n + j] = dw[j]; } } } } }
void RevSparseJacBool( size_t p , const VectorSet& s , VectorSet& r , size_t total_num_var , CppAD::vector<size_t>& dep_taddr , CppAD::vector<size_t>& ind_taddr , CppAD::player<Base>& play ) { // temporary indices size_t i, j; // check VectorSet is Simple Vector class with bool elements CheckSimpleVector<bool, VectorSet>(); // range and domain dimensions for F size_t m = dep_taddr.size(); size_t n = ind_taddr.size(); CPPAD_ASSERT_KNOWN( p > 0, "RevSparseJac: p (first argument) is not greater than zero" ); CPPAD_ASSERT_KNOWN( s.size() == p * m, "RevSparseJac: s (second argument) length is not equal to\n" "p (first argument) times range dimension for ADFun object." ); // vector of sets that will hold the results sparse_pack var_sparsity; var_sparsity.resize(total_num_var, p); // The sparsity pattern corresponding to the dependent variables for(i = 0; i < m; i++) { CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < total_num_var ); for(j = 0; j < p; j++) if( s[ i * m + j ] ) var_sparsity.add_element( dep_taddr[i], j ); } // evaluate the sparsity patterns RevJacSweep( n, total_num_var, &play, var_sparsity ); // return values corresponding to dependent variables CPPAD_ASSERT_UNKNOWN( r.size() == p * n ); for(j = 0; j < n; j++) { CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == (j+1) ); // ind_taddr[j] is operator taddr for j-th independent variable CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[j] ) == InvOp ); // extract the result from var_sparsity for(i = 0; i < p; i++) r[ i * n + j ] = false; CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == p ); var_sparsity.begin(j+1); i = var_sparsity.next_element(); while( i < p ) { r[ i * n + j ] = true; i = var_sparsity.next_element(); } } }
void RevSparseJacSet( bool transpose , bool dependency , size_t q , const VectorSet& r , VectorSet& s , size_t total_num_var , CppAD::vector<size_t>& dep_taddr , CppAD::vector<size_t>& ind_taddr , CppAD::player<Base>& play ) { // temporary indices size_t i, j; std::set<size_t>::const_iterator itr; // check VectorSet is Simple Vector class with sets for elements CheckSimpleVector<std::set<size_t>, VectorSet>( one_element_std_set<size_t>(), two_element_std_set<size_t>() ); // domain dimensions for F size_t n = ind_taddr.size(); size_t m = dep_taddr.size(); CPPAD_ASSERT_KNOWN( q > 0, "RevSparseJac: q is not greater than zero" ); CPPAD_ASSERT_KNOWN( size_t(r.size()) == q || transpose, "RevSparseJac: size of r is not equal to q and transpose is false." ); CPPAD_ASSERT_KNOWN( size_t(r.size()) == m || ! transpose, "RevSparseJac: size of r is not equal to m and transpose is true." ); // vector of lists that will hold the results CPPAD_INTERNAL_SPARSE_SET var_sparsity; var_sparsity.resize(total_num_var, q); // The sparsity pattern corresponding to the dependent variables if( transpose ) { for(i = 0; i < m; i++) { itr = r[i].begin(); while(itr != r[i].end()) { j = *itr++; CPPAD_ASSERT_KNOWN( j < q, "RevSparseJac: transpose is true and element of the set\n" "r[i] has value greater than or equal q." ); CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < total_num_var ); var_sparsity.add_element( dep_taddr[i], j ); } } } else { for(i = 0; i < q; i++) { itr = r[i].begin(); while(itr != r[i].end()) { j = *itr++; CPPAD_ASSERT_KNOWN( j < m, "RevSparseJac: transpose is false and element of the set\n" "r[i] has value greater than or equal range dimension." ); CPPAD_ASSERT_UNKNOWN( dep_taddr[j] < total_num_var ); var_sparsity.add_element( dep_taddr[j], i ); } } } // evaluate the sparsity patterns RevJacSweep( dependency, n, total_num_var, &play, var_sparsity ); // return values corresponding to dependent variables CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q || transpose ); CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == n || ! transpose ); for(j = 0; j < n; j++) { CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == (j+1) ); // ind_taddr[j] is operator taddr for j-th independent variable CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[j] ) == InvOp ); CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q ); var_sparsity.begin(j+1); i = var_sparsity.next_element(); while( i < q ) { if( transpose ) s[j].insert(i); else s[i].insert(j); i = var_sparsity.next_element(); } } }
void RevSparseJacBool( bool transpose , bool dependency , size_t q , const VectorSet& r , VectorSet& s , size_t total_num_var , CppAD::vector<size_t>& dep_taddr , CppAD::vector<size_t>& ind_taddr , CppAD::player<Base>& play ) { // temporary indices size_t i, j; // check VectorSet is Simple Vector class with bool elements CheckSimpleVector<bool, VectorSet>(); // range and domain dimensions for F size_t m = dep_taddr.size(); size_t n = ind_taddr.size(); CPPAD_ASSERT_KNOWN( q > 0, "RevSparseJac: q is not greater than zero" ); CPPAD_ASSERT_KNOWN( size_t(r.size()) == q * m, "RevSparseJac: size of r is not equal to\n" "q times range dimension for ADFun object." ); // vector of sets that will hold the results sparse_pack var_sparsity; var_sparsity.resize(total_num_var, q); // The sparsity pattern corresponding to the dependent variables for(i = 0; i < m; i++) { CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < total_num_var ); if( transpose ) { for(j = 0; j < q; j++) if( r[ j * m + i ] ) var_sparsity.add_element( dep_taddr[i], j ); } else { for(j = 0; j < q; j++) if( r[ i * q + j ] ) var_sparsity.add_element( dep_taddr[i], j ); } } // evaluate the sparsity patterns RevJacSweep( dependency, n, total_num_var, &play, var_sparsity ); // return values corresponding to dependent variables CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q * n ); for(j = 0; j < n; j++) { CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == (j+1) ); // ind_taddr[j] is operator taddr for j-th independent variable CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[j] ) == InvOp ); // extract the result from var_sparsity if( transpose ) { for(i = 0; i < q; i++) s[ j * q + i ] = false; } else { for(i = 0; i < q; i++) s[ i * n + j ] = false; } CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q ); var_sparsity.begin(j+1); i = var_sparsity.next_element(); while( i < q ) { if( transpose ) s[ j * q + i ] = true; else s[ i * n + j ] = true; i = var_sparsity.next_element(); } } }
void ADFun<Base>::ForSparseHesCase( const std::set<size_t>& set_type , const VectorSet& r , const VectorSet& s , VectorSet& h ) { size_t n = Domain(); # ifndef NDEBUG size_t m = Range(); # endif std::set<size_t>::const_iterator itr_1; // // check VectorSet is Simple Vector class with sets for elements CheckSimpleVector<std::set<size_t>, VectorSet>( local::one_element_std_set<size_t>(), local::two_element_std_set<size_t>() ); CPPAD_ASSERT_KNOWN( r.size() == 1, "ForSparseHes: size of s is not equal to one." ); CPPAD_ASSERT_KNOWN( s.size() == 1, "ForSparseHes: size of s is not equal to one." ); // // sparsity pattern corresponding to r local::sparse_list for_jac_pattern; for_jac_pattern.resize(num_var_tape_, n + 1); itr_1 = r[0].begin(); while( itr_1 != r[0].end() ) { size_t i = *itr_1++; CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < n + 1 ); // ind_taddr_[i] is operator taddr for i-th independent variable CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp ); // for_jac_pattern.add_element( ind_taddr_[i], ind_taddr_[i] ); } // compute forward Jacobiain sparsity pattern bool dependency = false; local::ForJacSweep( dependency, n, num_var_tape_, &play_, for_jac_pattern ); // sparsity pattern correspnding to s local::sparse_list rev_jac_pattern; rev_jac_pattern.resize(num_var_tape_, 1); itr_1 = s[0].begin(); while( itr_1 != s[0].end() ) { size_t i = *itr_1++; CPPAD_ASSERT_KNOWN( i < m, "ForSparseHes: an element of the set s[0] has value " "greater than or equal m" ); CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ ); rev_jac_pattern.add_element( dep_taddr_[i], 0); } // // compute reverse sparsity pattern for dependency analysis // (note that we are only want non-zero derivatives not true dependency) local::RevJacSweep( dependency, n, num_var_tape_, &play_, rev_jac_pattern ); // // vector of sets that will hold reverse Hessain values local::sparse_list for_hes_pattern; for_hes_pattern.resize(n+1, n+1); // // compute the Hessian sparsity patterns local::ForHesSweep( n, num_var_tape_, &play_, for_jac_pattern, rev_jac_pattern, for_hes_pattern ); // return values corresponding to independent variables // j is index corresponding to reverse mode partial h.resize(n); CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == n+1 ); for(size_t i = 0; i < n; i++) { CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] == i + 1 ); CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp ); // extract the result from for_hes_pattern local::sparse_list::const_iterator itr_2(for_hes_pattern, ind_taddr_[i] ); size_t j = *itr_2; while( j < for_hes_pattern.end() ) { CPPAD_ASSERT_UNKNOWN( 0 < j ) h[i].insert(j-1); j = *(++itr_2); } } }
void ADFun<Base>::ForSparseHesCase( bool set_type , const VectorSet& r , const VectorSet& s , VectorSet& h ) { size_t n = Domain(); size_t m = Range(); // // check Vector is Simple VectorSet class with bool elements CheckSimpleVector<bool, VectorSet>(); // CPPAD_ASSERT_KNOWN( size_t(r.size()) == n, "ForSparseHes: size of r is not equal to\n" "domain dimension for ADFun object." ); CPPAD_ASSERT_KNOWN( size_t(s.size()) == m, "ForSparseHes: size of s is not equal to\n" "range dimension for ADFun object." ); // // sparsity pattern corresponding to r local::sparse_pack for_jac_pattern; for_jac_pattern.resize(num_var_tape_, n + 1); for(size_t i = 0; i < n; i++) { CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < n + 1 ); // ind_taddr_[i] is operator taddr for i-th independent variable CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp ); // if( r[i] ) for_jac_pattern.add_element( ind_taddr_[i], ind_taddr_[i] ); } // compute forward Jacobiain sparsity pattern bool dependency = false; local::ForJacSweep( dependency, n, num_var_tape_, &play_, for_jac_pattern ); // sparsity pattern correspnding to s local::sparse_pack rev_jac_pattern; rev_jac_pattern.resize(num_var_tape_, 1); for(size_t i = 0; i < m; i++) { CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ ); if( s[i] ) rev_jac_pattern.add_element( dep_taddr_[i], 0); } // compute reverse sparsity pattern for dependency analysis // (note that we are only want non-zero derivatives not true dependency) local::RevJacSweep( dependency, n, num_var_tape_, &play_, rev_jac_pattern ); // vector of sets that will hold the forward Hessain values local::sparse_pack for_hes_pattern; for_hes_pattern.resize(n+1, n+1); // // compute the Hessian sparsity patterns local::ForHesSweep( n, num_var_tape_, &play_, for_jac_pattern, rev_jac_pattern, for_hes_pattern ); // initialize return values corresponding to independent variables h.resize(n * n); for(size_t i = 0; i < n; i++) { for(size_t j = 0; j < n; j++) h[ i * n + j ] = false; } // copy to result pattern CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == n+1 ); for(size_t i = 0; i < n; i++) { // ind_taddr_[i] is operator taddr for i-th independent variable CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] == i + 1 ); CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp ); // extract the result from for_hes_pattern local::sparse_pack::const_iterator itr(for_hes_pattern, ind_taddr_[i] ); size_t j = *itr; while( j < for_hes_pattern.end() ) { CPPAD_ASSERT_UNKNOWN( 0 < j ) h[ i * n + (j-1) ] = true; j = *(++itr); } } }
void RevSparseJacSet( size_t p , const VectorSet& s , VectorSet& r , size_t total_num_var , CppAD::vector<size_t>& dep_taddr , CppAD::vector<size_t>& ind_taddr , CppAD::player<Base>& play ) { // temporary indices size_t i, j; std::set<size_t>::const_iterator itr; // check VectorSet is Simple Vector class with sets for elements static std::set<size_t> two, three; if( two.empty() ) { two.insert(2); three.insert(3); } CPPAD_ASSERT_UNKNOWN( two.size() == 1 ); CPPAD_ASSERT_UNKNOWN( three.size() == 1 ); CheckSimpleVector<std::set<size_t>, VectorSet>(two, three); // range and domain dimensions for F size_t m = dep_taddr.size(); size_t n = ind_taddr.size(); CPPAD_ASSERT_KNOWN( p > 0, "RevSparseJac: p (first argument) is not greater than zero" ); CPPAD_ASSERT_KNOWN( s.size() == p, "RevSparseJac: s (second argument) length is not equal to " "p (first argument)." ); // vector of sets that will hold the results sparse_set var_sparsity; var_sparsity.resize(total_num_var, p); // The sparsity pattern corresponding to the dependent variables for(i = 0; i < p; i++) { itr = s[i].begin(); while(itr != s[i].end()) { j = *itr++; CPPAD_ASSERT_KNOWN( j < m, "RevSparseJac: an element of the set s[i] " "has value greater than or equal m." ); CPPAD_ASSERT_UNKNOWN( dep_taddr[j] < total_num_var ); var_sparsity.add_element( dep_taddr[j], i ); } } // evaluate the sparsity patterns RevJacSweep( n, total_num_var, &play, var_sparsity ); // return values corresponding to dependent variables CPPAD_ASSERT_UNKNOWN( r.size() == p ); for(j = 0; j < n; j++) { CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == (j+1) ); // ind_taddr[j] is operator taddr for j-th independent variable CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[j] ) == InvOp ); // extract result from rev_hes_sparsity // and add corresponding elements to sets in r CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == p ); var_sparsity.begin(j+1); i = var_sparsity.next_element(); while( i < p ) { r[i].insert(j); i = var_sparsity.next_element(); } } }
void ADFun<Base>::SparseJacobianCase( bool set_type , const VectorBase& x , const VectorSet& p , VectorBase& jac ) { typedef CppAD::vector<size_t> SizeVector; typedef CppAD::vectorBool VectorBool; size_t i, j, k; size_t m = Range(); size_t n = Domain(); // some values const Base zero(0); const Base one(1); // check VectorSet is Simple Vector class with bool elements CheckSimpleVector<bool, VectorSet>(); // check VectorBase is Simple Vector class with Base type elements CheckSimpleVector<Base, VectorBase>(); CPPAD_ASSERT_KNOWN( x.size() == n, "SparseJacobian: size of x not equal domain dimension for f" ); CPPAD_ASSERT_KNOWN( p.size() == m * n, "SparseJacobian: using bool values and size of p " " not equal range dimension times domain dimension for f" ); CPPAD_ASSERT_UNKNOWN(jac.size() == m * n); // point at which we are evaluating the Jacobian Forward(0, x); // initialize the return value for(i = 0; i < m; i++) for(j = 0; j < n; j++) jac[i * n + j] = zero; if( n <= m ) { // use forward mode ---------------------------------------- // initial coloring SizeVector color(n); for(j = 0; j < n; j++) color[j] = j; // See GreedyPartialD2Coloring Algorithm Section 3.6.2 of // Graph Coloring in Optimization Revisited by // Assefaw Gebremedhin, Fredrik Maane, Alex Pothen VectorBool forbidden(n); for(j = 0; j < n; j++) { // initial all colors as ok for this column for(k = 0; k < n; k++) forbidden[k] = false; // for each row that is connected to column j for(i = 0; i < m; i++) if( p[i * n + j] ) { // for each column that is connected to row i for(k = 0; k < n; k++) if( p[i * n + k] & (j != k) ) forbidden[ color[k] ] = true; } k = 0; while( forbidden[k] && k < n ) { k++; CPPAD_ASSERT_UNKNOWN( k < n ); } color[j] = k; } size_t n_color = 1; for(k = 0; k < n; k++) n_color = std::max(n_color, color[k] + 1); // direction vector for calls to forward VectorBase dx(n); // location for return values from Reverse VectorBase dy(m); // loop over colors size_t c; for(c = 0; c < n_color; c++) { // determine all the colums with this color for(j = 0; j < n; j++) { if( color[j] == c ) dx[j] = one; else dx[j] = zero; } // call forward mode for all these columns at once dy = Forward(1, dx); // set the corresponding components of the result for(j = 0; j < n; j++) if( color[j] == c ) { for(i = 0; i < m; i++) if( p[ i * n + j ] ) jac[i * n + j] = dy[i]; } } } else { // use reverse mode ---------------------------------------- // initial coloring SizeVector color(m); for(i = 0; i < m; i++) color[i] = i; // See GreedyPartialD2Coloring Algorithm Section 3.6.2 of // Graph Coloring in Optimization Revisited by // Assefaw Gebremedhin, Fredrik Maane, Alex Pothen VectorBool forbidden(m); for(i = 0; i < m; i++) { // initial all colors as ok for this row for(k = 0; k < m; k++) forbidden[k] = false; // for each column that is connected to row i for(j = 0; j < n; j++) if( p[i * n + j] ) { // for each row that is connected to column j for(k = 0; k < m; k++) if( p[k * n + j] & (i != k) ) forbidden[ color[k] ] = true; } k = 0; while( forbidden[k] && k < m ) { k++; CPPAD_ASSERT_UNKNOWN( k < n ); } color[i] = k; } size_t n_color = 1; for(k = 0; k < m; k++) n_color = std::max(n_color, color[k] + 1); // weight vector for calls to reverse VectorBase w(m); // location for return values from Reverse VectorBase dw(n); // loop over colors size_t c; for(c = 0; c < n_color; c++) { // determine all the rows with this color for(i = 0; i < m; i++) { if( color[i] == c ) w[i] = one; else w[i] = zero; } // call reverse mode for all these rows at once dw = Reverse(1, w); // set the corresponding components of the result for(i = 0; i < m; i++) if( color[i] == c ) { for(j = 0; j < n; j++) if( p[ i * n + j ] ) jac[i * n + j] = dw[j]; } } } }