Prev Next adolc_poly.cpp

Adolc Speed: Second Derivative of a Polynomial

link_poly
Routine that computes the second derivative of a polynomial using Adolc:
# include <vector>

# include <cppad/speed/uniform_01.hpp>
# include <cppad/poly.hpp>
# include <cppad/vector.hpp>

# include <adolc/adouble.h>
# include <adolc/interfaces.h>

bool link_poly(
     size_t                     size     , 
     size_t                     repeat   , 
     bool                       retape   ,
     CppAD::vector<double>     &a        ,  // coefficients of polynomial
     CppAD::vector<double>     &z        ,  // polynomial argument value
     CppAD::vector<double>     &ddp      )  // second derivative w.r.t z  
{
     // -----------------------------------------------------
     // setup
     int tag  = 0;  // tape identifier
     int keep = 1;  // keep forward mode results in buffer
     int m    = 1;  // number of dependent variables
     int n    = 1;  // number of independent variables
     int d    = 2;  // order of the derivative
     double f;      // function value
     int i;         // temporary index

     // choose a vector of polynomial coefficients
     CppAD::uniform_01(size, a);

     // AD copy of the polynomial coefficients
     std::vector<adouble> A(size);
     for(i = 0; i < int(size); i++)
          A[i] = a[i];

     // domain and range space AD values
     adouble Z, P;

     // allocate arguments to hos_forward
     double *x0 = 0;
     x0         = CPPAD_TRACK_NEW_VEC(n, x0);
     double *y0 = 0;
     y0         = CPPAD_TRACK_NEW_VEC(m, y0);
     double **x = 0;
     x          = CPPAD_TRACK_NEW_VEC(n, x);
     double **y = 0;
     y          = CPPAD_TRACK_NEW_VEC(m, y);
     for(i = 0; i < n; i++)
     {    x[i] = 0;
          x[i] = CPPAD_TRACK_NEW_VEC(d, x[i]);
     }
     for(i = 0; i < m; i++)
     {    y[i] = 0;
          y[i] = CPPAD_TRACK_NEW_VEC(d, y[i]);
     }
     // Taylor coefficient for argument
     x[0][0] = 1.;  // first order
     x[0][1] = 0.;  // second order
     

     if( retape ) while(repeat--)
     {    // choose an argument value
          CppAD::uniform_01(1, z);

          // declare independent variables
          trace_on(tag, keep);
          Z <<= z[0]; 

          // AD computation of the function value 
          P = CppAD::Poly(0, A, Z);

          // create function object f : Z -> P
          P >>= f;
          trace_off();

          // get the next argument value
          CppAD::uniform_01(1, z);
          x0[0] = z[0];

          // evaluate the polynomial at the new argument value
          hos_forward(tag, m, n, d, keep, x0, x, y0, y);

          // second derivative is twice second order Taylor coef
          ddp[0] = 2. * y[0][1];
     }
     else
     {
          // choose an argument value
          CppAD::uniform_01(1, z);

          // declare independent variables
          trace_on(tag, keep);
          Z <<= z[0]; 

          // AD computation of the function value 
          P = CppAD::Poly(0, A, Z);

          // create function object f : Z -> P
          P >>= f;
          trace_off();
          while(repeat--)
          {    // get the next argument value
               CppAD::uniform_01(1, z);
               x0[0] = z[0];

               // evaluate the polynomial at the new argument value
               hos_forward(tag, m, n, d, keep, x0, x, y0, y);

               // second derivative is twice second order Taylor coef
               ddp[0] = 2. * y[0][1];
          }
     }
     // ------------------------------------------------------
     // tear down
     CPPAD_TRACK_DEL_VEC(x0);
     CPPAD_TRACK_DEL_VEC(y0);
     for(i = 0; i < n; i++)
          CPPAD_TRACK_DEL_VEC(x[i]);
     for(i = 0; i < m; i++)
          CPPAD_TRACK_DEL_VEC(y[i]);
     CPPAD_TRACK_DEL_VEC(x);
     CPPAD_TRACK_DEL_VEC(y);

     return true;
}

Input File: speed/adolc/poly.cpp