xo-tokenizer2/include/xo/distribution/Exponential.hpp

94 lines
2.9 KiB
C++

/* @file Exponential.hpp */
#pragma once
#include "xo/distribution/Distribution.hpp"
#include <limits>
#include <cmath>
namespace xo {
namespace distribution {
/* Exponential probability distribution */
class Exponential : public Distribution<double> {
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<double>::infinity();
if(Fx >= 1.0)
return +1.0 * std::numeric_limits<double>::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<double> -----
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 */