Line data Source code
1 : #pragma once 2 : 3 : #include "Functional.h" 4 : #include "LinearOperator.h" 5 : 6 : #include <memory> 7 : 8 : namespace elsa 9 : { 10 : /** 11 : * @brief Class representing a negative log-likelihood functional for emission tomography. 12 : * 13 : * The EmissionLogLikelihood functional evaluates as \f$ \sum_{i=1}^n (x_i + r_i) - y_i\log(x_i 14 : * + r_i) \f$, with \f$ y=(y_i) \f$ denoting the measurements, \f$ r=(r_i) \f$ denoting the mean 15 : * number of background events, and \f$ x=(x_i) \f$. 16 : * 17 : * Typically, \f$ x \f$ is wrapped in a LinearResidual without a data vector, i.e. \f$ x \mapsto 18 : * Ax \f$. 19 : * 20 : * @tparam data_t data type for the domain of the residual of the functional, defaulting to 21 : * real_t 22 : * 23 : * @author 24 : * * Matthias Wieczorek - initial code 25 : * * Maximilian Hornung - modularization 26 : * * Tobias Lasser - rewrite 27 : * 28 : */ 29 : template <typename data_t = real_t> 30 : class EmissionLogLikelihood : public Functional<data_t> 31 : { 32 : public: 33 : /** 34 : * @brief Constructor for emission log-likelihood, using only y, and a residual as input 35 : * 36 : * @param[in] residual to be used when evaluating the functional (or its derivative) 37 : * @param[in] y the measurement data vector 38 : */ 39 : EmissionLogLikelihood(const LinearOperator<data_t>& A, const DataContainer<data_t>& y); 40 : 41 : /** 42 : * @brief Constructor for emission log-likelihood, using y and r, and a residual as input 43 : * 44 : * @param[in] residual to be used when evaluating the functional (or its derivative) 45 : * @param[in] y the measurement data vector 46 : * @param[in] r the background event data vector 47 : */ 48 : EmissionLogLikelihood(const LinearOperator<data_t>& A, const DataContainer<data_t>& y, 49 : const DataContainer<data_t>& r); 50 : 51 : /// make copy constructor deletion explicit 52 : EmissionLogLikelihood(const EmissionLogLikelihood<data_t>&) = delete; 53 : 54 : bool isDifferentiable() const override; 55 : 56 : /// default destructor 57 14 : ~EmissionLogLikelihood() override = default; 58 : 59 : protected: 60 : /// the evaluation of the emission log-likelihood 61 : data_t evaluateImpl(const DataContainer<data_t>& Rx) const override; 62 : 63 : /// the computation of the gradient (in place) 64 : void getGradientImpl(const DataContainer<data_t>& Rx, 65 : DataContainer<data_t>& out) const override; 66 : 67 : /// the computation of the Hessian 68 : LinearOperator<data_t> getHessianImpl(const DataContainer<data_t>& Rx) const override; 69 : 70 : /// implement the polymorphic clone operation 71 : EmissionLogLikelihood<data_t>* cloneImpl() const override; 72 : 73 : /// implement the polymorphic comparison operation 74 : bool isEqual(const Functional<data_t>& other) const override; 75 : 76 : private: 77 : /// optional linear operator to apply to x 78 : std::unique_ptr<LinearOperator<data_t>> A_{}; 79 : 80 : /// the measurement data vector y 81 : DataContainer<data_t> y_; 82 : 83 : /// the background event data vector r 84 : std::optional<DataContainer<data_t>> r_{}; 85 : }; 86 : 87 : } // namespace elsa