Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
BucketedDistribution Class Reference

Represents a bucketed probability distibution. More...

#include <qle/math/bucketeddistribution.hpp>

+ Collaboration diagram for BucketedDistribution:

Public Member Functions

 BucketedDistribution ()
 Default constructor. More...
 
 BucketedDistribution (QuantLib::Real min, QuantLib::Real max, QuantLib::Size numberBuckets)
 Build a default initial distribution from min and max and numberBuckets. More...
 
 BucketedDistribution (QuantLib::Real min, QuantLib::Real max, QuantLib::Size numberBuckets, QuantLib::Real initialValue)
 
 BucketedDistribution (const std::vector< QuantLib::Real > &buckets, const std::vector< QuantLib::Real > &initialProbabilities, const std::vector< QuantLib::Real > &initialPoints)
 Explicitly specify the initial distribution. More...
 
 BucketedDistribution (const BucketedDistribution &other)
 Copy constructor. More...
 
void add (const DiscreteDistribution &distribution)
 Update the bucketed distribution by adding a discrete distribution. More...
 
const std::vector< QuantLib::Real > & buckets () const
 Return the buckets of the distribution. More...
 
const std::vector< QuantLib::Real > & probabilities () const
 Get the probabilities. More...
 
std::vector< QuantLib::Real > & probabilities ()
 Set the probabilities. More...
 
const std::vector< QuantLib::Real > & points () const
 Return the points of the distribution. More...
 
Size numberBuckets () const
 Return the number of buckets in the distribution. More...
 
std::vector< QuantLib::Real > cumulativeProbabilities () const
 Return the cumulative probabilities of the distribution. More...
 
std::vector< QuantLib::Real > complementaryProbabilities () const
 Return 1.0 minus the cumulative probabilities of the distribution. More...
 
void applyShift (QuantLib::Real shift)
 Shift all buckets and points by an additive shift. More...
 
void applyFactor (QuantLib::Real factor)
 Shift all buckets and points by a multiplicative factor. More...
 
Real cumulativeProbability (QuantLib::Real x) const
 Return cumulative probability at point x using linear interpolation. More...
 
Real inverseCumulativeProbability (QuantLib::Real p) const
 Return inverse cumulative probability given a probability p using linear interpolation. More...
 
BucketedDistributionoperator+= (const BucketedDistribution &other)
 Utility functions. More...
 
DiscreteDistribution createDiscrete () const
 Create a DiscreteDistribution from a BucketedDistribution with discrete points at midpoints of the buckets. More...
 
void erase (QuantLib::Size n)
 Erase the first n buckets from the distribution. More...
 
QuantLib::Size bucket (QuantLib::Real value) const
 Returns the index of the bucket containing value. More...
 

Private Member Functions

void init (QuantLib::Real min, QuantLib::Real max, QuantLib::Size numberBuckets)
 Common code used in the constructor. More...
 

Private Attributes

std::vector< QuantLib::Real > buckets_
 Vector of numbers denoting buckets of distribution. More...
 
std::vector< QuantLib::Real > probabilities_
 Vector of numbers denoting probabilities in each bucket. More...
 
std::vector< QuantLib::Real > points_
 
std::vector< QuantLib::Real > previousProbabilities_
 
std::vector< QuantLib::Real > previousPoints_
 

Static Private Attributes

static const QuantLib::Real minProbability_ = 0.00000001
 

Detailed Description

Represents a bucketed probability distibution.

Definition at line 35 of file bucketeddistribution.hpp.

Constructor & Destructor Documentation

◆ BucketedDistribution() [1/5]

Default constructor.

Definition at line 38 of file bucketeddistribution.hpp.

38{}

◆ BucketedDistribution() [2/5]

BucketedDistribution ( QuantLib::Real  min,
QuantLib::Real  max,
QuantLib::Size  numberBuckets 
)

Build a default initial distribution from min and max and numberBuckets.

◆ BucketedDistribution() [3/5]

BucketedDistribution ( QuantLib::Real  min,
QuantLib::Real  max,
QuantLib::Size  numberBuckets,
QuantLib::Real  initialValue 
)

Build a default initial distribution from min and max and numberBuckets and set all probabilities to initialValue

◆ BucketedDistribution() [4/5]

BucketedDistribution ( const std::vector< QuantLib::Real > &  buckets,
const std::vector< QuantLib::Real > &  initialProbabilities,
const std::vector< QuantLib::Real > &  initialPoints 
)

Explicitly specify the initial distribution.

◆ BucketedDistribution() [5/5]

Copy constructor.

Definition at line 71 of file bucketeddistribution.cpp.

72 : buckets_(other.buckets_), probabilities_(other.probabilities_), points_(other.points_),
73 previousProbabilities_(other.previousProbabilities_), previousPoints_(other.previousPoints_) {}
std::vector< QuantLib::Real > points_
std::vector< QuantLib::Real > previousPoints_
std::vector< QuantLib::Real > previousProbabilities_
std::vector< QuantLib::Real > buckets_
Vector of numbers denoting buckets of distribution.
std::vector< QuantLib::Real > probabilities_
Vector of numbers denoting probabilities in each bucket.

Member Function Documentation

◆ add()

void add ( const DiscreteDistribution distribution)

Update the bucketed distribution by adding a discrete distribution.

Definition at line 77 of file bucketeddistribution.cpp.

77 {
78
79 // Update the distribution with the values provided
82 vector<Real> tempPoints(points_.size(), 0.0);
83 vector<Real> tempProbabilities = previousProbabilities_;
84 vector<bool> bucketsChanged(points_.size(), false);
85
86 for (Size i = 0; i < buckets_.size() - 1; i++) {
87 // Skip buckets that have no probability of being occupied
89 // Update buckets reachable from ith bucket
90 for (Size j = 0; j < distribution.size(); j++) {
91 Distributionpair pair = distribution.get(j);
92 Real transitionPoint = previousPoints_[i] + pair.x_;
93 Real transitionProbability = previousProbabilities_[i] * pair.y_;
94
95 // Find in which bucket transitionPoint lies
96 QL_REQUIRE(buckets_[0] <= transitionPoint && transitionPoint <= buckets_.back(),
97 "Value, " << transitionPoint << ", is out of range of buckets: (" << buckets_[0] << ", "
98 << buckets_.back() << ")");
99
100 // Either transition to a higher bucket or stay in the same bucket
101 if (transitionPoint >= buckets_[i + 1]) {
102 Size bucketIndex = 0;
103 vector<Real>::const_iterator it =
104 upper_bound(buckets_.begin() + i + 1, buckets_.end(), transitionPoint);
105 if (it == buckets_.end()) {
106 // If here, must be equal to upper end of last bucket
107 bucketIndex = buckets_.size() - 2;
108 } else {
109 bucketIndex = it - buckets_.begin() - 1;
110 }
111
112 // Update probability if moved to different bucket
113 probabilities_[i] -= transitionProbability;
114 probabilities_[bucketIndex] += transitionProbability;
115 // Update temp points (divide again in separate loop below)
116 tempPoints[bucketIndex] += transitionPoint * transitionProbability;
117 tempProbabilities[bucketIndex] += transitionProbability;
118 bucketsChanged[bucketIndex] = true;
119 } else {
120 // If bucket does not change, do not update probability but shift
121 // the conditional expectation i.e. point in bucket
122 points_[i] += pair.x_ * pair.y_;
123 }
124 }
125 }
126 }
127
128 // If the probability of being in bucket is non-zero and the bucket has been hit by
129 // the addition of the distribution above, update the conditional expectation (i.e. points_)
130 for (Size i = 0; i < buckets_.size() - 1; i++) {
131 if (tempProbabilities[i] > minProbability_ && bucketsChanged[i]) {
132 points_[i] = (previousProbabilities_[i] * points_[i] + tempPoints[i]) / tempProbabilities[i];
133 }
134 }
135}
static const QuantLib::Real minProbability_
+ Here is the call graph for this function:

◆ buckets()

const std::vector< QuantLib::Real > & buckets ( ) const

Return the buckets of the distribution.

Definition at line 55 of file bucketeddistribution.hpp.

55{ return buckets_; }
+ Here is the caller graph for this function:

◆ probabilities() [1/2]

const std::vector< QuantLib::Real > & probabilities ( ) const

Get the probabilities.

Definition at line 57 of file bucketeddistribution.hpp.

57{ return probabilities_; }
+ Here is the caller graph for this function:

◆ probabilities() [2/2]

std::vector< QuantLib::Real > & probabilities ( )

Set the probabilities.

Definition at line 59 of file bucketeddistribution.hpp.

59{ return probabilities_; }

◆ points()

const std::vector< QuantLib::Real > & points ( ) const

Return the points of the distribution.

Definition at line 61 of file bucketeddistribution.hpp.

61{ return points_; }
+ Here is the caller graph for this function:

◆ numberBuckets()

Size numberBuckets ( ) const

Return the number of buckets in the distribution.

Definition at line 63 of file bucketeddistribution.hpp.

63{ return buckets_.size() - 1; }
+ Here is the caller graph for this function:

◆ cumulativeProbabilities()

vector< Real > cumulativeProbabilities ( ) const

Return the cumulative probabilities of the distribution.

Definition at line 167 of file bucketeddistribution.cpp.

167 {
168 vector<Real> cumulativeProbabilities(buckets_.size(), 0.0);
170 // Calculate running sum i.e. probability that <= endpoint of each bucket
171 transform(probabilities_.begin(), probabilities_.end(), cumulativeProbabilities.begin(),
172 cumulativeProbabilities.begin() + 1, plus<Real>());
174}
std::vector< QuantLib::Real > cumulativeProbabilities() const
Return the cumulative probabilities of the distribution.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ complementaryProbabilities()

vector< Real > complementaryProbabilities ( ) const

Return 1.0 minus the cumulative probabilities of the distribution.

Definition at line 176 of file bucketeddistribution.cpp.

176 {
177 vector<Real> probabilities = cumulativeProbabilities();
178 // transform(probabilities.begin(), probabilities.end(), probabilities.begin(), std::bind1st(minus<Real>(), 1.0));
179 transform(probabilities.begin(), probabilities.end(), probabilities.begin(), [](const Real x) { return x - 1.0; });
180 return probabilities;
181}
const std::vector< QuantLib::Real > & probabilities() const
Get the probabilities.
+ Here is the call graph for this function:

◆ applyShift()

void applyShift ( QuantLib::Real  shift)

Shift all buckets and points by an additive shift.

Definition at line 183 of file bucketeddistribution.cpp.

183 {
184 // transform(buckets_.begin(), buckets_.end(), buckets_.begin(), std::bind1st(plus<Real>(), shift));
185 transform(buckets_.begin(), buckets_.end(), buckets_.begin(), [shift](const Real x) { return x + shift; });
186 // transform(points_.begin(), points_.end(), points_.begin(), std::bind1st(plus<Real>(), shift));
187 transform(points_.begin(), points_.end(), points_.begin(), [shift](const Real x) { return x + shift; });
188 // transform(previousPoints_.begin(), previousPoints_.end(), previousPoints_.begin(), std::bind1st(plus<Real>(),
189 // shift));
190 transform(previousPoints_.begin(), previousPoints_.end(), previousPoints_.begin(),
191 [shift](const Real x) { return x + shift; });
192}

◆ applyFactor()

void applyFactor ( QuantLib::Real  factor)

Shift all buckets and points by a multiplicative factor.

Definition at line 194 of file bucketeddistribution.cpp.

194 {
195 // If factor is negative, reverse everything before scaling so buckets are still ascending
196 if (factor < 0.0) {
197 reverse(buckets_.begin(), buckets_.end());
198 reverse(points_.begin(), points_.end());
199 reverse(previousPoints_.begin(), previousPoints_.end());
200 reverse(probabilities_.begin(), probabilities_.end());
201 reverse(previousProbabilities_.begin(), previousProbabilities_.end());
202 }
203 // transform(buckets_.begin(), buckets_.end(), buckets_.begin(), std::bind1st(multiplies<Real>(), factor));
204 transform(buckets_.begin(), buckets_.end(), buckets_.begin(), [factor](const Real x) { return x * factor; });
205 // transform(points_.begin(), points_.end(), points_.begin(), std::bind1st(multiplies<Real>(), factor));
206 transform(points_.begin(), points_.end(), points_.begin(), [factor](const Real x) { return x * factor; });
207 // transform(previousPoints_.begin(), previousPoints_.end(), previousPoints_.begin(),
208 // std::bind1st(multiplies<Real>(), factor));
209 transform(previousPoints_.begin(), previousPoints_.end(), previousPoints_.begin(),
210 [factor](const Real x) { return x * factor; });
211}

◆ cumulativeProbability()

Real cumulativeProbability ( QuantLib::Real  x) const

Return cumulative probability at point x using linear interpolation.

Definition at line 213 of file bucketeddistribution.cpp.

213 {
214 vector<Real> probabilities = cumulativeProbabilities();
215 vector<Real>::const_iterator it = lower_bound(buckets_.begin(), buckets_.end(), x);
216 // If x > upper end of last bucket
217 if (it == buckets_.end())
218 return 1.0;
219 // If x <= lower end of first bucket
220 if (it == buckets_.begin())
221 return 0.0;
222 // If x is in range of buckets
223 Size index = it - buckets_.begin();
224 return probabilities[index - 1] + (x - buckets_[index - 1]) * (probabilities[index] - probabilities[index - 1]) /
225 (buckets_[index] - buckets_[index - 1]);
226}
+ Here is the call graph for this function:

◆ inverseCumulativeProbability()

Real inverseCumulativeProbability ( QuantLib::Real  p) const

Return inverse cumulative probability given a probability p using linear interpolation.

Definition at line 228 of file bucketeddistribution.cpp.

228 {
229 QL_REQUIRE(0 <= p && p <= 1.0, "Probability must be between 0 and 1");
230 vector<Real> probabilities = cumulativeProbabilities();
231 vector<Real>::const_iterator it = lower_bound(probabilities.begin(), probabilities.end(), p);
232 // If p > last cumulative probability (shouldn't happen since p <= 1.0)
233 if (it == probabilities.end())
234 return buckets_.back();
235 // If p <= first cumulative probability (shouldn't happen since p >= 0.0)
236 if (it == probabilities.begin())
237 return buckets_.front();
238 // If p is in the range of probabilities
239 Size index = it - probabilities.begin();
240 return buckets_[index - 1] + (p - probabilities[index - 1]) * (buckets_[index] - buckets_[index - 1]) /
241 (probabilities[index] - probabilities[index - 1]);
242}
+ Here is the call graph for this function:

◆ operator+=()

BucketedDistribution & operator+= ( const BucketedDistribution other)

Utility functions.

Definition at line 244 of file bucketeddistribution.cpp.

244 {
245
246 QL_REQUIRE(buckets_.size() - 1 == other.numberBuckets(), "Distributions must have same number of buckets to sum");
247
248 bool bucketsEqual = equal(buckets_.begin(), buckets_.end(), other.buckets().begin(),
249 static_cast<bool (*)(Real, Real)>(&close_enough));
250 QL_REQUIRE(bucketsEqual, "Distributions must have the same buckets to sum");
251
252 transform(probabilities_.begin(), probabilities_.end(), other.probabilities().begin(), probabilities_.begin(),
253 plus<Real>());
254
255 return *this;
256}
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
Filter equal(Filter x, const Filter &y)
+ Here is the call graph for this function:

◆ createDiscrete()

DiscreteDistribution createDiscrete ( ) const

Create a DiscreteDistribution from a BucketedDistribution with discrete points at midpoints of the buckets.

Definition at line 258 of file bucketeddistribution.cpp.

258 {
259 // Create a vector containing midpoint of each bucket
260 vector<Real> midpoints(probabilities_.size(), 0.0);
261 transform(buckets_.begin(), buckets_.end() - 1, buckets_.begin() + 1, midpoints.begin(), plus<Real>());
262 // transform(midpoints.begin(), midpoints.end(), midpoints.begin(), std::bind2nd(divides<Real>(), 2.0));
263 transform(midpoints.begin(), midpoints.end(), midpoints.begin(),
264 [](const Real x) { return x / 2.0; }); // IS THIS CORRECT?!?
265
266 return DiscreteDistribution(midpoints, probabilities_);
267}

◆ erase()

void erase ( QuantLib::Size  n)

Erase the first n buckets from the distribution.

Warning:
This may invalidate the distribution if the buckets erased do not have negligible probability.

Definition at line 269 of file bucketeddistribution.cpp.

269 {
270 QL_REQUIRE(n < numberBuckets(), "There are not enough buckets to erase");
271 buckets_.erase(buckets_.begin(), buckets_.begin() + n);
272 probabilities_.erase(probabilities_.begin(), probabilities_.begin() + n);
273 points_.erase(points_.begin(), points_.begin() + n);
275 previousPoints_.erase(previousPoints_.begin(), previousPoints_.begin() + n);
276}
Size numberBuckets() const
Return the number of buckets in the distribution.
+ Here is the call graph for this function:

◆ bucket()

Size bucket ( QuantLib::Real  value) const

Returns the index of the bucket containing value.

Definition at line 137 of file bucketeddistribution.cpp.

137 {
138
139 QL_REQUIRE(buckets_[0] <= value && value <= buckets_.back(), "Value, " << value << ", is out of range of buckets: ("
140 << buckets_[0] << ", " << buckets_.back()
141 << ")");
142
143 vector<Real>::const_iterator it = upper_bound(buckets_.begin(), buckets_.end(), value);
144 if (it == buckets_.end()) {
145 // If here, must be equal to upper end of last bucket
146 return buckets_.size() - 2;
147 }
148 return it - buckets_.begin() - 1;
149}

◆ init()

void init ( QuantLib::Real  min,
QuantLib::Real  max,
QuantLib::Size  numberBuckets 
)
private

Common code used in the constructor.

Definition at line 151 of file bucketeddistribution.cpp.

151 {
152 // Initial checks
153 QL_REQUIRE(buckets_.size() >= 3, "There should be at least two buckets for the distribution");
154 QL_REQUIRE(max > min, "Max should be strictly greater than min");
155
156 // Divide [min, max] into equally sized buckets
157 Real bucketSize = (max - min) / numberBuckets;
158 for (Size i = 0; i < buckets_.size(); ++i) {
159 buckets_[i] = min + i * bucketSize;
160 }
161
162 // Initially set points to lower end of buckets
163 copy(buckets_.begin(), buckets_.end() - 1, points_.begin());
165}
CompiledFormula min(CompiledFormula x, const CompiledFormula &y)
CompiledFormula max(CompiledFormula x, const CompiledFormula &y)
+ Here is the call graph for this function:

Member Data Documentation

◆ buckets_

std::vector<QuantLib::Real> buckets_
private

Vector of numbers denoting buckets of distribution.

Definition at line 91 of file bucketeddistribution.hpp.

◆ probabilities_

std::vector<QuantLib::Real> probabilities_
private

Vector of numbers denoting probabilities in each bucket.

Definition at line 93 of file bucketeddistribution.hpp.

◆ points_

std::vector<QuantLib::Real> points_
private

Definition at line 94 of file bucketeddistribution.hpp.

◆ previousProbabilities_

std::vector<QuantLib::Real> previousProbabilities_
private

Definition at line 95 of file bucketeddistribution.hpp.

◆ previousPoints_

std::vector<QuantLib::Real> previousPoints_
private

Definition at line 96 of file bucketeddistribution.hpp.

◆ minProbability_

const Real minProbability_ = 0.00000001
staticprivate

Definition at line 99 of file bucketeddistribution.hpp.