cppadcg_gradient.hpp

View page source

Calculate Gradient Using CppAD CodeGen

Syntax

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

Purpose

This implements the cpp_gradient interface using CppAD CodeGen.

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_cppadcg.cpp contains an example and test using this class.

Source Code

# if CMPAD_HAS_CPPADCG

# include <filesystem>
# include <cmpad/gradient.hpp>
# include <cmpad/cppad/cppad.hpp>

namespace cmpad { namespace cppadcg { // BEGIN cmpad::cppadcg namespace
//
// cmpad::cppadcg::gradient
template < template<class ADVector> class Algo> class gradient
: public
cmpad::gradient {
private:
   //
   // Scalar, ADVector
   typedef CppAD::cg::CG<double>                   Scalar;
   typedef cmpad::vector< CppAD::AD<Scalar> >      ADVector;
   //
   // option_
   option_t                                           option_;
   //
   // algo_
   Algo<ADVector>                                     algo_;
   //
   // w_
   cmpad::vector<double>                              w_;
   //
   // dynamic_lib_
   std::unique_ptr< CppAD::cg::DynamicLib<double> >   dynamic_lib_;
   //
   // model_
   std::unique_ptr< CppAD::cg::GenericModel<double> > model_;
   //
   // g_
   cmpad::vector<double>                              g_;
//
public:
   // scalar_type
   typedef double scalar_type;
   //
   // vector_type
   typedef cmpad::vector<double> vector_type;
   //
   // option
   const option_t& option(void) const override
   {  return option_; }
   // setup
   void setup(const option_t& option) override
   {  // see https://github.com/joaoleal/CppADCodeGen/wiki/LibGeneration
      //
      // compiler
# if CMPAD_COMPILER_IS_GNU
      CppAD::cg::GccCompiler<double> compiler;
# endif
# if CMPAD_COMPILER_IS_CLANG
      CppAD::cg::ClangCompiler<double> compiler;
# endif
      // option_
      option_ = option;
      //
      // algo_
      algo_.setup(option);
      //
      // n
      size_t n = algo_.domain();
      //
      // m
      size_t m = algo_.range();
      //
      // optimize_options
      std::string optimize_options =
      "no_conditional_skip no_compare_op no_print_for_op no_cumulative_sum_op";
      //
      // tape
      CppAD::ADFun<Scalar>  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);
      //
      // path
      using std::filesystem::path;
      //
      // original_path
      path original_path = std::filesystem::current_path();
      //
      // current_path
      path temp_path = std::filesystem::temp_directory_path();
      std::filesystem::current_path(temp_path);
      //
      // cgen
      CppAD::cg::ModelCSourceGen<double> cgen(tape, "model");
      cgen.setCreateJacobian(true);
      //
      // libcgen
      CppAD::cg::ModelLibraryCSourceGen<double> libcgen(cgen);
      //
      // dynamic_lib_
      CppAD::cg::DynamicModelLibraryProcessor<double> proc(libcgen);
      dynamic_lib_ = nullptr;
      dynamic_lib_ = proc.createDynamicLibrary(compiler);
      //
      // model_
      model_ = nullptr;
      model_ = dynamic_lib_->model("model");
      //
      // current_path
      std::filesystem::current_path(original_path);
   }
   // domain
   size_t domain(void) const override
   {  return algo_.domain(); };
   //
   // operator
   const cmpad::vector<double>& operator()(
      const cmpad::vector<double>& x
   ) override
   {  g_ = model_->Jacobian(x);
      return g_;
   }
};

} } // END cmpad::cppadcg namespace

# endif // CMPAD_HAS_CPPADCG