QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
lmmnormaldriftcalculator.cpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2007 Giorgio Facchinetti
5 Copyright (C) 2007 Chiara Fornarola
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
22
23namespace QuantLib {
24
26 const std::vector<Time>& taus,
27 Size numeraire,
28 Size alive)
29 : numberOfRates_(taus.size()), numberOfFactors_(pseudo.columns()),
30 isFullFactor_(numberOfFactors_ == numberOfRates_), numeraire_(numeraire), alive_(alive),
31 oneOverTaus_(taus.size()), pseudo_(pseudo), tmp_(taus.size(), 0.0),
32 e_(pseudo_.columns(), pseudo_.rows(), 0.0), downs_(taus.size()), ups_(taus.size()) {
33
34 // Check requirements
35 QL_REQUIRE(numberOfRates_>0, "Dim out of range");
37 "pseudo.rows() not consistent with dim");
38 QL_REQUIRE(pseudo.columns()>0 && pseudo.columns()<=numberOfRates_,
39 "pseudo.rows() not consistent with pseudo.columns()");
40 QL_REQUIRE(alive<numberOfRates_, "Alive out of bounds");
41 QL_REQUIRE(numeraire_<=numberOfRates_, "Numeraire larger than dim");
42 QL_REQUIRE(numeraire_>=alive, "Numeraire smaller than alive");
43
44 // Precompute 1/taus
45 for (Size i=0; i<taus.size(); ++i)
46 oneOverTaus_[i] = 1.0/taus[i];
47
48 // Compute covariance matrix from pseudoroot
50 C_ = pseudo_*pT;
51
52 // Compute lower and upper extrema for (non reduced) drift calculation
53 for (Size i=alive_; i<numberOfRates_; ++i) {
54 downs_[i] = std::min(i+1, numeraire_);
55 ups_[i] = std::max(i+1, numeraire_);
56 }
57 }
58
60 std::vector<Real>& drifts) const {
61 compute(cs.forwardRates(), drifts);
62 }
63
64 void LMMNormalDriftCalculator::compute(const std::vector<Rate>& fwds,
65 std::vector<Real>& drifts) const {
66 #if defined(QL_EXTRA_SAFETY_CHECKS)
67 QL_REQUIRE(fwds.size()==numberOfRates_, "numberOfRates <> dim");
68 QL_REQUIRE(drifts.size()==numberOfRates_, "drifts.size() <> dim");
69 #endif
70
71 if (isFullFactor_)
72 computePlain(fwds, drifts);
73 else
74 computeReduced(fwds, drifts);
75 }
76
78 std::vector<Real>& drifts) const {
79 computePlain(cs.forwardRates(), drifts);
80 }
81
82 void LMMNormalDriftCalculator::computePlain(const std::vector<Rate>& forwards,
83 std::vector<Real>& drifts) const {
84
85 // Compute drifts without factor reduction,
86 // using directly the covariance matrix.
87
88 // Precompute forwards factor
89 Size i;
90 for(i=alive_; i<numberOfRates_; ++i)
91 tmp_[i] = 1.0/(oneOverTaus_[i]+forwards[i]);
92
93 // Compute drifts
94 for (i=alive_; i<numberOfRates_; ++i) {
95 drifts[i] = std::inner_product(tmp_.begin()+downs_[i],
96 tmp_.begin()+ups_[i],
97 C_.row_begin(i)+downs_[i], Real(0.0));
98 if (numeraire_>i+1)
99 drifts[i] = -drifts[i];
100 }
101 }
102
104 std::vector<Real>& drifts) const {
105 computeReduced(cs.forwardRates(), drifts);
106 }
107
108 void LMMNormalDriftCalculator::computeReduced(const std::vector<Rate>& forwards,
109 std::vector<Real>& drifts) const {
110
111 // Compute drifts with factor reduction,
112 // using the pseudo square root of the covariance matrix.
113
114 // Precompute forwards factor
115 for (Size i=alive_; i<numberOfRates_; ++i)
116 tmp_[i] = 1.0/(oneOverTaus_[i]+forwards[i]);
117
118 // Enforce initialization
119 for (Size r=0; r<numberOfFactors_; ++r)
120 e_[r][std::max(0,static_cast<Integer>(numeraire_)-1)] = 0.0;
121
122 // Now compute drifts: take the numeraire P_N (numeraire_=N)
123 // as the reference point, divide the summation into 3 steps,
124 // et impera:
125
126 // 1st step: the drift corresponding to the numeraire P_N is zero.
127 // (if N=0 no drift is null, if N=numberOfRates_ the last drift is null).
128 if (numeraire_>0) drifts[numeraire_-1] = 0.0;
129
130 // 2nd step: then, move backward from N-2 (included) back to
131 // alive (included) (if N=0 jumps to 3rd step, if N=numberOfRates_ the
132 // e_[r][N-1] are correctly initialized):
133
134 for (Integer i=static_cast<Integer>(numeraire_)-2;
135 i>=static_cast<Integer>(alive_); --i) {
136 drifts[i] = 0.0;
137 for (Size r=0; r<numberOfFactors_; ++r) {
138 e_[r][i] = e_[r][i+1] + tmp_[i+1] * pseudo_[i+1][r];
139 drifts[i] -= e_[r][i]*pseudo_[i][r];
140 }
141
142 }
143
144 // 3rd step: now, move forward from N (included) up to n (excluded)
145 // (if N=0 this is the only relevant computation):
146 for (Size i=numeraire_; i<numberOfRates_; ++i) {
147 drifts[i] = 0.0;
148 for (Size r=0; r<numberOfFactors_; ++r) {
149 if (i==0)
150 e_[r][i] = tmp_[i] * pseudo_[i][r];
151 else
152 e_[r][i] = e_[r][i-1] + tmp_[i] * pseudo_[i][r];
153 drifts[i] += e_[r][i]*pseudo_[i][r];
154 }
155 }
156 }
157
158}
Curve state for Libor market models
const std::vector< Rate > & forwardRates() const override
void computePlain(const LMMCurveState &cs, std::vector< Real > &drifts) const
void compute(const LMMCurveState &cs, std::vector< Real > &drifts) const
Computes the drifts.
void computeReduced(const LMMCurveState &cs, std::vector< Real > &drifts) const
LMMNormalDriftCalculator(const Matrix &pseudo, const std::vector< Time > &taus, Size numeraire, Size alive)
Matrix used in linear algebra.
Definition: matrix.hpp:41
const_row_iterator row_begin(Size i) const
Definition: matrix.hpp:360
Size rows() const
Definition: matrix.hpp:504
Size columns() const
Definition: matrix.hpp:508
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
QL_REAL Real
real number
Definition: types.hpp:50
QL_INTEGER Integer
integer number
Definition: types.hpp:35
std::size_t Size
size of a container
Definition: types.hpp:58
Drift computation for normal Libor market model.
Definition: any.hpp:35
Matrix transpose(const Matrix &m)
Definition: matrix.hpp:700
ext::shared_ptr< YieldTermStructure > r