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 The least squares functional / loss functional with the linear operator 12 : * in the exponential 13 : * 14 : * The exponential least squares loss is given by: 15 : * \[ 16 : * 0.5 * || \exp(-A(x)) - b ||_2^2 17 : * \] 18 : * 19 : * The gradient is given as 20 : * \[ 21 : * -A^T \exp(-Ax) (\exp(-Ax) - b) 22 : * \] 23 : * and the Hessian: 24 : * \[ 25 : * A^T \text{diag} \left(\exp(-Ax) (2 \exp(-Ax) - b) \right) B 26 : * \] 27 : * 28 : * This functional is non-linear (due to the exponential) and twice differentiable. 29 : * It is an important functional to model Gaussian noise of e.g. dark-field 30 : * signals for AXDT. 31 : * 32 : * @tparam data_t data type for the domain of the residual of the functional, defaulting to 33 : * real_t 34 : */ 35 : template <typename data_t = real_t> 36 : class ExpLeastSquares : public Functional<data_t> 37 : { 38 : public: 39 : ExpLeastSquares(const LinearOperator<data_t>& A, const DataContainer<data_t>& b); 40 : 41 : // make copy constructor deletion explicit 42 : ExpLeastSquares(const ExpLeastSquares<data_t>&) = delete; 43 : 44 : // default destructor 45 12 : ~ExpLeastSquares() override = default; 46 : 47 : const LinearOperator<data_t>& getOperator() const; 48 : 49 : const DataContainer<data_t>& getDataVector() const; 50 : 51 : bool isDifferentiable() const override; 52 : 53 : protected: 54 : data_t evaluateImpl(const DataContainer<data_t>& Rx) const override; 55 : 56 : void getGradientImpl(const DataContainer<data_t>& Rx, 57 : DataContainer<data_t>& out) const override; 58 : 59 : /// the computation of the Hessian 60 : LinearOperator<data_t> getHessianImpl(const DataContainer<data_t>& Rx) const override; 61 : 62 : /// implement the polymorphic clone operation 63 : ExpLeastSquares<data_t>* cloneImpl() const override; 64 : 65 : /// implement the polymorphic comparison operation 66 : bool isEqual(const Functional<data_t>& other) const override; 67 : 68 : private: 69 : std::unique_ptr<LinearOperator<data_t>> A_{}; 70 : 71 : DataContainer<data_t> b_{}; 72 : }; 73 : 74 : } // namespace elsa