Heidelberg Educational Numerics Library  Version 0.24 (from 9 September 2011)
newton.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil -*-
2 #ifndef HDNUM_NEWTON_HH
3 #define HDNUM_NEWTON_HH
4 
5 #include "lr.hh"
6 
11 namespace hdnum {
12 
19  template<class N>
21  {
22  public:
24  typedef std::size_t size_type;
25 
27  typedef N number_type;
28 
30  SquareRootProblem (number_type a_)
31  : a(a_)
32  {}
33 
35  std::size_t size () const
36  {
37  return 1;
38  }
39 
41  void F (const Vector<N>& x, Vector<N>& result) const
42  {
43  result[0] = x[0]*x[0] - a;
44  }
45 
47  void F_x (const Vector<N>& x, DenseMatrix<N>& result) const
48  {
49  result[0][0] = number_type(2.0)*x[0];
50  }
51 
52  private:
53  number_type a;
54  };
55 
56 
63  class Newton
64  {
65  typedef std::size_t size_type;
66 
67  public:
69  Newton ()
70  : maxit(25), linesearchsteps(10), verbosity(0),
71  reduction(1e-14), abslimit(1e-30), converged(false)
72  {}
73 
75  void set_maxit (size_type n)
76  {
77  maxit = n;
78  }
79 
81  void set_linesearchsteps (size_type n)
82  {
83  linesearchsteps = n;
84  }
85 
87  void set_verbosity (size_type n)
88  {
89  verbosity = n;
90  }
91 
93  void set_abslimit (double l)
94  {
95  abslimit = l;
96  }
97 
99  void set_reduction (double l)
100  {
101  reduction = l;
102  }
103 
105  template<class M>
106  void solve (const M& model, Vector<typename M::number_type> & x) const
107  {
108  typedef typename M::number_type N;
109  Vector<N> r(model.size()); // residual
110  DenseMatrix<N> A(model.size(),model.size()); // Jacobian matrix
111  Vector<N> y(model.size()); // temporary solution in line search
112  Vector<N> z(model.size()); // solution of linear system
113  Vector<N> s(model.size()); // scaling factors
114  Vector<size_type> p(model.size()); // row permutations
115  Vector<size_type> q(model.size()); // column permutations
116 
117  model.F(x,r); // compute nonlinear residual
118  N R0(norm(r)); // norm of initial residual
119  N R(R0); // current residual norm
120  if (verbosity>=1)
121  {
122  std::cout << "Newton "
123  << " norm=" << std::scientific << std::showpoint
124  << std::setprecision(4) << R0
125  << std::endl;
126  }
127 
128  converged = false;
129  for (size_type i=1; i<=maxit; i++) // do Newton iterations
130  {
131  // check absolute size of residual
132  if (R<=abslimit)
133  {
134  converged = true;
135  return;
136  }
137 
138  // solve Jacobian system for update
139  model.F_x(x,A); // compute Jacobian matrix
140  row_equilibrate(A,s); // equilibrate rows
141  lr_fullpivot(A,p,q); // LR decomposition of A
142  z = N(0.0); // clear solution
143  apply_equilibrate(s,r); // equilibration of right hand side
144  permute_forward(p,r); // permutation of right hand side
145  solveL(A,r,r); // forward substitution
146  solveR(A,z,r); // backward substitution
147  permute_backward(q,z); // backward permutation
148 
149  // line search
150  N lambda(1.0); // start with lambda=1
151  for (size_type k=0; k<linesearchsteps; k++)
152  {
153  y = x;
154  y.update(-lambda,z); // y = x+lambda*z
155  model.F(y,r); // r = F(y)
156  N newR(norm(r)); // compute norm
157  if (verbosity>=3)
158  {
159  std::cout << " line search " << std::setw(2) << k
160  << " lambda=" << std::scientific << std::showpoint
161  << std::setprecision(4) << lambda
162  << " norm=" << std::scientific << std::showpoint
163  << std::setprecision(4) << newR
164  << " red=" << std::scientific << std::showpoint
165  << std::setprecision(4) << newR/R
166  << std::endl;
167  }
168  if (newR<(1.0-0.25*lambda)*R) // check convergence
169  {
170  if (verbosity>=2)
171  {
172  std::cout << " step" << std::setw(3) << i
173  << " norm=" << std::scientific << std::showpoint
174  << std::setprecision(4) << newR
175  << " red=" << std::scientific << std::showpoint
176  << std::setprecision(4) << newR/R
177  << std::endl;
178  }
179  x = y;
180  R = newR;
181  break; // continue with Newton loop
182  }
183  else lambda *= 0.5; // reduce damping factor
184  if (k==linesearchsteps-1)
185  {
186  if (verbosity>=3)
187  std::cout << " line search not converged within " << linesearchsteps << " steps" << std::endl;
188  return;
189  }
190  }
191 
192  // check convergence
193  if (R<=reduction*R0)
194  {
195  if (verbosity>=1)
196  {
197  std::cout << "Newton converged in " << i << " steps"
198  << " reduction=" << std::scientific << std::showpoint
199  << std::setprecision(4) << R/R0
200  << std::endl;
201  }
202  converged = true;
203  return;
204  }
205  if (i==maxit)
206  {
207  if (verbosity>=2)
208  std::cout << "Newton not converged within " << maxit << " iterations" << std::endl;
209  }
210  }
211  }
212 
213  bool has_converged () const
214  {
215  return converged;
216  }
217 
218  private:
219  size_type maxit;
220  size_type linesearchsteps;
221  size_type verbosity;
222  double reduction;
223  double abslimit;
224  mutable bool converged;
225  };
226 
227 
228 
229 
237  class Banach
238  {
239  typedef std::size_t size_type;
240 
241  public:
244  : maxit(25), linesearchsteps(10), verbosity(0),
245  reduction(1e-14), abslimit(1e-30), sigma(1.0), converged(false)
246  {}
247 
249  void set_maxit (size_type n)
250  {
251  maxit = n;
252  }
253 
255  void set_sigma (double sigma_)
256  {
257  sigma = sigma_;
258  }
259 
261  void set_linesearchsteps (size_type n)
262  {
263  linesearchsteps = n;
264  }
265 
267  void set_verbosity (size_type n)
268  {
269  verbosity = n;
270  }
271 
273  void set_abslimit (double l)
274  {
275  abslimit = l;
276  }
277 
279  void set_reduction (double l)
280  {
281  reduction = l;
282  }
283 
285  template<class M>
286  void solve (const M& model, Vector<typename M::number_type> x) const
287  {
288  typedef typename M::number_type N;
289  Vector<N> r(model.size()); // residual
290  Vector<N> y(model.size()); // temporary solution in line search
291 
292  model.F(x,r); // compute nonlinear residual
293  N R0(norm(r)); // norm of initial residual
294  N R(R0); // current residual norm
295  if (verbosity>=1)
296  {
297  std::cout << "Banach "
298  << " norm=" << std::scientific << std::showpoint
299  << std::setprecision(4) << R0
300  << std::endl;
301  }
302 
303  converged = false;
304  for (size_type i=1; i<=maxit; i++) // do iterations
305  {
306  // check absolute size of residual
307  if (R<=abslimit)
308  {
309  converged = true;
310  return;
311  }
312 
313  // next iterate
314  y = x;
315  y.update(-sigma,r); // y = x+lambda*z
316  model.F(y,r); // r = F(y)
317  N newR(norm(r)); // compute norm
318  if (verbosity>=2)
319  {
320  std::cout << " " << std::setw(3) << i
321  << " norm=" << std::scientific << std::showpoint
322  << std::setprecision(4) << newR
323  << " red=" << std::scientific << std::showpoint
324  << std::setprecision(4) << newR/R
325  << std::endl;
326  }
327  x = y; // accept new iterate
328  R = newR; // remember new norm
329 
330  // check convergence
331  if (R<=reduction*R0 || R<=abslimit)
332  {
333  if (verbosity>=1)
334  {
335  std::cout << "Banach converged in " << i << " steps"
336  << " reduction=" << std::scientific << std::showpoint
337  << std::setprecision(4) << R/R0
338  << std::endl;
339  }
340  converged = true;
341  return;
342  }
343  }
344  }
345 
346  bool has_converged () const
347  {
348  return converged;
349  }
350 
351  private:
352  size_type maxit;
353  size_type linesearchsteps;
354  size_type verbosity;
355  double reduction;
356  double abslimit;
357  double sigma;
358  mutable bool converged;
359  };
360 
361 } // namespace hdnum
362 
363 #endif
Class with mathematical vector operations.
Definition: vector.hh:28
void solve(const M &model, Vector< typename M::number_type > x) const
do one step
Definition: newton.hh:286
void lr_fullpivot(DenseMatrix< T > &A, Vector< std::size_t > &p, Vector< std::size_t > &q)
lr decomposition of A with full pivoting
Definition: lr.hh:107
void permute_backward(const Vector< std::size_t > &q, Vector< T > &z)
apply permutations to a solution vector
Definition: lr.hh:176
Example class for a nonlinear model F(x) = 0;.
Definition: newton.hh:20
void solveR(const DenseMatrix< T > &A, Vector< T > &x, const Vector< T > &b)
Assume R = upper triangle of A and solve R x = b.
Definition: lr.hh:243
std::size_t size_type
export size_type
Definition: newton.hh:24
void set_verbosity(size_type n)
control output given 0=nothing, 1=summary, 2=every step, 3=include line search
Definition: newton.hh:267
Solve nonlinear problem using a fixed point iteration.
Definition: newton.hh:237
void set_maxit(size_type n)
maximum number of iterations before giving up
Definition: newton.hh:249
Newton()
constructor stores reference to the model
Definition: newton.hh:69
std::size_t size() const
return number of componentes for the model
Definition: newton.hh:35
void set_linesearchsteps(size_type n)
maximum number of steps in linesearch before giving up
Definition: newton.hh:81
void row_equilibrate(DenseMatrix< T > &A, Vector< T > &s)
perform a row equilibration of a matrix; return scaling for later use
Definition: lr.hh:192
void set_abslimit(double l)
basolute limit for defect
Definition: newton.hh:273
void apply_equilibrate(Vector< T > &s, Vector< T > &b)
apply row equilibration to right hand side vector
Definition: lr.hh:213
N number_type
export number_type
Definition: newton.hh:27
Vector & update(const REAL alpha, const Vector &y)
Update vector by addition of a scaled vector (x += a y )
Definition: vector.hh:194
void solveL(const DenseMatrix< T > &A, Vector< T > &x, const Vector< T > &b)
Assume L = lower triangle of A with l_ii=1, solve L x = b.
Definition: lr.hh:225
Banach()
constructor stores reference to the model
Definition: newton.hh:243
void F_x(const Vector< N > &x, DenseMatrix< N > &result) const
jacobian evaluation needed for implicit solvers
Definition: newton.hh:47
void set_sigma(double sigma_)
damping parameter
Definition: newton.hh:255
void set_reduction(double l)
reduction factor
Definition: newton.hh:99
void set_linesearchsteps(size_type n)
maximum number of steps in linesearch before giving up
Definition: newton.hh:261
This file implements a generic and dynamic vector class.
Class with mathematical matrix operations.
Definition: densematrix.hh:26
void set_verbosity(size_type n)
control output given 0=nothing, 1=summary, 2=every step, 3=include line search
Definition: newton.hh:87
void solve(const M &model, Vector< typename M::number_type > &x) const
do one step
Definition: newton.hh:106
void F(const Vector< N > &x, Vector< N > &result) const
model evaluation
Definition: newton.hh:41
void set_maxit(size_type n)
maximum number of iterations before giving up
Definition: newton.hh:75
void permute_forward(const Vector< std::size_t > &p, Vector< T > &b)
apply permutations to a right hand side vector
Definition: lr.hh:160
Definition: densematrix.hh:21
void set_abslimit(double l)
basolute limit for defect
Definition: newton.hh:93
Solve nonlinear problem using a damped Newton method.
Definition: newton.hh:63
SquareRootProblem(number_type a_)
constructor stores parameter lambda
Definition: newton.hh:30
void set_reduction(double l)
reduction factor
Definition: newton.hh:279