Line data Source code
1 : #pragma once 2 : 3 : #include "DataDescriptor.h" 4 : #include "Functional.h" 5 : #include "DataContainer.h" 6 : #include "LinearOperator.h" 7 : 8 : namespace elsa 9 : { 10 : /** 11 : * @brief Class representing the squared l2 norm functional. 12 : * 13 : * The l2 norm (squared) functional evaluates to \f$ 0.5 * \sum_{i=1}^n x_i^2 \f$ for \f$ 14 : * x=(x_i)_{i=1}^n \f$. 15 : * 16 : * @tparam data_t data type for the domain of the residual of the functional, defaulting to 17 : * real_t 18 : */ 19 : template <typename data_t = real_t> 20 : class L2Squared : public Functional<data_t> 21 : { 22 : public: 23 : /** 24 : * @brief Constructor for the l2 norm (squared) functional, mapping domain vector to a 25 : * scalar (without a residual) 26 : * 27 : * @param[in] domainDescriptor describing the domain of the functional 28 : */ 29 : explicit L2Squared(const DataDescriptor& domainDescriptor); 30 : 31 : /** 32 : * @brief Constructor the l2 norm (squared) functional with a LinearResidual 33 : * 34 : * @param[in] domainDescriptor describing the domain of the functional 35 : * @param[in] b data to use in the linear residual 36 : */ 37 : L2Squared(const DataContainer<data_t>& b); 38 : 39 : /// make copy constructor deletion explicit 40 : L2Squared(const L2Squared<data_t>&) = delete; 41 : 42 : /// default destructor 43 112 : ~L2Squared() override = default; 44 : 45 : bool hasDataVector() const; 46 : 47 : const DataContainer<data_t>& getDataVector() const; 48 : 49 : bool isDifferentiable() const override; 50 : 51 : bool isProxFriendly() const override; 52 : 53 : /** 54 : * The proximal of the squared L2 norm is given as: 55 : * @f[ 56 : * \operatorname{prox}_{\tau f}(x) = \frac{x + 2 \tau b}{1 + 2 \tau} 57 : * @f] 58 : */ 59 : DataContainer<data_t> proximal(const DataContainer<data_t>& x, 60 : SelfType_t<data_t> tau) const override; 61 : 62 : void proximal(const DataContainer<data_t>& x, SelfType_t<data_t> tau, 63 : DataContainer<data_t>& out) const override; 64 : 65 : /** 66 : * The convex conjugate for the squared l2 norm is given as: 67 : * - @f$ f(x)^* = \frac{1]{4} ||x||_2^2 @f$, if no translation is present 68 : * - @f$ f(x)^* = \frac{1]{4} ||x||_2^2 + \langle x, b \rangle @f$, if a translation is 69 : * present 70 : */ 71 : data_t convexConjugate(const DataContainer<data_t>& x) const override; 72 : 73 : protected: 74 : /// the evaluation of the l2 norm (squared) 75 : data_t evaluateImpl(const DataContainer<data_t>& Rx) const override; 76 : 77 : /// the computation of the gradient (in place) 78 : void getGradientImpl(const DataContainer<data_t>& Rx, 79 : DataContainer<data_t>& out) const override; 80 : 81 : /// the computation of the Hessian 82 : LinearOperator<data_t> getHessianImpl(const DataContainer<data_t>& Rx) const override; 83 : 84 : /// implement the polymorphic clone operation 85 : L2Squared<data_t>* cloneImpl() const override; 86 : 87 : /// implement the polymorphic comparison operation 88 : bool isEqual(const Functional<data_t>& other) const override; 89 : 90 : private: 91 : std::unique_ptr<LinearOperator<data_t>> A_{}; 92 : 93 : std::optional<DataContainer<data_t>> b_{}; 94 : }; 95 : 96 : } // namespace elsa