QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
isotropicrandomwalk.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2015 Andres Hernandez
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
24#ifndef quantlib_isotropic_random_walk_hpp
25#define quantlib_isotropic_random_walk_hpp
26
27#include <ql/math/array.hpp>
28#include <ql/math/randomnumbers/mt19937uniformrng.hpp>
29#include <ql/mathconstants.hpp>
30#include <utility>
31
32namespace QuantLib {
33
35
43 template <class Distribution, class Engine>
45 public:
47 Distribution dist,
48 Size dim,
49 Array weights = Array(),
50 unsigned long seed = 0)
51 : engine_(std::move(eng)), distribution_(std::move(dist)), rng_(seed), weights_(std::move(weights)), dim_(dim) {
52 if (weights_.empty())
53 weights_ = Array(dim, 1.0);
54 else
55 QL_REQUIRE(dim_ == weights_.size(), "Invalid weights");
56 }
57 template <class InputIterator>
58 inline void nextReal(InputIterator first) {
59 Real radius = distribution_(engine_);
61 if (dim_ > 1) {
62 //Isotropic random direction
63 Real phi = M_PI*rng_.nextReal();
64 for (Size i = 0; i < dim_ - 2; i++) {
65 *first++ = radius*cos(phi)*(*weight++);
66 radius *= sin(phi);
67 phi = M_PI*rng_.nextReal();
68 }
69 *first++ = radius*cos(2.0*phi)*(*weight++);
70 *first = radius*sin(2.0*phi)*(*weight);
71 }
72 else {
73 if (rng_.nextReal() < 0.5)
74 *first = -radius*(*weight);
75 else
76 *first = radius*(*weight);
77 }
78 }
79 inline void setDimension(Size dim) {
80 dim_ = dim;
81 weights_ = Array(dim, 1.0);
82 }
83 inline void setDimension(Size dim, const Array& weights) {
84 QL_REQUIRE(dim == weights.size(), "Invalid weights");
85 dim_ = dim;
86 weights_ = weights;
87 }
93 inline void setDimension(Size dim,
94 const Array& lowerBound, const Array& upperBound) {
95 QL_REQUIRE(dim == lowerBound.size(),
96 "Incompatible dimension and lower bound");
97 QL_REQUIRE(dim == upperBound.size(),
98 "Incompatible dimension and upper bound");
99 //Find largest bound
100 Array bounds = upperBound - lowerBound;
101 Real maxBound = bounds[0];
102 for (Size j = 1; j < dim; j++) {
103 if (bounds[j] > maxBound) maxBound = bounds[j];
104 }
105 //weights by dimension is the size of the bound
106 //divided by the largest bound
107 maxBound = 1.0 / maxBound;
108 bounds *= maxBound;
109 setDimension(dim, bounds);
110 }
111 protected:
112 Engine engine_;
117 };
118}
119#endif
1-D array used in linear algebra.
Definition: array.hpp:52
const Real * const_iterator
Definition: array.hpp:124
bool empty() const
whether the array is empty
Definition: array.hpp:499
Size size() const
dimension of the array
Definition: array.hpp:495
const_iterator begin() const
Definition: array.hpp:503
void nextReal(InputIterator first)
MersenneTwisterUniformRng rng_
void setDimension(Size dim, const Array &lowerBound, const Array &upperBound)
IsotropicRandomWalk(Engine eng, Distribution dist, Size dim, Array weights=Array(), unsigned long seed=0)
void setDimension(Size dim, const Array &weights)
Uniform random number generator.
Real nextReal() const
return a random number in the (0.0, 1.0)-interval
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
STL namespace.