Crocoddyl
smooth-1norm.hpp
1 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2020, LAAS-CNRS, University of Edinburgh
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
8 
9 #ifndef CROCODDYL_CORE_ACTIVATIONS_SMOOTH_1NORM_HPP_
10 #define CROCODDYL_CORE_ACTIVATIONS_SMOOTH_1NORM_HPP_
11 
12 #include <iostream>
13 #include <stdexcept>
14 
15 #include "crocoddyl/core/activation-base.hpp"
16 #include "crocoddyl/core/fwd.hpp"
17 #include "crocoddyl/core/utils/exception.hpp"
18 
19 namespace crocoddyl {
20 
36 template <typename _Scalar>
38  : public ActivationModelAbstractTpl<_Scalar> {
39  public:
40  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
41 
42  typedef _Scalar Scalar;
47  typedef typename MathBase::VectorXs VectorXs;
48  typedef typename MathBase::MatrixXs MatrixXs;
49 
58  explicit ActivationModelSmooth1NormTpl(const std::size_t nr,
59  const Scalar eps = Scalar(1.))
60  : Base(nr), eps_(eps) {
61  if (eps < Scalar(0.)) {
62  throw_pretty("Invalid argument: "
63  << "eps should be a positive value");
64  }
65  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  };
71  virtual ~ActivationModelSmooth1NormTpl(){};
72 
79  virtual void calc(const boost::shared_ptr<ActivationDataAbstract>& data,
80  const Eigen::Ref<const VectorXs>& r) {
81  if (static_cast<std::size_t>(r.size()) != nr_) {
82  throw_pretty("Invalid argument: "
83  << "r has wrong dimension (it should be " +
84  std::to_string(nr_) + ")");
85  }
86  boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
87 
88  d->a = (r.array().cwiseAbs2().array() + eps_).array().cwiseSqrt();
89  data->a_value = d->a.sum();
90  };
91 
98  virtual void calcDiff(const boost::shared_ptr<ActivationDataAbstract>& data,
99  const Eigen::Ref<const VectorXs>& r) {
100  if (static_cast<std::size_t>(r.size()) != nr_) {
101  throw_pretty("Invalid argument: "
102  << "r has wrong dimension (it should be " +
103  std::to_string(nr_) + ")");
104  }
105 
106  boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
107  data->Ar = r.cwiseProduct(d->a.cwiseInverse());
108  data->Arr.diagonal() =
109  d->a.cwiseProduct(d->a).cwiseProduct(d->a).cwiseInverse();
110  };
111 
117  virtual boost::shared_ptr<ActivationDataAbstract> createData() {
118  return boost::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this);
119  };
120 
126  virtual void print(std::ostream& os) const {
127  os << "ActivationModelSmooth1Norm {nr=" << nr_ << ", eps=" << eps_ << "}";
128  }
129 
130  protected:
131  using Base::nr_;
132  Scalar eps_;
133 };
134 
135 template <typename _Scalar>
137  : public ActivationDataAbstractTpl<_Scalar> {
138  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
139 
140  typedef _Scalar Scalar;
143  typedef typename MathBase::VectorXs VectorXs;
144  typedef typename MathBase::MatrixXs MatrixXs;
145 
146  template <typename Activation>
147  explicit ActivationDataSmooth1NormTpl(Activation* const activation)
148  : Base(activation), a(VectorXs::Zero(activation->get_nr())) {}
149 
150  VectorXs a;
151  using Base::Arr;
152 };
153 
154 } // namespace crocoddyl
155 
156 #endif // CROCODDYL_CORE_ACTIVATIONS_SMOOTH_1NORM_HPP_
virtual boost::shared_ptr< ActivationDataAbstract > createData()
Create the smooth-abs activation data.
virtual void calc(const boost::shared_ptr< ActivationDataAbstract > &data, const Eigen::Ref< const VectorXs > &r)
Compute the smooth-abs function.
virtual void print(std::ostream &os) const
Print relevant information of the smooth-1norm model.
Scalar eps_
< Dimension of the residual vector
virtual void calcDiff(const boost::shared_ptr< ActivationDataAbstract > &data, const Eigen::Ref< const VectorXs > &r)
Compute the derivatives of the smooth-abs function.
ActivationModelSmooth1NormTpl(const std::size_t nr, const Scalar eps=Scalar(1.))
Initialize the smooth-abs activation model.