Crocoddyl
 
Loading...
Searching...
No Matches
2norm-barrier.hpp
1
2// BSD 3-Clause License
3//
4// Copyright (C) 2021, LAAS-CNRS, Airbus, University of Edinburgh
5// Copyright note valid unless otherwise stated in individual files.
6// All rights reserved.
8
9#ifndef CROCODDYL_CORE_ACTIVATIONS_2NORM_BARRIER_HPP_
10#define CROCODDYL_CORE_ACTIVATIONS_2NORM_BARRIER_HPP_
11
12#include <pinocchio/utils/static-if.hpp>
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
19namespace crocoddyl {
20
41template <typename _Scalar>
43 : public ActivationModelAbstractTpl<_Scalar> {
44 public:
45 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
46
47 typedef _Scalar Scalar;
52 typedef typename MathBase::VectorXs VectorXs;
53
64 explicit ActivationModel2NormBarrierTpl(const std::size_t nr,
65 const Scalar alpha = Scalar(0.1),
66 const bool true_hessian = false)
67 : Base(nr), alpha_(alpha), true_hessian_(true_hessian) {
68 if (alpha < Scalar(0.)) {
69 throw_pretty("Invalid argument: " << "alpha should be a positive value");
70 }
71 };
73
80 virtual void calc(const std::shared_ptr<ActivationDataAbstract>& data,
81 const Eigen::Ref<const VectorXs>& r) {
82 if (static_cast<std::size_t>(r.size()) != nr_) {
83 throw_pretty(
84 "Invalid argument: " << "r has wrong dimension (it should be " +
85 std::to_string(nr_) + ")");
86 }
87 std::shared_ptr<Data> d = std::static_pointer_cast<Data>(data);
88
89 d->d = r.norm();
90 if (d->d < alpha_) {
91 data->a_value = Scalar(0.5) * (d->d - alpha_) * (d->d - alpha_);
92 } else {
93 data->a_value = Scalar(0.0);
94 }
95 };
96
103 virtual void calcDiff(const std::shared_ptr<ActivationDataAbstract>& data,
104 const Eigen::Ref<const VectorXs>& r) {
105 if (static_cast<std::size_t>(r.size()) != nr_) {
106 throw_pretty(
107 "Invalid argument: " << "r has wrong dimension (it should be " +
108 std::to_string(nr_) + ")");
109 }
110 std::shared_ptr<Data> d = std::static_pointer_cast<Data>(data);
111
112 if (d->d < alpha_) {
113 data->Ar = (d->d - alpha_) / d->d * r;
114 if (true_hessian_) {
115 data->Arr.diagonal() =
116 alpha_ * r.array().square() / std::pow(d->d, 3); // True Hessian
117 data->Arr.diagonal().array() += (d->d - alpha_) / d->d;
118 } else {
119 data->Arr.diagonal() =
120 r.array().square() / std::pow(d->d, 2); // GN Hessian approximation
121 }
122 } else {
123 data->Ar.setZero();
124 data->Arr.setZero();
125 }
126 };
127
133 virtual std::shared_ptr<ActivationDataAbstract> createData() {
134 return std::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this);
135 };
136
140 const Scalar& get_alpha() const { return alpha_; };
141 void set_alpha(const Scalar& alpha) { alpha_ = alpha; };
142
148 virtual void print(std::ostream& os) const {
149 os << "ActivationModel2NormBarrier {nr=" << nr_ << ", alpha=" << alpha_
150 << ", Hessian=" << true_hessian_ << "}";
151 }
152
153 protected:
154 using Base::nr_;
155 Scalar alpha_;
158};
159
160template <typename _Scalar>
162 : public ActivationDataAbstractTpl<_Scalar> {
163 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
164
165 typedef _Scalar Scalar;
167
168 template <typename Activation>
169 explicit ActivationData2NormBarrierTpl(Activation* const activation)
170 : Base(activation), d(Scalar(0)) {}
171
172 Scalar d;
173
174 using Base::a_value;
175 using Base::Ar;
176 using Base::Arr;
177};
178
179} // namespace crocoddyl
180
181#endif // CROCODDYL_CORE_ACTIVATIONS_2NORM_BARRIER_HPP_
const Scalar & get_alpha() const
Get and set the threshold factor.
Scalar alpha_
< Dimension of the residual vector
virtual void print(std::ostream &os) const
Print relevant information of the 2-norm barrier model.
ActivationModel2NormBarrierTpl(const std::size_t nr, const Scalar alpha=Scalar(0.1), const bool true_hessian=false)
Initialize the 2-norm barrier activation model.
virtual void calcDiff(const std::shared_ptr< ActivationDataAbstract > &data, const Eigen::Ref< const VectorXs > &r)
Compute the derivatives of the 2norm-barrier function.
virtual void calc(const std::shared_ptr< ActivationDataAbstract > &data, const Eigen::Ref< const VectorXs > &r)
Compute the 2-norm barrier function.
virtual std::shared_ptr< ActivationDataAbstract > createData()
Create the 2norm-barrier activation data.