1 //
2 // Created by tyler on 6/24/17.
3 //
4 
5 #ifndef BLAZE_ITERATIVE_ITERATIVE_TAG_HPP
6 #define BLAZE_ITERATIVE_ITERATIVE_TAG_HPP
7 
8 #include "TerminationStatus.hpp"
9 
10 
11 BLAZE_NAMESPACE_OPEN
12 ITERATIVE_NAMESPACE_OPEN
13 
14 class IterativeTag
15 {
16 
17 public:
IterativeTag()18     IterativeTag() {}
19 
terminateIteration(int iteration,double absolute_residual,double relative_residual)20     inline bool terminateIteration(int iteration, double absolute_residual, double relative_residual)
21     {
22         if (isConverged(absolute_residual, relative_residual)) {
23             return true;
24         } else if (iteration >= maximum_iterations) {
25             terminationStatus = TerminationStatus::ITERATION_LIMIT;
26             return true;
27         } else {
28             return false;
29         }
30     }
31 
32     template<typename T, typename=typename std::enable_if<std::is_convertible<T, double>::value>::type>
log_residual(T residual)33     inline void log_residual(T residual) { convergence_history_container.push_back(residual); }
34 
do_log()35     bool &do_log() { return record_convergence_history; }
36 
do_log() const37     bool do_log() const { return record_convergence_history; }
38 
status() const39     inline TerminationStatus status() const { return terminationStatus; }
40 
relativeResidualTolerance()41     double &relativeResidualTolerance() { return relative_residual_tolerance; }
42 
relativeResidualTolerance() const43     double relativeResidualTolerance() const { return relative_residual_tolerance; }
44 
absoluteResidualTolerance()45     double &absoluteResidualTolerance() { return absolute_residual_tolerance; }
46 
absoluteResidualTolerance() const47     double absoluteResidualTolerance() const { return absolute_residual_tolerance; }
48 
maximumIterations()49     std::size_t &maximumIterations() { return maximum_iterations; }
50 
maximumIterations() const51     std::size_t maximumIterations() const { return maximum_iterations; }
52 
convergence_history() const53     const std::vector<double> &convergence_history() const { return convergence_history_container; }
54 
55 protected:
56     std::size_t maximum_iterations{20};
57     double relative_residual_tolerance{1.0e-6};
58     double absolute_residual_tolerance{0.0};
59     std::string solverName{"Default"};
60     TerminationStatus terminationStatus{TerminationStatus::NOT_TERMINATED};
61     bool record_convergence_history{false};
62 
63     //container for relative residual convergence history
64     std::vector<double> convergence_history_container;
65 
isConverged(double absolute_residual,double relative_residual)66     inline bool isConverged(double absolute_residual, double relative_residual)
67     {
68         if (std::abs(relative_residual) < relative_residual_tolerance) {
69             terminationStatus = TerminationStatus::CONVERGED_RELATIVE_RESIDUAL;
70             return true;
71         } else if (std::abs(absolute_residual) < absolute_residual_tolerance) {
72             terminationStatus = TerminationStatus::CONVERGED_ABSOLUTE_RESIDUAL;
73             return true;
74         } else {
75             return false;
76         }
77     }
78 
79 };
80 
81 
82 ITERATIVE_NAMESPACE_CLOSE
83 BLAZE_NAMESPACE_CLOSE
84 
85 #endif //BLAZE_ITERATIVE_ITERATIVE_TAG_HPP
86