Line data Source code
1 : #pragma once 2 : 3 : #include <optional> 4 : 5 : #include "DataContainer.h" 6 : #include "StrongTypes.h" 7 : 8 : namespace elsa 9 : { 10 : /// @brief Proximal operator of the indicator functions for box and 11 : /// non-negativity sets. The proximal operator is the projection of onto 12 : /// the given set. 13 : /// 14 : /// Given the set \f$P\f$ of elements \f$a \leq x \leq b\f$, the proximal operator 15 : /// for the indicator function: 16 : /// \f[ 17 : /// f(x) = 18 : /// \begin{cases} 19 : /// 0 & \text{if } a \leq x \leq b \text{ everywhere}, \\ \infty & \text{else} 20 : /// \end{cases} 21 : /// \f] 22 : /// is given by: 23 : /// \f[ 24 : /// f(x) = 25 : /// \begin{cases} 26 : /// a & \text{if } x < a, \\ x & \text{if } a \leq x \leq b, \\ b & \text{if } x > b 27 : /// \end{cases} 28 : /// \f] 29 : /// The proximal operator is independent for each dimension, and hence, 30 : /// can be computed coefficient wise. 31 : /// 32 : /// Note: the proximal operator is independent of the step length 33 : /// 34 : /// @see IndicatorBox IndicatorNonNegativity 35 : template <class data_t> 36 : class ProximalBoxConstraint 37 : { 38 : public: 39 : /// defaulted default constructor 40 4 : ProximalBoxConstraint() = default; 41 : 42 : /// defaulted copy constructor 43 : ProximalBoxConstraint(const ProximalBoxConstraint<data_t>&) = default; 44 : 45 : /// defaulted copy assignment operator 46 : ProximalBoxConstraint& operator=(const ProximalBoxConstraint<data_t>&) = default; 47 : 48 : /// defaulted move constructor 49 : ProximalBoxConstraint(ProximalBoxConstraint<data_t>&&) noexcept = default; 50 : 51 : /// defaulted move assignment operator 52 : ProximalBoxConstraint& operator=(ProximalBoxConstraint<data_t>&&) noexcept = default; 53 : 54 : /// defaulted deconstructor 55 : ~ProximalBoxConstraint() = default; 56 : 57 : /// Construct proximal operator with only a lower bound 58 : explicit ProximalBoxConstraint(data_t lower); 59 : 60 : /// Construct proximal operator with a lower and upper bound 61 : ProximalBoxConstraint(data_t lower, data_t upper); 62 : 63 : /// Apply proximal operator to the given vector 64 : DataContainer<data_t> apply(const DataContainer<data_t>& v, SelfType_t<data_t> t) const; 65 : 66 : /// Apply proximal operator to the given vector, by projection the 67 : /// vector v onto the given set 68 : void apply(const DataContainer<data_t>& v, SelfType_t<data_t> t, 69 : DataContainer<data_t>& prox) const; 70 : 71 : template <class T> 72 : friend bool operator==(const ProximalBoxConstraint<T>&, const ProximalBoxConstraint<T>&); 73 : 74 : template <class T> 75 : friend bool operator!=(const ProximalBoxConstraint<T>&, const ProximalBoxConstraint<T>&); 76 : 77 : private: 78 : std::optional<data_t> lower_ = {}; 79 : std::optional<data_t> upper_ = {}; 80 : }; 81 : } // namespace elsa