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

cg.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 //  Conjugate gradient optimization method
00011 //
00012 //********************************************************
00013 #ifndef _conjugate_gradient_h
00014 #define _conjugate_gradient_h
00015 
00016 #include <iostream>
00017 #include <iomanip>
00018 #include <cmath>
00019 
00020 #include <optimizer.h>
00021 #include <linesearch.h>
00022 #include <criteria.h>
00023 #include <armijo.h>
00024 
00025 #include <ql/handle.hpp>
00026 
00027 //using QuantLib::Handle;
00028 
00039 template <class V>
00040 class ConjugateGradient : public OptimizationMethod<V> {
00042   QuantLib::Handle< LineSearch<V> > lineSearch_;
00043 public:
00045   ConjugateGradient()
00046     : OptimizationMethod<V>(), lineSearch_(QuantLib::Handle< LineSearch<V> >(new ArmijoLineSearch<V>()))
00047   {}
00049   ConjugateGradient(QuantLib::Handle< LineSearch<V> >& lineSearch)// Reference to a line search method
00050     : OptimizationMethod<V>(), lineSearch_(lineSearch)
00051   {}
00052 
00053 
00055   virtual ~ConjugateGradient() {}
00056 
00058   virtual void Minimize(OptimizationProblem<V> & P);
00059 };
00060 
00061 template <class V> void 
00062 ConjugateGradient<V>::Minimize(OptimizationProblem<V> & P) 
00063 {
00064   bool EndCriteria = false;
00065 
00066   // function and squared norm of gradient values;
00067   double f, fold, sd2, sdold2, g2, gold2, c = 0.,normdiff = 0;
00068   // classical initial value for line-search step
00069   double t = 1.;
00070 
00071   // reference X as the optimization problem variable
00072   V & X =  x();
00073   V & SearchDirection = searchDirection();
00074   // Set g at the size of the optimization problem search direction
00075   int sz = searchDirection().size();
00076   V g(sz), d(sz), sddiff(sz);
00077 
00078   f = P.valueAndFirstDerivative(g,X);
00079   SearchDirection = - g;
00080   g2 = DotProduct(g,g);
00081   sd2 = g2;
00082   normdiff = sqrt(sd2);
00083 
00084 
00085   do {
00086 
00087     P.Save(iterationNumber(), f, sqrt(g2), t, *this);
00088 
00089 #ifdef DEBUG_CG    
00090     std::cout << "searchDirection() = " << searchDirection()
00091           << "gradient          = " << g
00092           << "norm of gradient  = " << sqrt(g2) << std::endl
00093           << "search direction  = " << SearchDirection
00094           << "norm              = " << sqrt(sd2) << std::endl
00095           << "t                 = " << t << std::endl
00096           << "c                 = " << c << std::endl
00097           << "d                 = " << d 
00098           << "x                 = " << X << std::endl;
00099 #endif
00100     // Linesearch
00101     t = (*lineSearch_)(P,t,f,g2);
00102 
00103     if ( lineSearch_->succeed()) {
00104       // Updates
00105       d = SearchDirection;
00106       // New point
00107       X = lineSearch_->lastX();
00108       // New function value
00109       fold = f;
00110       f = lineSearch_->lastFunctionValue();
00111       // New gradient and search direction vectors
00112       g = lineSearch_->lastGradient();
00113       // orthogonalization coef
00114       gold2 = g2;
00115       g2 = lineSearch_->lastGradientNorm2();
00116       c = g2 / gold2;
00117       // conjugate gradient search direction
00118       sddiff = (-g+c*d) - SearchDirection;
00119       normdiff = sqrt(DotProduct(sddiff,sddiff));
00120       SearchDirection = -g+c*d;
00121       // New gradient squared norm
00122       sdold2 = sd2;
00123       sd2 = DotProduct(SearchDirection,SearchDirection);
00124       
00125       // End criteria
00126       EndCriteria = endCriteria()(iterationNumber_, fold, sqrt(gold2), 
00127                   f, sqrt(g2), normdiff
00128                   );
00129       
00130       // Increase interation number
00131       iterationNumber()++;
00132     }
00133   }
00134   while ( (EndCriteria == false)&&(lineSearch_->succeed()) );
00135 
00136   P.Save(iterationNumber(), f, sqrt(g2), t, *this);
00137 
00138   if ( !lineSearch_->succeed() ) throw Error("ConjugateGradient<V>::Minimize(...), line-search failed!");
00139 }
00140 
00141 
00142 #endif

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