Coverage Report

Created: 2025-11-04 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/math/optimization/leastsquare.cpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2001, 2002, 2003 Nicolas Di Césaré
5
 Copyright (C) 2005 StatPro Italia srl
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
 <https://www.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/conjugategradient.hpp>
22
#include <ql/math/optimization/leastsquare.hpp>
23
#include <ql/math/optimization/problem.hpp>
24
#include <utility>
25
26
namespace QuantLib {
27
28
0
    Real LeastSquareFunction::value(const Array & x) const {
29
        // size of target and function to fit vectors
30
0
        Array target(lsp_.size()), fct2fit(lsp_.size());
31
        // compute its values
32
0
        lsp_.targetAndValue(x, target, fct2fit);
33
        // do the difference
34
0
        Array diff = target - fct2fit;
35
        // and compute the scalar product (square of the norm)
36
0
        return DotProduct(diff, diff);
37
0
    }
38
39
0
    Array LeastSquareFunction::values(const Array& x) const {
40
        // size of target and function to fit vectors
41
0
        Array target(lsp_.size()), fct2fit(lsp_.size());
42
        // compute its values
43
0
        lsp_.targetAndValue(x, target, fct2fit);
44
        // do the difference
45
0
        Array diff = target - fct2fit;
46
0
        return diff*diff;
47
0
    }
48
49
    void LeastSquareFunction::gradient(Array& grad_f,
50
0
                                       const Array& x) const {
51
        // size of target and function to fit vectors
52
0
        Array target (lsp_.size ()), fct2fit (lsp_.size ());
53
        // size of gradient matrix
54
0
        Matrix grad_fct2fit (lsp_.size (), x.size ());
55
        // compute its values
56
0
        lsp_.targetValueAndGradient(x, grad_fct2fit, target, fct2fit);
57
        // do the difference
58
0
        Array diff = target - fct2fit;
59
        // compute derivative
60
0
        grad_f = -2.0*(transpose(grad_fct2fit)*diff);
61
0
    }
62
63
    Real LeastSquareFunction::valueAndGradient(Array& grad_f,
64
0
                                               const Array& x) const {
65
        // size of target and function to fit vectors
66
0
        Array target(lsp_.size()), fct2fit(lsp_.size());
67
        // size of gradient matrix
68
0
        Matrix grad_fct2fit(lsp_.size(), x.size());
69
        // compute its values
70
0
        lsp_.targetValueAndGradient(x, grad_fct2fit, target, fct2fit);
71
        // do the difference
72
0
        Array diff = target - fct2fit;
73
        // compute derivative
74
0
        grad_f = -2.0*(transpose(grad_fct2fit)*diff);
75
        // and compute the scalar product (square of the norm)
76
0
        return DotProduct(diff, diff);
77
0
    }
78
79
    NonLinearLeastSquare::NonLinearLeastSquare(Constraint& c,
80
                                               Real accuracy,
81
                                               Size maxiter)
82
0
    : exitFlag_(-1), accuracy_ (accuracy), maxIterations_ (maxiter),
83
0
      om_ (ext::shared_ptr<OptimizationMethod>(new ConjugateGradient())),
84
0
      c_(c)
85
0
    {}
86
87
    NonLinearLeastSquare::NonLinearLeastSquare(Constraint& c,
88
                                               Real accuracy,
89
                                               Size maxiter,
90
                                               ext::shared_ptr<OptimizationMethod> om)
91
0
    : exitFlag_(-1), accuracy_(accuracy), maxIterations_(maxiter), om_(std::move(om)), c_(c) {}
92
93
0
    Array& NonLinearLeastSquare::perform(LeastSquareProblem& lsProblem) {
94
0
        Real eps = accuracy_;
95
96
        // wrap the least square problem in an optimization function
97
0
        LeastSquareFunction lsf(lsProblem);
98
99
        // define optimization problem
100
0
        Problem P(lsf, c_, initialValue_);
101
102
        // minimize
103
0
        EndCriteria ec(maxIterations_,
104
0
            std::min(static_cast<Size>(maxIterations_/2), static_cast<Size>(100)),
105
0
            eps, eps, eps);
106
0
        exitFlag_ = om_->minimize(P, ec);
107
108
        // summarize results of minimization
109
        //        nbIterations_ = om_->iterationNumber();
110
111
0
        results_ = P.currentValue();
112
0
        resnorm_ = P.functionValue();
113
0
        bestAccuracy_ = P.functionValue();
114
115
0
        return results_;
116
0
    }
117
118
}