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