cppad_gradient.hpp

View page source

Calculate Gradient Using CppAD

Syntax

      # include <cmpad/cppad/gradient.hpp>
      cmpad::cppad::gradient < Algo > grad
      grad .setup ( option )
      g = grad ( x )

Purpose

This implements the cpp_gradient interface using CppAD.

Algo

see Algo for the base class.

ADVector

The type Algo ::vector_type is the ADVector type for this gradient.

vector_type

see vector_type for the base class.

scalar_type

see scalar_type for the base class.

setup

see the gradient setup for the base class.

option

This option_t object is used to specify the setup options.

Example

The file xam_gradient_cppad.cpp contains an example and test using this class.

Source Code

# if CMPAD_HAS_CPPAD
# include <cmpad/gradient.hpp>
# include <cmpad/cppad/cppad.hpp>

namespace cmpad { namespace cppad { // BEGIN cmpad::cppad namespace

// cmpad::cppad::gradient
template < template<class ADVector> class Algo> class gradient
: public
::cmpad::gradient {
public:
   //
   // scalar_type
   typedef double scalar_type;
   //
   // vector_type
   typedef ::cmpad::vector<scalar_type> vector_type;
   //
private:
   // ADVector
   typedef typename ::cmpad::vector< CppAD::AD<scalar_type> >  ADVector;
   //
   // option_
   option_t                      option_;
   //
   // algo_
   Algo<ADVector>                algo_;
   //
   // w_
   vector_type                   w_;
   //
   // tape_
   CppAD::ADFun<scalar_type>     tape_;
   //
   // g_
   vector_type                   g_;
   //
public:
   //
   // option
   const option_t& option(void) const override
   {  return option_; }
   //
   // setup
   void setup(const option_t& option) override
   {  //
      // option_
      option_ = option;
      //
      // algo_
      algo_.setup(option);
      //
      // n
      size_t n = algo_.domain();
      //
      // m
      size_t m = algo_.range();
      //
      // w_
      w_.resize(1);
      w_[0] = 1.0;
      //
      // optimize_options
      std::string optimize_options =
      "no_conditional_skip no_compare_op no_print_for_op no_cumulative_sum_op";
      //
      // tape_
      ADVector ax(n);
      for(size_t i = 0; i < n; ++i)
         ax[i] = 0.;
      CppAD::Independent(ax);
      ADVector ay(1), az;
      az    = algo_(ax);
      ay[0] = az[m-1];
      tape_.Dependent(ax, ay);
      if( ! option.time_setup )
         tape_.optimize(optimize_options);
      //
      // g_
      g_.resize(n);
   }
   // domain
   size_t domain(void) const override
   {  return algo_.domain(); };
   //
   // operator
   const vector_type& operator()(const vector_type& x) override
   {  tape_.Forward(0, x);
      g_ =  tape_.Reverse(1, w_);
      return g_;
   }
};

} } // END cmpad::cppad namespace

# endif // CMPAD_HAS_CPPAD