ug4
line_search.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3  * Author: Andreas Vogel
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef __H__UG__LIB_DISC__OPERATOR__NON_LINEAR_OPERATOR__LINE_SEARCH__
34 #define __H__UG__LIB_DISC__OPERATOR__NON_LINEAR_OPERATOR__LINE_SEARCH__
35 
36 #include <ostream>
37 #include <string>
38 #include <vector>
39 #include <cmath>
40 #include <sstream>
41 
42 #include "common/common.h"
43 
44 namespace ug{
45 
48 // Line Search
51 
58 template <typename TVector>
60 {
61  public:
62  typedef TVector vector_type;
63 
64  public:
66  virtual void set_offset(std::string offset) = 0;
67 
80  virtual bool search(SmartPtr<IOperator<vector_type> > spOp,
81  vector_type& u, vector_type& p,
82  vector_type& d, number defect) = 0;
83 
85 
92  virtual std::string config_string() const = 0;
93 
95  virtual ~ILineSearch() {}
96 };
97 
99 template <typename TVector>
100 class StandardLineSearch : public ILineSearch<TVector>
101 {
102  public:
103  // type of
104  typedef TVector vector_type;
105 
106  public:
109  : m_maxSteps(10), m_lambdaStart(1.0), m_lambdaReduce(0.5), m_alpha(0.25),
110  m_maxDefect(1e+10), m_verbose(true), m_bAcceptBest(false), m_bCheckAll(false), m_offset("")
111  {};
112 
114  StandardLineSearch(int maxSteps, number lambdaStart, number lambdaReduce, bool bAcceptBest)
115  : m_maxSteps(maxSteps), m_lambdaStart(lambdaStart), m_lambdaReduce(lambdaReduce), m_alpha(0.25),
116  m_maxDefect(1e+10), m_verbose(true), m_bAcceptBest(bAcceptBest), m_bCheckAll(false), m_offset("")
117  {};
118 
120  StandardLineSearch(int maxSteps, number lambdaStart, number lambdaReduce, bool bAcceptBest, bool bCheckAll)
121  : m_maxSteps(maxSteps), m_lambdaStart(lambdaStart), m_lambdaReduce(lambdaReduce), m_alpha(0.25),
122  m_maxDefect(1e+10), m_verbose(true), m_bAcceptBest(bAcceptBest), m_bCheckAll(bCheckAll), m_offset("")
123  {};
124 
126  virtual std::string config_string() const
127  {
128  std::stringstream ss;
129  ss << "StandardLineSearch( maxSteps = " << m_maxSteps << ", lambdaStart = " << m_lambdaStart << ", lambdaReduce = " << m_lambdaReduce << ", accept best = " <<
130  (m_bAcceptBest ? "true" : "false") << " check all = " << (m_bCheckAll ? "true" : "false");
131  return ss.str();
132 
133  }
134 
136  void set_maximum_steps(int steps) {m_maxSteps = steps;}
137 
139  void set_lambda_start(number start) {m_lambdaStart = start;}
140 
142  void set_reduce_factor(number factor) {m_lambdaReduce = factor;}
143 
145  void set_suff_descent_factor(number factor) {m_alpha = factor;}
146 
148  void set_accept_best(bool bAcceptBest) {m_bAcceptBest = bAcceptBest;}
149 
151  void set_check_all(bool bCheckAll) {m_bCheckAll = bCheckAll;}
152 
154  void set_maximum_defect(number maxDef) {m_maxDefect = maxDef;}
155 
157  void set_verbose(bool level) {m_verbose = level;}
158 
160  virtual void set_offset(std::string offset) {m_offset = offset;};
161 
164  vector_type& u, vector_type& p,
165  vector_type& d, number defect)
166  {
167  PROFILE_BEGIN_GROUP(StandardLineSearch_search, ""); // group?
168  // clone pattern for s
169  s.resize(u.size());
170 
171  // start factor
172  number lambda = m_lambdaStart;
173 
174  // some values
175  number norm, norm_old = defect;
176  bool converged = false;
177  std::vector<number> vRho;
178 
179  // remember u
180  s = u;
181 
182  // print heading line
183  if(m_verbose)
184  UG_LOG(m_offset << " ++++ Line Search:\n"
185  << " + Iter lambda Defect Rate \n");
186 
187 
188  // loop line search steps
189  for(int k = 1; k <= m_maxSteps; ++k)
190  {
191  // try on line u := u - lambda*p
192  VecScaleAdd(u, 1.0, u, (-1)*lambda, p);
193 
194  // compute new Defect
195  spOp->prepare(u);
196  spOp->apply(d, u);
197 
198  // compute new Residuum
199  norm = d.norm();
200 
201  // compute reduction
202  vRho.push_back(norm/norm_old);
203 
204  // print rate
205  if(m_verbose)
206  UG_LOG(m_offset << " + " << std::setw(4)
207  << k << ": " << std::setw(11)
208  << std::resetiosflags( ::std::ios::scientific )<<
209  lambda << " "
210  << std::scientific << norm << " " << vRho.back() <<"\n");
211 
212  // check if reduction fits
213  if(vRho.back() <= 1 - m_alpha * std::fabs(lambda))
214  {
215  converged = true;
216  if(!m_bCheckAll) break;
217  }
218 
219  lambda *= m_lambdaReduce;
220 
221  // check if maximum number of steps reached
222  if(k == m_maxSteps)
223  {
224  // if not accept best, line search failed
225  if(!m_bAcceptBest)
226  {
227  UG_LOG(m_offset << " ++++ Line Search did not converge.\n");
228  return false;
229  }
230 
231  // search minimum
232  size_t best = 0;
233  number rho_min = vRho.front();
234  for(size_t i = 1; i < vRho.size(); ++i)
235  {
236  if(rho_min > vRho[i])
237  {
238  rho_min = vRho[i];
239  best = i;
240  }
241  }
242 
243  /* check if best is converging (i.e. rho < 1)
244  if(vRho[best] >= 1)
245  {
246  UG_LOG(m_offset << " ++++ Accept Best: No try with "
247  "Rate < 1, cannot accept any line search step.\n");
248  UG_LOG(m_offset << " ++++ Line Search did not converge.\n");
249  return false;
250  }*/
251 
252  // accept best
253  if(m_verbose)
254  UG_LOG(m_offset << " ++++ Accept Best: Accepting step " <<
255  best+1 << ", Rate = "<< vRho[best] <<".\n");
256 
257  // try on line u := u - lambda*p
258  VecScaleAdd(u, 1.0, s, (-1)*m_lambdaStart*std::pow(m_lambdaReduce, (number)best), p);
259 
260  // compute new Defect
261  spOp->prepare(u);
262  spOp->apply(d, u);
263 
264  // compute new Residuum
265  norm = d.norm();
266 
267  // check if defect-norm is smaller than maximum allowed defect value
268  if (norm > m_maxDefect)
269  {
270  UG_LOG("ERROR in 'StandardLineSearch::search':"
271  " maximum defect-limit is reached.\n");
272  return false;
273  }
274 
275  // break to finish
276  break;
277  }
278 
279  // reset u
280  u = s;
281  }
282 
283  // print end line
284  if(m_verbose)
285  {
286  //only for rate < 1, we call it "Line Search converged"
287  if(converged)
288  UG_LOG(m_offset << " ++++ Line Search converged.\n");
289  }
290 
291  // we're done
292  return true;
293  }
294 
295  protected:
298 
299  protected:
302 
305 
308 
311 
314 
316  bool m_verbose;
317 
320 
323 
325  std::string m_offset;
326 };
327 
328 } // end namespace ug
329 
330 #endif /* __H__UG__LIB_DISC__OPERATOR__NON_LINEAR_OPERATOR__LINE_SEARCH__ */
parameterString p
Definition: smart_pointer.h:108
Definition: line_search.h:60
virtual std::string config_string() const =0
returns information about configuration parameters
virtual void set_offset(std::string offset)=0
set string to be printed before each output of line search
virtual ~ILineSearch()
virtual destructor
Definition: line_search.h:95
TVector vector_type
Definition: line_search.h:62
virtual bool search(SmartPtr< IOperator< vector_type > > spOp, vector_type &u, vector_type &p, vector_type &d, number defect)=0
describes a mapping X->Y
Definition: operator.h:86
standard implementation of the line search based on the "sufficient descent"
Definition: line_search.h:101
void set_reduce_factor(number factor)
sets factor by which line search factor is multiplied in each step
Definition: line_search.h:142
std::string m_offset
number of spaces inserted before output
Definition: line_search.h:325
number m_lambdaStart
initial step length scaling
Definition: line_search.h:304
int m_maxSteps
maximum number of steps to be performed
Definition: line_search.h:301
void set_check_all(bool bCheckAll)
sets iff all the max_steps line search steps must be tested even if the sufficient descent is achieve...
Definition: line_search.h:151
void set_suff_descent_factor(number factor)
sets the factor controlling the sufficient descent
Definition: line_search.h:145
vector_type s
solution in line direction
Definition: line_search.h:297
number m_alpha
sufficient descent factor
Definition: line_search.h:310
virtual std::string config_string() const
returns information about configuration parameters
Definition: line_search.h:126
TVector vector_type
Definition: line_search.h:104
number m_maxDefect
maximum allowed defect
Definition: line_search.h:313
void set_maximum_defect(number maxDef)
sets maximum allowed norm of the defect (an exception is thrown if this value if exceeded)
Definition: line_search.h:154
virtual void set_offset(std::string offset)
set string to be printed before each output of line search
Definition: line_search.h:160
void set_maximum_steps(int steps)
sets maximum number of line search steps
Definition: line_search.h:136
void set_verbose(bool level)
sets if info should be printed
Definition: line_search.h:157
void set_lambda_start(number start)
sets start factor
Definition: line_search.h:139
StandardLineSearch(int maxSteps, number lambdaStart, number lambdaReduce, bool bAcceptBest)
constructor
Definition: line_search.h:114
StandardLineSearch()
default constructor (setting default values)
Definition: line_search.h:108
void set_accept_best(bool bAcceptBest)
sets iff after max_steps the best try is used
Definition: line_search.h:148
bool m_bAcceptBest
accept best
Definition: line_search.h:319
virtual bool search(SmartPtr< IOperator< vector_type > > spOp, vector_type &u, vector_type &p, vector_type &d, number defect)
Definition: line_search.h:163
bool m_bCheckAll
check all
Definition: line_search.h:322
bool m_verbose
verbosity level
Definition: line_search.h:316
StandardLineSearch(int maxSteps, number lambdaStart, number lambdaReduce, bool bAcceptBest, bool bCheckAll)
constructor
Definition: line_search.h:120
number m_lambdaReduce
reduction factor for the step length
Definition: line_search.h:307
#define UG_LOG(msg)
Definition: log.h:367
double number
Definition: types.h:124
void VecScaleAdd(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1, typename vector_t::value_type s2, const vector_t &v2)
Scales two Vectors, adds them and returns the sum in a third vector.
Definition: math_vector_functions_common_impl.hpp:265
the ug namespace
#define PROFILE_BEGIN_GROUP(name, groups)
Definition: profiler.h:255