\(\newcommand{\B}[1]{ {\bf #1} }\) \(\newcommand{\R}[1]{ {\rm #1} }\)
cppadcg_gradient.hpp¶
View page sourceCalculate 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