Line data Source code
1 : #pragma once 2 : 3 : #include "Functional.h" 4 : #include "LinearResidual.h" 5 : 6 : namespace elsa 7 : { 8 : /** 9 : * @brief Class representing a quadric functional. 10 : * 11 : * @author Matthias Wieczorek - initial code 12 : * @author Maximilian Hornung - modularization 13 : * @author Tobias Lasser - modernization 14 : * @author Nikola Dinev - add functionality 15 : * 16 : * @tparam data_t data type for the domain of the residual of the functional, defaulting to 17 : * real_t 18 : * 19 : * The Quadric functional evaluates to \f$ \frac{1}{2} x^tAx - x^tb \f$ for a symmetric positive 20 : * definite operator A and a vector b. 21 : * 22 : * Please note: contrary to other functionals, Quadric does not allow wrapping an explicit 23 : * residual. 24 : */ 25 : template <typename data_t = real_t> 26 : class Quadric : public Functional<data_t> 27 : { 28 : public: 29 : /** 30 : * @brief Constructor for the Quadric functional, using operator A and vector b (no 31 : * residual). 32 : * 33 : * @param[in] A the operator (has to be symmetric positive definite) 34 : * @param[in] b the data vector 35 : */ 36 : Quadric(const LinearOperator<data_t>& A, const DataContainer<data_t>& b); 37 : 38 : /** 39 : * @brief Constructor for the Quadric functional \f$ \frac{1}{2} x^tAx \f$ (trivial data 40 : * vector) 41 : * 42 : * @param[in] A the operator (has to be symmetric positive definite) 43 : */ 44 : explicit Quadric(const LinearOperator<data_t>& A); 45 : 46 : /** 47 : * @brief Constructor for the Quadric functional \f$ \frac{1}{2} x^tx - x^tb \f$ (trivial 48 : * operator) 49 : * 50 : * @param[in] b the data vector 51 : */ 52 : explicit Quadric(const DataContainer<data_t>& b); 53 : 54 : /** 55 : * @brief Constructor for the Quadric functional \f$ \frac{1}{2} x^tx \f$ (trivial operator 56 : * and data vector) 57 : * 58 : * @param[in] domainDescriptor the descriptor of x 59 : */ 60 : explicit Quadric(const DataDescriptor& domainDescriptor); 61 : 62 : /// make copy constructor deletion explicit 63 : Quadric(const Quadric<data_t>&) = delete; 64 : 65 : /// default destructor 66 548 : ~Quadric() override = default; 67 : 68 : /// returns the residual \f$ Ax - b \f$, which also corresponds to the gradient of the 69 : /// functional 70 : const LinearResidual<data_t>& getGradientExpression() const; 71 : 72 : protected: 73 : /// the evaluation of the Quadric functional 74 : data_t evaluateImpl(const DataContainer<data_t>& Rx) override; 75 : 76 : /// the computation of the gradient (in place) 77 : void getGradientInPlaceImpl(DataContainer<data_t>& Rx) override; 78 : 79 : /// the computation of the Hessian 80 : LinearOperator<data_t> getHessianImpl(const DataContainer<data_t>& Rx) override; 81 : 82 : /// implement the polymorphic clone operation 83 : Quadric<data_t>* cloneImpl() const override; 84 : 85 : /// implement the polymorphic comparison operation 86 : bool isEqual(const Functional<data_t>& other) const override; 87 : 88 : private: 89 : /// storing A,b in a linear residual 90 : LinearResidual<data_t> _linearResidual; 91 : 92 : /// lift from base class 93 : using Functional<data_t>::_domainDescriptor; 94 : }; 95 : 96 : } // namespace elsa