24#include <ql/experimental/credit/distribution.hpp>
25#include <ql/math/comparison.hpp>
26#include <ql/errors.hpp>
36 xmin_(xmin), xmax_(xmax), count_(nBuckets),
37 x_(nBuckets,0), dx_(nBuckets,0),
39 cumulativeDensity_(nBuckets,0),
40 excessProbability_(nBuckets,0),
41 cumulativeExcessProbability_(nBuckets,0),
43 overFlow_(0), underFlow_(0),
44 isNormalized_(false) {
45 for (
int i = 0; i < nBuckets; i++) {
46 dx_[i] = (xmax - xmin) / nBuckets;
47 x_[i] = (i == 0 ? xmin :
x_[i-1] +
dx_[i-1]);
51 dx_.back() = xmax -
x_.back();
57 QL_REQUIRE ((
x >=
x_.front() ||
close(
x,
x_.front())) &&
58 (
x <=
x_.back() +
dx_.back()
61 <<
" out of range [" <<
x_.front() <<
"; "
62 <<
x_.back() +
dx_.back() <<
"]");
63 for (
Size i = 0; i <
x_.size(); i++) {
84 if (
x_[i] +
dx_[i] > value) {
97 QL_REQUIRE (bucket >= 0 && bucket <
size_,
"bucket out of range");
105 QL_REQUIRE (bucket >= 0 && bucket <
size_,
"bucket out of range");
117 for (
int i = 0; i <
size_; i++)
122 for (
int i = 0; i <
size_; i++) {
154 for (
int i = 0; i <
size_; i++) {
156 return x_[i] +
dx_[i];
158 return x_.back() +
dx_.back();
166 for (
int i = 0; i <
size_; i++) {
178 for (
int i = 0; i <
size_; i++) {
207 QL_REQUIRE (b <=
xmax_,
208 "end of interval " << b <<
" out of range ["
210 QL_REQUIRE (a >=
xmin_,
211 "start of interval " << a <<
" out of range ["
223 QL_REQUIRE (
x > 0,
"x must be positive");
225 for (
int i = 0; i <
size_; i++) {
226 if (
x_[i] +
dx_[i] + tiny >=
x)
230 QL_FAIL (
"x = " <<
x <<
" beyond distribution cutoff "
231 <<
x_.back() +
dx_.back());
238 QL_REQUIRE (attachmentPoint < detachmentPoint,
239 "attachment >= detachment point");
240 QL_REQUIRE (
x_.back() > attachmentPoint &&
241 x_.back()+
dx_.back() >= detachmentPoint,
242 "attachment or detachment too large");
247 while (
x_[0] < attachmentPoint) {
248 x_.erase(
x_.begin());
257 auto detachPosit = std::find_if(
x_.begin(),
x_.end(), [=](
Real x){ return x > detachmentPoint; });
258 if(detachPosit !=
x_.end())
259 x_.erase(detachPosit + 1,
x_.end());
270 i = std::min(std::max(i - attachmentPoint, 0.), detachmentPoint - attachmentPoint);
292 QL_REQUIRE (d1.
dx_[0] == d2.
dx_[0],
"bucket sizes differ in d1 and d2");
293 for (
Size i = 1; i < d1.
size(); i++)
294 QL_REQUIRE (d1.
dx_[i] == d1.
dx_[i-1],
"bucket size varies in d1");
295 for (
Size i = 1; i < d2.
size(); i++)
296 QL_REQUIRE (d2.
dx_[i] == d2.
dx_[i-1],
"bucket size varies in d2");
299 QL_REQUIRE (d1.
xmin_ == 0.0 && d2.
xmin_ == 0.0,
300 "distributions offset larger than 0");
306 for (
Size i1 = 0; i1 < d1.
size(); i1++) {
308 for (
Size i2 = 0; i2 < d2.
size(); i2++)
314 for (
Size i = 0; i < dist.
size(); i++) {
330 QL_REQUIRE(percValue >= 0. && percValue <= 1.,
331 "Incorrect percentile");
336 if(iVal ==
size_-1)
return x_.back();
338 for (
int i = iVal; i <
size_; i++)
void tranche(Real attachmentPoint, Real detachmentPoint)
std::vector< Real > density_
std::vector< Real > excessProbability_
Real cumulativeDensity(Real x)
Real cumulativeExcessProbability(Real a, Real b)
Real confidenceLevel(Real quantil)
std::vector< int > count_
std::vector< Real > cumulativeDensity_
std::vector< Real > cumulativeExcessProbability_
Real trancheExpectedValue(Real a, Real d)
std::vector< Real > & x()
std::vector< Real > & dx()
void addDensity(int bucket, Real value)
Real expectedShortfall(Real percValue)
std::vector< Real > average_
void addAverage(int bucket, Real value)
static Distribution convolve(const Distribution &d1, const Distribution &d2)
QL_INTEGER Integer
integer number
std::size_t Size
size of a container
bool close(const Quantity &m1, const Quantity &m2, Size n)