LCOV - code coverage report
Current view: top level - Utility - SimplifiedVectorizedNewtonRaphson.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 19 19 100.0 %
Date: 2021-02-18 20:07:22 Functions: 16 28 57.1 %

          Line data    Source code
       1             : /**
       2             :  * \file SimplifiedVectorizedNewtonRaphson.h
       3             :  */
       4             : 
       5             : #ifndef ATK_UTILITY_SIMPLIFIEDVECTORIZEDNEWTONRAPHSON_H
       6             : #define ATK_UTILITY_SIMPLIFIEDVECTORIZEDNEWTONRAPHSON_H
       7             : 
       8             : #include <ATK/config.h>
       9             : 
      10             : #include <Eigen/Dense>
      11             : 
      12             : #include <cmath>
      13             : #include <limits>
      14             : 
      15             : namespace ATK
      16             : {
      17             :   /// Simplified Vectorized Newton Raphson optimizer
      18             :   /*!
      19             :    * A NR optimizer, 10 iterations max, for stabilized computation
      20             :    */
      21             :   template<typename Function, int size, int max_iterations=10>
      22             :   class SimplifiedVectorizedNewtonRaphson
      23             :   {
      24             :     using DataType = typename Function::DataType;
      25             :     using Vector = Eigen::Matrix<DataType, size, 1>;
      26             : 
      27             :     Function function;
      28             :     
      29             :     DataType precision;
      30             :     DataType maxstep{10};
      31             :     Vector y0{Vector::Zero()};
      32             :     
      33             :   public:
      34             :     /*!
      35             :      * @brief Constructs the optimizer
      36             :      * @param function is the function that we will try to optimize.
      37             :      *   It is a functor taking x[n-1], x[n], y[n-1] and an estimate y[n], returning the value of the cost function and its derivative according to y[n]
      38             :      * @param precision is the precision that the optimizer will try to achieve. By default uses $$\\sqrt{\\epsilon_{Datatype}}$$
      39             :      */
      40             :     SimplifiedVectorizedNewtonRaphson(Function&& function, DataType precision = 0)
      41             :     :function(std::move(function)), precision(precision)
      42             :     {
      43             :       if(precision == 0)
      44             :       {
      45             :         this->precision = std::sqrt(std::numeric_limits<DataType>::epsilon());
      46             :       }
      47             :     }
      48             : 
      49          12 :     SimplifiedVectorizedNewtonRaphson(Function&& function, Vector&& y0, DataType precision = 0)
      50          12 :       :function(std::move(function)), precision(precision), y0(y0)
      51             :     {
      52          12 :       if (precision == 0)
      53             :       {
      54          12 :         this->precision = std::sqrt(std::numeric_limits<DataType>::epsilon());
      55             :       }
      56          12 :     }
      57             : 
      58             : 
      59             :     SimplifiedVectorizedNewtonRaphson(const SimplifiedVectorizedNewtonRaphson&) = delete;
      60             :     SimplifiedVectorizedNewtonRaphson& operator=(const SimplifiedVectorizedNewtonRaphson&) = delete;
      61             : 
      62             :     /// Optimize the function and sets its internal state
      63          12 :     Vector optimize()
      64             :     {
      65          12 :       Vector y1 = y0;
      66             :       gsl::index j;
      67         171 :       for(j = 0; j < max_iterations; ++j)
      68             :       {
      69         169 :         Vector cx = function(y1);
      70         169 :         auto maximum = cx.maxCoeff();
      71         169 :         auto minimum = cx.minCoeff();
      72         169 :         auto r = std::max(maximum, -minimum);
      73         169 :         if(r > maxstep)
      74             :         {
      75          75 :           cx *= maxstep/r;
      76             :         }
      77             : 
      78         169 :         auto yk = y1 - cx;
      79         169 :         if((cx.array().abs() < precision).all())
      80             :         {
      81          10 :           return yk;
      82             :         }
      83         159 :         y1 = yk;
      84             :       }
      85           2 :       return y1;
      86             :     }
      87             :   };
      88             : }
      89             : 
      90             : #endif

Generated by: LCOV version TK-3.3.0-4-gdba42eea