IterationController.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24 
25 /* NOTE The class IterationController has been adapted from the iteration
26  * class of the GMM++ and ITL libraries.
27  */
28 
29 //=======================================================================
30 // Copyright (C) 1997-2001
31 // Authors: Andrew Lumsdaine <lums@osl.iu.edu>
32 // Lie-Quan Lee <llee@osl.iu.edu>
33 //
34 // This file is part of the Iterative Template Library
35 //
36 // You should have received a copy of the License Agreement for the
37 // Iterative Template Library along with the software; see the
38 // file LICENSE.
39 //
40 // Permission to modify the code and to distribute modified code is
41 // granted, provided the text of this NOTICE is retained, a notice that
42 // the code was modified is included with the above COPYRIGHT NOTICE and
43 // with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
44 // file is distributed with the modified code.
45 //
46 // LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
47 // By way of example, but not limitation, Licensor MAKES NO
48 // REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
49 // PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
50 // OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
51 // OR OTHER RIGHTS.
52 //=======================================================================
53 
54 //========================================================================
55 //
56 // Copyright (C) 2002-2007 Yves Renard
57 //
58 // This file is a part of GETFEM++
59 //
60 // Getfem++ is free software; you can redistribute it and/or modify
61 // it under the terms of the GNU Lesser General Public License as
62 // published by the Free Software Foundation; version 2.1 of the License.
63 //
64 // This program is distributed in the hope that it will be useful,
65 // but WITHOUT ANY WARRANTY; without even the implied warranty of
66 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
67 // GNU Lesser General Public License for more details.
68 // You should have received a copy of the GNU Lesser General Public
69 // License along with this program; if not, write to the Free Software
70 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
71 // USA.
72 //
73 //========================================================================
74 
75 #ifndef EIGEN_ITERATION_CONTROLLER_H
76 #define EIGEN_ITERATION_CONTROLLER_H
77 
78 namespace Eigen {
79 
89 {
90  protected :
91  double m_rhsn;
92  size_t m_maxiter;
93  int m_noise;
94  double m_resmax;
95  double m_resminreach, m_resadd;
96  size_t m_nit;
97  double m_res;
98  bool m_written;
99  void (*m_callback)(const IterationController&);
100  public :
101 
102  void init()
103  {
104  m_nit = 0; m_res = 0.0; m_written = false;
105  m_resminreach = 1E50; m_resadd = 0.0;
106  m_callback = 0;
107  }
108 
109  IterationController(double r = 1.0E-8, int noi = 0, size_t mit = size_t(-1))
110  : m_rhsn(1.0), m_maxiter(mit), m_noise(noi), m_resmax(r) { init(); }
111 
112  void operator ++(int) { m_nit++; m_written = false; m_resadd += m_res; }
113  void operator ++() { (*this)++; }
114 
115  bool first() { return m_nit == 0; }
116 
117  /* get/set the "noisyness" (verbosity) of the solvers */
118  int noiseLevel() const { return m_noise; }
119  void setNoiseLevel(int n) { m_noise = n; }
120  void reduceNoiseLevel() { if (m_noise > 0) m_noise--; }
121 
122  double maxResidual() const { return m_resmax; }
123  void setMaxResidual(double r) { m_resmax = r; }
124 
125  double residual() const { return m_res; }
126 
127  /* change the user-definable callback, called after each iteration */
128  void setCallback(void (*t)(const IterationController&))
129  {
130  m_callback = t;
131  }
132 
133  size_t iteration() const { return m_nit; }
134  void setIteration(size_t i) { m_nit = i; }
135 
136  size_t maxIterarions() const { return m_maxiter; }
137  void setMaxIterations(size_t i) { m_maxiter = i; }
138 
139  double rhsNorm() const { return m_rhsn; }
140  void setRhsNorm(double r) { m_rhsn = r; }
141 
142  bool converged() const { return m_res <= m_rhsn * m_resmax; }
143  bool converged(double nr)
144  {
145  m_res = internal::abs(nr);
146  m_resminreach = (std::min)(m_resminreach, m_res);
147  return converged();
148  }
149  template<typename VectorType> bool converged(const VectorType &v)
150  { return converged(v.squaredNorm()); }
151 
152  bool finished(double nr)
153  {
154  if (m_callback) m_callback(*this);
155  if (m_noise > 0 && !m_written)
156  {
157  converged(nr);
158  m_written = true;
159  }
160  return (m_nit >= m_maxiter || converged(nr));
161  }
162  template <typename VectorType>
163  bool finished(const MatrixBase<VectorType> &v)
164  { return finished(double(v.squaredNorm())); }
165 
166 };
167 
168 } // end namespace Eigen
169 
170 #endif // EIGEN_ITERATION_CONTROLLER_H