Back to Geometrically-distributed random numbers
#ifndef PASTELSYS_RANDOM_GEOMETRIC_HPP
#define PASTELSYS_RANDOM_GEOMETRIC_HPP
#include "pastel/sys/random/random_geometric.h"
#include "pastel/sys/random/random_uniform.h"
#include <cmath>
namespace Pastel
{
template <typename Real>
integer randomGeometric(
const NoDeduction<Real>& success)
{
PENSURE(success > 0);
PENSURE(success < 1);
// Generates an exponentially distributed
// random number, and rounds it down.
return std::log(randomOpen0<Real>()) /
std::log(1 - success);
}
template <typename Real>
Real geometricPdf(
const NoDeduction<Real>& k,
const NoDeduction<Real>& success)
{
PENSURE(k >= 0);
PENSURE(success > 0);
PENSURE(success < 1);
// The probability of having a k consecutive
// failures before the first success in a
// Bernoulli process is
//
// P(X = k) = (1 - p)^k p.
// Note that when success is either 0 or 1,
// P is not a probability mass function.
return std::pow(1 - success, k) * success;
}
template <typename Real>
Real geometricCdf(
const NoDeduction<Real>& k,
const NoDeduction<Real>& success)
{
PENSURE(k >= 0);
PENSURE(success > 0);
PENSURE(success < 1);
// The probability of having at most k
// consecutive failures before the first
// success in a Bernoulli process is
//
// P(X <= k)
// = sum_{i = 0}^k P(X = i)
// = sum_{i = 0}^k (1 - p)^i p
// = p sum_{i = 0}^k (1 - p)^i
// = p (1 - (1 - p)^{k + 1}) / (1 - (1 - p))
// = 1 - (1 - p)^{k + 1}.
return 1 - std::pow(1 - success, k + 1);
}
}
#endif