GCC Code Coverage Report


Directory: ./
File: unittest/test_activations.cpp
Date: 2025-03-26 19:23:43
Exec Total Coverage
Lines: 89 89 100.0%
Branches: 178 354 50.3%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2025, LAAS-CNRS, New York University,
5 // Max Planck Gesellschaft, University of Edinburgh,
6 // INRIA, Heriot-Watt University
7 // Copyright note valid unless otherwise stated in individual files.
8 // All rights reserved.
9 ///////////////////////////////////////////////////////////////////////////////
10
11 #define BOOST_TEST_NO_MAIN
12 #define BOOST_TEST_ALTERNATIVE_INIT_API
13
14 #include "crocoddyl/core/activations/quadratic-barrier.hpp"
15 #include "factory/activation.hpp"
16 #include "unittest_common.hpp"
17
18 using namespace boost::unit_test;
19 using namespace crocoddyl::unittest;
20
21 //----------------------------------------------------------------------------//
22
23 9 void test_construct_data(ActivationModelTypes::Type activation_type) {
24 // create the model
25
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 ActivationModelFactory factory;
26 const std::shared_ptr<crocoddyl::ActivationModelAbstract>& model =
27
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 factory.create(activation_type);
28
29 // Run the print function
30
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 std::ostringstream tmp;
31
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 tmp << *model;
32
33 // create the corresponding data object
34 const std::shared_ptr<crocoddyl::ActivationDataAbstract>& data =
35
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 model->createData();
36 const std::shared_ptr<crocoddyl::ActivationDataAbstractTpl<float>>&
37
2/4
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
9 casted_data = model->cast<float>()->createData();
38 9 }
39
40 9 void test_calc_returns_a_value(ActivationModelTypes::Type activation_type) {
41 // create the model
42
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 ActivationModelFactory factory;
43 const std::shared_ptr<crocoddyl::ActivationModelAbstract>& model =
44
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 factory.create(activation_type);
45
46 // create the corresponding data object
47 const std::shared_ptr<crocoddyl::ActivationDataAbstract>& data =
48
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 model->createData();
49
50 // Generating random input vector
51
3/6
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
9 const Eigen::VectorXd r = Eigen::VectorXd::Random(model->get_nr());
52 9 data->a_value = nan("");
53
54 // Getting the state dimension from calc() call
55
2/4
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
9 model->calc(data, r);
56
57 // Checking that calc returns a value
58
6/12
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 16 taken 9 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 9 times.
✗ Branch 20 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 9 times.
9 BOOST_CHECK(!std::isnan(data->a_value));
59
60 // Checking that casted computation is the same
61 const std::shared_ptr<crocoddyl::ActivationModelAbstractTpl<float>>&
62
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 casted_model = model->cast<float>();
63 const std::shared_ptr<crocoddyl::ActivationDataAbstractTpl<float>>&
64
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 casted_data = casted_model->createData();
65
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 const Eigen::VectorXf r_f = r.cast<float>();
66 9 casted_data->a_value = float(nan(""));
67
2/4
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
9 casted_model->calc(casted_data, r_f);
68
6/12
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 16 taken 9 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 9 times.
✗ Branch 20 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 9 times.
9 BOOST_CHECK(!std::isnan(casted_data->a_value));
69
6/12
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 17 taken 9 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 9 times.
✗ Branch 21 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 9 times.
9 BOOST_CHECK(std::abs(data->a_value - casted_data->a_value) < 1e-6);
70 9 }
71
72 9 void test_partial_derivatives_against_numdiff(
73 ActivationModelTypes::Type activation_type) {
74 // create the model
75
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 ActivationModelFactory factory;
76 const std::shared_ptr<crocoddyl::ActivationModelAbstract>& model =
77
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 factory.create(activation_type);
78
79 // create the corresponding data object and set the cost to nan
80 const std::shared_ptr<crocoddyl::ActivationDataAbstract>& data =
81
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 model->createData();
82
83
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 crocoddyl::ActivationModelNumDiff model_num_diff(model);
84 std::shared_ptr<crocoddyl::ActivationDataAbstract> data_num_diff =
85
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 model_num_diff.createData();
86
87 // Generating random values for the state and control
88
3/6
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
9 const Eigen::VectorXd r = Eigen::VectorXd::Random(model->get_nr());
89
90 // Computing the activation derivatives
91
2/4
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
9 model->calc(data, r);
92
2/4
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
9 model->calcDiff(data, r);
93
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 model_num_diff.calc(data_num_diff, r);
94
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 model_num_diff.calcDiff(data_num_diff, r);
95
96 // Tolerance defined as in
97 // http://www.it.uom.gr/teaching/linearalgebra/NumericalRecipiesInC/c5-7.pdf
98
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 double tol = std::pow(model_num_diff.get_disturbance(), 1. / 3.);
99
6/12
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 17 taken 9 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 9 times.
✗ Branch 21 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 9 times.
9 BOOST_CHECK(std::abs(data->a_value - data_num_diff->a_value) < tol);
100
8/16
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 16 taken 9 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 9 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 9 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 9 times.
✗ Branch 26 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 9 times.
9 BOOST_CHECK((data->Ar - data_num_diff->Ar).isZero(tol));
101
102 // numerical differentiation of the Hessian is not good enough to be tested.
103 // BOOST_CHECK((data->Arr - data_num_diff->Arr).isMuchSmallerThan(1.0, tol));
104
105 // Checking that casted computation is the same
106 const std::shared_ptr<crocoddyl::ActivationModelAbstractTpl<float>>&
107
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 casted_model = model->cast<float>();
108 const std::shared_ptr<crocoddyl::ActivationDataAbstractTpl<float>>&
109
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 casted_data = casted_model->createData();
110
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 const Eigen::VectorXf r_f = r.cast<float>();
111
2/4
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
9 casted_model->calc(casted_data, r_f);
112
2/4
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
9 casted_model->calcDiff(casted_data, r_f);
113 float tol_f =
114
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 std::pow(model_num_diff.cast<float>().get_disturbance(), float(1. / 3.));
115
6/12
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 17 taken 9 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 9 times.
✗ Branch 21 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 9 times.
9 BOOST_CHECK(std::abs(data->a_value - casted_data->a_value) < tol_f);
116
9/18
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 16 taken 9 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 9 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 9 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 9 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 9 times.
✗ Branch 29 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 9 times.
9 BOOST_CHECK((data->Ar.cast<float>() - casted_data->Ar).isZero(tol_f));
117 9 }
118
119 1 void test_activation_bounds_with_infinity() {
120
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Eigen::VectorXd lb(1);
121
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Eigen::VectorXd ub(1);
122 double beta;
123 1 beta = 0.1;
124
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lb[0] = 0;
125
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 ub[0] = std::numeric_limits<double>::infinity();
126
127 Eigen::VectorXd m =
128
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 0.5 * (lb + Eigen::VectorXd::Constant(
129
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
2 lb.size(), std::numeric_limits<double>::max()));
130 Eigen::VectorXd d =
131
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 0.5 * (Eigen::VectorXd::Constant(lb.size(),
132
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
2 std::numeric_limits<double>::max()) -
133
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lb);
134
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 crocoddyl::ActivationBounds bounds(lb, ub, beta);
135
9/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
1 BOOST_CHECK(bounds.lb != m - beta * d);
136
137 // Checking that casted computation is the same
138
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 crocoddyl::ActivationBoundsTpl<float> casted_bounds = bounds.cast<float>();
139
8/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
1 BOOST_CHECK(bounds.lb.cast<float>() == casted_bounds.lb);
140 1 }
141
142 //----------------------------------------------------------------------------//
143
144 9 void register_unit_tests(ActivationModelTypes::Type activation_type) {
145
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 boost::test_tools::output_test_stream test_name;
146
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 test_name << "test_" << activation_type;
147
4/8
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 9 times.
✗ Branch 11 not taken.
9 std::cout << "Running " << test_name.str() << std::endl;
148
4/8
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
9 test_suite* ts = BOOST_TEST_SUITE(test_name.str());
149
5/10
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 9 times.
✗ Branch 15 not taken.
9 ts->add(BOOST_TEST_CASE(boost::bind(&test_construct_data, activation_type)));
150
5/10
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 9 times.
✗ Branch 15 not taken.
9 ts->add(BOOST_TEST_CASE(
151 boost::bind(&test_calc_returns_a_value, activation_type)));
152
5/10
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 9 times.
✗ Branch 15 not taken.
9 ts->add(BOOST_TEST_CASE(
153 boost::bind(&test_partial_derivatives_against_numdiff, activation_type)));
154
3/6
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
9 framework::master_test_suite().add(ts);
155 9 }
156
157 1 bool register_bounds_unit_test() {
158
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 boost::test_tools::output_test_stream test_name;
159 test_name << "test_"
160
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 << "ActivationBoundsInfinity";
161
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
1 std::cout << "Running " << test_name.str() << std::endl;
162
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
1 test_suite* ts = BOOST_TEST_SUITE(test_name.str());
163
5/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
1 ts->add(BOOST_TEST_CASE(boost::bind(&test_activation_bounds_with_infinity)));
164
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
1 framework::master_test_suite().add(ts);
165 1 return true;
166 1 }
167
168 1 bool init_function() {
169
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 1 times.
10 for (size_t i = 0; i < ActivationModelTypes::all.size(); ++i) {
170 9 register_unit_tests(ActivationModelTypes::all[i]);
171 }
172 1 register_bounds_unit_test();
173 1 return true;
174 }
175
176 1 int main(int argc, char** argv) {
177 1 return ::boost::unit_test::unit_test_main(&init_function, argc, argv);
178 }
179