Skip to content

Commit 8eb8216

Browse files
committed
QPR-12140 add burley generator
1 parent d776550 commit 8eb8216

2 files changed

Lines changed: 97 additions & 23 deletions

File tree

ql/models/marketmodels/browniangenerators/sobolbrowniangenerator.cpp

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,10 @@ namespace QuantLib {
107107
}
108108

109109

110-
SobolBrownianGenerator::SobolBrownianGenerator(Size factors,
110+
SobolBrownianGeneratorBase::SobolBrownianGeneratorBase(Size factors,
111111
Size steps,
112-
Ordering ordering,
113-
unsigned long seed,
114-
SobolRsg::DirectionIntegers integers)
112+
Ordering ordering)
115113
: factors_(factors), steps_(steps), ordering_(ordering),
116-
generator_(SobolRsg(factors * steps, seed, integers), InverseCumulativeNormal()),
117114
bridge_(steps), orderedIndices_(factors, std::vector<Size>(steps)),
118115
bridgedVariates_(factors, std::vector<Real>(steps)) {
119116

@@ -133,12 +130,8 @@ namespace QuantLib {
133130
}
134131

135132

136-
Real SobolBrownianGenerator::nextPath() {
137-
typedef InverseCumulativeRsg<SobolRsg,
138-
InverseCumulativeNormal>::sample_type
139-
sample_type;
140-
141-
const sample_type& sample = generator_.nextSequence();
133+
Real SobolBrownianGeneratorBase::nextPath() {
134+
const auto& sample = nextSequence();
142135
// Brownian-bridge the variates according to the ordered indices
143136
for (Size i=0; i<factors_; ++i) {
144137
bridge_.transform(boost::make_permutation_iterator(
@@ -155,11 +148,11 @@ namespace QuantLib {
155148

156149

157150
const std::vector<std::vector<Size> >&
158-
SobolBrownianGenerator::orderedIndices() const {
151+
SobolBrownianGeneratorBase::orderedIndices() const {
159152
return orderedIndices_;
160153
}
161154

162-
std::vector<std::vector<Real> > SobolBrownianGenerator::transform(
155+
std::vector<std::vector<Real> > SobolBrownianGeneratorBase::transform(
163156
const std::vector<std::vector<Real> >& variates) {
164157

165158
QL_REQUIRE( (variates.size() == factors_*steps_),
@@ -190,7 +183,7 @@ namespace QuantLib {
190183
return retVal;
191184
}
192185

193-
Real SobolBrownianGenerator::nextStep(std::vector<Real>& output) {
186+
Real SobolBrownianGeneratorBase::nextStep(std::vector<Real>& output) {
194187
#if defined(QL_EXTRA_SAFETY_CHECKS)
195188
QL_REQUIRE(output.size() == factors_, "size mismatch");
196189
QL_REQUIRE(lastStep_<steps_, "sequence exhausted");
@@ -201,11 +194,21 @@ namespace QuantLib {
201194
return 1.0;
202195
}
203196

204-
Size SobolBrownianGenerator::numberOfFactors() const { return factors_; }
197+
Size SobolBrownianGeneratorBase::numberOfFactors() const { return factors_; }
205198

206-
Size SobolBrownianGenerator::numberOfSteps() const { return steps_; }
199+
Size SobolBrownianGeneratorBase::numberOfSteps() const { return steps_; }
207200

201+
SobolBrownianGenerator::SobolBrownianGenerator(Size factors,
202+
Size steps,
203+
Ordering ordering,
204+
unsigned long seed,
205+
SobolRsg::DirectionIntegers integers)
206+
: SobolBrownianGeneratorBase(factors, steps, ordering, seed, integers),
207+
generator_(SobolRsg(factors * steps, seed, integers), InverseCumulativeNormal()) {}
208208

209+
const std::vector<Real>& SobolBrownianGenerator::nextSequence() {
210+
return generator_.nextSequence();
211+
}
209212

210213
SobolBrownianGeneratorFactory::SobolBrownianGeneratorFactory(
211214
SobolBrownianGenerator::Ordering ordering,
@@ -220,5 +223,32 @@ namespace QuantLib {
220223
seed_, integers_));
221224
}
222225

226+
Burley2020SobolBrownianGenerator::Burley2020SobolBrownianGenerator(
227+
Size factors,
228+
Size steps,
229+
Ordering ordering,
230+
unsigned long seed,
231+
SobolRsg::DirectionIntegers integers,
232+
unsigned long scrambleSeed)
233+
: SobolBrownianGeneratorBase(factors, steps, ordering, seed, integers),
234+
generator_(Burley2020SobolRsg(factors * steps, seed, integers, scrambleSeed),
235+
InverseCumulativeNormal()) {}
236+
237+
const std::vector<Real>& Burley2020xSobolBrownianGenerator::nextSequence() {
238+
return generator_.nextSequence();
239+
}
240+
241+
Burley2020SobolBrownianGeneratorFactory::Burley2020SobolBrownianGeneratorFactory(
242+
SobolBrownianGenerator::Ordering ordering,
243+
unsigned long seed,
244+
SobolRsg::DirectionIntegers integers,
245+
unsigned long scrambleSeed)
246+
: ordering_(ordering), seed_(seed), integers_(integers), scrambleSeed_(scrambleSeed) {}
247+
248+
ext::shared_ptr<BrownianGenerator>
249+
Burley2020SobolBrownianGeneratorFactory::create(Size factors, Size steps) const {
250+
return ext::shared_ptr<BrownianGenerator>(new Burley2020SobolBrownianGenerator(
251+
factors, steps, ordering_, seed_, integers_, scrambleSeed_));
252+
}
223253
}
224254

ql/models/marketmodels/browniangenerators/sobolbrowniangenerator.hpp

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <ql/models/marketmodels/browniangenerator.hpp>
2525
#include <ql/math/randomnumbers/inversecumulativersg.hpp>
2626
#include <ql/math/randomnumbers/sobolrsg.hpp>
27+
#include <ql/math/randomnumbers/burley2020sobolrsg.hpp>
2728
#include <ql/methods/montecarlo/brownianbridge.hpp>
2829
#include <ql/math/distributions/normaldistribution.hpp>
2930
#include <vector>
@@ -34,7 +35,7 @@ namespace QuantLib {
3435
/*! Incremental Brownian generator using a Sobol generator,
3536
inverse-cumulative Gaussian method, and Brownian bridging.
3637
*/
37-
class SobolBrownianGenerator : public BrownianGenerator {
38+
class SobolBrownianGeneratorBase : public BrownianGenerator {
3839
public:
3940
enum Ordering {
4041
Factors, /*!< The variates with the best quality will be
@@ -46,13 +47,10 @@ namespace QuantLib {
4647
most important factors and the largest
4748
steps. */
4849
};
49-
SobolBrownianGenerator(
50+
SobolBrownianGeneratorBase(
5051
Size factors,
5152
Size steps,
52-
Ordering ordering,
53-
unsigned long seed = 0,
54-
SobolRsg::DirectionIntegers directionIntegers
55-
= SobolRsg::Jaeckel);
53+
Ordering ordering);
5654

5755
Real nextPath() override;
5856
Real nextStep(std::vector<Real>&) override;
@@ -65,17 +63,32 @@ namespace QuantLib {
6563
std::vector<std::vector<Real> > transform(
6664
const std::vector<std::vector<Real> >& variates);
6765

66+
protected:
67+
virtual const std::vector<Real>& nextSequence() = 0;
68+
6869
private:
6970
Size factors_, steps_;
7071
Ordering ordering_;
71-
InverseCumulativeRsg<SobolRsg,InverseCumulativeNormal> generator_;
7272
BrownianBridge bridge_;
7373
// work variables
7474
Size lastStep_ = 0;
7575
std::vector<std::vector<Size> > orderedIndices_;
7676
std::vector<std::vector<Real> > bridgedVariates_;
7777
};
7878

79+
class SobolBrownianGenerator : public SobolBrownianGeneratorBase {
80+
public:
81+
SobolBrownianGenerator(Size factors,
82+
Size steps,
83+
Ordering ordering,
84+
unsigned long seed = 0,
85+
SobolRsg::DirectionIntegers directionIntegers = SobolRsg::Jaeckel);
86+
87+
private:
88+
virtual const std::vector<Real>& nextSequence() override;
89+
InverseCumulativeRsg<SobolRsg, InverseCumulativeNormal> generator_;
90+
};
91+
7992
class SobolBrownianGeneratorFactory : public BrownianGeneratorFactory {
8093
public:
8194
SobolBrownianGeneratorFactory(
@@ -91,6 +104,37 @@ namespace QuantLib {
91104
SobolRsg::DirectionIntegers integers_;
92105
};
93106

107+
class Burley2020SobolBrownianGenerator : public SobolBrownianGeneratorBase {
108+
public:
109+
Burley2020SobolBrownianGenerator(
110+
Size factors,
111+
Size steps,
112+
Ordering ordering,
113+
unsigned long seed = 42,
114+
SobolRsg::DirectionIntegers directionIntegers = SobolRsg::Jaeckel,
115+
unsigned long scrambleSeed = 43);
116+
117+
private:
118+
virtual const std::vector<Real>& nextSequence() override;
119+
InverseCumulativeRsg<Burley2020SobolRsg, InverseCumulativeNormal> generator_;
120+
};
121+
122+
class Burley2020SobolBrownianGeneratorFactory : public BrownianGeneratorFactory {
123+
public:
124+
Burley2020SobolBrownianGeneratorFactory(
125+
SobolBrownianGenerator::Ordering ordering,
126+
unsigned long seed = 42,
127+
SobolRsg::DirectionIntegers directionIntegers = SobolRsg::Jaeckel,
128+
unsigned long scrambleSeed = 43);
129+
ext::shared_ptr<BrownianGenerator> create(Size factors, Size steps) const override;
130+
131+
private:
132+
SobolBrownianGenerator::Ordering ordering_;
133+
unsigned long seed_;
134+
SobolRsg::DirectionIntegers integers_;
135+
unsigned long scrambleSeed_;
136+
};
137+
94138
}
95139

96140

0 commit comments

Comments
 (0)