Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
piecewiseconstanthelper.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19/*! \file piecewiseconstanthelper.hpp
20 \brief helper classes for piecewise constant parametrizations
21 \ingroup models
22*/
23
24#ifndef quantext_piecewiseconstant_helper_hpp
25#define quantext_piecewiseconstant_helper_hpp
26
28
29#include <ql/experimental/math/piecewisefunction.hpp>
30#include <ql/math/array.hpp>
31#include <ql/math/comparison.hpp>
32#include <ql/time/date.hpp>
33
34namespace QuantExt {
35using namespace QuantLib;
36
37//! Piecewise Constant Helper 1
38/*! \ingroup models
39 */
41public:
43 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint = QuantLib::ext::make_shared<QuantLib::NoConstraint>());
44 PiecewiseConstantHelper1(const std::vector<Date>& dates, const Handle<YieldTermStructure>& yts,
45 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint = QuantLib::ext::make_shared<QuantLib::NoConstraint>());
46
47 const Array& t() const;
48 const QuantLib::ext::shared_ptr<Parameter> p() const;
49 void update() const;
50 /*! this returns the transformed value */
51 Real y(const Time t) const;
52 //! int_0^t y^2(s) ds
53 Real int_y_sqr(const Time t) const;
54
55 Real direct(const Real x) const;
56 Real inverse(const Real y) const;
57
58protected:
59 const Array t_;
60 /*! y are the raw values in the sense of parameter transformation */
61 const QuantLib::ext::shared_ptr<PseudoParameter> y_;
62
63private:
64 mutable std::vector<Real> b_;
65};
66
67//! Piecewise Constant Helper 11
68/*! this is PiecewiseConstantHelper1 with two sets of (t,y)
69 \ingroup models
70*/
72public:
73 /*! y are the raw values in the sense of parameter transformation */
74 PiecewiseConstantHelper11(const Array& t1, const Array& t2,
75 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint1 = QuantLib::ext::make_shared<QuantLib::NoConstraint>(),
76 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint2 = QuantLib::ext::make_shared<QuantLib::NoConstraint>());
77 PiecewiseConstantHelper11(const std::vector<Date>& dates1, const std::vector<Date>& dates2,
78 const Handle<YieldTermStructure>& yts,
79 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint1 = QuantLib::ext::make_shared<QuantLib::NoConstraint>(),
80 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint2 = QuantLib::ext::make_shared<QuantLib::NoConstraint>());
81
82 const PiecewiseConstantHelper1& helper1() const;
83 const PiecewiseConstantHelper1& helper2() const;
84
85private:
87};
88
89//! Piecewise Constant Helper2
90/*! \ingroup models
91 */
93public:
94 PiecewiseConstantHelper2(const Array& t, const QuantLib::ext::shared_ptr<PseudoParameter>& y);
96 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint = QuantLib::ext::make_shared<QuantLib::NoConstraint>());
97 PiecewiseConstantHelper2(const std::vector<Date>& dates, const Handle<YieldTermStructure>& yts,
98 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint = QuantLib::ext::make_shared<QuantLib::NoConstraint>());
99 const Array& t() const;
100 const QuantLib::ext::shared_ptr<Parameter> p() const;
101 void update() const;
102 /*! this returns the transformed value */
103 Real y(const Time t) const;
104 //! exp(int_0^t -y(s)) ds
105 Real exp_m_int_y(const Time t) const;
106 //! int_0^t exp(int_0^s -y(u) du) ds
107 Real int_exp_m_int_y(const Time t) const;
108
109 Real direct(const Real x) const;
110 Real inverse(const Real y) const;
111
112private:
113 const Real zeroCutoff_;
114
115protected:
116 const Array t_;
117 /*! y are the raw values in the sense of parameter transformation */
118 const QuantLib::ext::shared_ptr<PseudoParameter> y_;
119
120private:
121 mutable std::vector<Real> b_, c_;
122};
123
124//! Piecewise Constant Helper 3
125/*! \ingroup models
126 */
128public:
129 PiecewiseConstantHelper3(const Array& t1, const Array& t2,
130 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint1 = QuantLib::ext::make_shared<QuantLib::NoConstraint>(),
131 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint2 = QuantLib::ext::make_shared<QuantLib::NoConstraint>());
132 PiecewiseConstantHelper3(const std::vector<Date>& dates1, const std::vector<Date>& dates2,
133 const Handle<YieldTermStructure>& yts,
134 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint1 = QuantLib::ext::make_shared<QuantLib::NoConstraint>(),
135 const QuantLib::ext::shared_ptr<QuantLib::Constraint>& constraint2 = QuantLib::ext::make_shared<QuantLib::NoConstraint>());
136
137 const Array& t1() const;
138 const Array& t2() const;
139 const Array& tUnion() const;
140 const QuantLib::ext::shared_ptr<Parameter> p1() const;
141 const QuantLib::ext::shared_ptr<Parameter> p2() const;
142 /* update is required after construction for helper 3 ! */
143 void update() const;
144 /*! this returns the transformed value */
145 Real y1(const Time t) const;
146 /*! this returns the transformed value */
147 Real y2(const Time t) const;
148 //! int_0^t y1^2(s) exp(2*int_0^s y2(u) du) ds
149 Real int_y1_sqr_exp_2_int_y2(const Time t) const;
150
151 Real direct1(const Real x) const;
152 Real inverse1(const Real y) const;
153 Real direct2(const Real x) const;
154 Real inverse2(const Real y) const;
155
156private:
157 const Real zeroCutoff_;
158
159protected:
160 const Array t1_, t2_;
161 mutable Array tUnion_;
162 /*! y1, y2 are the raw values in the sense of parameter transformation */
163 const QuantLib::ext::shared_ptr<PseudoParameter> y1_, y2_;
164 mutable Array y1Union_, y2Union_;
165
166private:
167 mutable std::vector<Real> b_, c_;
168};
169
170// inline
171
172inline const Array& PiecewiseConstantHelper1::t() const { return t_; }
173
174inline const QuantLib::ext::shared_ptr<Parameter> PiecewiseConstantHelper1::p() const { return y_; }
175
176inline Real PiecewiseConstantHelper1::direct(const Real x) const { return x * x; }
177
178inline Real PiecewiseConstantHelper1::inverse(const Real y) const { return std::sqrt(y); }
179
181 Real sum = 0.0;
182 b_.resize(t_.size());
183 for (Size i = 0; i < t_.size(); ++i) {
184 sum += direct(y_->params()[i]) * direct(y_->params()[i]) * (t_[i] - (i == 0 ? 0.0 : t_[i - 1]));
185 b_[i] = sum;
186 }
187}
188
190
192
193inline const Array& PiecewiseConstantHelper2::t() const { return t_; }
194
195inline const QuantLib::ext::shared_ptr<Parameter> PiecewiseConstantHelper2::p() const { return y_; }
196
197inline Real PiecewiseConstantHelper2::direct(const Real x) const { return x; }
198
199inline Real PiecewiseConstantHelper2::inverse(const Real y) const { return y; }
200
202 Real sum = 0.0, sum2 = 0.0;
203 b_.resize(t_.size());
204 c_.resize(t_.size());
205 for (Size i = 0; i < t_.size(); ++i) {
206 Real t0 = (i == 0 ? 0.0 : t_[i - 1]);
207 sum += direct(y_->params()[i]) * (t_[i] - t0);
208 b_[i] = sum;
209 Real b2Tmp = (i == 0 ? 0.0 : b_[i - 1]);
210 if (std::fabs(direct(y_->params()[i])) < zeroCutoff_) {
211 sum2 += (t_[i] - t0) * std::exp(-b2Tmp);
212 } else {
213 sum2 += (std::exp(-b2Tmp) - std::exp(-b2Tmp - direct(y_->params()[i]) * (t_[i] - t0))) /
214 direct(y_->params()[i]);
215 }
216 c_[i] = sum2;
217 }
218}
219
220inline const Array& PiecewiseConstantHelper3::t1() const { return t1_; }
221inline const Array& PiecewiseConstantHelper3::t2() const { return t2_; }
222inline const Array& PiecewiseConstantHelper3::tUnion() const { return tUnion_; }
223
224inline const QuantLib::ext::shared_ptr<Parameter> PiecewiseConstantHelper3::p1() const { return y1_; }
225
226inline const QuantLib::ext::shared_ptr<Parameter> PiecewiseConstantHelper3::p2() const { return y2_; }
227
228inline Real PiecewiseConstantHelper3::direct1(const Real x) const { return x * x; }
229
230inline Real PiecewiseConstantHelper3::inverse1(const Real y) const { return std::sqrt(y); }
231
232inline Real PiecewiseConstantHelper3::direct2(const Real x) const { return x; }
233
234inline Real PiecewiseConstantHelper3::inverse2(const Real y) const { return y; }
235
237 std::vector<Real> tTmp(t1_.begin(), t1_.end());
238 tTmp.insert(tTmp.end(), t2_.begin(), t2_.end());
239 std::sort(tTmp.begin(), tTmp.end());
240 std::vector<Real>::const_iterator end =
241 std::unique(tTmp.begin(), tTmp.end(), [](const Real x, const Real y) { return QuantLib::close_enough(x, y); });
242 tTmp.resize(end - tTmp.begin());
243 tUnion_ = Array(tTmp.begin(), tTmp.end());
244 y1Union_ = Array(tUnion_.size() + 1);
245 y2Union_ = Array(tUnion_.size() + 1);
246 for (Size i = 0; i < tUnion_.size() + 1; ++i) {
247 // choose a safe t for y1 and y2 evaluation
248 Real t = (i == tUnion_.size() ? (tUnion_.size() == 0 ? 1.0 : tUnion_.back() + 1.0)
249 : (0.5 * (tUnion_[i] + (i > 0 ? tUnion_[i - 1] : 0.0))));
250 y1Union_[i] = QL_PIECEWISE_FUNCTION(t1_, y1_->params(), t);
251 y2Union_[i] = QL_PIECEWISE_FUNCTION(t2_, y2_->params(), t);
252 }
253 Real sum = 0.0, sum2 = 0.0;
254 b_.resize(tUnion_.size());
255 c_.resize(tUnion_.size());
256 for (Size i = 0; i < tUnion_.size(); ++i) {
257 Real t0 = (i == 0 ? 0.0 : tUnion_[i - 1]);
258 sum += direct2(y2Union_[i]) * (tUnion_[i] - t0);
259 b_[i] = sum;
260 Real b2Tmp = (i == 0 ? 0.0 : b_[i - 1]);
261 if (std::fabs(direct2(y2Union_[i])) < zeroCutoff_) {
262 sum2 += direct1(y1Union_[i]) * direct1(y1Union_[i]) * (tUnion_[i] - t0) * std::exp(2.0 * b2Tmp);
263 } else {
264 sum2 += direct1(y1Union_[i]) * direct1(y1Union_[i]) *
265 (std::exp(2.0 * b2Tmp + 2.0 * direct2(y2Union_[i]) * (tUnion_[i] - t0)) - std::exp(2.0 * b2Tmp)) /
266 (2.0 * direct2(y2Union_[i]));
267 }
268 c_[i] = sum2;
269 }
270}
271
272inline Real PiecewiseConstantHelper1::y(const Time t) const {
273 return direct(QL_PIECEWISE_FUNCTION(t_, y_->params(), t));
274}
275
276inline Real PiecewiseConstantHelper2::y(const Time t) const {
277 return direct(QL_PIECEWISE_FUNCTION(t_, y_->params(), t));
278}
279
280inline Real PiecewiseConstantHelper3::y1(const Time t) const {
281 return direct1(QL_PIECEWISE_FUNCTION(t1_, y1_->params(), t));
282}
283
284inline Real PiecewiseConstantHelper3::y2(const Time t) const {
285 return direct2(QL_PIECEWISE_FUNCTION(t2_, y2_->params(), t));
286}
287
288inline Real PiecewiseConstantHelper1::int_y_sqr(const Time t) const {
289 if (t < 0.0)
290 return 0.0;
291 Size i = std::upper_bound(t_.begin(), t_.end(), t) - t_.begin();
292 Real res = 0.0;
293 if (i >= 1)
294 res += b_[std::min(i - 1, b_.size() - 1)];
295 Real a = direct(y_->params()[std::min(i, y_->size() - 1)]);
296 res += a * a * (t - (i == 0 ? 0.0 : t_[i - 1]));
297 return res;
298}
299
300inline Real PiecewiseConstantHelper2::exp_m_int_y(const Time t) const {
301 if (t < 0.0)
302 return 1.0;
303 Size i = std::upper_bound(t_.begin(), t_.end(), t) - t_.begin();
304 Real res = 0.0;
305 if (i >= 1)
306 res += b_[std::min(i - 1, b_.size() - 1)];
307 Real a = y_->params()[std::min(i, y_->size() - 1)];
308 res += a * (t - (i == 0 ? 0.0 : t_[i - 1]));
309 return std::exp(-res);
310}
311
312inline Real PiecewiseConstantHelper2::int_exp_m_int_y(const Time t) const {
313 if (t < 0.0)
314 return 0.0;
315 Size i = std::upper_bound(t_.begin(), t_.end(), t) - t_.begin();
316 Real res = 0.0;
317 if (i >= 1)
318 res += c_[std::min(i - 1, c_.size() - 1)];
319 Real a = direct(y_->params()[std::min(i, y_->size() - 1)]);
320 Real t0 = (i == 0 ? 0.0 : t_[i - 1]);
321 Real b2Tmp = (i == 0 ? 0.0 : b_[i - 1]);
322 if (std::fabs(a) < zeroCutoff_) {
323 res += std::exp(-b2Tmp) * (t - t0);
324 } else {
325 res += (std::exp(-b2Tmp) - std::exp(-b2Tmp - a * (t - t0))) / a;
326 }
327 return res;
328}
329
331 if (t < 0.0)
332 return 0.0;
333 Size i = std::upper_bound(tUnion_.begin(), tUnion_.end(), t) - tUnion_.begin();
334 Real res = 0.0;
335 if (i >= 1)
336 res += c_[std::min(i - 1, c_.size() - 1)];
337 Real a = direct2(y2Union_[std::min(i, y2Union_.size() - 1)]);
338 Real b = direct1(y1Union_[std::min(i, y1Union_.size() - 1)]);
339 Real t0 = (i == 0 ? 0.0 : tUnion_[i - 1]);
340 Real b2Tmp = (i == 0 ? 0.0 : b_[i - 1]);
341 if (std::fabs(a) < zeroCutoff_) {
342 res += b * b * std::exp(2.0 * b2Tmp) * (t - t0);
343 } else {
344 res += b * b * (std::exp(2.0 * b2Tmp + 2.0 * a * (t - t0)) - std::exp(2.0 * b2Tmp)) / (2.0 * a);
345 }
346 return res;
347}
348
349} // namespace QuantExt
350
351#endif
const PiecewiseConstantHelper1 & helper1() const
PiecewiseConstantHelper11(const Array &t1, const Array &t2, const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint1=QuantLib::ext::make_shared< QuantLib::NoConstraint >(), const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint2=QuantLib::ext::make_shared< QuantLib::NoConstraint >())
PiecewiseConstantHelper11(const std::vector< Date > &dates1, const std::vector< Date > &dates2, const Handle< YieldTermStructure > &yts, const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint1=QuantLib::ext::make_shared< QuantLib::NoConstraint >(), const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint2=QuantLib::ext::make_shared< QuantLib::NoConstraint >())
const PiecewiseConstantHelper1 & helper2() const
PiecewiseConstantHelper1(const std::vector< Date > &dates, const Handle< YieldTermStructure > &yts, const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint=QuantLib::ext::make_shared< QuantLib::NoConstraint >())
const QuantLib::ext::shared_ptr< PseudoParameter > y_
const QuantLib::ext::shared_ptr< Parameter > p() const
Real int_y_sqr(const Time t) const
int_0^t y^2(s) ds
PiecewiseConstantHelper1(const Array &t, const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint=QuantLib::ext::make_shared< QuantLib::NoConstraint >())
PiecewiseConstantHelper2(const Array &t, const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint=QuantLib::ext::make_shared< QuantLib::NoConstraint >())
Real exp_m_int_y(const Time t) const
exp(int_0^t -y(s)) ds
PiecewiseConstantHelper2(const std::vector< Date > &dates, const Handle< YieldTermStructure > &yts, const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint=QuantLib::ext::make_shared< QuantLib::NoConstraint >())
Real int_exp_m_int_y(const Time t) const
int_0^t exp(int_0^s -y(u) du) ds
const QuantLib::ext::shared_ptr< PseudoParameter > y_
const QuantLib::ext::shared_ptr< Parameter > p() const
const QuantLib::ext::shared_ptr< PseudoParameter > y1_
PiecewiseConstantHelper3(const Array &t1, const Array &t2, const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint1=QuantLib::ext::make_shared< QuantLib::NoConstraint >(), const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint2=QuantLib::ext::make_shared< QuantLib::NoConstraint >())
Real int_y1_sqr_exp_2_int_y2(const Time t) const
int_0^t y1^2(s) exp(2*int_0^s y2(u) du) ds
const QuantLib::ext::shared_ptr< Parameter > p2() const
const QuantLib::ext::shared_ptr< PseudoParameter > y2_
const QuantLib::ext::shared_ptr< Parameter > p1() const
PiecewiseConstantHelper3(const std::vector< Date > &dates1, const std::vector< Date > &dates2, const Handle< YieldTermStructure > &yts, const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint1=QuantLib::ext::make_shared< QuantLib::NoConstraint >(), const QuantLib::ext::shared_ptr< QuantLib::Constraint > &constraint2=QuantLib::ext::make_shared< QuantLib::NoConstraint >())
Real sum(const Cash &c, const Cash &d)
Definition: bondbasket.cpp:107
parameter giving access to calibration machinery