cppadcg/basic.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2018-2019 CNRS INRIA
3 //
4 
6 
9 
10 #include <iostream>
11 
12 #include <boost/test/unit_test.hpp>
13 #include <boost/utility/binary.hpp>
14 
15 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
16 
17 BOOST_AUTO_TEST_CASE(test_simple_cppadcg)
18 {
19  using namespace CppAD;
20  using namespace CppAD::cg;
21 
22  typedef CG<double> CGD;
23  typedef AD<CGD> ADCG;
24 
25  /***************************************************************************
26  * the model
27  **************************************************************************/
28 
29  // independent variable vector
30  CppAD::vector<ADCG> x(2);
31  x[0] = 2.;
32  x[1] = 3.;
33  Independent(x);
34 
35  // dependent variable vector
36  CppAD::vector<ADCG> y(1);
37 
38  // the model
39  ADCG a = x[0] / 1. + x[1] * x[1];
40  y[0] = a / 2;
41 
42  ADFun<CGD> fun(x, y); // the model tape
43 
44  /***************************************************************************
45  * Generate the C source code
46  **************************************************************************/
47 
51  CodeHandler<double> handler;
52 
53  CppAD::vector<CGD> indVars(2);
54  handler.makeVariables(indVars);
55 
56  CppAD::vector<CGD> jac = fun.SparseJacobian(indVars);
57 
58  LanguageC<double> langC("double");
59  LangCDefaultVariableNameGenerator<double> nameGen;
60 
61  std::ostringstream code;
62  handler.generateCode(code, langC, jac, nameGen);
63  std::cout << code.str();
64 }
65 
66 BOOST_AUTO_TEST_CASE(test_eigen_support)
67 {
68  typedef CppAD::cg::CG<double> CGD;
69  typedef CppAD::AD<CGD> ADCG;
70 
71  typedef Eigen::Matrix<ADCG, Eigen::Dynamic, 1> ADCGVector;
72 
73  ADCGVector vec_zero(ADCGVector::Zero(100));
74  BOOST_CHECK(vec_zero.isZero());
75 
76  ADCGVector vec_ones(10);
77  vec_ones.fill((ADCG)1);
78  BOOST_CHECK(vec_ones.isOnes());
79  // std::cout << (ADCG)1 << std::endl;
80 
81  ADCG value_one(1.);
82 
83  ADCG value_nan;
84  value_nan = NAN;
85 
86  // nan
87  ADCGVector vec_nan(10);
88  vec_nan.fill((ADCG)NAN);
90  // std::cout << vec_nan.transpose() << std::endl;
91  //
92  // // abs
93  ADCG val_minus_one(-1.);
94  ADCG val_abs(abs(val_minus_one));
95  ADCGVector vec_minus_one(10);
96  vec_minus_one.fill(val_minus_one);
97  vec_minus_one.array().abs();
98 
99  BOOST_CHECK(!vec_ones.isUnitary());
100 }
101 
103 {
104  typedef CppAD::cg::CG<double> CGScalar;
105  typedef CppAD::AD<double> ADScalar;
106  typedef CppAD::AD<float> ADFloat;
107  typedef pinocchio::ModelTpl<CGScalar> CGModel;
108 
110  typedef pinocchio::SE3Tpl<CGScalar> CGSE3;
111 
112  CGSE3 cg_M = M.cast<CGScalar>();
113  BOOST_CHECK(cg_M.cast<double>().isApprox(M));
114 
115  pinocchio::SE3::Vector3 axis(1., 1., 1.);
116  axis.normalize();
117  BOOST_CHECK(axis.isUnitary());
118 
120  typedef pinocchio::JointModelPrismaticUnalignedTpl<CGScalar> CGJointModelPrismaticUnaligned;
121 
122  CGScalar cg_value;
123  cg_value = -1.;
124  ADScalar ad_value;
125  ad_value = -1.;
126  ADFloat ad_float;
127  ad_float = -1.;
128  abs(ad_value);
129  abs(ad_float);
130  abs(cg_value);
131 
132  CPPAD_TESTVECTOR(ADScalar) ad_x(3);
133  CGJointModelPrismaticUnaligned cg_jmodel_prismatic(axis.cast<CGScalar>());
134 
137 
138  CGModel cg_model = model.cast<CGScalar>();
139 
140  {
141  CppAD::AD<double> ad_value(-1.);
142  abs(ad_value); // works perfectly
143 
144  CppAD::cg::CG<double> cg_value(-1.);
145  abs(cg_value); // does not compile because abs<double>(const CppAD::cg::CG<double>&) is defined
146  // in namespace CppAD and not CppAD::cg
147  }
148 }
149 
150 BOOST_AUTO_TEST_CASE(test_dynamic_link)
151 {
152  using namespace CppAD;
153  using namespace CppAD::cg;
154 
155  // use a special object for source code generation
156  typedef CG<double> CGD;
157  typedef AD<CGD> ADCG;
158 
159  typedef AD<double> ADScalar;
160 
161  /***************************************************************************
162  * the model
163  **************************************************************************/
164 
165  // independent variable vector
166  std::vector<ADCG> x(2);
167  Independent(x);
168 
169  // dependent variable vector
170  std::vector<ADCG> y(1);
171 
172  // the model equation
173  ADCG a = x[0] / 1. + x[1] * x[1];
174  y[0] = a / 2;
175 
176  ADFun<CGD> fun(x, y);
177 
178  /***************************************************************************
179  * Create the dynamic library
180  * (generates and compiles source code)
181  **************************************************************************/
182  // generates source code
183  ModelCSourceGen<double> cgen(fun, "model");
184  cgen.setCreateJacobian(true);
185  cgen.setCreateForwardOne(true);
186  cgen.setCreateReverseOne(true);
187  cgen.setCreateReverseTwo(true);
188  ModelLibraryCSourceGen<double> libcgen(cgen);
189 
190  // compile source code
191  DynamicModelLibraryProcessor<double> p(libcgen);
192 
193  GccCompiler<double> compiler(PINOCCHIO_CXX_COMPILER);
194  std::unique_ptr<DynamicLib<double>> dynamicLib = p.createDynamicLibrary(compiler);
195 
196  // save to files (not really required)
197  SaveFilesModelLibraryProcessor<double> p2(libcgen);
198  p2.saveSources();
199 
200  /***************************************************************************
201  * Use the dynamic library
202  **************************************************************************/
203 
204  std::unique_ptr<GenericModel<double>> model = dynamicLib->model("model");
205  CPPAD_TESTVECTOR(double) xv(x.size());
206  xv[0] = 2.5;
207  xv[1] = 3.5;
208  CPPAD_TESTVECTOR(double) jac = model->Jacobian(xv);
209 
210  std::vector<ADScalar> x_ad(2);
211  Independent(x_ad);
212 
213  // dependent variable vector
214  std::vector<ADScalar> y_ad(1);
215 
216  // the model equation
217  ADScalar a_ad = x_ad[0] / 1. + x_ad[1] * x_ad[1];
218  y_ad[0] = a_ad / 2;
219 
220  ADFun<double> ad_fun(x_ad, y_ad);
221 
222  CPPAD_TESTVECTOR(double) jac_ref = ad_fun.Jacobian(xv);
223 
224  // print out the result
225  std::cout << jac[0] << " " << jac[1] << std::endl;
226 
227  BOOST_CHECK(
228  Eigen::Map<Eigen::Vector2d>(jac.data()).isApprox(Eigen::Map<Eigen::Vector2d>(jac_ref.data())));
229 }
230 
231 BOOST_AUTO_TEST_SUITE_END()
pinocchio::SE3Tpl< context::Scalar, context::Options >::Vector3
traits< SE3Tpl >::Vector3 Vector3
Definition: spatial/se3-tpl.hpp:55
cppadcg.hpp
codegen-rnea.jac
jac
Definition: codegen-rnea.py:41
y
y
pinocchio::SE3Tpl< context::Scalar, context::Options >
model.hpp
pinocchio::buildModels::humanoidRandom
void humanoidRandom(ModelTpl< Scalar, Options, JointCollectionTpl > &model, bool usingFF=true)
Create a humanoid kinematic tree with 6-DOF limbs and random joint placements.
CppAD
Definition: autodiff/cppad.hpp:146
codegen-rnea.langC
langC
Definition: codegen-rnea.py:43
anymal-simulation.model
model
Definition: anymal-simulation.py:8
dpendulum.p
p
Definition: dpendulum.py:7
codegen-rnea.handler
handler
Definition: codegen-rnea.py:36
codegen-rnea.nameGen
nameGen
Definition: codegen-rnea.py:44
x
x
M
M
axis
axis
codegen-rnea.code
code
Definition: codegen-rnea.py:45
a
Vec3f a
pinocchio::JointModelPrismaticUnalignedTpl
Definition: multibody/joint/fwd.hpp:94
pinocchio::SE3Tpl::Random
static SE3Tpl Random()
Definition: spatial/se3-tpl.hpp:154
sample-models.hpp
codegen-rnea.fun
fun
Definition: codegen-rnea.py:27
pinocchio::ModelTpl
Definition: context/generic.hpp:20
CppAD::cg
Definition: codegen/cppadcg.hpp:95
codegen-rnea.indVars
indVars
Definition: codegen-rnea.py:38
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(test_simple_cppadcg)
Definition: cppadcg/basic.cpp:17


pinocchio
Author(s):
autogenerated on Thu Dec 19 2024 03:41:25