Coverage Report

Created: 2026-03-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/models/marketmodels/evolutiondescription.cpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2006, 2007 Ferdinando Ametrano
5
 Copyright (C) 2006 Marco Bianchetti
6
 Copyright (C) 2006 Cristina Duminuco
7
 Copyright (C) 2006 Giorgio Facchinetti
8
 Copyright (C) 2006, 2007 Mark Joshi
9
10
 This file is part of QuantLib, a free-software/open-source library
11
 for financial quantitative analysts and developers - http://quantlib.org/
12
13
 QuantLib is free software: you can redistribute it and/or modify it
14
 under the terms of the QuantLib license.  You should have received a
15
 copy of the license along with this program; if not, please email
16
 <quantlib-dev@lists.sf.net>. The license is also available online at
17
 <https://www.quantlib.org/license.shtml>.
18
19
 This program is distributed in the hope that it will be useful, but WITHOUT
20
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21
 FOR A PARTICULAR PURPOSE.  See the license for more details.
22
*/
23
24
#include <ql/models/marketmodels/evolutiondescription.hpp>
25
#include <ql/models/marketmodels/utilities.hpp>
26
#include <ql/math/matrix.hpp>
27
#include <ql/utilities/dataformatters.hpp>
28
29
namespace QuantLib {
30
31
    EvolutionDescription::EvolutionDescription(
32
                     const std::vector<Time>& rateTimes,
33
                     const std::vector<Time>& evolutionTimes,
34
                     const std::vector<std::pair<Size,Size> >& relevanceRates)
35
0
    : numberOfRates_(rateTimes.empty() ? 0 : rateTimes.size()-1),
36
0
      rateTimes_(rateTimes),
37
0
      evolutionTimes_(evolutionTimes.empty() && !rateTimes.empty() ?
38
0
                      std::vector<Time>(rateTimes.begin(), rateTimes.end()-1) :
39
0
                      evolutionTimes),
40
0
      relevanceRates_(relevanceRates),
41
0
      rateTaus_(numberOfRates_),
42
      //effStopTime_(evolutionTimes_.size(), rateTimes_.size()-1),
43
0
      firstAliveRate_(evolutionTimes_.size())
44
0
    {
45
46
0
        checkIncreasingTimesAndCalculateTaus(rateTimes_, rateTaus_);
47
48
0
        checkIncreasingTimes(evolutionTimes_);
49
0
        Size numberOfSteps = evolutionTimes_.size();
50
51
0
        QL_REQUIRE(evolutionTimes_.back()<=rateTimes[rateTimes.size()-2],
52
0
                   "The last evolution time (" << evolutionTimes_.back() <<
53
0
                   ") is past the last fixing time (" <<
54
0
                   rateTimes[numberOfRates_-2] << ")");
55
56
0
        if (relevanceRates.empty())
57
0
            relevanceRates_ = std::vector<std::pair<Size,Size> >(
58
0
                                numberOfSteps, std::make_pair(0,numberOfRates_));
59
0
        else
60
0
            QL_REQUIRE(relevanceRates.size() == numberOfSteps,
61
0
                       "relevanceRates / evolutionTimes mismatch");
62
63
        //for (Size j=0; j<numberOfSteps; ++j) {
64
        //    for (Size i=0; i<numberOfRates_; ++i)
65
        //        effStopTime_[j][i] =
66
        //            std::min(evolutionTimes_[j], rateTimes_[i]);
67
        //}
68
69
0
        Time currentEvolutionTime = 0.0;
70
0
        Size firstAliveRate = 0;
71
0
        for (Size j=0; j<numberOfSteps; ++j) {
72
0
            while (rateTimes_[firstAliveRate] <= currentEvolutionTime)
73
0
                ++firstAliveRate;
74
0
            firstAliveRate_[j] = firstAliveRate;
75
0
            currentEvolutionTime = evolutionTimes_[j];
76
0
        }
77
0
    }
78
79
0
    const std::vector<Time>& EvolutionDescription::rateTimes() const {
80
0
        return rateTimes_;
81
0
    }
82
83
0
    const std::vector<Time>& EvolutionDescription::rateTaus() const {
84
0
        return rateTaus_;
85
0
    }
86
87
0
    const std::vector<Time>& EvolutionDescription::evolutionTimes() const {
88
0
        return evolutionTimes_;
89
0
    }
90
91
    //const Matrix& EvolutionDescription::effectiveStopTimes() const {
92
    //    return effStopTime_;
93
    //}
94
95
0
    const std::vector<Size>& EvolutionDescription::firstAliveRate() const {
96
0
        return firstAliveRate_;
97
0
    }
98
99
0
    const std::vector<std::pair<Size,Size> >& EvolutionDescription::relevanceRates() const {
100
0
        return relevanceRates_;
101
0
    }
102
103
0
    Size EvolutionDescription::numberOfRates() const {
104
0
        return numberOfRates_;
105
0
    }
106
107
0
    Size EvolutionDescription::numberOfSteps() const {
108
0
        return evolutionTimes_.size();
109
0
    }
110
111
    void checkCompatibility(const EvolutionDescription& evolution,
112
                            const std::vector<Size>& numeraires)
113
0
    {
114
0
        const std::vector<Time>& evolutionTimes = evolution.evolutionTimes();
115
0
        Size n = evolutionTimes.size();
116
0
        QL_REQUIRE(numeraires.size() == n,
117
0
                   "Size mismatch between numeraires (" << numeraires.size()
118
0
                   << ") and evolution times (" << n << ")");
119
120
0
        const std::vector<Time>& rateTimes = evolution.rateTimes();
121
0
        for (Size i=0; i<n-1; i++)
122
0
            QL_REQUIRE(rateTimes[numeraires[i]] >= evolutionTimes[i],
123
0
                       io::ordinal(i+1) << " step, evolution time " <<
124
0
                       evolutionTimes[i] << ": the numeraire (" << numeraires[i] <<
125
0
                       "), corresponding to rate time " <<
126
0
                       rateTimes[numeraires[i]] << ", is expired");
127
0
    }
128
129
    bool isInTerminalMeasure(const EvolutionDescription& evolution,
130
0
                             const std::vector<Size>& numeraires) {
131
0
        const std::vector<Time>& rateTimes = evolution.rateTimes();
132
0
        return *std::min_element(numeraires.begin(), numeraires.end()) ==
133
0
                                                          rateTimes.size()-1;
134
0
    }
135
136
    bool isInMoneyMarketPlusMeasure(const EvolutionDescription& evolution,
137
                                    const std::vector<Size>& numeraires,
138
0
                                    Size offset) {
139
0
        bool res = true;
140
0
        const std::vector<Time>& rateTimes = evolution.rateTimes();
141
0
        Size maxNumeraire=rateTimes.size()-1;
142
0
        QL_REQUIRE(offset<=maxNumeraire,
143
0
                   "offset (" << offset <<
144
0
                   ") is greater than the max allowed value for numeraire ("
145
0
                   << maxNumeraire << ")");
146
0
        const std::vector<Time>& evolutionTimes = evolution.evolutionTimes();
147
0
        for (Size i=0, j=0; i<evolutionTimes.size(); ++i) {
148
0
            while (rateTimes[j] < evolutionTimes[i])
149
0
                j++;
150
0
            res = (numeraires[i] == std::min(j+offset, maxNumeraire)) && res;
151
0
        }
152
0
        return res;
153
0
    }
154
155
    bool isInMoneyMarketMeasure(const EvolutionDescription& evolution,
156
0
                                const std::vector<Size>& numeraires) {
157
0
        return isInMoneyMarketPlusMeasure(evolution, numeraires, 0);
158
0
    }
159
160
    std::vector<Size> terminalMeasure(const EvolutionDescription& evolution)
161
0
    {
162
0
        return std::vector<Size>(evolution.evolutionTimes().size(),
163
0
                                 evolution.rateTimes().size()-1);
164
0
    }
165
166
    std::vector<Size> moneyMarketPlusMeasure(const EvolutionDescription& ev,
167
0
                                             Size offset) {
168
0
        const std::vector<Time>& rateTimes = ev.rateTimes();
169
0
        Size maxNumeraire = rateTimes.size()-1;
170
0
        QL_REQUIRE(offset<=maxNumeraire,
171
0
                   "offset (" << offset <<
172
0
                   ") is greater than the max allowed value for numeraire ("
173
0
                   << maxNumeraire << ")");
174
175
0
        const std::vector<Time>& evolutionTimes = ev.evolutionTimes();
176
0
        Size n = evolutionTimes.size();
177
0
        std::vector<Size> numeraires(n);
178
0
        for (Size i=0, j=0; i<n; ++i) {
179
0
            while (rateTimes[j] < evolutionTimes[i])
180
0
                j++;
181
0
            numeraires[i] = std::min(j+offset, maxNumeraire);
182
0
        }
183
0
        return numeraires;
184
0
    }
185
186
0
    std::vector<Size> moneyMarketMeasure(const EvolutionDescription& evol) {
187
0
        return moneyMarketPlusMeasure(evol, 0);
188
0
    }
189
190
}