/* @file Exponential.hpp */ #pragma once #include "xo/distribution/Distribution.hpp" #include #include namespace xo { namespace distribution { /* Exponential probability distribution */ class Exponential : public Distribution { public: explicit Exponential(double lm) : lambda_(lm) {} /* exponential probability density: * * -lm.x * p(x) = { lm . e , x > 0 * { 0 , x <= 0 * */ static double density_impl(double lambda, double x) { if(x <= 0.0) return 0.0; return lambda * ::exp(-lambda * x); } /*density_impl*/ /* exponential distribution: * * -lm.x * F(x) = 1 - e , x > 0 * F(x) = 0 , x <= 0 */ static double distr_impl(double lambda, double x) { if(x <= 0.0) return 0.0; return 1.0 - ::exp(-lambda * x); } /*distr_impl*/ /* compute x: F(x)=y, where F(x) * is the cumulative exponential probability distributio. * * -lm.x * F(x) = 1 - e , x>0 * * -lm.x * e = 1 - F(x) * * -lm.x = ln(1 - F(x)) * * x = -ln(1 - F(x)) / lm, 0 < F(x) < 1 */ static double distr_inverse_impl(double lambda, double Fx) { if(Fx < 0.0) return -1.0 * std::numeric_limits::infinity(); if(Fx >= 1.0) return +1.0 * std::numeric_limits::infinity(); return (-1.0 / lambda) * ::log(1.0 - Fx); } /*distr_inverse_impl*/ double lambda() const { return lambda_; } double density(double x) const { return density_impl(this->lambda_, x); } /*density*/ double distribution(double x) const { return distr_impl(this->lambda_, x); } /*distribution*/ double distribution_inverse(double y) const { return distr_inverse_impl(this->lambda_, y); } /*distribution_inverse*/ // ----- inherited from Distribution ----- virtual double cdf(double const & x) const override { return distribution(x); } /*cdf*/ private: /* intensity parameter. * require: lambda > 0 */ double lambda_ = 1.0; }; /*Exponential*/ } /*namespace distribution*/ } /*namespace xo*/ /* end Exponential.cpp */