crocoddyl 1.9.0
Contact RObot COntrol by Differential DYnamic programming Library (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 <stdexcept>
13#include <pinocchio/utils/static-if.hpp>
14#include "crocoddyl/core/fwd.hpp"
15#include "crocoddyl/core/activation-base.hpp"
16#include "crocoddyl/core/utils/exception.hpp"
17
18namespace crocoddyl {
19
38template <typename _Scalar>
40 public:
41 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
42
43 typedef _Scalar Scalar;
48 typedef typename MathBase::VectorXs VectorXs;
49
60 explicit ActivationModel2NormBarrierTpl(const std::size_t nr, const Scalar alpha = Scalar(0.1),
61 const bool true_hessian = false)
62 : Base(nr), alpha_(alpha), true_hessian_(true_hessian) {
63 if (alpha < Scalar(0.)) {
64 throw_pretty("Invalid argument: "
65 << "alpha should be a positive value");
66 }
67 };
69
76 virtual void calc(const boost::shared_ptr<ActivationDataAbstract>& data, const Eigen::Ref<const VectorXs>& r) {
77 if (static_cast<std::size_t>(r.size()) != nr_) {
78 throw_pretty("Invalid argument: "
79 << "r has wrong dimension (it should be " + std::to_string(nr_) + ")");
80 }
81 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
82
83 d->d = r.norm();
84 if (d->d < alpha_) {
85 data->a_value = Scalar(0.5) * (d->d - alpha_) * (d->d - alpha_);
86 } else {
87 data->a_value = Scalar(0.0);
88 }
89 };
90
97 virtual void calcDiff(const boost::shared_ptr<ActivationDataAbstract>& data, const Eigen::Ref<const VectorXs>& r) {
98 if (static_cast<std::size_t>(r.size()) != nr_) {
99 throw_pretty("Invalid argument: "
100 << "r has wrong dimension (it should be " + std::to_string(nr_) + ")");
101 }
102 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
103
104 if (d->d < alpha_) {
105 data->Ar = (d->d - alpha_) / d->d * r;
106 if (true_hessian_) {
107 data->Arr.diagonal() = alpha_ * r.array().square() / std::pow(d->d, 3); // True Hessian
108 data->Arr.diagonal().array() += (d->d - alpha_) / d->d;
109 } else {
110 data->Arr.diagonal() = r.array().square() / std::pow(d->d, 2); // GN Hessian approximation
111 }
112 } else {
113 data->Ar.setZero();
114 data->Arr.setZero();
115 }
116 };
117
123 virtual boost::shared_ptr<ActivationDataAbstract> createData() {
124 return boost::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this);
125 };
126
130 const Scalar& get_alpha() const { return alpha_; };
131 void set_alpha(const Scalar& alpha) { alpha_ = alpha; };
132
138 virtual void print(std::ostream& os) const {
139 os << "ActivationModel2NormBarrier {nr=" << nr_ << ", alpha=" << alpha_ << ", hessian=" << true_hessian_ << "}";
140 }
141
142 protected:
143 using Base::nr_;
144 Scalar alpha_;
146};
147
148template <typename _Scalar>
150 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
151
152 typedef _Scalar Scalar;
154
155 template <typename Activation>
156 explicit ActivationData2NormBarrierTpl(Activation* const activation) : Base(activation), d(Scalar(0)) {}
157
158 Scalar d;
159
160 using Base::a_value;
161 using Base::Ar;
162 using Base::Arr;
163};
164
165} // namespace crocoddyl
166
167#endif // CROCODDYL_CORE_ACTIVATIONS_2NORM_BARRIER_HPP_
virtual boost::shared_ptr< ActivationDataAbstract > createData()
Create the 2norm-barrier activation data.
const Scalar & get_alpha() const
Get and set the threshold factor.
Scalar alpha_
< Dimension of the residual vector
virtual void calc(const boost::shared_ptr< ActivationDataAbstract > &data, const Eigen::Ref< const VectorXs > &r)
Compute the 2-norm barrier function.
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 boost::shared_ptr< ActivationDataAbstract > &data, const Eigen::Ref< const VectorXs > &r)
Compute the derivatives of the 2norm-barrier function.
bool true_hessian_
Use true hessian in calcDiff if true, Gauss-Newton approximation if false.