vMF: von Mises-Fisher distribution

vMFR Documentation

von Mises–Fisher distribution

Description

Density and simulation of the von Mises–Fisher (vMF) distribution on \mathcal{S}^{p-1}:=\{\boldsymbol{x}\in \mathbb{R}^p:\|\boldsymbol{x}\|=1\}, p\ge 1. The density at \boldsymbol{x} \in \mathcal{S}^{p-1} is given by

c^{\mathrm{vMF}}_{p,\kappa} e^{\kappa\boldsymbol{x}' \boldsymbol{\mu}} \quad\mathrm{with}\quad c^{\mathrm{vMF}}_{p,\kappa}:= \kappa^{(p-2)/2}/((2\pi)^{p/2} I_{(p-2)/2}(\kappa))

where \boldsymbol{\mu}\in \mathcal{S}^{p-1} is the directional mean, \kappa\ge 0 is the concentration parameter about \boldsymbol{\mu}, and I_\nu is the order-\nu modified Bessel function of the first kind.

The angular function of the vMF is g(t) := e^{\kappa t}. The associated cosines density is \tilde g(v):= \omega_{p-1} c^{\mathrm{vMF}}_{p,\kappa} g(v) (1 - v^2)^{(p-3)/2}, where \omega_{p-1} is the surface area of \mathcal{S}^{p-2}.

Usage

d_vMF(x, mu, kappa, log = FALSE)

c_vMF(p, kappa, log = FALSE)

r_vMF(n, mu, kappa)

g_vMF(t, p, kappa, scaled = TRUE, log = FALSE)

r_g_vMF(n, p, kappa)

Arguments

x

locations in \mathcal{S}^{p-1} to evaluate the density. Either a matrix of size c(nx, p) or a vector of length p. Normalized internally if required (with a warning message).

mu

the directional mean \boldsymbol{\mu} of the vMF. A unit-norm vector of length p.

kappa

concentration parameter \kappa of the vMF. A nonnegative scalar. Can be a vector for c_vMF.

log

flag to indicate if the logarithm of the density (or the normalizing constant) is to be computed.

p

dimension of the ambient space \mathbb{R}^p that contains \mathcal{S}^{p-1}. A positive integer.

n

sample size, a positive integer.

t

a vector with values in [-1, 1].

scaled

whether to scale the angular function by the von Mises–Fisher normalizing constant. Defaults to TRUE.

Details

r_g_vMF implements algorithm VM in Wood (1994), except for p = 3, where the cosines density is the truncated exponential \propto e^{\kappa t} and is simulated exactly by inverse transform. c_vMF is vectorized on p and kappa.

Value

Depending on the function:

  • d_vMF: a vector of length nx or 1 with the evaluated density at x.

  • r_vMF: a matrix of size c(n, p) with the random sample.

  • c_vMF: the normalizing constant.

  • g_vMF: a vector of size length(t) with the evaluated angular function.

  • r_g_vMF: a matrix of size c(n, 1) containing simulated values from the cosines density associated to the angular function.

References

Wood, A. T. A. (1994) Simulation of the von Mises Fisher distribution. Commun. Stat. Simulat., 23(1):157–164. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1080/03610919408813161")}

See Also

tangent-vMF, unif, tang-norm-decomp.

Examples

# Simulation and density evaluation for p = 2
mu <- c(0, 1)
kappa <- 2
n <- 1e3
x <- r_vMF(n = n, mu = mu, kappa = kappa)
dens <- d_vMF(x = x, mu = mu, kappa = kappa)
col <- viridisLite::viridis(n)
r <- runif(n, 0.95, 1.05) # Radius perturbation to improve visualization
plot(r * x, pch = 16, col = col[rank(dens)])

# Simulation and density evaluation for p = 3
mu <- c(0, 0, 1)
kappa <- 2
x <- r_vMF(n = n, mu = mu, kappa = kappa)
dens <- d_vMF(x = x, mu = mu, kappa = kappa)
scatterplot3d::scatterplot3d(x, xlim = c(-1, 1), ylim = c(-1, 1),
                             zlim = c(-1, 1), color = col[rank(dens)],
                             pch = 16, xlab = "", ylab = "", zlab = "",
                             angle = 20)

# Cosines density
g_tilde <- function(t, p, kappa) {
  exp(w_p(p = p - 1, log = TRUE) +
        g_vMF(t = t, p = p, kappa = kappa, scaled = TRUE, log = TRUE) +
        ((p - 3) / 2) * log(1 - t^2))
}

# Simulated data from the cosines density
n <- 1e3
p <- 3
kappa <- 2
hist(r_g_vMF(n = n, p = p, kappa = kappa), breaks = seq(-1, 1, l = 20),
     probability = TRUE, main = "Simulated data from g_vMF", xlab = "t")
t <- seq(-1, 1, by = 0.01)
lines(t, g_tilde(t = t, p = p, kappa = kappa))

# Cosine density as a function of the dimension
M <- 100
col <- viridisLite::viridis(M)
plot(t, g_tilde(t = t, p = 2, kappa = kappa), col = col[2], type = "l",
     ylab = "Density")
for (p in 3:M) {
  lines(t, g_tilde(t = t, p = p, kappa = kappa), col = col[p])
}

rotasym documentation built on July 26, 2026, 9:06 a.m.