multiprecision-mpfr.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 INRIA
3 //
4 
5 #include "pinocchio/math/multiprecision-mpfr.hpp"
6 
7 #include <boost/math/special_functions/gamma.hpp>
8 #include <boost/multiprecision/cpp_dec_float.hpp>
9 #include <boost/test/unit_test.hpp>
10 #include <boost/utility/binary.hpp>
11 #include <iostream>
12 
13 #include "pinocchio/algorithm/aba.hpp"
14 #include "pinocchio/algorithm/center-of-mass.hpp"
15 #include "pinocchio/algorithm/centroidal.hpp"
16 #include "pinocchio/algorithm/crba.hpp"
17 #include "pinocchio/algorithm/jacobian.hpp"
18 #include "pinocchio/algorithm/joint-configuration.hpp"
19 #include "pinocchio/algorithm/rnea.hpp"
20 #include "pinocchio/math/multiprecision.hpp"
21 #include "pinocchio/parsers/sample-models.hpp"
22 
23 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
24 
26 {
27  using namespace boost::multiprecision;
28 
29  // Operations at fixed precision and full numeric_limits support:
30  mpfr_float_100 b = 2;
31  std::cout << std::numeric_limits<mpfr_float_100>::digits << std::endl;
32  std::cout << std::numeric_limits<mpfr_float_100>::digits10 << std::endl;
33  // We can use any C++ std lib function, lets print all the digits as well:
34  std::cout << std::setprecision(
35  std::numeric_limits<mpfr_float_100>::max_digits10)
36  << log(b)
37  << std::endl; // print log(2)
38  // We can also use any function from Boost.Math:
39  std::cout << boost::math::tgamma(b) << std::endl;
40  // These even work when the argument is an expression template:
41  std::cout << boost::math::tgamma(b * b) << std::endl;
42  // And since we have an extended exponent range we can generate some really
43  // large numbers here (4.0238726007709377354370243e+2564):
44  std::cout << boost::math::tgamma(mpfr_float_100(1000)) << std::endl;
45 }
46 
48 {
49  using namespace boost::multiprecision;
50  typedef mpfr_float_100 heap_float_100;
51  typedef number<mpfr_float_backend<100, allocate_stack> > stack_float_100;
52  {
53  heap_float_100 x;
54  heap_float_100 s;
55  heap_float_100 c;
56  x = 100;
57  pinocchio::SINCOS(x, &s, &c);
58  BOOST_CHECK(s == sin(x));
59  BOOST_CHECK(c == cos(x));
60  }
61  {
62  stack_float_100 x;
63  stack_float_100 s;
64  stack_float_100 c;
65  x = 100;
66  pinocchio::SINCOS(x, &s, &c);
67  BOOST_CHECK(s == sin(x));
68  BOOST_CHECK(c == cos(x));
69  }
70 }
71 
73 {
74  typedef boost::multiprecision::mpfr_float_100 float_100;
75 
76  // Test Scalar cast
77  double initial_value = boost::math::constants::pi<double>();
78  float_100 value_100(initial_value);
79  double value_cast = value_100.convert_to<double>();
80  BOOST_CHECK(initial_value == value_cast);
81 
82  typedef Eigen::Matrix<float_100, Eigen::Dynamic, 1> VectorFloat100;
83  static const Eigen::DenseIndex dim = 100;
84  Eigen::VectorXd initial_vec = Eigen::VectorXd::Random(dim);
85  VectorFloat100 vec_float_100 = initial_vec.cast<float_100>();
86  Eigen::VectorXd vec = vec_float_100.cast<double>();
87 
88  BOOST_CHECK(vec == initial_vec);
89 }
90 
91 #define BOOST_CHECK_IS_APPROX(double_field, multires_field, Scalar) \
92  BOOST_CHECK(double_field.isApprox(multires_field.cast<Scalar>()))
93 
94 BOOST_AUTO_TEST_CASE(test_mutliprecision)
95 {
96  using namespace pinocchio;
97 
98  Model model;
100  Data data(model);
101 
102  model.lowerPositionLimit.head<3>().fill(-1.);
103  model.upperPositionLimit.head<3>().fill(1.);
104 
105  typedef boost::multiprecision::mpfr_float_100 float_100;
106  typedef ModelTpl<float_100> ModelMulti;
107  typedef DataTpl<float_100> DataMulti;
108 
109  ModelMulti model_multi = model.cast<float_100>();
110  DataMulti data_multi(model_multi);
111 
112  ModelMulti::ConfigVectorType q_multi = randomConfiguration(model_multi);
113  ModelMulti::TangentVectorType v_multi =
114  ModelMulti::TangentVectorType::Random(model_multi.nv);
115  ModelMulti::TangentVectorType a_multi =
116  ModelMulti::TangentVectorType::Random(model_multi.nv);
117  ModelMulti::TangentVectorType tau_multi =
118  ModelMulti::TangentVectorType::Random(model_multi.nv);
119 
120  // Model::ConfigVectorType q = randomConfiguration(model);
121  // Model::TangentVectorType v = Model::TangentVectorType::Random(model.nv);
122  // Model::TangentVectorType a = Model::TangentVectorType::Random(model.nv);
123  // Model::TangentVectorType tau = Model::TangentVectorType::Random(model.nv);
124 
125  Model::ConfigVectorType q = q_multi.cast<double>();
126  Model::TangentVectorType v = v_multi.cast<double>();
127  Model::TangentVectorType a = a_multi.cast<double>();
128  Model::TangentVectorType tau = tau_multi.cast<double>();
129 
130  forwardKinematics(model_multi, data_multi, q_multi, v_multi, a_multi);
131  forwardKinematics(model, data, q, v, a);
132 
133  for (JointIndex joint_id = 1; joint_id < (JointIndex)model.njoints;
134  ++joint_id)
135  {
136  BOOST_CHECK_IS_APPROX(data.oMi[joint_id], data_multi.oMi[joint_id], double);
137  BOOST_CHECK_IS_APPROX(data.v[joint_id], data_multi.v[joint_id], double);
138  BOOST_CHECK_IS_APPROX(data.a[joint_id], data_multi.a[joint_id], double);
139  }
140 
141  // Jacobians
142  computeJointJacobians(model_multi, data_multi, q_multi);
143  computeJointJacobians(model, data, q);
144 
145  BOOST_CHECK_IS_APPROX(data.J, data_multi.J, double);
146 
147  // Inverse Dynamics
148  rnea(model_multi, data_multi, q_multi, v_multi, a_multi);
149  rnea(model, data, q, v, a);
150 
151  BOOST_CHECK_IS_APPROX(data.tau, data_multi.tau, double);
152 
153  // Forward Dynamics
154  aba(model_multi, data_multi, q_multi, v_multi, tau_multi);
155  aba(model, data, q, v, tau);
156 
157  BOOST_CHECK_IS_APPROX(data.ddq, data_multi.ddq, double);
158 
159  // Mass matrix
160  crba(model_multi, data_multi, q_multi);
161  data_multi.M.triangularView<Eigen::StrictlyLower>() =
162  data_multi.M.transpose().triangularView<Eigen::StrictlyLower>();
163 
164  crba(model, data, q);
165  data.M.triangularView<Eigen::StrictlyLower>() =
166  data.M.transpose().triangularView<Eigen::StrictlyLower>();
167 
168  BOOST_CHECK_IS_APPROX(data.M, data_multi.M, double);
169 }
170 
171 BOOST_AUTO_TEST_SUITE_END()
const DataTpl< Scalar, Options, JointCollectionTpl >::TangentVectorType & aba(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType1 > &v, const Eigen::MatrixBase< TangentVectorType2 > &tau)
The Articulated-Body algorithm. It computes the forward dynamics, aka the joint accelerations given t...
TangentVectorType tau
Vector of joint torques (dim model.nv).
const DataTpl< Scalar, Options, JointCollectionTpl >::MatrixXs & crba(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q)
Computes the upper triangular part of the joint space inertia matrix M by using the Composite Rigid B...
q
Matrix6x J
Jacobian of joint placements.
Vec3f b
void rnea(const int num_threads, ModelPoolTpl< Scalar, Options, JointCollectionTpl > &pool, const Eigen::MatrixBase< ConfigVectorPool > &q, const Eigen::MatrixBase< TangentVectorPool1 > &v, const Eigen::MatrixBase< TangentVectorPool2 > &a, const Eigen::MatrixBase< TangentVectorPool3 > &tau)
The Recursive Newton-Euler algorithm. It computes the inverse dynamics, aka the joint torques accordi...
ModelTpl< NewScalar, Options, JointCollectionTpl > cast() const
int njoints
Number of joints.
ConfigVectorType lowerPositionLimit
Lower joint configuration limit.
void randomConfiguration(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorIn1 > &lowerLimits, const Eigen::MatrixBase< ConfigVectorIn2 > &upperLimits, const Eigen::MatrixBase< ReturnType > &qout)
Generate a configuration vector uniformly sampled among provided limits.
Vec3f c
int dim
VectorXs TangentVectorType
Dense vectorized version of a joint tangent vector (e.g. velocity, acceleration, etc). It also handles the notion of co-tangent vector (e.g. torque, etc).
fill
vec
void forwardKinematics(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q)
Update the joint placements according to the current joint configuration.
x
MatrixXs M
The joint space inertia matrix (a square matrix of dim model.nv).
Vec3f a
TangentVectorType ddq
The joint accelerations computed from ABA.
void SINCOS(const S1 &a, S2 *sa, S3 *ca)
Computes sin/cos values of a given input scalar.
Definition: sincos.hpp:26
Main pinocchio namespace.
Definition: timings.cpp:28
const DataTpl< Scalar, Options, JointCollectionTpl >::Matrix6x & computeJointJacobians(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q)
Computes the full model Jacobian, i.e. the stack of all motion subspace expressed in the world frame...
BOOST_AUTO_TEST_CASE(test_basic)
VectorXs ConfigVectorType
Dense vectorized version of a joint configuration vector.
ConfigVectorType upperPositionLimit
Upper joint configuration limit.
#define BOOST_CHECK_IS_APPROX(double_field, multires_field, Scalar)
void humanoidRandom(ModelTpl< Scalar, Options, JointCollectionTpl > &model, bool usingFF=true)
Create a humanoid kinematic tree with 6-DOF limbs and random joint placements.
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > VectorXd
Definition: conversions.cpp:14


pinocchio
Author(s):
autogenerated on Fri Jun 23 2023 02:38:32