bool link_sparse_hessian( size_t size , size_t repeat , CppAD::vector<double>& x , const CppAD::vector<size_t>& row , const CppAD::vector<size_t>& col , CppAD::vector<double>& hessian ) { // ----------------------------------------------------- // setup typedef vector<double> DblVector; typedef vector< std::set<size_t> > SetVector; typedef CppAD::AD<double> ADScalar; typedef vector<ADScalar> ADVector; size_t i, j, k; size_t order = 0; // derivative order corresponding to function size_t m = 1; // number of dependent variables size_t n = size; // number of independent variables size_t K = row.size(); // number of non-zeros in lower triangle ADVector a_x(n); // AD domain space vector ADVector a_y(m); // AD range space vector DblVector w(m); // double range space vector DblVector hes(K); // non-zeros in lower triangle CppAD::ADFun<double> f; // AD function object // weights for hessian calculation (only one component of f) w[0] = 1.; // use the unspecified fact that size is non-decreasing between calls static size_t previous_size = 0; bool print = (repeat > 1) & (previous_size != size); previous_size = size; // declare sparsity pattern # if USE_SET_SPARSITY SetVector sparsity(n); # else typedef vector<bool> BoolVector; BoolVector sparsity(n * n); # endif // initialize all entries as zero for(i = 0; i < n; i++) { for(j = 0; j < n; j++) hessian[ i * n + j] = 0.; } // ------------------------------------------------------ extern bool global_retape; if( global_retape) while(repeat--) { // choose a value for x CppAD::uniform_01(n, x); for(j = 0; j < n; j++) a_x[j] = x[j]; // declare independent variables Independent(a_x); // AD computation of f(x) CppAD::sparse_hes_fun<ADScalar>(n, a_x, row, col, order, a_y); // create function object f : X -> Y f.Dependent(a_x, a_y); extern bool global_optimize; if( global_optimize ) { print_optimize(f, print, "cppad_sparse_hessian_optimize", size); print = false; } // calculate the Hessian sparsity pattern for this function calc_sparsity(sparsity, f); // structure that holds some of work done by SparseHessian CppAD::sparse_hessian_work work; // calculate this Hessian at this x f.SparseHessian(x, w, sparsity, row, col, hes, work); for(k = 0; k < K; k++) { hessian[ row[k] * n + col[k] ] = hes[k]; hessian[ col[k] * n + row[k] ] = hes[k]; } } else { // choose a value for x CppAD::uniform_01(n, x); for(j = 0; j < n; j++) a_x[j] = x[j]; // declare independent variables Independent(a_x); // AD computation of f(x) CppAD::sparse_hes_fun<ADScalar>(n, a_x, row, col, order, a_y); // create function object f : X -> Y f.Dependent(a_x, a_y); extern bool global_optimize; if( global_optimize ) { print_optimize(f, print, "cppad_sparse_hessian_optimize", size); print = false; } // calculate the Hessian sparsity pattern for this function calc_sparsity(sparsity, f); // declare structure that holds some of work done by SparseHessian CppAD::sparse_hessian_work work; while(repeat--) { // choose a value for x CppAD::uniform_01(n, x); // calculate sparsity at this x f.SparseHessian(x, w, sparsity, row, col, hes, work); for(k = 0; k < K; k++) { hessian[ row[k] * n + col[k] ] = hes[k]; hessian[ col[k] * n + row[k] ] = hes[k]; } } } return true; }
bool link_sparse_jacobian( size_t size , size_t repeat , size_t m , const CppAD::vector<size_t>& row , const CppAD::vector<size_t>& col , CppAD::vector<double>& x , CppAD::vector<double>& jacobian , size_t& n_sweep ) { if( global_atomic ) return false; # ifndef CPPAD_COLPACK_SPEED if( global_colpack ) return false; # endif // ----------------------------------------------------- // setup typedef vector< std::set<size_t> > SetVector; typedef CppAD::AD<double> ADScalar; typedef CppAD::vector<ADScalar> ADVector; size_t j; size_t order = 0; // derivative order corresponding to function size_t n = size; // number of independent variables ADVector a_x(n); // AD domain space vector ADVector a_y(m); // AD range space vector y = g(x) CppAD::ADFun<double> f; // AD function object // declare sparsity pattern SetVector set_sparsity(m); BoolVector bool_sparsity(m * n); // ------------------------------------------------------ if( ! global_onetape ) while(repeat--) { // choose a value for x CppAD::uniform_01(n, x); for(j = 0; j < n; j++) a_x[j] = x[j]; // declare independent variables Independent(a_x); // AD computation of f (x) CppAD::sparse_jac_fun<ADScalar>(m, n, a_x, row, col, order, a_y); // create function object f : X -> Y f.Dependent(a_x, a_y); if( global_optimize ) f.optimize(); // skip comparison operators f.compare_change_count(0); // calculate the Jacobian sparsity pattern for this function if( global_boolsparsity ) calc_sparsity(bool_sparsity, f); else calc_sparsity(set_sparsity, f); // structure that holds some of the work done by SparseJacobian CppAD::sparse_jacobian_work work; # ifdef CPPAD_COLPACK_SPEED if( global_colpack ) work.color_method = "colpack"; # endif // calculate the Jacobian at this x // (use forward mode because m > n ?) if( global_boolsparsity) n_sweep = f.SparseJacobianForward( x, bool_sparsity, row, col, jacobian, work ); else n_sweep = f.SparseJacobianForward( x, set_sparsity, row, col, jacobian, work ); } else { // choose a value for x CppAD::uniform_01(n, x); for(j = 0; j < n; j++) a_x[j] = x[j]; // declare independent variables Independent(a_x); // AD computation of f (x) CppAD::sparse_jac_fun<ADScalar>(m, n, a_x, row, col, order, a_y); // create function object f : X -> Y f.Dependent(a_x, a_y); if( global_optimize ) f.optimize(); // skip comparison operators f.compare_change_count(0); // calculate the Jacobian sparsity pattern for this function if( global_boolsparsity ) calc_sparsity(bool_sparsity, f); else calc_sparsity(set_sparsity, f); // structure that holds some of the work done by SparseJacobian CppAD::sparse_jacobian_work work; # ifdef CPPAD_COLPACK_SPEED if( global_colpack ) work.color_method = "colpack"; # endif while(repeat--) { // choose a value for x CppAD::uniform_01(n, x); // calculate the Jacobian at this x // (use forward mode because m > n ?) if( global_boolsparsity ) n_sweep = f.SparseJacobianForward( x, bool_sparsity, row, col, jacobian, work ); else n_sweep = f.SparseJacobianForward( x, set_sparsity, row, col, jacobian, work ); } } return true; }