27#include <ql/errors.hpp>
28#include <ql/math/comparison.hpp>
38 : buckets_(numberBuckets + 1, 0.0), probabilities_(numberBuckets, 0.0), points_(numberBuckets, 0.0) {
40 init(min, max, numberBuckets);
43 probabilities_[0] = 1.0;
44 previousProbabilities_ = probabilities_;
47BucketedDistribution::BucketedDistribution(Real min, Real max, Size numberBuckets, Real initialValue)
48 : buckets_(numberBuckets + 1, 0.0), probabilities_(numberBuckets, initialValue), points_(numberBuckets, 0.0),
49 previousProbabilities_(probabilities_) {
51 init(min, max, numberBuckets);
54BucketedDistribution::BucketedDistribution(
const vector<Real>& buckets,
const vector<Real>& initialProbabilities,
55 const vector<Real>& initialPoints)
56 : buckets_(buckets), probabilities_(initialProbabilities), points_(initialPoints),
57 previousProbabilities_(initialProbabilities), previousPoints_(initialPoints) {
60 QL_REQUIRE(buckets_.size() >= 3,
"There should be at least two buckets for the distribution");
61 QL_REQUIRE(buckets_.size() == probabilities_.size() + 1,
"The number of elements in the buckets "
62 "vector must exceed the number of probabilities by 1");
63 QL_REQUIRE(buckets_.size() == points_.size() + 1,
"The number of elements in the buckets "
64 "vector must exceed the number of point masses by 1");
67 vector<Real>::iterator pos = adjacent_find(buckets_.begin(), buckets_.end(), greater<Real>());
68 QL_REQUIRE(pos == buckets_.end(),
"The vector of buckets must be sorted in ascending order");
72 : buckets_(other.buckets_), probabilities_(other.probabilities_), points_(other.points_),
73 previousProbabilities_(other.previousProbabilities_), previousPoints_(other.previousPoints_) {}
82 vector<Real> tempPoints(
points_.size(), 0.0);
84 vector<bool> bucketsChanged(
points_.size(),
false);
86 for (Size i = 0; i <
buckets_.size() - 1; i++) {
90 for (Size j = 0; j < distribution.
size(); j++) {
96 QL_REQUIRE(
buckets_[0] <= transitionPoint && transitionPoint <=
buckets_.back(),
97 "Value, " << transitionPoint <<
", is out of range of buckets: (" <<
buckets_[0] <<
", "
101 if (transitionPoint >=
buckets_[i + 1]) {
102 Size bucketIndex = 0;
103 vector<Real>::const_iterator it =
109 bucketIndex = it -
buckets_.begin() - 1;
116 tempPoints[bucketIndex] += transitionPoint * transitionProbability;
117 tempProbabilities[bucketIndex] += transitionProbability;
118 bucketsChanged[bucketIndex] =
true;
130 for (Size i = 0; i <
buckets_.size() - 1; i++) {
139 QL_REQUIRE(
buckets_[0] <= value && value <=
buckets_.back(),
"Value, " << value <<
", is out of range of buckets: ("
143 vector<Real>::const_iterator it = upper_bound(
buckets_.begin(),
buckets_.end(), value);
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");
158 for (Size i = 0; i <
buckets_.size(); ++i) {
187 transform(
points_.begin(),
points_.end(),
points_.begin(), [shift](
const Real x) { return x + shift; });
191 [shift](
const Real x) { return x + shift; });
206 transform(
points_.begin(),
points_.end(),
points_.begin(), [factor](
const Real x) { return x * factor; });
210 [factor](
const Real x) { return x * factor; });
215 vector<Real>::const_iterator it = lower_bound(
buckets_.begin(),
buckets_.end(), x);
229 QL_REQUIRE(0 <= p && p <= 1.0,
"Probability must be between 0 and 1");
246 QL_REQUIRE(
buckets_.size() - 1 == other.
numberBuckets(),
"Distributions must have same number of buckets to sum");
250 QL_REQUIRE(bucketsEqual,
"Distributions must have the same buckets to sum");
263 transform(midpoints.begin(), midpoints.end(), midpoints.begin(),
264 [](
const Real x) { return x / 2.0; });
270 QL_REQUIRE(n <
numberBuckets(),
"There are not enough buckets to erase");
290 [factor](
const Real x) { return x * factor; });
Deals with a bucketed distribution.
Represents a bucketed probability distibution.
void erase(QuantLib::Size n)
Erase the first n buckets from the distribution.
BucketedDistribution & operator+=(const BucketedDistribution &other)
Utility functions.
void applyShift(QuantLib::Real shift)
Shift all buckets and points by an additive shift.
BucketedDistribution()
Default constructor.
void applyFactor(QuantLib::Real factor)
Shift all buckets and points by a multiplicative factor.
void init(QuantLib::Real min, QuantLib::Real max, QuantLib::Size numberBuckets)
Common code used in the constructor.
const std::vector< QuantLib::Real > & probabilities() const
Get the probabilities.
std::vector< QuantLib::Real > points_
Size numberBuckets() const
Return the number of buckets in the distribution.
Real inverseCumulativeProbability(QuantLib::Real p) const
Return inverse cumulative probability given a probability p using linear interpolation.
std::vector< QuantLib::Real > previousPoints_
const std::vector< QuantLib::Real > & buckets() const
Return the buckets of the distribution.
std::vector< QuantLib::Real > previousProbabilities_
void add(const DiscreteDistribution &distribution)
Update the bucketed distribution by adding a discrete distribution.
std::vector< QuantLib::Real > cumulativeProbabilities() const
Return the cumulative probabilities of the distribution.
Real cumulativeProbability(QuantLib::Real x) const
Return cumulative probability at point x using linear interpolation.
std::vector< QuantLib::Real > buckets_
Vector of numbers denoting buckets of distribution.
QuantLib::Size bucket(QuantLib::Real value) const
Returns the index of the bucket containing value.
const std::vector< QuantLib::Real > & points() const
Return the points of the distribution.
DiscreteDistribution createDiscrete() const
Create a DiscreteDistribution from a BucketedDistribution with discrete points at midpoints of the bu...
static const QuantLib::Real minProbability_
std::vector< QuantLib::Real > probabilities_
Vector of numbers denoting probabilities in each bucket.
std::vector< QuantLib::Real > complementaryProbabilities() const
Return 1.0 minus the cumulative probabilities of the distribution.
virtual vector< Distributionpair > get() const
virtual Size size() const
Distributionpair is a helper class for DiscretDistribution.
BucketedDistribution operator+(const BucketedDistribution &lhs, const BucketedDistribution &rhs)
Sum probabilities in two bucketed distributions with equal buckets.
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
CompiledFormula min(CompiledFormula x, const CompiledFormula &y)
CompiledFormula max(CompiledFormula x, const CompiledFormula &y)
Filter equal(Filter x, const Filter &y)
BucketedDistribution operator*(Real factor, const BucketedDistribution &rhs)