Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
block_monitor.h
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Stokhos Package
4 //
5 // Copyright 2009 NTESS and the Stokhos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 /*
11  * Copyright 2008-2009 NVIDIA Corporation
12  *
13  * Licensed under the Apache License, Version 2.0 (the "License");
14  * you may not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  * http://www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an "AS IS" BASIS,
21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  */
25 
30 #pragma once
31 
32 #include <cusp/detail/config.h>
33 #include <cusp/array1d.h>
34 #include <cusp/blas.h>
35 #include <cusp/array2d.h>
36 #include <cusp/print.h>
37 
38 #include <limits>
39 #include <iostream>
40 #include <iomanip>
41 
42 // Classes to monitor iterative solver progress, check for convergence, etc.
43 // Follows the implementation of Iteration in the ITL:
44 // http://www.osl.iu.edu/research/itl/doc/Iteration.html
45 
46 namespace cusp
47 {
62 template <typename ValueType>
64 {
65 public:
66  typedef typename norm_type<ValueType>::type Real;
67 
82  template <typename MV>
83  default_block_monitor(const MV& b,
84  size_t iteration_limit = 500,
85  Real absolute_tolerance = 1e-6,
86  Real relative_tolerance = 1e-6,
87  bool verbose = true) :
88  numRHS(b.num_cols),
93  verbose_(verbose),
94  b_norm(b.num_cols)
95  {
96  for (int i = 0; i < numRHS; i++)
97  b_norm[i] = cusp::blas::nrm2(b.column(i));
98  }
99 
102  void operator++(void) { ++iteration_count_; } // prefix increment
103 
109  template <typename MV>
110  bool finished(const MV& r)
111  {
112 
113  if (converged(r))
114  {
115  if (verbose_) {
116  cusp::array1d<ValueType, cusp::host_memory> resid(numRHS);
117  std::cout << "Successfully converged after " << iteration_count() << " iterations to tolerance " << tolerance(0) << std::endl;
118  std::cout << "with max residual norm ";
119  Real norm_max = 0;
120  for (int i = 0; i < numRHS; i++) {
121  resid[i] = cusp::blas::nrm2(r.column(i));
122  if (resid[i] > norm_max) norm_max = resid[i];
123  }
124  std::cout << norm_max << std::endl;
125 
126  //cusp::print(resid);
127  }
128 
129  return true;
130  }
131  else if (iteration_count() >= iteration_limit())
132  {
133  if (verbose_) {
134  cusp::array1d<ValueType, cusp::host_memory> resid(numRHS);
135  std::cout << "Failed to converge after " << iteration_count() << " iterations." << std::endl;
136  std::cout << "with max residual norm ";
137  Real norm_max = 0;
138  for (int i = 0; i < numRHS; i++) {
139  resid[i] = cusp::blas::nrm2(r.column(i));
140  if (resid[i] > norm_max) norm_max = resid[i];
141  }
142  std::cout << norm_max << std::endl;
143 
144  //cusp::print(resid);
145  }
146 
147  return true;
148  }
149  else
150  {
151  return false;
152  }
153 
154 
155  }
156 
159  template <typename MV>
160  bool converged(MV& r) const
161  {
162  for (int i = 0; i < numRHS; i++){
163 
164  if (cusp::blas::nrm2(r.column(i)) > tolerance(i)){
165  return false;
166  }
167  }
168 
169  return true;
170  }
171 
174  size_t iteration_count() const { return iteration_count_; }
175 
178  size_t iteration_limit() const { return iteration_limit_; }
179 
183 
187 
193  Real tolerance(int i) const { return absolute_tolerance() + relative_tolerance() * b_norm[i]; }
194 
195 protected:
196 
199  bool verbose_;
200  size_t numRHS;
203  cusp::array1d<ValueType, cusp::host_memory> b_norm;
204 
205 };
206 
216 /*
217 template <typename ValueType>
218 class verbose_block_monitor : public default_block_monitor<ValueType>
219 {
220  typedef typename norm_type<ValueType>::type Real;
221  typedef cusp::default_block_monitor<ValueType> super;
222 
223  public:
224 
225  *! Construct a \p verbose_monitor for a given right-hand-side \p b
226  *
227  * The \p verbose_monitor terminates iteration when the residual norm
228  * satisfies the condition
229  * ||b - A x|| <= absolute_tolerance + relative_tolerance * ||b||
230  * or when the iteration limit is reached.
231  *
232  * \param b right-hand-side of the linear system A x = b
233  * \param iteration_limit maximum number of solver iterations to allow
234  * \param relative_tolerance determines convergence criteria
235  * \param absolute_tolerance determines convergence criteria
236  *
237  * \tparam VectorType vector
238  *
239 
240 
241  template <typename MV>
242  verbose_block_monitor(const MV& b, size_t iteration_limit = 500, Real relative_tolerance = 1e-5, Real absolute_tolerance = 0)
243  : super(b, iteration_limit, relative_tolerance, absolute_tolerance)
244  {
245  std::cout << "Solver will continue until ";
246  std::cout << "residual norm" << super::tolerance() << " or reaching ";
247  std::cout << super::iteration_limit() << " iterations " << std::endl;
248  std::cout << " Iteration Number | Residual Norm" << std::endl;
249  }
250 
251  template <typename MV>
252  bool finished(const MV& r)
253  {
254  for (int i = 0; i < r.num_cols; i++)
255  super::r_norm[i] = cusp::blas::nrm2(r.column(i));
256 
257  std::cout << " " << std::setw(10) << super::iteration_count();
258  std::cout << " " << std::setw(10) << std::scientific << super::residual_norm_average() << std::endl;
259 
260  if (super::converged(r))
261  {
262  std::cout << "Successfully converged after " << super::iteration_count() << " iterations." << std::endl;
263  return true;
264  }
265  else if (super::iteration_count() >= super::iteration_limit())
266  {
267  std::cout << "Failed to converge after " << super::iteration_count() << " iterations." << std::endl;
268  return true;
269  }
270  else
271  {
272  return false;
273  }
274  }
275 };
276 
277 */
278 
282 } // end namespace cusp
bool converged(MV &r) const
default_block_monitor(const MV &b, size_t iteration_limit=500, Real absolute_tolerance=1e-6, Real relative_tolerance=1e-6, bool verbose=true)
Definition: block_monitor.h:83
bool finished(const MV &r)
norm_type< ValueType >::type Real
Definition: block_monitor.h:66
size_t iteration_count() const
size_t iteration_limit() const
Real tolerance(int i) const
cusp::array1d< ValueType, cusp::host_memory > b_norm
Real absolute_tolerance() const
Real relative_tolerance() const