cyclic_iteration.hpp 3.07 KB
Newer Older
1
// Software License for MTL
2
//
3
4
5
6
7
// Copyright (c) 2007 The Trustees of Indiana University.
//               2008 Dresden University of Technology and the Trustees of Indiana University.
//               2010 SimuNova UG (haftungsbeschränkt), www.simunova.com.
// All rights reserved.
// Authors: Peter Gottschling and Andrew Lumsdaine
8
//
9
// This file is part of the Matrix Template Library2
10
//
11
12
13
14
15
16
17
18
19
20
21
22
// See also license.mtl.txt in the distribution.

#ifndef ITL_CYCLIC_ITERATION_INCLUDE
#define ITL_CYCLIC_ITERATION_INCLUDE

#include <iostream>
#include <boost/numeric/itl/iteration/basic_iteration.hpp>

namespace itl {

  /// Class for iteration control that cyclically prints residual
  template <class Real, class OStream = std::ostream>
23
  class cyclic_iteration : public basic_iteration<Real>
24
25
26
27
28
29
30
31
  {
      typedef basic_iteration<Real> super;
      typedef cyclic_iteration self;

      void print_resid()
      {
	  if (!this->my_quite && this->i % cycle == 0)
	      if (multi_print || this->i != last_print) { // Avoid multiple print-outs in same iteration
32
		  out << "iteration " << this->i << ": resid " << this->resid()
33
34
35
36
37
38
39
		      // << " / " << this->norm_r0 << " = " << this->resid() / this->norm_r0 << " (rel. error)"
		      << std::endl;
		  last_print= this->i;
	      }
      }

    public:
40

41
42
43
44
45
46
47
48
49
50
      template <class Vector>
      cyclic_iteration(const Vector& r0, int max_iter_, Real tol_, Real atol_ = Real(0), int cycle_ = 100,
		       OStream& out = std::cout)
	: super(r0, max_iter_, tol_, atol_), cycle(cycle_), last_print(-1), multi_print(false), out(out)
      {}

      cyclic_iteration(Real r0, int max_iter_, Real tol_, Real atol_ = Real(0), int cycle_ = 100,
		       OStream& out = std::cout)
	: super(r0, max_iter_, tol_, atol_), cycle(cycle_), last_print(-1), multi_print(false), out(out)
      {}
51

52
53
54
55

      bool finished() { return super::finished(); }

      template <typename T>
56
      bool finished(const T& r)
57
58
59
60
61
62
63
      {
	  bool ret= super::finished(r);
	  print_resid();
	  return ret;
      }

      inline self& operator++() { ++this->i; return *this; }
64

65
66
67
68
69
70
71
72
73
74
      inline self& operator+=(int n) { this->i+= n; return *this; }

      operator int() const { return error_code(); }

      /// Whether the residual is printed multiple times in iteration
      bool is_multi_print() const { return multi_print; }

      /// Set whether the residual is printed multiple times in iteration
      void set_multi_print(bool m) { multi_print= m; }

75
      int error_code() const
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
      {
	  if (!this->my_suppress)
	      out << "finished! error code = " << this->error << '\n'
		  << this->iterations() << " iterations\n"
		  << this->resid() << " is actual final residual. \n"
		  << this->relresid() << " is actual relative tolerance achieved. \n"
		  << "Relative tol: " << this->rtol_ << "  Absolute tol: " << this->atol_ << '\n'
		  << "Convergence:  " << pow(this->relresid(), 1.0 / double(this->iterations())) << std::endl;
	  return this->error;
      }
    protected:
      int        cycle, last_print;
      bool       multi_print;
      OStream&   out;
  };



} // namespace itl

#endif // ITL_CYCLIC_ITERATION_INCLUDE