Adolc Speed: Sparse Hessian
Keywords: adolc speed: sparse hessian link_sparse_hessian speed specifications implementation

| Prev | Next |  |  |  |  |  | adolc_sparse_hessian.cpp |

Adolc Speed: Sparse Hessian
Specifications
See link_sparse_hessian .
Implementation `

    # include <adolc/adolc.h>
    # include <adolc/adolc_sparse.h>
    # include <cppad/utility/vector.hpp>
    # include <cppad/speed/uniform_01.hpp>
    # include <cppad/utility/thread_alloc.hpp>
    # include <cppad/speed/sparse_hes_fun.hpp>

    // list of possible options
    extern bool global_memory, global_onetape, global_atomic, global_optimize;
    extern bool global_colpack, global_boolsparsity;

    bool link_sparse_hessian(
         size_t                           size     ,
         size_t                           repeat   ,
         const CppAD::vector<size_t>&     row      ,
         const CppAD::vector<size_t>&     col      ,
         CppAD::vector<double>&           x_return ,
         CppAD::vector<double>&           hessian  ,
         size_t&                          n_sweep )
    {
         if( global_atomic || (! global_colpack) )
              return false;
         if( global_memory || global_optimize || global_boolsparsity )
              return false;
         // -----------------------------------------------------
         // setup
         typedef unsigned int*    SizeVector;
         typedef double*          DblVector;
         typedef adouble          ADScalar;
         typedef ADScalar*        ADVector;

         size_t i, j, k;         // temporary indices
         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

         // setup for thread_alloc memory allocator (fast and checks for leaks)
         using CppAD::thread_alloc; // the allocator
         size_t capacity;           // capacity of an allocation

         // tape identifier
         int tag  = 0;
         // AD domain space vector
         ADVector a_x = thread_alloc::create_array<ADScalar>(n, capacity);
         // AD range space vector
         ADVector a_y = thread_alloc::create_array<ADScalar>(m, capacity);
         // double argument value
         DblVector x = thread_alloc::create_array<double>(n, capacity);
         // double function value
         double f;

         // options that control sparse_hess
         int        options[2];
         options[0] = 0; // safe mode
         options[1] = 0; // indirect recovery

         // structure that holds some of the work done by sparse_hess
         int        nnz;                   // number of non-zero values
         SizeVector rind   = CPPAD_NULL;   // row indices
         SizeVector cind   = CPPAD_NULL;   // column indices
         DblVector  values = CPPAD_NULL;   // Hessian values

         // ----------------------------------------------------------------------
         if( ! global_onetape ) while(repeat--)
         {    // choose a value for x
              CppAD::uniform_01(n, x);

              // declare independent variables
              int keep = 0; // keep forward mode results
              trace_on(tag, keep);
              for(j = 0; j < n; j++)
                   a_x[j] <<= x[j];

              // AD computation of f (x)
              CppAD::sparse_hes_fun<ADScalar>(n, a_x, row, col, order, a_y);

              // create function object f : x -> y
              a_y[0] >>= f;
              trace_off();

              // is this a repeat call with the same sparsity pattern
              int same_pattern = 0;

              // calculate the hessian at this x
              rind   = CPPAD_NULL;
              cind   = CPPAD_NULL;
              values = CPPAD_NULL;
              sparse_hess(tag, int(n),
                   same_pattern, x, &nnz, &rind, &cind, &values, options
              );
              // only needed last time through loop
              if( repeat == 0 )
              {    size_t K = row.size();
                   for(int ell = 0; ell < nnz; ell++)
                   {    i = size_t(rind[ell]);
                        j = size_t(cind[ell]);
                        for(k = 0; k < K; k++)
                        {    if( (row[k]==i && col[k]==j) || (row[k]==j && col[k]==i) )
                                  hessian[k] = values[ell];
                        }
                   }
              }

              // free raw memory allocated by sparse_hess
              free(rind);
              free(cind);
              free(values);
         }
         else
         {    // choose a value for x
              CppAD::uniform_01(n, x);

              // declare independent variables
              int keep = 0; // keep forward mode results
              trace_on(tag, keep);
              for(j = 0; j < n; j++)
                   a_x[j] <<= x[j];

              // AD computation of f (x)
              CppAD::sparse_hes_fun<ADScalar>(n, a_x, row, col, order, a_y);

              // create function object f : x -> y
              a_y[0] >>= f;
              trace_off();

              // is this a repeat call at the same argument
              int same_pattern = 0;

              while(repeat--)
              {    // choose a value for x
                   CppAD::uniform_01(n, x);

                   // calculate the hessian at this x
                   sparse_hess(tag, int(n),
                        same_pattern, x, &nnz, &rind, &cind, &values, options
                   );
                   same_pattern = 1;
              }
              size_t K = row.size();
              for(int ell = 0; ell < nnz; ell++)
              {    i = size_t(rind[ell]);
                   j = size_t(cind[ell]);
                   for(k = 0; k < K; k++)
                   {    if( (row[k]==i && col[k]==j) || (row[k]==j && col[k]==i) )
                             hessian[k] = values[ell];
                   }
              }
              // free raw memory allocated by sparse_hessian
              free(rind);
              free(cind);
              free(values);
         }
         // --------------------------------------------------------------------
         // return argument
         for(j = 0; j < n; j++)
              x_return[j] = x[j];

         // do not know how to return number of sweeps used
         n_sweep = 0;

         // tear down
         thread_alloc::delete_array(a_x);
         thread_alloc::delete_array(a_y);
         thread_alloc::delete_array(x);
         return true;

    }

`

Input File: speed/adolc/sparse_hessian.cpp