Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

armijo.h

00001 // Emacs will be in -*- Mode: c++ -*-
00002 //
00003 // ************ DO NOT REMOVE THIS BANNER ****************
00004 //
00005 //  Nicolas Di Cesare <Nicolas.Dicesare@free.fr>
00006 //  http://acm.emath.fr/~dicesare
00007 //
00008 //********************************************************
00009 //
00010 //  Armijo Line Search
00011 //
00012 //********************************************************
00013 #ifndef _armijo_h_
00014 #define _armijo_h
00015 
00016 #include <linesearch.h>
00017 #include <optimizer.h>
00018 
00031 template <class V>
00032 class ArmijoLineSearch : public LineSearch<V> {
00033 public:
00034   typedef double value_type;
00035 protected:  
00037   double alpha_, beta_;
00038 public:
00040   ArmijoLineSearch(double eps = 1e-8,double alpha = 0.5, double beta = 0.65)
00041     : LineSearch<V>(eps), alpha_(alpha), beta_(beta)  { }
00043   virtual ~ArmijoLineSearch() {}
00044 
00046   virtual value_type operator() (OptimizationProblem<V>& P, // Optimization problem 
00047                  value_type t_ini,          // initial value of line-search step
00048                  value_type q0,             // function value
00049                  value_type qp0)            // squared norm of gradient vector
00050   {
00051     bool maxIter = false;
00052     qt_ = q0; qpt_ = qp0;
00053     double qtold, qptnew, t = t_ini;
00054     int loopNumber = 0;
00055 
00056     OptimizationMethod<V> & method = P.optimisationMethod();
00057     V & x = method.x();
00058     V & d = method.searchDirection();
00059 
00060     // Initialize gradient
00061     gradient_ = V(x.size());
00062     // Compute new point
00063     xtd_ = x + t * d;
00064     // Compute function value at the new point
00065     qt_ = P.value(xtd_);
00066 
00067     // Enter in the loop if the criterion is not satisfied
00068 #ifdef DEBUG_ARMIJO
00069     std::cout << "qt_ - q0 = " << (qt_ - q0) << ", - alpha_ * t * qpt_ = " << (- alpha_ * t * qpt_) << std::endl;
00070 #endif
00071 
00072     if ((qt_ - q0) > - alpha_ * t * qpt_ ) {
00073       do {
00074     loopNumber++;
00075     // Decrease step
00076     t *= beta_;
00077     // Store old value of the function
00078     qtold = qt_;
00079     // New point value
00080     xtd_ = x + t * d;
00081     // Compute function value at the new point
00082     qt_ = P.value(xtd_);
00083     P.firstDerivative(gradient_,xtd_);
00084     // and it squared norm
00085     qptnew = DotProduct(gradient_,gradient_);
00086 #ifdef DEBUG_ARMIJO
00087     std::cout << loopNumber << ", qt_ - q0 = " << (qt_ - q0) << ", - alpha_ * t * qpt_ = " << (- alpha_ * t * qpt_) << std::endl;
00088     std::cout << "qtold - q0 = " << (qtold - q0) << ", - alpha_ * t * qpt_ / beta_ = " << (- alpha_ * t * qpt_ / beta_) << std::endl;
00089 #endif
00090     maxIter = P.optimisationMethod().endCriteria().checkIterationNumber(loopNumber);
00091       } // Armijo criteria
00092       while ( 
00093          ( ( (qt_ - q0) > (-alpha_ * t * qpt_) ) 
00094            || ((qtold - q0) <= (-alpha_ * t * qpt_ / beta_)) ) 
00095          && (!maxIter)
00096          );
00097     }
00098   
00099     if ( maxIter ) {
00100       succeed_ = false;
00101     }
00102 
00103     // Compute new gradient
00104     P.firstDerivative(gradient_,xtd_);
00105     // and it squared norm
00106     qpt_ = DotProduct(gradient_,gradient_);
00107 
00108     // Return new step value
00109     return t;
00110   }
00111 
00112 };
00113 
00114 
00115 #endif

Generated at Wed Nov 7 16:25:59 2001 for Optimization by doxygen1.2.9 written by Dimitri van Heesch, © 1997-2001