QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
lsmbasissystem.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) 2006 Klaus Spanderen
5 Copyright (C) 2010 Kakhkhor Abdijalilov
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/*! \file lsmbasissystem.cpp
22 \brief utility classes for longstaff schwartz early exercise Monte Carlo
23*/
24
27#include <numeric>
28#include <set>
29#include <utility>
30
31namespace QuantLib {
32
33 namespace {
34
35 // makes typing a little easier
36 typedef std::vector<ext::function<Real(Real)> > VF_R;
37 typedef std::vector<ext::function<Real(Array)> > VF_A;
38 typedef std::vector<std::vector<Size> > VV;
39
40 // pow(x, order)
41 class MonomialFct {
42 public:
43 explicit MonomialFct(Size order): order_(order) {}
44 inline Real operator()(const Real x) const {
45 Real ret = 1.0;
46 for(Size i=0; i<order_; ++i)
47 ret *= x;
48 return ret;
49 }
50 private:
51 const Size order_;
52 };
53
54 /* multiplies [Real -> Real] functors
55 to create [Array -> Real] functor */
56 class MultiDimFct {
57 public:
58 explicit MultiDimFct(VF_R b) : b_(std::move(b)) {
59 QL_REQUIRE(!b_.empty(), "zero size basis");
60 }
61 inline Real operator()(const Array& a) const {
62 #if defined(QL_EXTRA_SAFETY_CHECKS)
63 QL_REQUIRE(b_.size()==a.size(), "wrong argument size");
64 #endif
65 Real ret = b_[0](a[0]);
66 for(Size i=1; i<b_.size(); ++i)
67 ret *= b_[i](a[i]);
68 return ret;
69 }
70 private:
71 const VF_R b_;
72 };
73
74 // check size and order of tuples
75 void check_tuples(const VV& v, Size dim, Size order) {
76 for (const auto& i : v) {
77 QL_REQUIRE(dim == i.size(), "wrong tuple size");
78 QL_REQUIRE(order == std::accumulate(i.begin(), i.end(), 0UL), "wrong tuple order");
79 }
80 }
81
82 // build order N+1 tuples from order N tuples
83 VV next_order_tuples(const VV& v) {
84 const Size order = std::accumulate(v[0].begin(), v[0].end(), 0UL);
85 const Size dim = v[0].size();
86
87 check_tuples(v, dim, order);
88
89 // the set of unique tuples
90 std::set<std::vector<Size> > tuples;
91 std::vector<Size> x;
92 for(Size i=0; i<dim; ++i) {
93 // increase i-th value in every tuple by 1
94 for (const auto& j : v) {
95 x = j;
96 x[i] += 1;
97 tuples.insert(x);
98 }
99 }
100
101 VV ret(tuples.begin(), tuples.end());
102 return ret;
103 }
104
105 }
106
107 // LsmBasisSystem static methods
108
110 VF_R ret(order+1);
111 for (Size i=0; i<=order; ++i) {
112 switch (type) {
113 case Monomial:
114 ret[i] = MonomialFct(i);
115 break;
116 case Laguerre:
117 {
119 ret[i] = [=](Real x){ return p.weightedValue(i, x); };
120 }
121 break;
122 case Hermite:
123 {
125 ret[i] = [=](Real x){ return p.weightedValue(i, x); };
126 }
127 break;
128 case Hyperbolic:
129 {
131 ret[i] = [=](Real x){ return p.weightedValue(i, x); };
132 }
133 break;
134 case Legendre:
135 {
137 ret[i] = [=](Real x){ return p.weightedValue(i, x); };
138 }
139 break;
140 case Chebyshev:
141 {
143 ret[i] = [=](Real x){ return p.weightedValue(i, x); };
144 }
145 break;
146 case Chebyshev2nd:
147 {
149 ret[i] = [=](Real x){ return p.weightedValue(i, x); };
150 }
151 break;
152 default:
153 QL_FAIL("unknown regression type");
154 }
155 }
156 return ret;
157 }
158
160 PolynomialType type) {
161 QL_REQUIRE(dim>0, "zero dimension");
162 // get single factor basis
163 VF_R pathBasis = pathBasisSystem(order, type);
164 VF_A ret;
165 // 0-th order term
166 VF_R term(dim, pathBasis[0]);
167 ret.emplace_back(MultiDimFct(term));
168 // start with all 0 tuple
169 VV tuples(1, std::vector<Size>(dim));
170 // add multi-factor terms
171 for(Size i=1; i<=order; ++i) {
172 tuples = next_order_tuples(tuples);
173 // now we have all tuples of order i
174 // for each tuple add the corresponding term
175 for (auto& tuple : tuples) {
176 for(Size k=0; k<dim; ++k)
177 term[k] = pathBasis[tuple[k]];
178 ret.emplace_back(MultiDimFct(term));
179 }
180 }
181 return ret;
182 }
183
184}
Gauss-Chebyshev polynomial (second kind)
static std::vector< ext::function< Real(Real)> > pathBasisSystem(Size order, PolynomialType type)
static std::vector< ext::function< Real(Array)> > multiPathBasisSystem(Size dim, Size order, PolynomialType type)
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Definition: errors.hpp:92
ext::function< Real(Real)> b
Integral of a 1-dimensional function using the Gauss quadratures.
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
const VF_R b_
const Size order_
utility classes for Longstaff-Schwartz early-exercise Monte Carlo
Definition: any.hpp:35
ext::shared_ptr< BlackVolTermStructure > v