Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
randomvariable.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#pragma once
20
21#include <ql/errors.hpp>
22#include <ql/math/array.hpp>
23#include <ql/math/comparison.hpp>
24#include <ql/math/matrix.hpp>
25#include <ql/methods/montecarlo/lsmbasissystem.hpp>
26#include <ql/patterns/singleton.hpp>
27#include <ql/types.hpp>
28
29#include <ql/functional.hpp>
30#include <boost/timer/timer.hpp>
31
32#include <initializer_list>
33#include <vector>
34
35namespace QuantExt {
36
37using namespace QuantLib;
38
39// statistics
40
41struct RandomVariableStats : public QuantLib::Singleton<RandomVariableStats> {
43 data_timer.start();
44 data_timer.stop();
45 calc_timer.start();
46 calc_timer.stop();
47 }
48
49 void reset() {
50 enabled = false;
51 data_ops = 0;
52 calc_ops = 0;
53 data_timer.stop();
54 calc_timer.stop();
55 }
56
57 bool enabled = false;
58 std::size_t data_ops = 0;
59 std::size_t calc_ops = 0;
60 boost::timer::cpu_timer data_timer;
61 boost::timer::cpu_timer calc_timer;
62};
63
64// filter class
65
66struct Filter {
67 // ctors
68 ~Filter();
69 Filter();
70 Filter(const Filter& r);
71 Filter(Filter&& r);
72 Filter& operator=(const Filter& r);
74
75 explicit Filter(const Size n, const bool value = false);
76 // modifiers
77 void clear();
78 void set(const Size i, const bool v);
79 void setAll(const bool v);
80 void resetSize(const Size n);
81
82 // inspectors
83 // true => det., but false => non-det. only after updateDeterministic()
84 bool deterministic() const { return deterministic_; }
86
87 bool initialised() const { return n_ != 0; }
88 Size size() const { return n_; }
89 bool operator[](const Size i) const; // undefined if uninitialized or i out of bounds
90 bool at(const Size i) const; // with checks for initialized, i within bounds
91 //
92 friend Filter operator&&(Filter, const Filter&);
93 friend Filter operator||(Filter, const Filter&);
94 friend Filter equal(Filter, const Filter&);
95 friend Filter operator!(Filter);
96 friend bool operator==(const Filter&, const Filter&);
97
98 // expand vector to full size and set deterministic to false
99 void expand();
100
101 // pointer to raw data, this is null for deterministic variables
102 bool* data();
103
104private:
105 // for invariants see the corresponding section below in class RandomVariable
106 Size n_;
108 bool* data_;
110};
111
112// inline element-wise access operators
113
114inline void Filter::set(const Size i, const bool v) {
115 QL_REQUIRE(i < n_, "Filter::set(" << i << "): out of bounds, size is " << n_);
116 if (deterministic_) {
117 if (v != constantData_)
118 expand();
119 else
120 return;
121 }
122 data_[i] = v;
123}
124
125inline bool Filter::operator[](const Size i) const {
126 if (deterministic_)
127 return constantData_;
128 else
129 return data_[i];
130}
131
132inline bool Filter::at(const Size i) const {
133 QL_REQUIRE(n_ > 0, "Filter::at(" << i << "): dimension is zero");
134 if (deterministic_)
135 return constantData_;
136 QL_REQUIRE(i < n_, "Filter::at(" << i << "): out of bounds, size is " << n_);
137 return operator[](i);
138}
139
140inline bool* Filter::data() { return data_; }
141
142bool operator==(const Filter& a, const Filter& b);
143bool operator!=(const Filter& a, const Filter& b);
144
147Filter equal(Filter, const Filter&);
149
150// random variable class
151
153 // ctors
160
161 explicit RandomVariable(const Size n, const Real value = 0.0, const Real time = Null<Real>());
162 explicit RandomVariable(const Filter& f, const Real valueTrue = 1.0, const Real valueFalse = 0.0,
163 const Real time = Null<Real>());
164 explicit RandomVariable(const Size n, const Real* const data, const Real time = Null<Real>());
165 explicit RandomVariable(const std::vector<double>& data, const Real time = Null<Real>());
166 // interop with ql classes
167 explicit RandomVariable(const QuantLib::Array& data, const Real time = Null<Real>());
168 void copyToMatrixCol(QuantLib::Matrix&, const Size j) const;
169 void copyToArray(QuantLib::Array& array) const;
170 // modifiers
171 void clear();
172 void set(const Size i, const Real v);
173 // all negative times are treated as 0 ( = deterministic value )
174 void setTime(const Real time) { time_ = std::max(time, 0.0); }
175 void setAll(const Real v);
176 void resetSize(const Size n);
177
178 // inspectors
179 // true => det., but false => non-det. only after updateDeterministic()
180 bool deterministic() const { return deterministic_; }
181 void updateDeterministic();
182 bool initialised() const { return n_ != 0; }
183 Size size() const { return n_; }
184 Real operator[](const Size i) const; // undefined if uninitialized or i out of bounds
185 Real at(const Size i) const; // with checks for initialized, i within bounds
186 Real time() const { return time_; }
191 friend bool operator==(const RandomVariable&, const RandomVariable&);
208 friend Filter close_enough(const RandomVariable&, const RandomVariable&);
209 friend Filter operator<(const RandomVariable&, const RandomVariable&);
210 friend Filter operator<=(const RandomVariable&, const RandomVariable&);
211 friend Filter operator>(const RandomVariable&, const RandomVariable&);
212 friend Filter operator>=(const RandomVariable&, const RandomVariable&);
213 friend bool close_enough_all(const RandomVariable&, const RandomVariable&);
217 friend RandomVariable indicatorEq(RandomVariable, const RandomVariable&, const Real trueVal, const Real falseVal);
218 friend RandomVariable indicatorGt(RandomVariable, const RandomVariable&, const Real trueVal, const Real falseVal,
219 const Real eps);
220 friend RandomVariable indicatorGeq(RandomVariable, const RandomVariable&, const Real trueVal, const Real falseVal,
221 const Real eps);
222
223 void expand();
224 // pointer to raw data, this is null for deterministic variables
225 double* data();
226
227 static std::function<void(RandomVariable&)> deleter;
228
229private:
230 void checkTimeConsistencyAndUpdate(const Real t);
231 /* Invariants that hold at all times for instances of this class:
232
233 n_ = 0 means uninitialized, n_ > 0 means initialized.
234
235 For an uninitialized instance:
236 - constantData_ = 0.0, data_ = nullptr, deterministic_ = false, time_ = Null<Real>()
237
238 For an initialized instance:
239 - if deterministic = true a constant value is represented with
240 - constantData_ the constant value
241 - data_ = nullptr
242 - if deterministic = false a possibly non-constant value is represented with
243 - constantData_ initialized with last constant value that was set
244 - data_ an array of size n_
245 */
246 Size n_;
248 double* data_;
250 Real time_;
251};
252
253bool operator==(const RandomVariable& a, const RandomVariable& b);
254bool operator!=(const RandomVariable& a, const RandomVariable& b);
255
272RandomVariable indicatorEq(RandomVariable, const RandomVariable&, const Real trueVal = 1.0, const Real falseVal = 0.0);
273RandomVariable indicatorGt(RandomVariable, const RandomVariable&, const Real trueVal = 1.0, const Real falseVal = 0.0,
274 const Real eps = 0.0);
275RandomVariable indicatorGeq(RandomVariable, const RandomVariable&, const Real trueVal = 1.0, const Real falseVal = 0.0,
276 const Real eps = 0.0);
277
280
282
283void checkTimeConsistency(const RandomVariable& x, const RandomVariable& y);
284
285// set all entries to 0 where filter = false, leave the others unchanged
287// set all entries to 0 where filter = true, leave the others unchanged
289
290/* Perform a factor reduction: We keep m factors so that "1 - varianceCutoff" of the total variance of the n regressor
291 variables is explained by the m factors. The return value is m x n transforming from original coordinates to new
292 coordinates. This can be a useful preprocessing step for linear regression to reduce the dimensionality or also to
293 handle collinear regressors. */
294Matrix pcaCoordinateTransform(const std::vector<const RandomVariable*>& regressor, const Real varianceCutoff = 1E-5);
295
296/* Apply a coordinate transform */
297std::vector<RandomVariable> applyCoordinateTransform(const std::vector<const RandomVariable*>& regressor,
298 const Matrix& transform);
299
300/* Create vector of pointers to rvs from vector of rvs */
301std::vector<const RandomVariable*> vec2vecptr(const std::vector<RandomVariable>& values);
302
303// compute regression coefficients
306 RandomVariable r, std::vector<const RandomVariable*> regressor,
307 const std::vector<std::function<RandomVariable(const std::vector<const RandomVariable*>&)>>& basisFn,
308 const Filter& filter = Filter(), const RandomVariableRegressionMethod = RandomVariableRegressionMethod::QR,
309 const std::string& debugLabel = std::string());
310
311// evaluate regression function
312RandomVariable conditionalExpectation(
313 const std::vector<const RandomVariable*>& regressor,
314 const std::vector<std::function<RandomVariable(const std::vector<const RandomVariable*>&)>>& basisFn,
315 const Array& coefficients);
316
317// compute and evaluate regression in one run
318RandomVariable conditionalExpectation(
319 const RandomVariable& r, const std::vector<const RandomVariable*>& regressor,
320 const std::vector<std::function<RandomVariable(const std::vector<const RandomVariable*>&)>>& basisFn,
321 const Filter& filter = Filter(), const RandomVariableRegressionMethod = RandomVariableRegressionMethod::QR);
322
323// time zero expectation
324RandomVariable expectation(const RandomVariable& r);
325
326// time zero variance
327RandomVariable variance(const RandomVariable& r);
328
329// time zero covariance
330RandomVariable covariance(const RandomVariable& r, const RandomVariable& s);
331
332// black formula
333RandomVariable black(const RandomVariable& omega, const RandomVariable& t, const RandomVariable& strike,
334 const RandomVariable& forward, const RandomVariable& impliedVol);
335
336// derivative of indicator function 1_{x>0}
337RandomVariable indicatorDerivative(const RandomVariable& x, const double eps);
338
339// is the given random variable deterministic and zero?
341 return x.deterministic() && QuantLib::close_enough(x[0], 0.0);
342}
343
344// inline element-wise access operators
345
346inline void RandomVariable::set(const Size i, const Real v) {
347 QL_REQUIRE(i < n_, "RandomVariable::set(" << i << "): out of bounds, size is " << n_);
348 if (deterministic_) {
349 if (!QuantLib::close_enough(v, constantData_)) {
350 expand();
351 } else {
352 return;
353 }
354 }
355 data_[i] = v;
356}
357
358inline Real RandomVariable::operator[](const Size i) const {
359 if (deterministic_)
360 return constantData_;
361 else
362 return data_[i];
363}
364
365inline Real RandomVariable::at(const Size i) const {
366 QL_REQUIRE(n_ > 0, "RandomVariable::at(" << i << "): dimension is zero");
367 if (deterministic_)
368 return constantData_;
369 QL_REQUIRE(i < n_, "RandomVariable::at(" << i << "): out of bounds, size is " << n_);
370 return operator[](i);
371}
372
373inline double* RandomVariable::data() { return data_; }
374
375/*! helper function that returns a LSM basis system with size restriction: the order is reduced until
376 the size of the basis system is not greater than the given bound (if this is not null) or the order is 1 */
377std::vector<std::function<RandomVariable(const std::vector<const RandomVariable*>&)>>
378multiPathBasisSystem(Size dim, Size order, QuantLib::LsmBasisSystem::PolynomialType type,
379 Size basisSystemSizeBound = Null<Size>());
380
381} // namespace QuantExt
BucketedDistribution operator+(const BucketedDistribution &lhs, const BucketedDistribution &rhs)
Sum probabilities in two bucketed distributions with equal buckets.
std::vector< std::function< RandomVariable(const std::vector< const RandomVariable * > &)> > multiPathBasisSystem(Size dim, Size order, QuantLib::LsmBasisSystem::PolynomialType type, Size basisSystemSizeBound)
bool operator!=(const Filter &a, const Filter &b)
RandomVariable sqrt(RandomVariable x)
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
RandomVariable variance(const RandomVariable &r)
RandomVariable cos(RandomVariable x)
CompiledFormula exp(CompiledFormula x)
RandomVariable sin(RandomVariable x)
RandomVariableRegressionMethod
bool close_enough_all(const RandomVariable &x, const RandomVariable &y)
Filter operator!(Filter x)
bool isDeterministicAndZero(const ExternalRandomVariable &x)
RandomVariable conditionalResult(const Filter &f, RandomVariable x, const RandomVariable &y)
CompiledFormula min(CompiledFormula x, const CompiledFormula &y)
RandomVariable indicatorDerivative(const RandomVariable &x, const double eps)
RandomVariable black(const RandomVariable &omega, const RandomVariable &t, const RandomVariable &strike, const RandomVariable &forward, const RandomVariable &impliedVol)
RandomVariable covariance(const RandomVariable &r, const RandomVariable &s)
bool operator==(const Dividend &d1, const Dividend &d2)
Compare dividends.
CompiledFormula pow(CompiledFormula x, const CompiledFormula &y)
std::vector< const RandomVariable * > vec2vecptr(const std::vector< RandomVariable > &values)
RandomVariable expectation(const RandomVariable &r)
RandomVariable normalCdf(RandomVariable x)
RandomVariable conditionalExpectation(const std::vector< const RandomVariable * > &regressor, const std::vector< std::function< RandomVariable(const std::vector< const RandomVariable * > &)> > &basisFn, const Array &coefficients)
Filter operator&&(Filter x, const Filter &y)
RandomVariable applyInverseFilter(RandomVariable x, const Filter &f)
RandomVariable indicatorGeq(RandomVariable x, const RandomVariable &y, const Real trueVal, const Real falseVal, const Real eps)
CompiledFormula max(CompiledFormula x, const CompiledFormula &y)
CompiledFormula abs(CompiledFormula x)
RandomVariable applyFilter(RandomVariable x, const Filter &f)
RandomVariable indicatorEq(RandomVariable x, const RandomVariable &y, const Real trueVal, const Real falseVal)
RandomVariable normalPdf(RandomVariable x)
Filter equal(Filter x, const Filter &y)
Filter operator||(Filter x, const Filter &y)
Matrix pcaCoordinateTransform(const std::vector< const RandomVariable * > &regressor, const Real varianceCutoff)
CompiledFormula log(CompiledFormula x)
void checkTimeConsistency(const RandomVariable &x, const RandomVariable &y)
CompiledFormula operator-(CompiledFormula x, const CompiledFormula &y)
CompiledFormula operator/(CompiledFormula x, const CompiledFormula &y)
Array regressionCoefficients(RandomVariable r, std::vector< const RandomVariable * > regressor, const std::vector< std::function< RandomVariable(const std::vector< const RandomVariable * > &)> > &basisFn, const Filter &filter, const RandomVariableRegressionMethod regressionMethod, const std::string &debugLabel)
RandomVariable indicatorGt(RandomVariable x, const RandomVariable &y, const Real trueVal, const Real falseVal, const Real eps)
std::vector< RandomVariable > applyCoordinateTransform(const std::vector< const RandomVariable * > &regressor, const Matrix &transform)
BucketedDistribution operator*(Real factor, const BucketedDistribution &rhs)
void set(const Size i, const bool v)
friend Filter operator&&(Filter, const Filter &)
friend Filter equal(Filter, const Filter &)
bool operator[](const Size i) const
friend Filter operator||(Filter, const Filter &)
bool deterministic() const
void setAll(const bool v)
Size size() const
bool initialised() const
friend Filter operator!(Filter)
friend bool operator==(const Filter &, const Filter &)
bool at(const Size i) const
Filter & operator=(const Filter &r)
void resetSize(const Size n)
friend bool close_enough_all(const RandomVariable &, const RandomVariable &)
static std::function< void(RandomVariable &)> deleter
friend RandomVariable sin(RandomVariable)
friend Filter operator<=(const RandomVariable &, const RandomVariable &)
RandomVariable(const std::vector< double > &data, const Real time=Null< Real >())
void copyToMatrixCol(QuantLib::Matrix &, const Size j) const
RandomVariable & operator+=(const RandomVariable &)
friend RandomVariable sqrt(RandomVariable)
friend RandomVariable min(RandomVariable, const RandomVariable &)
friend RandomVariable indicatorGt(RandomVariable, const RandomVariable &, const Real trueVal, const Real falseVal, const Real eps)
friend bool operator==(const RandomVariable &, const RandomVariable &)
friend Filter operator>=(const RandomVariable &, const RandomVariable &)
friend Filter operator<(const RandomVariable &, const RandomVariable &)
friend RandomVariable operator*(RandomVariable, const RandomVariable &)
void checkTimeConsistencyAndUpdate(const Real t)
friend RandomVariable normalCdf(RandomVariable)
Real at(const Size i) const
RandomVariable & operator=(const RandomVariable &r)
friend RandomVariable max(RandomVariable, const RandomVariable &)
friend RandomVariable operator/(RandomVariable, const RandomVariable &)
void set(const Size i, const Real v)
void setTime(const Real time)
RandomVariable & operator-=(const RandomVariable &)
friend Filter operator>(const RandomVariable &, const RandomVariable &)
RandomVariable & operator*=(const RandomVariable &)
friend RandomVariable indicatorEq(RandomVariable, const RandomVariable &, const Real trueVal, const Real falseVal)
friend RandomVariable operator+(RandomVariable, const RandomVariable &)
friend RandomVariable pow(RandomVariable, const RandomVariable &)
void copyToArray(QuantLib::Array &array) const
friend RandomVariable operator-(RandomVariable, const RandomVariable &)
friend RandomVariable cos(RandomVariable)
friend RandomVariable exp(RandomVariable)
friend RandomVariable normalPdf(RandomVariable)
Real operator[](const Size i) const
friend RandomVariable conditionalResult(const Filter &, RandomVariable, const RandomVariable &)
friend RandomVariable indicatorGeq(RandomVariable, const RandomVariable &, const Real trueVal, const Real falseVal, const Real eps)
RandomVariable & operator/=(const RandomVariable &)
friend RandomVariable log(RandomVariable)
void setAll(const Real v)
friend RandomVariable applyInverseFilter(RandomVariable, const Filter &)
friend RandomVariable abs(RandomVariable)
friend Filter close_enough(const RandomVariable &, const RandomVariable &)
void resetSize(const Size n)
friend RandomVariable applyFilter(RandomVariable, const Filter &)
boost::timer::cpu_timer calc_timer
boost::timer::cpu_timer data_timer