joaoleal / CppADCodeGen

Source Code Generation for Automatic Differentiation using Operator Overloading
Other
162 stars 36 forks source link

Examples on using CppADCodeGen with Eigen #71

Open fdevinc opened 2 years ago

fdevinc commented 2 years ago

I am struggling to generate AD code involving Eigen vectors (both with fixed and dynamic sizes) and matrices (both sparse and dense). Until now, I have been using autodiff with great satisfaction. Unfortunately, now I require very efficient code, and since autodiff does not separately generate the derivatives, it is not sufficient anymore. Hence my decision to switch to CppADCodeGen! However, its documentation is very succinct and not user-friendly -- at least, for an AD layman like myself. This is especially true when talking about the differentiation of Eigen-based functions.

Would it be possible for some advanced users/developers of CppADCodeGen to add more examples using Eigen types? The more articulated, the better! As a starting point, you may consider the examples from the autodiff library I mentioned, which are clear and exhaustive in my opinion. As a user, that is exactly what I would like to have when I start using a new library: it quickly sets me on track to employ it and, eventually, contribute to it.

Thank you very much!

P.S.: if such examples exist and I missed them, could you kindly address me to them?

bradbell commented 2 years ago

You might take a look at https://coin-or.github.io/CppAD/doc/code_gen_fun.htm

You could combine this with any of the CppAD examples and generate compiled code for a function that corresponded to the derivatives you want. For CppAD examples using Eigen; see https://coin-or.github.io/CppAD/doc/eigen.htm

The problem with this example is that it makes CppAD depend on CppADCodeGen which in turn depends on CppAD. This makes the install of CppAD with this utility difficult.

It would be nice if some made this part of CppADCodeGen.

joaoleal commented 2 years ago

Hello,

At the moment there is no page explicitly for Eigen in the wiki. There really isn't anything special regarding the use of CppADCodeGen with Eigen with the exception that there is an additional file that should be included:

#include "cppad/cg/support/cppadcg_eigen.hpp"

I will add an example in the wiki.

Please bear in mind that it is not recommended to use Eigen with operations that depend on the values of variables (e.g., solving a linear system) to decide which operations must be done since CppADCodeGen creates static code.

Kind regards.

fdevinc commented 2 years ago

You might take a look at https://coin-or.github.io/CppAD/doc/code_gen_fun.htm

The problem with this example is that it makes CppAD depend on CppADCodeGen which in turn depends on CppAD. This makes the install of CppAD with this utility difficult.

It would be nice if some made this part of CppADCodeGen.

@bradbell Another problem with this example is that it is hard to understand, especially if you compare it to the ones of autodiff, and I do not see where Eigen is mentioned.

At the moment there is no page explicitly for Eigen in the wiki. There really isn't anything special regarding the use of CppADCodeGen with Eigen with the exception that there is an additional file that should be included:

#include "cppad/cg/support/cppadcg_eigen.hpp"

I will add an example in the wiki.

@joaoleal Thank you very much, I think it would be very helpful for the community! It would be great if you could show a somewhat complete example, where you mix static and dynamic matrices, dense and sparse Jacobians, maybe even Hessians. Something structured like this would be a nice start in my opinion.

Please bear in mind that it is not recommended to use Eigen with operations that depend on the values of variables (e.g., solving a linear system) to decide which operations must be done since CppADCodeGen creates static code.

I see, thank you for letting me know. I guess that matrix inversions should be fine, right?

ccasam commented 2 years ago

Hello,

I am also interested in using CppADCodeGen and the lack of well structured and exhaustive examples is currently being a showstopper for me. I think there are many functionalities that are not explained. @joaoleal I really look forward to seeing more examples/improvements in the wiki, it would help us a lot!

Thank you very much! :)

nikolalm commented 1 year ago

Hi,

I am trying to use eigen inverse with CppADCG. However, it reports "GreaterThanZero cannot be called for non-parameters" error when the codes are generated for eigen inverse. The codes are compiled ok though. This error occurs at run-time when auto diff codes are generated. My code snippets are listed below:

using ad_base_t = CppAD::cg::CG<double>;
using ad_scalar_t = CppAD::AD<ad_base_t>;
using ad_vector_t = Eigen::Matrix<ad_scalar_t, Eigen::Dynamic, 1>;
using ad_matrix_t = Eigen::Matrix<ad_scalar_t, Eigen::Dynamic, Eigen::Dynamic>;

ad_matrix_t inv = De_robot(q).inverse();
// De_robot is a function defined as 
//Eigen::Matrix<ocs2::ad_scalar_t,18,18> De_robot(const Eigen::Matrix<ocs2::ad_scalar_t,18,1> &var1). 
//q is the independent variable.

Please bear in mind that it is not recommended to use Eigen with operations that depend on the values of variables (e.g., solving a linear system) to decide which operations must be done since CppADCodeGen creates static code.

@joaoleal Does this statement imply that matrices cannot be inverted.