code_gen_fun.cpp

View page source

code_gen_fun Class Member Implementation

See Also

code_gen_fun , code_gen_fun.hpp

Source

# include <cppad/example/code_gen_fun.hpp>

// ---------------------------------------------------------------------------
// code_gen_fun fun_name(file_name, cg_name, eval_jac)
// ---------------------------------------------------------------------------
// BEGIN_CTOR_CG_FUN
code_gen_fun::code_gen_fun(
   const std::string&                     file_name  ,
   CppAD::ADFun< CppAD::cg::CG<double> >& cg_fun     ,
   evaluation_enum                        eval_jac   )
// END_CTOR_CG_FUN
{  // Generate source code
   CppAD::cg::ModelCSourceGen<double> cgen(cg_fun, "model");
   switch(eval_jac)
   {  case none_enum:
      break;

      case dense_enum:
      cgen.setCreateJacobian(true);
      break;

      case sparse_enum:
      cgen.setCreateSparseJacobian(true);
      break;
   }
   CppAD::cg::ModelLibraryCSourceGen<double> libcgen(cgen);

   // Compile source, create the library file, and load the library
   CppAD::cg::DynamicModelLibraryProcessor<double> proc(libcgen, file_name);
   CppAD::cg::ClangCompiler<double> compiler;
   bool loadLib = true;
   dynamic_lib_ = proc.createDynamicLibrary(compiler, loadLib);
   //
   // create the model object
   model_        = dynamic_lib_->model("model");
}
// ---------------------------------------------------------------------------
// code_gen_fun fun_name(file_name)
// ---------------------------------------------------------------------------
// BEGIN_CTOR_FILE_NAME
code_gen_fun::code_gen_fun(const std::string&  file_name )
// END_CTOR_FILE_NAME
{  // file name plus extension used for dynamic libraries on this system
   std::string file_name_ext = file_name +
      CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION;

   // load the library
   CppAD::cg::DynamicLib<double>* ptr =
      new CppAD::cg::LinuxDynamicLib<double>(file_name_ext);
   dynamic_lib_  = std::unique_ptr< CppAD::cg::DynamicLib<double> >(ptr);
   //
   // create the model object
   model_        = dynamic_lib_->model("model");
}
// ---------------------------------------------------------------------------
// code_gen_fun fun_name
// ---------------------------------------------------------------------------
// BEGIN_CTOR_VOID
code_gen_fun::code_gen_fun(void)
// END_CTOR_VOID
{ }
// --------------------------------------------------------------------------
// fun_name.swap(other_fun)
// --------------------------------------------------------------------------
// BEGIN_SWAP_OTHER_FUN
void code_gen_fun::swap(code_gen_fun& other_fun)
// END_SWAP_OTHER_FUN
{  std::swap(dynamic_lib_, other_fun.dynamic_lib_);
   std::swap(model_, other_fun.model_ );
}
// --------------------------------------------------------------------------
// y = fun_name(x)
// --------------------------------------------------------------------------
// BEGIN_FUN_NAME_X
CppAD::vector<double>
code_gen_fun::operator()(const CppAD::vector<double>& x)
// END_FUN_NAME_X
{  return model_->ForwardZero(x);
}
// --------------------------------------------------------------------------
// J = fun_name.jacobian(x)
// --------------------------------------------------------------------------
// BEGIN_JACOBIAN
CppAD::vector<double>
code_gen_fun::jacobian(const CppAD::vector<double>& x)
// END_JACOBIAN
{  CPPAD_ASSERT_KNOWN( model_->isJacobianAvailable() ,
      "code_gen_fun: dense jacobian not enables during constructor"
   );
   return model_-> Jacobian(x);
}
// --------------------------------------------------------------------------
// Jrcv = fun_name.sparse_jacobian(x)
// --------------------------------------------------------------------------
// BEGIN_SPARSE_JACOBIAN
CppAD::sparse_rcv< CppAD::vector<size_t>, CppAD::vector<double> >
code_gen_fun::sparse_jacobian(const CppAD::vector<double>& x)
// END_SPARSE_JACOBIAN
{  CPPAD_ASSERT_KNOWN( model_->isSparseJacobianAvailable() ,
      "code_gen_fun: sparse jacobian not enabled during constructor"
   );
   // x_std
   size_t n = model_->Domain();
   std::vector<double> x_std(n);
   for(size_t j = 0; j < n; ++j)
      x_std[j] = x[j];
   //
   // 2DO: Prepahs CppAD should have a sparse_rcv constructor (jac, row, col)
   // that uses swap to swap the vectors
   //
   // jac, row, col
   std::vector<double> jac;
   std::vector<size_t> row, col;
   model_-> SparseJacobian(x_std, jac, row, col);
   //
   // sparse_rc
   size_t nr  = model_->Range();
   size_t nc  = model_->Domain();
   size_t nnz = row.size();
   CppAD::sparse_rc< CppAD::vector<size_t> > pattern(nr, nc, nnz);
   for(size_t k = 0; k < nnz; ++k)
      pattern.set(k, row[k], col[k]);
   // sparse_rcv
   CppAD::sparse_rcv< CppAD::vector<size_t>, CppAD::vector<double> >
   Jrcv(pattern);
   for(size_t k = 0; k < nnz; ++k)
      Jrcv.set(k, jac[k]);
   //
   return Jrcv;
}