Line data Source code
1 : #pragma once 2 : 3 : #include "Functional.h" 4 : 5 : namespace elsa 6 : { 7 : /** 8 : * @brief Class representing the Huber norm. 9 : * 10 : * @author Matthias Wieczorek - initial code 11 : * @author Maximilian Hornung - modularization 12 : * @author Tobias Lasser - modernization 13 : * 14 : * @tparam data_t data type for the domain of the residual of the functional, defaulting to 15 : * real_t 16 : * 17 : * The Huber norm evaluates to \f$ \sum_{i=1}^n \begin{cases} \frac{1}{2} x_i^2 & \text{for } 18 : * |x_i| \leq \delta \\ \delta\left(|x_i| - \frac{1}{2}\delta\right) & \text{else} \end{cases} 19 : * \f$ for \f$ x=(x_i)_{i=1}^n \f$ and a cut-off parameter \f$ \delta \f$. 20 : * 21 : * Reference: https://doi.org/10.1214%2Faoms%2F1177703732 22 : */ 23 : template <typename data_t = real_t> 24 : class Huber : public Functional<data_t> 25 : { 26 : public: 27 : /** 28 : * @brief Constructor for the Huber functional, mapping domain vector to scalar (without a 29 : * residual) 30 : * 31 : * @param[in] domainDescriptor describing the domain of the functional 32 : * @param[in] delta parameter for linear/square cutoff (defaults to 1e-6) 33 : */ 34 : explicit Huber(const DataDescriptor& domainDescriptor, 35 : real_t delta = static_cast<real_t>(1e-6)); 36 : 37 : /** 38 : * @brief Constructor for the Huber functional, using a residual as input to map to a scalar 39 : * 40 : * @param[in] residual to be used when evaluating the functional (or its derivative) 41 : * @param[in] delta parameter for linear/square cutoff (defaults to 1e-6) 42 : */ 43 : explicit Huber(const Residual<data_t>& residual, real_t delta = static_cast<real_t>(1e-6)); 44 : 45 : /// make copy constructor deletion explicit 46 : Huber(const Huber<data_t>&) = delete; 47 : 48 : /// default destructor 49 36 : ~Huber() override = default; 50 : 51 : protected: 52 : /// the evaluation of the Huber norm 53 : data_t evaluateImpl(const DataContainer<data_t>& Rx) override; 54 : 55 : /// the computation of the gradient (in place) 56 : void getGradientInPlaceImpl(DataContainer<data_t>& Rx) override; 57 : 58 : /// the computation of the Hessian 59 : LinearOperator<data_t> getHessianImpl(const DataContainer<data_t>& Rx) override; 60 : 61 : /// implement the polymorphic clone operation 62 : Huber<data_t>* cloneImpl() const override; 63 : 64 : /// implement the polymorphic comparison operation 65 : bool isEqual(const Functional<data_t>& other) const override; 66 : 67 : private: 68 : /// the cut-off delta 69 : const real_t _delta; 70 : }; 71 : 72 : } // namespace elsa