Skip to contents

Returns a single point drawn uniformly from the spherical cap of axis \(\hat{\mu}\) and maximum planar angle \(\theta_0\) in dimension \(n\), using the O(n) algorithm of Arun & Venkatapathi (2025).

Usage

generate_cone_sample(mu_hat, theta0, method = c("inverse", "rejection"))

Arguments

mu_hat

Numeric vector. Central axis direction (will be normalized to unit vector).

theta0

Numeric. Maximum planar angle (cone half-angle) in radians, \(0 < \theta_0 \le \pi\).

method

Character. Method for generating planar angle: "inverse" for inverse transform sampling (default), or "rejection" for rejection sampling. Use "rejection" for numerical stability with large n and small \(\theta_0\).

Value

Numeric vector. Unit vector uniformly distributed on the spherical cap.

Details

The spherical cap is the set of unit vectors \(\hat{x}\) satisfying \(\hat{x} \cdot \hat{\mu} \ge \cos\theta_0\). The algorithm samples a random planar angle \(\theta \in [0, \theta_0]\) from the appropriate marginal distribution (generate_planar_angle_inverse or generate_planar_angle_rejection depending on method), draws a random point on the \((n-1)\)-sphere for the perpendicular component (generate_point_on_sphere), composes the canonical representation \(\hat{x} = \sin\theta \cdot \mathrm{perp} + \cos\theta \cdot \hat{e}_n\), and rotates the result to align \(\hat{e}_n\) with \(\hat{\mu}\) via rotate_from_canonical. The total cost is \(O(n)\) per sample.

References

Arun, I., & Venkatapathi, M. (2025). An O(n) algorithm for generating uniform random vectors in n-dimensional cones. Sankhya A: The Indian Journal of Statistics, 87(2), 327-348. doi:10.1007/s13171-025-00387-9

See also

generate_cone_samples for the vectorised C++-accelerated batch sampler; generate_hollow_cone_sample for the hollow- cone variant; verify_cone_uniformity for goodness-of-fit tests on the resulting samples; rejection_cost for the expected per-sample cost of the rejection variant.

Examples

# 30-degree cap around the z-axis in R^3
mu_hat <- c(0, 0, 1)
samples <- replicate(1000, generate_cone_sample(mu_hat, pi / 6))
summary(acos(samples[3, ]))     # cap-axis angles in [0, pi/6]
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#>  0.0124  0.2631  0.3689  0.3498  0.4544  0.5233 

# High dimension: use the rejection planar-angle generator
mu_hat_100d <- c(rep(0, 99), 1)
generate_cone_sample(mu_hat_100d, pi / 12, method = "rejection")
#>   [1]  2.165654e-03  2.737157e-02  4.771550e-02 -3.246124e-03  4.470982e-02
#>   [6] -3.565361e-02  9.863948e-03  3.724912e-02 -9.478066e-03 -1.483450e-02
#>  [11] -5.580486e-04 -9.215287e-03  5.047322e-03  9.406004e-03 -2.157529e-02
#>  [16] -2.035962e-02 -5.022154e-02 -4.233905e-02  6.404445e-05  3.998341e-02
#>  [21] -2.114430e-02  1.916251e-02  1.894475e-02  2.534573e-02  7.114902e-02
#>  [26] -4.018155e-02  2.030905e-03 -1.742624e-02  3.125488e-03  2.031583e-02
#>  [31] -3.041791e-02  9.273892e-03  3.400321e-03  8.467942e-03  1.159747e-02
#>  [36] -3.452720e-02  2.365519e-02 -6.411304e-04  1.757033e-02  3.352350e-02
#>  [41] -3.482176e-02 -4.788801e-03  3.124557e-02  2.893887e-03  2.862626e-02
#>  [46]  1.727168e-03  2.067664e-02 -1.586578e-02 -2.265890e-02 -2.597956e-02
#>  [51]  1.273299e-02  4.050435e-02  2.299778e-02 -2.456604e-03 -2.069528e-02
#>  [56] -1.149575e-02 -3.037743e-02 -3.734539e-02 -1.263590e-02 -2.045075e-02
#>  [61] -1.109519e-02  4.818618e-03  2.717746e-02  3.162033e-03 -4.990603e-02
#>  [66] -8.123262e-03  8.557226e-03 -2.943851e-02  6.031834e-03 -1.355745e-03
#>  [71]  3.012027e-02 -2.701522e-02  5.234762e-02 -1.514159e-02  8.960320e-03
#>  [76]  4.781797e-02  3.464497e-02 -1.587921e-02 -8.911850e-03  3.949949e-03
#>  [81]  5.822647e-03  3.142382e-04  3.317067e-02 -2.802916e-02  2.079756e-02
#>  [86] -1.400535e-02  4.734750e-02  2.735475e-02 -3.011533e-02 -1.707576e-02
#>  [91] -4.023621e-02  4.197483e-03 -6.253627e-02 -1.193154e-02 -1.766857e-02
#>  [96]  1.153212e-02  1.279554e-03 -3.494777e-02  1.238288e-03  9.661854e-01