30 template <
int IN_DIM,
int OUT_DIM>
31 class DerivativesCppadCG
34 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
36 typedef ADCGScalar CG_SCALAR;
37 typedef ADCGValueType CG_VALUE_TYPE;
39 typedef Eigen::Matrix<CG_SCALAR, IN_DIM, 1> IN_TYPE_CG;
40 typedef Eigen::Matrix<CG_SCALAR, OUT_DIM, 1> OUT_TYPE_CG;
41 typedef Eigen::Matrix<bool, IN_DIM, OUT_DIM> Sparsity;
42 typedef Eigen::Matrix<bool, IN_DIM, IN_DIM> HessianSparsity;
44 typedef std::function<OUT_TYPE_CG(const IN_TYPE_CG&)> FUN_TYPE_CG;
59 DerivativesCppadCG(FUN_TYPE_CG& f,
int inputDim = IN_DIM,
int outputDim = OUT_DIM)
60 : cgStdFun_(f), inputDim_(inputDim), outputDim_(outputDim), tmpVarCount_(0)
62 if (outputDim > 0 && inputDim > 0)
67 DerivativesCppadCG(
const DerivativesCppadCG& arg)
68 : cgStdFun_(arg.cgStdFun_), inputDim_(arg.inputDim_), outputDim_(arg.outputDim_), tmpVarCount_(arg.tmpVarCount_)
73 virtual ~DerivativesCppadCG() =
default;
75 DerivativesCppadCG* clone()
const {
return new DerivativesCppadCG<IN_DIM, OUT_DIM>(*this); }
92 void generateJacobianSource(
const std::string& derivativeName,
93 const std::string& outputDir = ct::core::CODEGEN_OUTPUT_DIR,
94 const std::string& templateDir = ct::core::CODEGEN_TEMPLATE_DIR,
95 const std::string& ns1 =
"core",
96 const std::string& ns2 =
"generated",
97 const Sparsity& sparsity = Sparsity::Ones(),
98 bool useReverse =
true,
99 bool ignoreZero =
true)
101 internal::SparsityPattern pattern;
102 pattern.initPattern(sparsity);
104 size_t jacDimension = IN_DIM * OUT_DIM;
106 std::string codeJac = internal::CGHelpers::generateJacobianSource(
107 cgCppadFun_, pattern, jacDimension, tmpVarCount_, useReverse, ignoreZero);
109 writeCodeFile(templateDir,
"/Jacobian.tpl.h",
"/Jacobian.tpl.cpp", outputDir, derivativeName, ns1, ns2, codeJac,
110 "AUTOGENERATED_CODE_PLACEHOLDER");
129 void generateForwardZeroSource(
const std::string& forwardZeroName,
130 const std::string& outputDir = ct::core::CODEGEN_OUTPUT_DIR,
131 const std::string& templateDir = ct::core::CODEGEN_TEMPLATE_DIR,
132 const std::string& ns1 =
"core",
133 const std::string& ns2 =
"generated",
134 bool ignoreZero =
true)
136 std::string codeJac = internal::CGHelpers::generateForwardZeroSource(cgCppadFun_, tmpVarCount_, ignoreZero);
138 writeCodeFile(templateDir,
"/ForwardZero.tpl.h",
"/ForwardZero.tpl.cpp", outputDir, forwardZeroName, ns1, ns2,
139 codeJac,
"AUTOGENERATED_CODE_PLACEHOLDER");
160 void generateHessianSource(
const std::string& derivativeName,
161 const std::string& outputDir = ct::core::CODEGEN_OUTPUT_DIR,
162 const std::string& templateDir = ct::core::CODEGEN_TEMPLATE_DIR,
163 const std::string& ns1 =
"core",
164 const std::string& ns2 =
"generated",
165 const HessianSparsity& sparsity = HessianSparsity::Ones(),
166 bool useReverse =
true,
167 bool ignoreZero =
true)
169 internal::SparsityPattern pattern;
170 pattern.initPattern(sparsity);
172 size_t hesDimension = IN_DIM * IN_DIM;
174 std::string codeHes =
175 internal::CGHelpers::generateHessianSource(cgCppadFun_, pattern, hesDimension, tmpVarCount_, ignoreZero);
177 writeCodeFile(templateDir,
"/Hessian.tpl.h",
"/Hessian.tpl.cpp", outputDir, derivativeName, ns1, ns2, codeHes,
178 "AUTOGENERATED_CODE_PLACEHOLDER");
187 Eigen::Matrix<CG_SCALAR, Eigen::Dynamic, 1>
x(inputDim_);
192 CppAD::Independent(x);
195 Eigen::Matrix<CG_SCALAR, Eigen::Dynamic, 1> y(outputDim_);
200 CppAD::ADFun<CG_VALUE_TYPE> fCodeGen(x, y);
204 cgCppadFun_ = fCodeGen;
217 void writeCodeFile(
const std::string& templateDir,
218 const std::string& tplHeaderName,
219 const std::string& tplSourceName,
220 const std::string& outputDir,
221 const std::string& derivativeName,
222 const std::string& ns1,
223 const std::string& ns2,
224 const std::string& codeJac,
225 const std::string& codePlaceholder)
227 std::cout <<
"Writing code of " + derivativeName +
" to file..." << std::endl;
229 std::string header = internal::CGHelpers::parseFile(templateDir + tplHeaderName);
230 std::string source = internal::CGHelpers::parseFile(templateDir + tplSourceName);
232 replaceSizesAndNames(header, derivativeName, ns1, ns2);
233 replaceSizesAndNames(source, derivativeName, ns1, ns2);
235 internal::CGHelpers::replaceOnce(header,
"MAX_COUNT", std::to_string(tmpVarCount_));
236 internal::CGHelpers::replaceOnce(source, codePlaceholder, codeJac);
239 internal::CGHelpers::writeFile(outputDir +
"/" + derivativeName +
".h", header);
240 internal::CGHelpers::writeFile(outputDir +
"/" + derivativeName +
".cpp", source);
243 std::cout <<
"... Done! Successfully generated " + derivativeName << std::endl;
255 void replaceSizesAndNames(std::string& file,
256 const std::string& systemName,
257 const std::string& ns1,
258 const std::string& ns2)
260 internal::CGHelpers::replaceAll(file,
"DERIVATIVE_NAME", systemName);
261 internal::CGHelpers::replaceAll(file,
"NS1", ns1);
262 internal::CGHelpers::replaceAll(file,
"NS2", ns2);
263 internal::CGHelpers::replaceAll(file,
"IN_DIM", std::to_string(IN_DIM));
264 internal::CGHelpers::replaceAll(file,
"OUT_DIM", std::to_string(OUT_DIM));
267 std::function<OUT_TYPE_CG(const IN_TYPE_CG&)> cgStdFun_;
272 CppAD::ADFun<CG_VALUE_TYPE> cgCppadFun_;
ct::core::StateVector< state_dim > x