Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Von Mises Distribution

#include <boost/math/distributions/von_mises.hpp>
namespace boost{ namespace math{
 template <typename RealType = double,
           typename Policy   = policies::policy<> >
 class von_mises_distribution;

 using von_mises = von_mises_distribution<>;

 template <typename RealType, typename Policy>
 class von_mises_distribution
 {
 public:
    using value_type = RealType;
    using policy_type = Policy;

    explicit von_mises_distribution(RealType mean = 0, RealType concentration = 1);

    RealType mean() const;
    RealType concentration() const;
    RealType location() const;
    RealType scale() const;
 };

}} // namespaces

The von Mises distribution, also known as the circular normal distribution, is a continuous probability distribution of an angle. With mean μ and concentration κ its probability density function is

f(x; μ, κ) = eκ cos(x - μ) / (2π I0(κ))

for μ - π <= x <= μ + π, where I0 is the modified Bessel function of the first kind. With κ = 0 it is the uniform distribution on the circle, and as κ grows it approaches a normal distribution with variance 1/κ.

Member Functions
explicit von_mises_distribution(RealType mean = 0, RealType concentration = 1);

Constructs a von Mises distribution with mean mean and concentration concentration.

Requires that mean is finite and that concentration is finite and non-negative; otherwise calls domain_error.

RealType mean() const;
RealType location() const;

Return the mean parameter of this distribution.

RealType concentration() const;
RealType scale() const;

Return the concentration parameter of this distribution.

Non-member Accessors

All the usual non-member accessor functions that are generic to all distributions are supported: Cumulative Distribution Function, Probability Density Function, Quantile, Hazard Function, Cumulative Hazard Function, __logcdf, __logpdf, mean, median, mode, variance, standard deviation, skewness, kurtosis, kurtosis_excess, range and support.

The support is one turn centred on the mean, μ - π <= x <= μ + π. Outside it the pdf is zero and the cdf is 0 or 1.

The mean, median and mode are all μ, and the skewness is zero. The moments are those of circular statistics: variance returns the circular variance 1 - I1(κ)/I0(κ), and standard_deviation returns the circular standard deviation √(-2 ln(I1(κ)/I0(κ))), so the standard deviation is not the square root of the variance. With zero concentration the circular standard deviation is infinite, and standard_deviation calls overflow_error.

Accuracy

The pdf and cdf have full relative accuracy in both tails, at any precision, apart from the growth of error inherent in exp(κ cos(x - μ)) when κ is large. The plots below compare double against cpp_bin_float_50, with the condition number of the function drawn as an envelope; they are generated by reporting/accuracy/von_mises_ulps.cpp.

Implementation

The normalization e-κI0(κ) is computed from cyl_bessel_i, or from its asymptotic series when eκ would overflow.

For x <= μ the cdf is

F(x) = e-2κ sin2(a/2) / (2π e-κI0(κ)) ∫0π-a e-2κ sin(a + s/2) sin(s/2) ds

with a = μ - x. The integrand is positive, so there is no cancellation in the left tail, and it decays like e-κ s sin(a), so the range is cut where it falls below machine epsilon. Up to double precision the integral is evaluated with a 30-point Gauss-Legendre rule, and beyond that with tanh-sinh quadrature. For x > μ the cdf is 1 - F(2μ - x), and the complement follows by symmetry.

The circular variance is computed as e-κ(I0(κ) - I1(κ)) / e-κI0(κ), never as a difference of the Bessel functions: for moderate κ both are integrals of positive functions over a full period, which the trapezoidal rule evaluates to geometric accuracy, and for large κ every term of their asymptotic series is positive.

The quantile is found by Newton iteration on the cdf, starting from the normal approximation.

References

PrevUpHomeNext