9 #ifndef CROCODDYL_CORE_ACTIVATIONS_QUADRATIC_BARRIER_HPP_
10 #define CROCODDYL_CORE_ACTIVATIONS_QUADRATIC_BARRIER_HPP_
14 #include <pinocchio/utils/static-if.hpp>
17 #include "crocoddyl/core/activation-base.hpp"
18 #include "crocoddyl/core/fwd.hpp"
19 #include "crocoddyl/core/utils/exception.hpp"
23 template <
typename _Scalar>
25 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
27 typedef _Scalar Scalar;
29 typedef typename MathBase::VectorXs VectorXs;
30 typedef typename MathBase::MatrixXs MatrixXs;
33 const Scalar b = (Scalar)1.)
34 : lb(lower), ub(upper), beta(b) {
35 if (lb.size() != ub.size()) {
36 throw_pretty(
"Invalid argument: "
37 <<
"The lower and upper bounds don't have the same "
38 "dimension (lb,ub dimensions equal to " +
39 std::to_string(lb.size()) +
"," +
40 std::to_string(ub.size()) +
", respectively)");
42 if (beta < Scalar(0) || beta > Scalar(1.)) {
43 throw_pretty(
"Invalid argument: "
44 <<
"The range of beta is between 0 and 1");
47 for (std::size_t i = 0; i < static_cast<std::size_t>(lb.size()); ++i) {
48 if (isfinite(lb(i)) && isfinite(ub(i))) {
49 if (lb(i) - ub(i) > 0) {
50 throw_pretty(
"Invalid argument: "
51 <<
"The lower and upper bounds are badly defined; ub "
52 "has to be bigger / equals to lb");
56 if (!isfinite(lb(i))) {
57 lb(i) = -std::numeric_limits<Scalar>::max();
59 if (!isfinite(ub(i))) {
60 ub(i) = std::numeric_limits<Scalar>::max();
64 if (beta >= Scalar(0) && beta <= Scalar(1.)) {
65 VectorXs m = Scalar(0.5) * (lb + ub);
66 VectorXs d = Scalar(0.5) * (ub - lb);
74 : lb(other.lb), ub(other.ub), beta(other.beta) {}
91 template <
typename _Scalar>
95 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
97 typedef _Scalar Scalar;
103 typedef typename MathBase::VectorXs VectorXs;
104 typedef typename MathBase::MatrixXs MatrixXs;
107 :
Base(bounds.lb.size()), bounds_(bounds){};
110 virtual void calc(
const boost::shared_ptr<ActivationDataAbstract>& data,
111 const Eigen::Ref<const VectorXs>& r) {
112 if (
static_cast<std::size_t
>(r.size()) != nr_) {
113 throw_pretty(
"Invalid argument: "
114 <<
"r has wrong dimension (it should be " +
115 std::to_string(nr_) +
")");
118 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
120 d->rlb_min_ = (r - bounds_.lb).array().min(Scalar(0.));
121 d->rub_max_ = (r - bounds_.ub).array().max(Scalar(0.));
122 data->a_value = Scalar(0.5) * d->rlb_min_.matrix().squaredNorm() +
123 Scalar(0.5) * d->rub_max_.matrix().squaredNorm();
126 virtual void calcDiff(
const boost::shared_ptr<ActivationDataAbstract>& data,
127 const Eigen::Ref<const VectorXs>& r) {
128 if (
static_cast<std::size_t
>(r.size()) != nr_) {
129 throw_pretty(
"Invalid argument: "
130 <<
"r has wrong dimension (it should be " +
131 std::to_string(nr_) +
")");
134 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
135 data->Ar = (d->rlb_min_ + d->rub_max_).matrix();
137 using pinocchio::internal::if_then_else;
138 for (Eigen::Index i = 0; i < data->Arr.cols(); i++) {
139 data->Arr.diagonal()[i] = if_then_else(
140 pinocchio::internal::LE, r[i] - bounds_.lb[i], Scalar(0.), Scalar(1.),
141 if_then_else(pinocchio::internal::GE, r[i] - bounds_.ub[i],
142 Scalar(0.), Scalar(1.), Scalar(0.)));
146 virtual boost::shared_ptr<ActivationDataAbstract> createData() {
147 return boost::allocate_shared<Data>(Eigen::aligned_allocator<Data>(),
this);
158 virtual void print(std::ostream& os)
const {
159 os <<
"ActivationModelQuadraticBarrier {nr=" << nr_ <<
"}";
169 template <
typename _Scalar>
172 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
174 typedef _Scalar Scalar;
176 typedef typename MathBase::ArrayXs ArrayXs;
179 template <
typename Activation>
182 rlb_min_(activation->get_nr()),
183 rub_max_(activation->get_nr()) {
virtual void print(std::ostream &os) const
Print relevant information of the quadratic barrier model.