20template <
typename RealType>
37 [[nodiscard]]
double f(
const RealType &x)
const override;
38 [[nodiscard]]
double logf(
const RealType &x)
const override;
39 [[nodiscard]]
double F(
const RealType &x)
const override;
40 [[nodiscard]]
double S(
const RealType &x)
const override;
42 template <std::uniform_random_bit_generator G>
46 RealType quantileImpl(
double p)
const override;
47 RealType quantileImpl1m(
double p)
const override;
49 std::complex<double> CFImpl(
double t)
const override;
52 [[nodiscard]]
long double Entropy()
const;
63template <
typename RealType>
72 [[nodiscard]] std::string
Name()
const override;
89template <
typename RealType>
98 [[nodiscard]]
inline double GetShift() const noexcept {
return this->
m; }
116template <
typename RealType>
124 [[nodiscard]] std::string
Name()
const override;
126 template <std::uniform_random_bit_generator G>
132 DoublePair getOneSidedSums(std::span<const RealType> sample);
148template <
typename RealType>
155 [[nodiscard]] std::string
Name()
const override;
156 template <std::uniform_random_bit_generator G>
169template <
typename RealType>
177template <
typename RealType>
180 this->SetLocation((1.0 - this->kappaSq) * this->gamma * this->kappaInv);
183template <
typename RealType>
187 throw std::invalid_argument(
"Laplace distribution: scale should be positive, but it's equal to " +
188 std::to_string(scale));
193template <
typename RealType>
196 return this->pdfLaplace(x - this->m);
199template <
typename RealType>
202 return this->logpdfLaplace(x - this->m);
205template <
typename RealType>
208 return this->cdfLaplace(x - this->m);
211template <
typename RealType>
214 return this->cdfLaplaceCompl(x - this->m);
217template <
typename RealType>
218template <std::uniform_random_bit_generator G>
223 return this->m + this->gamma * X;
226template <
typename RealType>
229 if (this->kappa == 1) {
230 for (RealType &var : outputData)
231 var = this->m + this->gamma *
LaplaceRand<RealType>::StandardVariate(g);
233 for (RealType &var : outputData)
234 var = this->m + this->gamma * AsymmetricLaplaceRand<RealType>::StandardVariate(this->kappa, g);
238template <
typename RealType>
239std::complex<double> AsymmetricLaplaceDistribution<RealType>::CFImpl(
double t)
const
241 double bt = this->gamma * t;
242 double btSq = bt * bt;
243 double denominator = (1 + this->kappaSq * btSq) * (1 + btSq / this->kappaSq);
244 std::complex<double> y(std::cos(this->m * t), std::sin(this->m * t));
245 std::complex<double> x(1, -this->kappa * bt), z(1, bt * this->kappaInv);
246 return x * y * z / denominator;
249template <
typename RealType>
250RealType AsymmetricLaplaceDistribution<RealType>::quantileImpl(
double p)
const
252 return this->quantileLaplace(p);
255template <
typename RealType>
256RealType AsymmetricLaplaceDistribution<RealType>::quantileImpl1m(
double p)
const
258 return this->quantileLaplace1m(p);
261template <
typename RealType>
264 double y = this->kappaInv + this->kappa;
265 return 1.0 + std::log(this->gamma * y);
268template <
typename RealType>
271 double deviation = 0.0;
272 for (
const RealType &x : sample) {
274 deviation += this->kappa * (x - this->m);
276 deviation -= (x - this->m) / this->kappa;
278 deviation /= sample.size();
282template <
typename RealType>
287 double minVar = *std::min_element(sample.begin(), sample.end());
288 double maxVar = *std::max_element(sample.begin(), sample.end());
289 if (minVar == maxVar) {
290 this->SetShift(minVar);
294 [
this, sample](
double med) {
296 for (
const RealType &x : sample) {
306 this->SetShift(median);
309template <
typename RealType>
312 this->FitShift(sample);
313 this->FitScale(sample);
315template <
typename RealType>
318 return "Centered Asymmetric-Laplace(" + this->toStringWithPrecision(this->GetScale()) +
", " +
319 this->toStringWithPrecision(this->GetAsymmetry()) +
")";
322template <
typename RealType>
325 return {std::max<double>(x, 0.0), std::max<double>(-x, 0.0)};
328template <
typename RealType>
331 return {this->GetScale(), this->GetAsymmetry()};
334template <
typename RealType>
337 double scale = sourceParameters.first, asymmetry = sourceParameters.second;
338 return {-asymmetry / scale, -1.0 / (scale * asymmetry)};
341template <
typename RealType>
344 return std::log(-1.0 / theta.first - 1.0 / theta.second);
347template <
typename RealType>
350 double sum = -1.0 / theta.first - 1.0 / theta.second;
351 return {1.0 / (theta.first * theta.first * sum), 1.0 / (theta.second * theta.second * sum)};
354template <
typename RealType>
359template <
typename RealType>
362 return "Asymmetric-Laplace(" + this->toStringWithPrecision(this->GetShift()) +
", " +
363 this->toStringWithPrecision(this->GetScale()) +
", " + this->toStringWithPrecision(this->GetAsymmetry()) +
367template <
typename RealType>
371 this->ChangeLocation();
374template <
typename RealType>
375template <std::uniform_random_bit_generator G>
383template <
typename RealType>
386 double xPlus = 0.0, xMinus = 0.0;
387 for (
const RealType &x : sample) {
389 xMinus += (x - this->m);
391 xPlus += (x - this->m);
396template <
typename RealType>
399 auto [xPlus, xMinus] = getOneSidedSums(sample);
400 double gammaN = this->gamma * sample.size();
401 double asymmetry = 0;
405 asymmetry = -xMinus / gammaN;
406 else if (xMinus == 0) {
407 asymmetry = gammaN / xPlus;
410 double a = xPlus / gammaN;
411 double c = (xPlus + xMinus) / gammaN;
412 double e = xMinus / gammaN;
415 double delta1 = 2 * std::pow(c, 3) + 9 * c + 27 * (a + e) - 72 * ae * c;
416 double delta0 = c * c + 3 + 12 * ae;
417 double p2 = delta1 + std::sqrt(delta1 * delta1 - 4 * std::pow(delta0, 3));
418 double Q = std::cbrt(0.5 * p2);
419 double temp = 8 * a * a;
420 double p = (8 * a * c - 3.0) / temp;
421 double q = (-1.0 + 4 * a * c + temp) / (a * temp);
422 double S = 0.5 * std::sqrt(-2.0 / 3 * p + (Q + delta0 / Q) / (3 * a));
424 double c1 = -0.25 / a, b1 = -4 * S * S - 2 * p, b2 = q / S;
426 asymmetry = c1 + S + 0.5 * std::sqrt(b1 + b2);
428 asymmetry = c1 - S + 0.5 * std::sqrt(b1 - b2);
431 SetAsymmetry(asymmetry);
433template <
typename RealType>
436 return "Laplace(" + this->toStringWithPrecision(this->GetShift()) +
", " +
437 this->toStringWithPrecision(this->GetScale()) +
")";
440template <
typename RealType>
441template <std::uniform_random_bit_generator G>
The AsymmetricLaplaceDistribution class Abstract parent class for general Laplace and Asymmetric La...
Definition laplace.hpp:22
double GetAsymmetry() const noexcept
Definition laplace.hpp:35
void SetScale(double scale)
Definition laplace.hpp:184
double F(const RealType &x) const override
Definition laplace.hpp:206
void FitScale(std::span< const RealType > sample)
Definition laplace.hpp:269
void ChangeLocation()
Definition laplace.hpp:178
long double Entropy() const
Definition laplace.hpp:262
double logf(const RealType &x) const override
Definition laplace.hpp:200
double S(const RealType &x) const override
Definition laplace.hpp:212
AsymmetricLaplaceDistribution(double shift=0, double scale=1, double asymmetry=1)
Definition laplace.hpp:170
RealType operator()(G &g) const
Definition laplace.hpp:219
double f(const RealType &x) const override
Definition laplace.hpp:194
The AsymmetricLaplaceRand class Asymmetric Laplace distribution.
Definition laplace.hpp:118
static RealType StandardVariate(double asymmetry, G &g)
Definition laplace.hpp:376
void FitAsymmetry(std::span< const RealType > sample)
Definition laplace.hpp:397
std::string Name() const override
Definition laplace.hpp:360
void SetAsymmetry(double asymmetry)
Definition laplace.hpp:368
AsymmetricLaplaceRand(double shift=0, double scale=1, double asymmetry=1)
Definition laplace.hpp:120
static int StandardVariate(G &g)
Definition bernoulli.hpp:106
The CenteredAsymmetricLaplaceRand class Centered Laplace distribution.
Definition laplace.hpp:66
DoublePair SourceParameters() const override
Definition laplace.hpp:329
DoublePair LogNormalizerGradient(DoublePair theta) const override
Definition laplace.hpp:348
double LogNormalizer(DoublePair theta) const override
Definition laplace.hpp:342
DoublePair SufficientStatistic(RealType x) const override
Sufficient statistic (max(x, 0), max(-x, 0)) with natural parameters (-κ/γ, -1/(γκ))
Definition laplace.hpp:323
double CarrierMeasure(RealType) const override
Definition laplace.hpp:355
std::string Name() const override
Definition laplace.hpp:316
DoublePair SourceToNatural(DoublePair sourceParameters) const override
Definition laplace.hpp:335
CenteredAsymmetricLaplaceRand(double scale=1, double asymmetry=1)
Definition laplace.hpp:68
Definition exponential_family.hpp:14
The GeneralGeometricStableDistribution class Abstract class for general interface of Asymmetric Lapla...
Definition geometric_stable.hpp:19
void SetAsymmetry(double asymmetry)
Definition geometric_stable.hpp:260
double m
shift m
Definition geometric_stable.hpp:30
void SetShift(double shift)
Definition geometric_stable.hpp:242
double kappa
parameters for α = 2
Definition geometric_stable.hpp:35
void SetScale(double scale)
Definition geometric_stable.hpp:250
The LaplaceRand class Laplace distribution.
Definition laplace.hpp:150
LaplaceRand(double shift=0, double scale=1)
Definition laplace.hpp:152
void Fit(std::span< const RealType > sample)
Definition laplace.hpp:158
std::string Name() const override
Definition laplace.hpp:434
static RealType StandardVariate(G &g)
Definition laplace.hpp:442
The ShiftedAsymmetricLaplaceDistribution class Abstract parent class for shifted Laplace and Asymme...
Definition laplace.hpp:91
void FitShiftAndScale(std::span< const RealType > sample)
Definition laplace.hpp:310
void FitShift(std::span< const RealType > sample)
Definition laplace.hpp:283
ShiftedAsymmetricLaplaceDistribution(double shift=0, double scale=1, double asymmetry=1)
Definition laplace.hpp:93
double GetShift() const noexcept
Definition laplace.hpp:98
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
#define RANDLIB_DETAIL_SUPPRESS_DEPRECATED_END
Definition fwd.hpp:26
#define RANDLIB_DETAIL_SUPPRESS_DEPRECATED_BEGIN
Definition fwd.hpp:25
#define RANDLIB_DEPRECATED_FIT_MEMBER
Definition fwd.hpp:9
Real standardNormal(G &g)
Ziggurat algorithm of Marsaglia and Tsang with 256 layers and an explicit sign bit.
Definition variates.hpp:45
Real findRoot(const F &f, std::type_identity_t< Real > a, std::type_identity_t< Real > b, int maxIterations=200)
Definition roots.hpp:205
Definition bivariate_normal.hpp:10
Pair< double > DoublePair
Definition fwd.hpp:39