GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/core/activations/smooth-1norm.hpp
Date: 2025-03-26 19:23:43
Exec Total Coverage
Lines: 31 36 86.1%
Branches: 21 88 23.9%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2025, LAAS-CNRS, University of Edinburgh,
5 // Heriot-Watt University
6 // Copyright note valid unless otherwise stated in individual files.
7 // All rights reserved.
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #ifndef CROCODDYL_CORE_ACTIVATIONS_SMOOTH_1NORM_HPP_
11 #define CROCODDYL_CORE_ACTIVATIONS_SMOOTH_1NORM_HPP_
12
13 #include <iostream>
14 #include <stdexcept>
15
16 #include "crocoddyl/core/activation-base.hpp"
17 #include "crocoddyl/core/fwd.hpp"
18
19 namespace crocoddyl {
20
21 /**
22 * @brief Smooth-abs activation
23 *
24 * This activation function describes a smooth representation of an absolute
25 * activation (1-norm) for each element of a residual vector, i.e. \f[
26 * \begin{equation} sum^nr_{i=0} \sqrt{\epsilon + \|r_i\|^2} \end{equation} \f]
27 * where \f$\epsilon\f$ defines the smoothing factor, \f$r_i\f$ is the scalar
28 * residual for the \f$i\f$ constraints, \f$nr\f$ is the dimension of the
29 * residual vector.
30 *
31 * The computation of the function and it derivatives are carried out in
32 * `calc()` and `caldDiff()`, respectively.
33 *
34 * \sa `calc()`, `calcDiff()`, `createData()`
35 */
36 template <typename _Scalar>
37 class ActivationModelSmooth1NormTpl
38 : public ActivationModelAbstractTpl<_Scalar> {
39 public:
40 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
41 16 CROCODDYL_DERIVED_CAST(ActivationModelBase, ActivationModelSmooth1NormTpl)
42
43 typedef _Scalar Scalar;
44 typedef MathBaseTpl<Scalar> MathBase;
45 typedef ActivationModelAbstractTpl<Scalar> Base;
46 typedef ActivationDataAbstractTpl<Scalar> ActivationDataAbstract;
47 typedef ActivationDataSmooth1NormTpl<Scalar> Data;
48 typedef typename MathBase::VectorXs VectorXs;
49 typedef typename MathBase::MatrixXs MatrixXs;
50
51 /**
52 * @brief Initialize the smooth-abs activation model
53 *
54 * The default `eps` value is defined as 1.
55 *
56 * @param[in] nr Dimension of the residual vector
57 * @param[in] eps Smoothing factor (default: 1.)
58 */
59 227 explicit ActivationModelSmooth1NormTpl(const std::size_t nr,
60 const Scalar eps = Scalar(1.))
61 227 : Base(nr), eps_(eps) {
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 227 times.
227 if (eps < Scalar(0.)) {
63 throw_pretty("Invalid argument: " << "eps should be a positive value");
64 }
65
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 227 times.
227 if (eps == Scalar(0.)) {
66 std::cerr << "Warning: eps=0 leads to derivatives discontinuities in the "
67 "origin, it becomes the absolute function"
68 << std::endl;
69 }
70 227 };
71 466 virtual ~ActivationModelSmooth1NormTpl() = default;
72
73 /**
74 * @brief Compute the smooth-abs function
75 *
76 * @param[in] data Smooth-abs activation data
77 * @param[in] r Residual vector \f$\mathbf{r}\in\mathbb{R}^{nr}\f$
78 */
79 9677 virtual void calc(const std::shared_ptr<ActivationDataAbstract>& data,
80 const Eigen::Ref<const VectorXs>& r) override {
81
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9677 times.
9677 if (static_cast<std::size_t>(r.size()) != nr_) {
82 throw_pretty(
83 "Invalid argument: " << "r has wrong dimension (it should be " +
84 std::to_string(nr_) + ")");
85 }
86 9677 std::shared_ptr<Data> d = std::static_pointer_cast<Data>(data);
87
88
5/10
✓ Branch 1 taken 9677 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9677 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 9677 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 9677 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 9677 times.
✗ Branch 17 not taken.
9677 d->a = (r.array().cwiseAbs2().array() + eps_).array().cwiseSqrt();
89
1/2
✓ Branch 2 taken 9677 times.
✗ Branch 3 not taken.
9677 data->a_value = d->a.sum();
90 9677 };
91
92 /**
93 * @brief Compute the derivatives of the smooth-abs function
94 *
95 * @param[in] data Smooth-abs activation data
96 * @param[in] r Residual vector \f$\mathbf{r}\in\mathbb{R}^{nr}\f$
97 */
98 305 virtual void calcDiff(const std::shared_ptr<ActivationDataAbstract>& data,
99 const Eigen::Ref<const VectorXs>& r) override {
100
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 305 times.
305 if (static_cast<std::size_t>(r.size()) != nr_) {
101 throw_pretty(
102 "Invalid argument: " << "r has wrong dimension (it should be " +
103 std::to_string(nr_) + ")");
104 }
105
106 305 std::shared_ptr<Data> d = std::static_pointer_cast<Data>(data);
107
3/6
✓ Branch 2 taken 305 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 305 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 305 times.
✗ Branch 10 not taken.
305 data->Ar = r.cwiseProduct(d->a.cwiseInverse());
108
2/4
✓ Branch 1 taken 305 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 305 times.
✗ Branch 7 not taken.
305 data->Arr.diagonal() =
109
2/4
✓ Branch 3 taken 305 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 305 times.
✗ Branch 8 not taken.
305 d->a.cwiseProduct(d->a).cwiseProduct(d->a).cwiseInverse();
110 305 };
111
112 /**
113 * @brief Create the smooth-abs activation data
114 *
115 * @return the activation data
116 */
117 7840 virtual std::shared_ptr<ActivationDataAbstract> createData() override {
118
1/2
✓ Branch 2 taken 7840 times.
✗ Branch 3 not taken.
7840 return std::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this);
119 };
120
121 template <typename NewScalar>
122 4 ActivationModelSmooth1NormTpl<NewScalar> cast() const {
123 typedef ActivationModelSmooth1NormTpl<NewScalar> ReturnType;
124 4 ReturnType res(nr_, scalar_cast<NewScalar>(eps_));
125 4 return res;
126 }
127
128 /**
129 * @brief Print relevant information of the smooth-1norm model
130 *
131 * @param[out] os Output stream object
132 */
133 37 virtual void print(std::ostream& os) const override {
134 37 os << "ActivationModelSmooth1Norm {nr=" << nr_ << ", eps=" << eps_ << "}";
135 37 }
136
137 protected:
138 using Base::nr_; //!< Dimension of the residual vector
139 Scalar eps_; //!< Smoothing factor
140 };
141
142 template <typename _Scalar>
143 struct ActivationDataSmooth1NormTpl
144 : public ActivationDataAbstractTpl<_Scalar> {
145 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
146
147 typedef _Scalar Scalar;
148 typedef ActivationDataAbstractTpl<Scalar> Base;
149 typedef MathBaseTpl<Scalar> MathBase;
150 typedef typename MathBase::VectorXs VectorXs;
151 typedef typename MathBase::MatrixXs MatrixXs;
152 typedef typename MathBase::DiagonalMatrixXs DiagonalMatrixXs;
153
154 template <typename Activation>
155 7842 explicit ActivationDataSmooth1NormTpl(Activation* const activation)
156
3/6
✓ Branch 2 taken 7840 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 7840 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 7840 times.
✗ Branch 9 not taken.
7842 : Base(activation), a(VectorXs::Zero(activation->get_nr())) {}
157 15680 virtual ~ActivationDataSmooth1NormTpl() = default;
158
159 VectorXs a;
160
161 using Base::a_value;
162 using Base::Ar;
163 using Base::Arr;
164 };
165
166 } // namespace crocoddyl
167
168 CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS(
169 crocoddyl::ActivationModelSmooth1NormTpl)
170 CROCODDYL_DECLARE_EXTERN_TEMPLATE_STRUCT(
171 crocoddyl::ActivationDataSmooth1NormTpl)
172
173 #endif // CROCODDYL_CORE_ACTIVATIONS_SMOOTH_1NORM_HPP_
174