QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
linesearchbasedmethod.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2006 Ferdinando Ametrano
5 Copyright (C) 2009 Frédéric Degraeve
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21#include <ql/math/optimization/armijo.hpp>
22#include <ql/math/optimization/linesearch.hpp>
23#include <ql/math/optimization/linesearchbasedmethod.hpp>
24#include <ql/math/optimization/problem.hpp>
25#include <utility>
26
27namespace QuantLib {
28
29 LineSearchBasedMethod::LineSearchBasedMethod(ext::shared_ptr<LineSearch> lineSearch)
30 : lineSearch_(std::move(lineSearch)) {
31 if (!lineSearch_)
32 lineSearch_ = ext::shared_ptr<LineSearch>(new ArmijoLineSearch);
33 }
34
37 const EndCriteria& endCriteria) {
38 // Initializations
39 Real ftol = endCriteria.functionEpsilon();
40 Size maxStationaryStateIterations_
41 = endCriteria.maxStationaryStateIterations();
42 EndCriteria::Type ecType = EndCriteria::None; // reset end criteria
43 P.reset(); // reset problem
44 Array x_ = P.currentValue(); // store the starting point
45 Size iterationNumber_ = 0;
46 // dimension line search
47 lineSearch_->searchDirection() = Array(x_.size());
48 bool done = false;
49
50 // function and squared norm of gradient values;
51 Real fnew, fold, gold2;
52 Real fdiff;
53 // classical initial value for line-search step
54 Real t = 1.0;
55 // Set gradient g at the size of the optimization problem
56 // search direction
57 Size sz = lineSearch_->searchDirection().size();
58 Array prevGradient(sz), d(sz), sddiff(sz), direction(sz);
59 // Initialize cost function, gradient prevGradient and search direction
60 P.setFunctionValue(P.valueAndGradient(prevGradient, x_));
61 P.setGradientNormValue(DotProduct(prevGradient, prevGradient));
62 lineSearch_->searchDirection() = -prevGradient;
63
64 bool first_time = true;
65 // Loop over iterations
66 do {
67 // Linesearch
68 if (!first_time)
69 prevGradient = lineSearch_->lastGradient();
70 t = (*lineSearch_)(P, ecType, endCriteria, t);
71 // don't throw: it can fail just because maxIterations exceeded
72 //QL_REQUIRE(lineSearch_->succeed(), "line-search failed!");
73 if (lineSearch_->succeed())
74 {
75 // Updates
76
77 // New point
78 x_ = lineSearch_->lastX();
79 // New function value
80 fold = P.functionValue();
81 P.setFunctionValue(lineSearch_->lastFunctionValue());
82 // New gradient and search direction vectors
83
84 // orthogonalization coef
85 gold2 = P.gradientNormValue();
86 P.setGradientNormValue(lineSearch_->lastGradientNorm2());
87
88 // conjugate gradient search direction
89 direction = getUpdatedDirection(P, gold2, prevGradient);
90
91 sddiff = direction - lineSearch_->searchDirection();
92 lineSearch_->searchDirection() = direction;
93 // Now compute accuracy and check end criteria
94 // Numerical Recipes exit strategy on fx (see NR in C++, p.423)
95 fnew = P.functionValue();
96 fdiff = 2.0*std::fabs(fnew-fold) /
97 (std::fabs(fnew) + std::fabs(fold) + QL_EPSILON);
98 if (fdiff < ftol ||
99 endCriteria.checkMaxIterations(iterationNumber_, ecType)) {
100 endCriteria.checkStationaryFunctionValue(0.0, 0.0,
101 maxStationaryStateIterations_, ecType);
102 endCriteria.checkMaxIterations(iterationNumber_, ecType);
103 return ecType;
104 }
105 P.setCurrentValue(x_); // update problem current value
106 ++iterationNumber_; // Increase iteration number
107 first_time = false;
108 } else {
109 done = true;
110 }
111 } while (!done);
112 P.setCurrentValue(x_);
113 return ecType;
114 }
115
116}
Armijo line search.
Definition: armijo.hpp:48
1-D array used in linear algebra.
Definition: array.hpp:52
Criteria to end optimization process:
Definition: endcriteria.hpp:40
Real functionEpsilon() const
Size maxStationaryStateIterations() const
virtual Array getUpdatedDirection(const Problem &P, Real gold2, const Array &gradient)=0
computes the new search direction
LineSearchBasedMethod(ext::shared_ptr< LineSearch > lSearch=ext::shared_ptr< LineSearch >())
ext::shared_ptr< LineSearch > lineSearch_
line search
EndCriteria::Type minimize(Problem &P, const EndCriteria &endCriteria) override
minimize the optimization problem P
Constrained optimization problem.
Definition: problem.hpp:42
const Array & currentValue() const
current value of the local minimum
Definition: problem.hpp:81
void setGradientNormValue(Real squaredNorm)
Definition: problem.hpp:90
void setFunctionValue(Real functionValue)
Definition: problem.hpp:83
void setCurrentValue(const Array &currentValue)
Definition: problem.hpp:76
Real valueAndGradient(Array &grad_f, const Array &x)
call cost function computation and it gradient
Definition: problem.hpp:132
#define QL_EPSILON
Definition: qldefines.hpp:178
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
Real DotProduct(const Array &v1, const Array &v2)
Definition: array.hpp:553
STL namespace.