LCOV - code coverage report
Current view: top level - elsa/solvers - BA_GMRES.h (source / functions) Hit Total Coverage
Test: coverage-all.lcov Lines: 1 1 100.0 %
Date: 2024-05-16 04:22:26 Functions: 1 2 50.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <memory>
       4             : #include <optional>
       5             : 
       6             : #include "Solver.h"
       7             : #include "LinearOperator.h"
       8             : #include <Eigen/Core>
       9             : 
      10             : namespace elsa
      11             : {
      12             :     /**
      13             :      * @brief Class implementing the BA_GMRES method for solving with an unmatched Back Projector
      14             :      *
      15             :      * GMRES is an iterative method for solving an indefinite nonsymmetric linear system \f$ Ax = b
      16             :      * \f$ It solves the system by minimizing a least squares Problem for \f$ J(y) = \left\| \beta
      17             :      * {e_{1}} - \bar{H}y \right\| \f$ where \f$ \beta \f$ is \f$ \left\| f - Ax \right\| \f$, \f$
      18             :      * {e_{1}} \f$ is the first column of the \f$ (k + 1) \times (k + 1) \f$ identity matrix and \f$
      19             :      * \bar{H} \f$ is \f$ (k + 1) \times (k) \f$ matrix whose only nonzero entries are generated by
      20             :      * the algorithm.
      21             :      *
      22             :      * We implement an expanded BA_GMRES method for solving large sparse least square problems. Here
      23             :      * we define \f$ A^T = B \f$ for our matrix \f$ A \epsilon \mathbb{R}^{m \times n} \f$ with
      24             :      * \f$ B \epsilon \mathbb{R}^{n \times m} \f$. We solve the so-called unmatched normal equations
      25             :      * \f$ BAx = Bb \f$ and \f$ ABy = b \f$  where \f$ x = By \f$:
      26             :      *
      27             :      * BA_GMRES solves \f$ min_{x \epsilon \mathbb{R}^m} \left\| Bb - BAx \right\|\f$.
      28             :      *
      29             :      * \f$ A \f$ can be imagined as a discretization of the forward projector, while \f$ B \f$
      30             :      * represents an matched or unmatched back projector or preconditioner/backprojector, the
      31             :      * algorithm can reach semi-convergence when \f$ A^T \neq B \f$ as long as valid models for
      32             :      * the projector / backprojector pair are chosen
      33             :      *
      34             :      * Convergence is considered reached when \f$ ||r|| <= epsilon \f$
      35             :      *
      36             :      * References:
      37             :      * http://epubs.siam.org/doi/10.1137/0907058
      38             :      * http://epubs.siam.org/doi/10.1137/070696313
      39             :      * http://arxiv.org/abs/2110.01481
      40             :      *
      41             :      * @author Daniel Klitzner - initial code
      42             :      */
      43             :     template <typename data_t = real_t>
      44             :     class BA_GMRES : public Solver<data_t>
      45             :     {
      46             :     public:
      47             :         /// Scalar alias
      48             :         using Scalar = typename Solver<data_t>::Scalar;
      49             : 
      50             :         /**
      51             :          * @brief Constructor for BA_GMRES, accepting a forward projector A, *a sinogram b and an
      52             :          *optional value for epsilon, the backprojector B will be the adjoint *of projector A
      53             :          *
      54             :          * @param[in] projector Discretization of a forward projector
      55             :          * @param[in] sinogram sinogram of measured Data when applying phantom to projector
      56             :          * @param[in] epsilon affects the stopping condition
      57             :          **/
      58             :         explicit BA_GMRES(const LinearOperator<data_t>& projector,
      59             :                           const DataContainer<data_t>& sinogram,
      60             :                           data_t epsilon = std::numeric_limits<data_t>::epsilon());
      61             : 
      62             :         /**
      63             :          * @brief Constructor for BA_GMRES, accepting a forward projector A, an *unmatched
      64             :          *backprojector B, a sinogram b and an optional value for *epsilon
      65             :          *
      66             :          * @param[in] projector Discretization of a forward projector A
      67             :          * @param[in] backprojector An optional unmatched/matched backprojector B
      68             :          * @param[in] sinogram sinogram "b" of measured Data when applying phantom to projector
      69             :          * @param[in] epsilon affects the stopping condition
      70             :          **/
      71             :         BA_GMRES(const LinearOperator<data_t>& projector,
      72             :                  const LinearOperator<data_t>& backprojector, const DataContainer<data_t>& sinogram,
      73             :                  data_t epsilon = std::numeric_limits<data_t>::epsilon());
      74             : 
      75             :         /// make copy constructor deletion explicit
      76             :         BA_GMRES(const BA_GMRES<data_t>&) = delete;
      77             : 
      78             :         /// default destructor
      79           4 :         ~BA_GMRES() override = default;
      80             : 
      81             :         /**
      82             :          * @brief Solves the given Linear System using BA-GMRES as default, i.e. apply i iterations
      83             :          *with r restarts of BA-GMRES
      84             :          *
      85             :          * @param[in] iterations number of iterations to execute
      86             :          * @param[in] restarts number of restarts to execute after iterations
      87             :          * @param[in] x0 optional approximate starting positions (used for preconditioning)
      88             :          * @return an approximated solution
      89             :          **/
      90             :         DataContainer<data_t>
      91             :             solveAndRestart(index_t iterations, index_t restarts,
      92             :                             std::optional<DataContainer<data_t>> x0 = std::nullopt);
      93             : 
      94             :         /**
      95             :          * @brief Solves the given Linear System using BA-GMRES as default, i.e. apply i iterations
      96             :          *of BA-GMRES
      97             :          *
      98             :          * @param[in] iterations number of iterations to execute
      99             :          * @param[in] x0 optional approximate starting positions (used for preconditioning)
     100             :          * @return an approximated solution
     101             :          **/
     102             :         DataContainer<data_t>
     103             :             solve(index_t iterations,
     104             :                   std::optional<DataContainer<data_t>> x0 = std::nullopt) override;
     105             : 
     106             :     private:
     107             :         /// Projector A
     108             :         std::unique_ptr<LinearOperator<data_t>> _A;
     109             : 
     110             :         /// Unmatched Backprojector B, used for Preconditioning
     111             :         std::unique_ptr<LinearOperator<data_t>> _B;
     112             : 
     113             :         /// sinogram b
     114             :         DataContainer<data_t> _b;
     115             : 
     116             :         /// variable affecting the stopping condition
     117             :         data_t _epsilon;
     118             : 
     119             :         /// implement the polymorphic clone operation
     120             :         BA_GMRES<data_t>* cloneImpl() const override;
     121             : 
     122             :         /// implement the polymorphic comparison operation
     123             :         bool isEqual(const Solver<data_t>& other) const override;
     124             :     };
     125             : } // namespace elsa

Generated by: LCOV version 1.14