37 QL_REQUIRE(dataPoints.size() == probabilities.size(),
"Must be the same number of data points and probabilities");
39 for (Size i = 0; i < dataPoints.size(); i++) {
55 QL_REQUIRE(0 <= i && i <
data_.size(),
"Asked for probability outside range of distribution");
61 QL_REQUIRE(0 <= i && i <
data_.size(),
"Asked for data point outside range of distribution");
68 vector<Distributionpair> result(buckets);
70 vector<Distributionpair> x1pm1 = a.
get();
71 vector<Distributionpair> x2pm2 = b.
get();
72 vector<Distributionpair> xpconvtemp;
74 for (Size i = 0; i < x1pm1.size(); i++) {
75 for (Size j = 0; j < x2pm2.size(); j++) {
77 xpconvtemp.push_back(xp);
83 std::sort(xpconvtemp.begin(), xpconvtemp.end());
90 Real xmin = xpconvtemp.front().x_;
91 Real xmax = xpconvtemp.back().x_;
92 Real Bucketsize = (xmax - xmin) / buckets;
100 for (Size i = 0; i < buckets; i++) {
101 xpconv[i].x_ = xmin + i * Bucketsize;
104 for (Size j = 0; j < xpconvtemp.size(); j++) {
105 Size bucket =
static_cast<Size
>((xpconvtemp[j].x_ - xmin) / Bucketsize);
106 QL_REQUIRE(bucket <= buckets,
"Number of buckets in Convolution incorrect");
107 if (bucket == buckets) {
111 Real probs = xpconv[bucket].y_ + xpconvtemp[j].y_;
115 if (probs < 1.0e-20) {
116 xpconv[bucket].y_ = 0.0;
117 xpconv[bucket].x_ += 0.0;
119 Real intermed = (xpconv[bucket].x_ * xpconv[bucket].y_ + xpconvtemp[j].x_ * xpconvtemp[j].y_) / probs;
120 xpconv[bucket].y_ += xpconvtemp[j].y_;
121 xpconv[bucket].x_ = intermed;
151 vector<Distributionpair> xptemp = a.
get();
153 std::sort(xptemp.begin(), xptemp.end());
155 Real xmin = xptemp.front().x_;
156 Real xmax = xptemp.back().x_;
157 Real Bucketsize = (xmax - xmin) / buckets;
172 for (Size i = 0; i < buckets; i++) {
173 xp[i].x_ = xmin + i * Bucketsize;
176 for (Size j = 0; j < xptemp.size(); j++) {
177 Size bucket =
static_cast<Size
>((xptemp[j].x_ - xmin) / Bucketsize);
178 QL_REQUIRE(bucket <= buckets,
"Number of buckets in Rebucket incorrect");
179 if (bucket == buckets) {
183 Real probs = xp[bucket].y_ + xptemp[j].y_;
187 if (probs < 1.0e-30) {
189 xp[bucket].x_ += 0.0;
191 Real intermed = (xp[bucket].x_ * xp[bucket].y_ + xptemp[j].x_ * xptemp[j].y_) / probs;
192 xp[bucket].y_ += xptemp[j].y_;
193 xp[bucket].x_ = intermed;
203 vector<Distributionpair> xptemp = a.
get();
205 std::sort(xptemp.begin(), xptemp.end());
208 Real xmin = xptemp.front().x_;
209 Real xmax = xptemp.back().x_;
214 buckets =
static_cast<Size
>(ceil((xmax - xmin) / step));
225 for (Size i = 0; i < buckets; i++) {
226 xp[i].x_ = xmin + i * step;
229 for (Size j = 0; j < xptemp.size(); j++) {
230 Size bucket =
static_cast<Size
>((xptemp[j].x_ - xmin) / step);
231 QL_REQUIRE(bucket <= buckets,
"Number of buckets in Rebucket incorrect");
232 if (bucket == buckets) {
236 Real probs = xp[bucket].y_ + xptemp[j].y_;
240 if (probs < 1.0e-30) {
242 xp[bucket].x_ += 0.0;
244 Real intermed = (xp[bucket].x_ * xp[bucket].y_ + xptemp[j].x_ * xptemp[j].y_) / probs;
245 xp[bucket].y_ += xptemp[j].y_;
246 xp[bucket].x_ = intermed;
257 vector<Distributionpair> x1pm1 = a.
get();
258 vector<Distributionpair> x2pm2 = b.
get();
259 vector<Distributionpair> xpsumtemp;
261 for (Size i = 0; i < x1pm1.size(); i++) {
263 xpsumtemp.push_back(xp);
266 for (Size i = 0; i < x2pm2.size(); i++) {
268 xpsumtemp.push_back(xp);
271 std::sort(xpsumtemp.begin(), xpsumtemp.end());
278 Real xmin = xpsumtemp.front().x_;
279 Real xmax = xpsumtemp.back().x_;
280 Real Bucketsize = (xmax - xmin) / buckets;
287 for (Size i = 0; i < buckets; i++) {
288 xpsum[i].x_ = i * Bucketsize;
291 for (Size j = 0; j < xpsumtemp.size(); j++) {
292 Size bucket =
static_cast<Size
>((xpsumtemp[j].x_ - xmin) / Bucketsize);
293 QL_REQUIRE(bucket <= buckets,
"Number of buckets in Convolution incorrect: " << bucket);
294 if (bucket == buckets) {
298 Real probs = xpsum[bucket].y_ + xpsumtemp[j].y_;
302 if (probs < 1.0e-30) {
303 xpsum[bucket].y_ = 0.0;
304 xpsum[bucket].x_ += 0.0;
306 Real intermed = (xpsum[bucket].x_ * xpsum[bucket].y_ + xpsumtemp[j].x_ * xpsumtemp[j].y_) / probs;
307 xpsum[bucket].y_ += xpsumtemp[j].y_;
308 xpsum[bucket].x_ = intermed;
331 vector<Distributionpair> x1pm1 = a.
get();
332 vector<Distributionpair> x2pm2 = b.
get();
335 std::sort(x2pm2.begin(), x2pm2.end());
337 std::sort(x1pm1.begin(), x1pm1.end());
339 std::sort(x1pm1.rbegin(), x1pm1.rend());
344 for (Size i = 0; i < x2pm2.size(); i++) {
345 if (x2pm2[i].x_ <= c_) {
349 for (Size i = 0; i < x1pm1.size(); i++) {
352 target = x1pm1[i].x_;
362 vector<Distributionpair> aData = a.
get();
363 vector<Distributionpair> bData = b.
get();
364 sort(aData.begin(), aData.end());
365 sort(bData.begin(), bData.end());
368 Real probability = 0.0;
370 vector<Distributionpair>::iterator itVar = lower_bound(bData.begin(), bData.end(), dummy);
371 if (itVar == bData.end()) {
372 for (Size i = 0; i < bData.size(); i++)
373 probability += bData[i].y_;
374 }
else if (itVar == bData.begin()) {
375 probability = itVar->y_;
377 Size startIndex = itVar - bData.begin() - 1;
378 for (Size i = 0; i <= startIndex; i++)
379 probability += bData[i].y_;
380 probability += (c - bData[startIndex].x_) * itVar->y_ / (itVar->x_ - bData[startIndex].x_);
385 vector<Real> aCumulative(aData.size());
386 vector<Real> aValues(aData.size());
387 for (Size i = 0; i < aData.size(); i++) {
389 aCumulative[i] =
sum;
390 aValues[i] = aData[i].x_;
393 vector<Real>::iterator itProb = lower_bound(aCumulative.begin(), aCumulative.end(), probability);
394 if (itProb == aCumulative.end()) {
395 return aValues.back();
396 }
else if (itProb == aCumulative.begin()) {
397 return aValues.front();
399 Size low = itProb - aCumulative.begin() - 1;
400 Real target = aValues[low];
401 target += (aValues[low + 1] - aValues[low]) * (probability - aCumulative[low]) /
402 (aCumulative[low + 1] - aCumulative[low]);
411 vector<Distributionpair> x1pm1 = a.
get();
412 vector<Distributionpair> x2pm2 = b.
get();
414 vector<Distributionpair> xpsumtemp;
422 for (Size i = 0; i < x2pm2.size(); i++) {
423 cumNow += x2pm2[i].y_;
425 for (Size j = 0; j < x1pm1.size(); j++) {
426 cumX1 += x1pm1[j].y_;
427 if ((cumX1 > cumLast) && (cumX1 <= cumNow)) {
428 x1pm1[j].x_ += x2pm2[i].x_ * c_;
442 vector<Distributionpair> x1pm1 = a.
get();
443 vector<Distributionpair> x2pm2 = b.
get();
445 vector<Distributionpair> xpsumtemp;
447 std::sort(x1pm1.begin(), x1pm1.end());
448 std::sort(x2pm2.begin(), x2pm2.end());
453 for (Size i = 0; i < x2pm2.size(); i++) {
454 cumNow += x2pm2[i].y_;
456 for (Size j = 0; j < x1pm1.size(); j++) {
457 cumX1 += x1pm1[j].y_;
458 if ((cumX1 >= cumLast) && (cumX1 < cumNow)) {
459 x1pm1[j].x_ += x2pm2[i].x_ * c_;
473 vector<Distributionpair> x1pm1 = a.
get();
474 vector<Distributionpair> x2pm2 = b.
get();
476 vector<Distributionpair> xpsumtemp;
478 std::sort(x1pm1.begin(), x1pm1.end());
479 std::sort(x2pm2.begin(), x2pm2.end());
484 for (Size i = x2pm2.size(); i > 0; i--) {
485 cumNow += x2pm2[i - 1].y_;
487 for (Size j = x1pm1.size(); j > 0; j--) {
488 cumX1 += x1pm1[j - 1].y_;
489 if ((cumX1 >= cumLast) && (cumX1 < cumNow)) {
490 x1pm1[j - 1].x_ += x2pm2[i - 1].x_ * c_;
504 vector<Distributionpair> x1pm1 = a.
get();
505 vector<Distributionpair> x2pm2 = b.
get();
506 vector<Distributionpair> xpsumtemp;
507 Real probmNNzero = 0.;
508 Real probKicker = 0.;
512 for (Size i = 0; i < x1pm1.size(); i++) {
515 if (x1pm1[i].x_ >= 0) {
516 xpsumtemp.push_back(xp);
518 probmNNzero += x1pm1[i].y_;
522 for (Size i = 0; i < x2pm2.size(); i++) {
524 if (x2pm2[i].x_ < 0) {
525 xpsumtemp.push_back(xp);
526 probKicker += x2pm2[i].y_;
530 QL_REQUIRE(xp.
y_ >= 0,
"Problem with probabilities in Mezz Splice");
531 xpsumtemp.push_back(xp);
533 std::sort(xpsumtemp.begin(), xpsumtemp.end());
542 vector<Distributionpair> x1pm1 = a.
get();
544 vector<Distributionpair> scalarmult;
546 for (Size i = 0; i < x1pm1.size(); i++) {
549 scalarmult.push_back(xp);
558 vector<Distributionpair> x1pm1 = a.
get();
560 vector<Distributionpair> scalarmult;
562 for (Size i = 0; i < x1pm1.size(); i++) {
565 scalarmult.push_back(xp);
574 vector<Distributionpair> x1pm1 = a.
get();
576 vector<Distributionpair> scalarmult;
578 for (Size i = 0; i < x1pm1.size(); i++) {
581 scalarmult.push_back(xp);
590 vector<Distributionpair> x1pm1 = a.
get();
592 vector<Distributionpair> func;
594 std::sort(x1pm1.begin(), x1pm1.end());
598 for (Size i = 0; i < x1pm1.size(); i++) {
599 if (x1pm1[i].x_ <=
b_) {
606 for (Size i = 0; i < x1pm1.size(); i++) {
607 if (x1pm1[i].x_ >
b_) {
620 vector<Distributionpair> x1pm1 = a.
get();
622 vector<Distributionpair> func;
624 std::sort(x1pm1.begin(), x1pm1.end());
626 for (Size i = 0; i < x1pm1.size(); i++) {
627 if (x1pm1[i].x_ <
b_) {
635 for (Size i = 0; i < x1pm1.size(); i++) {
636 if (x1pm1[i].x_ >=
b_) {
650 vector<Distributionpair> x1pm1 = a.
get();
653 for (Size i = 0; i < x1pm1.size(); i++) {
655 exp += x1pm1[i].
x_ * x1pm1[i].y_;
664 vector<Distributionpair> x1pm1 = a.
get();
668 for (Size i = 0; i < x1pm1.size(); i++) {
670 variance +=
pow((x1pm1[i].x_ - mu), 2) * x1pm1[i].y_;
680 vector<Distributionpair> x1pm1 = a.
get();
684 for (Size i = 0; i < x1pm1.size(); i++) {
685 if (x1pm1[i].x_ - mu < 0.0)
686 variance +=
pow((x1pm1[i].x_ - mu), 2) * x1pm1[i].y_;
697 file.open(o.str().c_str());
699 QL_FAIL(
"error opening file " << o.str());
700 file.setf(ios::scientific, ios::floatfield);
701 file.setf(ios::showpoint);
703 for (Size k = 0; k < a.
size(); k++) {
704 file << k <<
" " << a.
get(k).x_ <<
" " << a.
get(k).y_ << endl;
DiscreteDistribution()
Default constructor with probability 1.0 at 0.0.
virtual vector< Distributionpair > get() const
Real data(Size i) const
Return data at index i.
Real probability(Size i) const
Return probability for data at index i.
vector< Distributionpair > data_
virtual Size size() const
Distributionpair is a helper class for DiscretDistribution.
static DiscreteDistribution scalarshiftx(const DiscreteDistribution &a, const Real &b)
static DiscreteDistribution scalarmultprob(const DiscreteDistribution &a, const Real &b)
static DiscreteDistribution scalarmultx(const DiscreteDistribution &a, const Real &b)
static DiscreteDistribution splicemezz(const DiscreteDistribution &a, const DiscreteDistribution &b, Real c)
static DiscreteDistribution functionmax(const DiscreteDistribution &a, const Real &b)
static DiscreteDistribution sum(const DiscreteDistribution &a, const DiscreteDistribution &b, Size buckets)
static DiscreteDistribution sumspecialunsorted(const DiscreteDistribution &a, const DiscreteDistribution &b, Real c)
static DiscreteDistribution rebucketfixedstep(const DiscreteDistribution &a, Real step)
static Real probabilitymatch(const DiscreteDistribution &a, const DiscreteDistribution &b, Real c, bool forward)
static DiscreteDistribution sumspecialright(const DiscreteDistribution &a, const DiscreteDistribution &b, Real c)
static Real expectation(const DiscreteDistribution &a)
static Real stdev(const DiscreteDistribution &a)
static DiscreteDistribution rebucketfixednumber(const DiscreteDistribution &a, Size buckets)
static DiscreteDistribution functionmin(const DiscreteDistribution &a, const Real &b)
static DiscreteDistribution sumspecial(const DiscreteDistribution &a, const DiscreteDistribution &b, Real c)
static Real leftstdev(const DiscreteDistribution &a)
static DiscreteDistribution convolve(const DiscreteDistribution &a, const DiscreteDistribution &b, Size buckets)
static Real print(const DiscreteDistribution &a, const ostringstream &o)
Discretized probability density and cumulative probability.
RandomVariable sqrt(RandomVariable x)
RandomVariable variance(const RandomVariable &r)
CompiledFormula exp(CompiledFormula x)
CompiledFormula min(CompiledFormula x, const CompiledFormula &y)
CompiledFormula pow(CompiledFormula x, const CompiledFormula &y)
CompiledFormula max(CompiledFormula x, const CompiledFormula &y)