00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _steepest_descent_h
00014 #define _steepest_descent_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.h>
00026
00027
00035 template <class V>
00036 class SteepestDescent : public OptimizationMethod<V> {
00038 QuantLib::Handle< LineSearch<V> > lineSearch_;
00039 public:
00041 SteepestDescent()
00042 : OptimizationMethod<V>(),
00043 lineSearch_(QuantLib::Handle< LineSearch<V> >(new ArmijoLineSearch<V>())) {}
00045 SteepestDescent(QuantLib::Handle< LineSearch<V> >& lineSearch)
00046 : OptimizationMethod<V>(), lineSearch_(lineSearch) {}
00048 virtual ~SteepestDescent() {}
00049
00051 virtual void Minimize(OptimizationProblem<V> & P);
00052 };
00053
00054
00055 template <class V> void
00056 SteepestDescent<V>::Minimize(OptimizationProblem<V> & P)
00057 {
00058 bool EndCriteria = false;
00059
00060
00061 double fold, gold2, normdiff;
00062
00063 double t = 1.;
00064
00065
00066 V & X = x();
00067
00068 V gold(searchDirection().size()), gdiff(searchDirection().size());
00069
00070 fold = P.valueAndFirstDerivative(gold,X);
00071 searchDirection() = - gold;
00072 gold2 = DotProduct(gold,gold);
00073 normdiff = sqrt(gold2);
00074
00075 do {
00076 P.Save(iterationNumber(), fold, sqrt(gold2), t, *this);
00077
00078
00079 t = (*lineSearch_)(P,t,fold,gold2);
00080
00081 if ( lineSearch_->succeed()) {
00082
00083 EndCriteria = endCriteria()(iterationNumber_, fold, sqrt(gold2),
00084 lineSearch_->lastFunctionValue(),
00085 sqrt(lineSearch_->lastGradientNorm2()),
00086 normdiff
00087 );
00088
00089
00090
00091 X = lineSearch_->lastX();
00092
00093 fold = lineSearch_->lastFunctionValue();
00094
00095 gdiff = gold - lineSearch_->lastGradient();
00096 normdiff = sqrt(DotProduct(gdiff,gdiff));
00097 gold = lineSearch_->lastGradient();
00098 searchDirection() = - gold;
00099
00100 gold2 = lineSearch_->lastGradientNorm2();
00101
00102
00103 iterationNumber()++;
00104 }
00105 }
00106 while ( (EndCriteria == false)&&(lineSearch_->succeed()) );
00107
00108 P.Save(iterationNumber(), fold, sqrt(gold2), t, *this);
00109
00110 if ( !lineSearch_->succeed() ) throw Error("SteepestDescent<V>::Minimize(...), line-search failed!");
00111 }
00112
00113
00114 #endif