# libbingham C Tutorial

## Contents

## What is a Bingham Distribution?

The Bingham distribution is an antipodally-symmetric probability distribution on a unit hypersphere. Its probability density function (PDF) is

where is a unit vector on the surface of the sphere , is a normalization constant, is a vector of non-positive ( ) concentration parameters, and the columns of the matrix are orthogonal unit vectors.

Note that a large-magnitude indicates that the distribution is highly peaked along the direction , while a small-magnitude indicates that the distribution is spread out along .

The Bingham distribution is derived from a zero-mean Gaussian on , conditioned to lie on the surface of the unit hypersphere . Thus, the exponent of the Bingham PDF is the same as the exponent of a zero-mean Gaussian distribution (in principal components form, with one of the eigenvalues of the covariance matrix set to infinity).

The Bingham distribution is the
*maximum entropy
* distribution on the hypersphere which matches the sample inertia matrix
. Therefore, it may be better suited to representing random process noise on the hypersphere than some other distributions, such as (projected) tangent-space Gaussians. Binghams are also quite flexible, since a concentration parameter,
, of zero indicates that the distribution is completely uniform in the direction of
. They are therefore very useful in tracking problems where there is high, anisotropic noise.

## C Support in libbingham / Installation

In bingham/c, run:

make sudo make install

The main C header file in libbingham is located at bingham/c/include/bingham.h. Most functions only support Bingham distributions up to dimension 4. (That is, up to .)

## Usage / Examples

After installation, to use the libbingham in your own project, add "*-lbingham*" to your linker flags include *bingham.h* at the top of your program.
There are several example programs in bingham/c:
bingham_sample.c,
fit_bingham.c,
bingham_lookup.c,
cluster_bingham.c, and
test_bingham.c.

## Creating a Bingham Distribution in C

Bingham distributions are represented as a C struct, called *bingham_t*:

typedef struct { int d; // dimensions double **V; // axes double *Z; // concentrations double F; // normalization constant bingham_stats_t *stats; } bingham_t;

The *bingham_stats_t* struct contains various statistics of the Bingham distribution, such as the entropy, mode, and scatter matrix.
(See bingham.h for details.)
To create a new *bingham_t*, use one of

void bingham_new(bingham_t *B, int d, double **V, double *Z); void bingham_new_uniform(bingham_t *B, int d); void bingham_new_S1(bingham_t *B, double *v1, double z1); void bingham_new_S2(bingham_t *B, double *v1, double *v2, double z1, double z2); void bingham_new_S3(bingham_t *B, double *v1, double *v2, double *v3, double z1, double z2, double z3);

For example,

bingham_t B; bingham_new_uniform(&B, 4);

will create a new uniform 4-D Bingham distribution, as will

double Z[3] = {0, 0, 0}; double V[3][4] = {{0,1,0,0}, {0,0,1,0}, {0,0,0,1}}; double *Vp[3] = {&V[0][0], &V[1][0], &V[2][0]}; bingham_t B; bingham_new(&B, 4, Vp, Z);

or

double v1[4] = {0,1,0,0}; double v2[4] = {0,0,1,0}; double v3[4] = {0,0,0,1}; bingham_t B; bingham_new(&B, 4, v1, v2, v3, 0, 0, 0);

Note that all of the *bingham_new* functions will automatically compute the normalization constant,
so there is no need to call *bingham_F(bingham_t *B)* unless you create the *bingham_t* manually.

**Note:** When you are finished using a *bingham_t*, be sure to free its contents with

void bingham_free(bingham_t *B);

## Fitting

Given a matrix *X* with unit vectors in the rows, you can compute the maximum likelihood Bingham distribution given *X* with

void bingham_fit(bingham_t *B, double **X, int n, int d);

where *X* is an *n-by-d* double matrix created by:

double **new_matrix2(int n, int m);

which can be found in bingham/c/include/bingham/util.h. For example,

// create n 4-D unit vectors int n = 10; double **X = new_matrix2(n,4); for (int i = 0; i < n; i++) { for (int j = 0; j < 4; j++) X[i][j] = normrand(0,1); normalize(X[i], X[i], 4); } // fit a Bingham distribution to X bingham_t B; bingham_fit(&B, X, n, 4); // do something with B here... // cleanup free_matrix2(X); bingham_free(&B);

**Note:** *bingham_fit()* allocates memory in the *bingham_t* struct, so make sure the *bingham_t*
you pass in is deallocated. Otherwise, calling *bingham_fit()* will result in a memory leak.

## Sampling

To sample *n* unit vectors from a Bingham distribution, use:

void bingham_sample(double **X, bingham_t *B, int n);

For example,

bingham_t B; bingham_new_uniform(&B, 4); double **X = new_matrix2(100,4); bingham_sample(X, &B, 100);

## Computing the PDF

To compute the PDF of a unit vector *x* under a Bingham *B*, use:

double bingham_pdf(double *x, bingham_t *B);

For example, assuming *bingham_t B* exists with *B.d = 4*,

double x[4] = {0,1,0,0}; double f = bingham_pdf(x, &B);