void RevSparseHesSet( bool transpose , size_t q , const VectorSet& s , VectorSet& h , size_t total_num_var , CppAD::vector<size_t>& dep_taddr , CppAD::vector<size_t>& ind_taddr , CppAD::player<Base>& play , Sparsity& 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(total_num_var); for(i = 0; i < total_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] < total_num_var ); RevJac[ dep_taddr[i] ] = true; } // vector of sets that will hold reverse Hessain values Sparsity rev_hes_sparsity; rev_hes_sparsity.resize(total_num_var, q); // compute the Hessian sparsity patterns RevHesSweep( n, total_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] < total_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 total_num_var , CppAD::vector<size_t>& dep_taddr , CppAD::vector<size_t>& ind_taddr , CppAD::player<Base>& play , Sparsity& 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(total_num_var); for(i = 0; i < total_num_var; i++) RevJac[i] = false; for(i = 0; i < m; i++) { CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < total_num_var ); RevJac[ dep_taddr[i] ] = s[i]; } // vector of sets that will hold reverse Hessain values Sparsity rev_hes_sparsity; rev_hes_sparsity.resize(total_num_var, q); // compute the Hessian sparsity patterns RevHesSweep( n, total_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] < total_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; }