00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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,
00047 value_type t_ini,
00048 value_type q0,
00049 value_type qp0)
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
00061 gradient_ = V(x.size());
00062
00063 xtd_ = x + t * d;
00064
00065 qt_ = P.value(xtd_);
00066
00067
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
00076 t *= beta_;
00077
00078 qtold = qt_;
00079
00080 xtd_ = x + t * d;
00081
00082 qt_ = P.value(xtd_);
00083 P.firstDerivative(gradient_,xtd_);
00084
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 }
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
00104 P.firstDerivative(gradient_,xtd_);
00105
00106 qpt_ = DotProduct(gradient_,gradient_);
00107
00108
00109 return t;
00110 }
00111
00112 };
00113
00114
00115 #endif