Estimates

\[\int_{-\inf}^{\inf} \text{ExpFam}(\theta, g(x)) \mathcal{N} (x | \mu, \sigma^2) \mathrm d x\]

via a very fast and deterministic numerical integration.

Installยถ

You can install it via conda

conda install -c conda-forge liknorm

or by building it yourself via the following command:

# DO_CMD=sudo
curl -fsSL https://git.io/JerYI | GITHUB_USER=horta GITHUB_PROJECT=logaddexp bash
curl -fsSL https://git.io/JerYI | GITHUB_USER=limix GITHUB_PROJECT=liknorm bash

The above command should work on Windows, Linux, and MacOS.

Introductionยถ

The single-parameter exponential family is a class of distributions that can be expressed as:

f(y; ฮธ, ๐œ™) = exp{(yฮธ - b(ฮธ))/a(๐œ™) + c(y,๐œ™)}.

for which ๐œ™ is assumed to be known. The definition of the functions a(.), b(.), and c(.) determines a probabilistic distribution having the canonical parameter ฮธ. The expectation of y, denoted here by ๐œ‡, determines the value of ฮธ via the following relation:

b'(ฮธ) = ๐œ‡

Still, the value ๐œ‡ is often set indirectly via the natural parameter ฮท, which relates to each other through a link function g(.):

ฮท = g(๐œ‡)

If g(.) is the so-called canonical function, we have the desirable equality:

ฮธ = ฮท

Usage exampleยถ

Suppose you have the file

/* example.c */
#include "liknorm.h"

#include <stdio.h>

int main()
{
  double log_zeroth, mean, variance;
  double prior_var = 2.5;
  double prior_mean = -2.0;
  double nsuccesses = 2;
  double ntrials = 15;

  struct LikNormMachine *machine = liknorm_create_machine(500);

  liknorm_set_binomial(machine, nsuccesses, ntrials);
  liknorm_set_prior(machine, 1 / prior_var, prior_mean / prior_var);

  liknorm_integrate(machine, &log_zeroth, &mean, &variance);

  printf("%f\n", log_zeroth);
  printf("%f\n", mean);
  printf("%f\n", variance);

  liknorm_destroy_machine(machine);
}

Compiling, linking, and running it via

cc libliknorm.a example.c -o example
./example

should print:

-2.049961
-2.038184
0.524308

Interfaceยถ

Liknorm machineยถ

LIKNORM_API void liknorm_integrate(struct LikNormMachine * machine, double * log_zeroth, double * mean, double * variance)

Perform numerical integration.

Parameters
  • machine: Machine to perform integration.

  • log_zeroth: Zeroth moment.

  • log_mean: First moment of the normalized distribution.

  • log_variance: Variance of the normalized distribution.

LIKNORM_API void liknorm_destroy_machine(struct LikNormMachine * machine)

Destroy a Machine instance.

Parameters
  • machine: Machine to be destroyed. Always call it before exiting your program, otherwise it will leak memory.

Priorยถ

LIKNORM_API void liknorm_set_prior(struct LikNormMachine * machine, double tau, double eta)

Set the natural parameters of Normal prior.

Parameters
  • machine: Machine to perform integration.

  • tau: It equals to ฯƒโปยฒ.

  • eta: It equals to ฮผฯƒโปยฒ.

Bernoulliยถ

LIKNORM_API void liknorm_set_bernoulli(struct LikNormMachine * machine, double k)

Bernoulli distribution.

It is the discrete probability distribution of a random variable which takes the value 1 with probability p and the value 0 with probability 1 โˆ’ p. (Wikipedia.)

Parameters
  • machine: Liknorm handler.

  • k: Number of successes.

Binomialยถ

LIKNORM_API void liknorm_set_binomial(struct LikNormMachine * machine, double k, double n)

Binomial distribution.

It is the discrete probability distribution of the number of successes k in a sequence of n independent experiments. (Wikipedia.) The probability mass function is given by:

Binom(k, n) pแต (1 - p)โฟโปแต,

for which Binom(m, n) = n! / (m! (n - m)!).

Parameters
  • machine: Liknorm handler.

  • k: Number of successes.

  • n: Number of trials.

Gammaยถ

LIKNORM_API void liknorm_set_gamma(struct LikNormMachine * machine, double x, double a)

Gamma distribution.

A gamma distribution is a general type of statistical distribution that is related to the beta distribution and arises naturally in processes for which the waiting times between Poisson distributed events are relevant. (Wolfram.)

Parameters
  • machine: Liknorm handler.

  • x: Waiting time.

  • a: Shape parameter ฮฑ.

Geometricยถ

LIKNORM_API void liknorm_set_geometric(struct LikNormMachine * machine, double x)

Geometric distribution.

Parameters
  • machine: Liknorm handler.

  • x: Number of trials to success.

Negative binomialยถ

LIKNORM_API void liknorm_set_nbinomial(struct LikNormMachine * machine, double k, double r)

Negative binomial distribution.

It is a discrete probability distribution of the number of successes in a sequence of independent and identically distributed Bernoulli trials before a specified (non-random) number of failures (denoted r) occurs. (Wikipedia.) Let k be the number of successes. The probability mass function is given by:

Binom(k, k + r - 1) pแต (1 - p)สณ,

for which Binom(m, n) = n! / (m! (n - m)!).

Parameters
  • machine: Liknorm handler.

  • k: Number of successes.

  • r: Number of failures.

Poissonยถ

LIKNORM_API void liknorm_set_poisson(struct LikNormMachine * machine, double k)

Poisson distribution.

It is a discrete probability distribution that expresses the probability of a given number of events occurring in a fixed interval of time or space if these events occur with a known constant rate and independently of the time since the last event. (Wikipedia.) The probability mass function is given by:

ฮปแตe^{-ฮป} / k!,

for which ฮป is the rate of occurrence and k the number of occurrences.

Parameters
  • machine: Liknorm handler.

  • k: Number of occurrences.

Implementationยถ

ExpFamยถ

struct ExpFamยถ

Exponential family of distributions.

We adopt the following representation::

f(y; ฮธ, ๐œ™) = exp{(yฮธ - b(ฮธ))/a(๐œ™) + c(y,๐œ™)},

for which::

y     : random variable value.
ฮธ     : canonical parameter.
๐œ™     : nuisance parameter.
a(๐œ™)  :
b(ฮธ)  : log-partition function.
c(y,๐œ™): normaliser.

The mean and variance are given by::

E[y]   = b'(ฮธ)
Var[y] = b''(ฮธ)a(๐œ™)

In order to define a generalised linear mixed model (GLMM) we use the so-called natural parameter ฮท. Given a link function g(.), the natural parameter relates to the canonical parameter as follows::

ฮท = g(E[y]) = g(b'(ฮธ)).

Every member of the exponential family has a canonical link function, which greatly simplifies the relationship::

ฮท = ฮธ

Public Members

double yยถ

Random variable value

double aยถ

a(๐œ™)

double logaยถ

log(a(๐œ™))

double cยถ

c(y,๐œ™)

log_partition *lpยถ

b(ฮธ)

log_partition_fderivative *lpfdยถ

log(b'(ฮธ))

log_partition_derivatives *lpdยถ

log(b''(ฮธ))

Likelihoodยถ

We assume the canonical link function for every likelihood.

Bernoulliยถ

y assumes 1 or 0 for failure. We make use of the Binomial implementation. So, please, refer to the next section for details.

static double bernoulli_log_partition(const double theta)ยถ

Bernoulli log-partition function.

Please, refer to the binomial_log_partition() function.

static double bernoulli_log_partition_fderivative(const double theta)ยถ

First derivative of the Bernoulli log-partition function.

Please, refer to the binomial_log_partition_fderivative() function.

static void bernoulli_log_partition_derivatives(const double theta, double *b0, double *logb1, double *logb2)ยถ

Zeroth, first, and second derivatives of the Bernoulli log-partition function.

Please, refer to the bernoulli_log_partition_fderivative() function.

Binomialยถ

The random variable is given by y = k/n. The support is therefore y ฯต {0/n, 1/n, ..., r/n}. The exponential family functions are:

๐œ™      = n
a(๐œ™)   = 1/๐œ™
b(ฮธ)   = log(1 + exp(ฮธ))
c(y,๐œ™) = log(binom(n, y๐œ™))

Let us define:

๐œ‡ = E[y] = p.

The canonical link function and its inverse are given by:

canonical(๐œ‡)     = log(๐œ‡/(1+๐œ‡)) = ฮท
canonical_inv(ฮท) = 1/(1 + exp(-ฮท))
double binomial_log_partition(const double theta)ยถ

Binomial log-partition function.

Definition:

b(๐œƒ) = log(1 + exp(๐œƒ)).

double binomial_log_partition_fderivative(const double theta)ยถ

First derivative of the Binomial log-partition function.

Definition:

log(b'(๐œƒ)) = ๐œƒ - log(1 + exp(๐œƒ))

void binomial_log_partition_derivatives(const double theta, double *b0, double *logb1, double *logb2)ยถ

Zeroth, first, and second derivatives of the Binomial log-partition function.

Implements b(๐œƒ), log(b'(๐œƒ)), and:

log(b''(๐œƒ)) = ๐œƒ - 2log(1 + exp(๐œƒ))

Negative Binomialยถ

The random variable is given by y = k/r. The support is therefore y ฯต {0/r, 1/r, ..., r/r}. The exponential family functions are:

๐œ™ = r
a(๐œ™) = 1/๐œ™
b(ฮธ) = -log(1 - exp(ฮธ))
c(y,๐œ™) = log(binom(y๐œ™ + ๐œ™ - 1, y๐œ™))

Let us define:

๐œ‡ = E[y] = p / (1 - p)

The canonical link function and its inverse are given by:

canonical(๐œ‡)     = log(๐œ‡ / (1 + ๐œ‡)) = ฮท
canonical_inv(ฮท) = exp(ฮท) / (1 - exp(ฮท))
double nbinomial_log_partition(const double theta)ยถ

Negative binomial log-partition function.

Definition:

b(๐œƒ) = -log(1 - exp(๐œƒ)).

double nbinomial_log_partition_fderivative(const double theta)ยถ

First derivative of the Negative Binomial log-partition function.

Definition:

log(b'(๐œƒ)) = ๐œƒ - log(1 - exp(๐œƒ)).

void nbinomial_log_partition_derivatives(const double theta, double *b0, double *logb1, double *logb2)ยถ

Zeroth, first, and second derivatives of the Negative Binomial log-partition func.

Implements b(๐œƒ), log(b'(๐œƒ)), and:

log(b''(๐œƒ)) = ๐œƒ - 2log(1 - exp(๐œƒ))

Poissonยถ

The support is y ฯต {0, 1, ...}. The exponential family functions are:

๐œ™      = 1
a(๐œ™)   = ๐œ™
b(๐œƒ)   = exp(๐œƒ)
b'(๐œƒ)  = exp(๐œƒ)
b'(๐œƒ)  = exp(๐œƒ)
c(y,๐œ™) = -log(y!)

Let us define:

๐œ‡ = E[y] = ฮป,

for which ฮป is the Poisson distribution parameter. The canonical link function and its inverse are given by:

canonical(๐œ‡)     = log(๐œ‡ / (1 + ๐œ‡)) = ฮท
canonical_inv(ฮท) = exp(ฮท) / (1 - exp(ฮท))
double poisson_log_partition(const double theta)ยถ

Poisson log-partition function.

Definition:

b(๐œƒ) = exp(๐œƒ)

double poisson_log_partition_fderivative(const double theta)ยถ

Log of the first derivative of the Poisson log-partition function.

Definition:

log(b'(๐œƒ)) = ๐œƒ

void poisson_log_partition_derivatives(const double theta, double *b0, double *logb1, double *logb2)ยถ

Log of the derivatives of the Poisson log-partition function.

Implements b(๐œƒ), log(b'(๐œƒ)), and:

log(b''(๐œƒ)) = ๐œƒ

Comments and bugsยถ

You can get the source and open issues on Github.