Line data Source code
1 : #pragma once 2 : 3 : #include "DataContainer.h" 4 : #include "Functional.h" 5 : 6 : namespace elsa 7 : { 8 : /** 9 : * @brief Class representing the l1 norm functional. 10 : * 11 : * The l1 norm functional evaluates to \f$ \sum_{i=1}^n |x_i| \f$ for \f$ x=(x_i)_{i=1}^n \f$. 12 : * Please note that it is not differentiable, hence getGradient and getHessian will throw 13 : * exceptions. 14 : * 15 : * @tparam data_t data type for the domain of the residual of the functional, defaulting to 16 : * real_t 17 : * 18 : * @author 19 : * * Matthias Wieczorek - initial code 20 : * * Maximilian Hornung - modularization 21 : * * Tobias Lasser - modernization 22 : * 23 : */ 24 : template <typename data_t = real_t> 25 : class L1Norm : public Functional<data_t> 26 : { 27 : public: 28 : /** 29 : * @brief Constructor for the l1 norm functional, mapping domain vector to a scalar (without 30 : * a residual) 31 : * 32 : * @param[in] domainDescriptor describing the domain of the functional 33 : */ 34 : explicit L1Norm(const DataDescriptor& domainDescriptor); 35 : 36 : /// make copy constructor deletion explicit 37 : L1Norm(const L1Norm<data_t>&) = delete; 38 : 39 : /// default destructor 40 70 : ~L1Norm() override = default; 41 : 42 : bool isProxFriendly() const override; 43 : 44 : /** 45 : * @brief The convex convex conjugate of the l1 norm is the indicator 46 : * of the L-infinity norm. 47 : * @f[ 48 : * \mathbb{I}_{\{\|\cdot\|_{\infty} \leq 1\}}(x) = 49 : * \begin{cases} 50 : * 0, & \text{if } \|x\|_{\infty} \leq 1 \\ 51 : * \infty, && \text{otherwise} 52 : * \end{cases} 53 : * @f] 54 : */ 55 : data_t convexConjugate(const DataContainer<data_t>& x) const override; 56 : 57 : DataContainer<data_t> proximal(const DataContainer<data_t>& v, 58 : SelfType_t<data_t> t) const override; 59 : 60 : void proximal(const DataContainer<data_t>& v, SelfType_t<data_t> t, 61 : DataContainer<data_t>& out) const override; 62 : 63 : protected: 64 : /// the evaluation of the l1 norm 65 : data_t evaluateImpl(const DataContainer<data_t>& Rx) const override; 66 : 67 : /// the computation of the gradient (in place) 68 : void getGradientImpl(const DataContainer<data_t>& Rx, 69 : DataContainer<data_t>& out) const override; 70 : 71 : /// the computation of the Hessian 72 : LinearOperator<data_t> getHessianImpl(const DataContainer<data_t>& Rx) const override; 73 : 74 : /// implement the polymorphic clone operation 75 : L1Norm<data_t>* cloneImpl() const override; 76 : 77 : /// implement the polymorphic comparison operation 78 : bool isEqual(const Functional<data_t>& other) const override; 79 : }; 80 : 81 : } // namespace elsa