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