eqsp package

Module contents

PyEQSP: Python Equal Area Sphere Partitioning Library.

This module provides functions for equal area sphere partitioning, including: - Creating partitions (eq_regions, eq_point_set, eq_caps) - Calculating properties (point_set_props, region_props) - Utilities (utilities) - Illustrations (illustrations)

eqsp.area_of_cap(dim, s_cap)[source]

Area of spherical cap on the manifold S^dim in R^(dim+1).

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • s_cap (float or array_like) – Spherical radius/radii of the cap(s), in [0, pi].

Returns:

area – Area(s) of the spherical cap(s).

Return type:

float or ndarray

Notes

The area is defined via the Lebesgue measure on S^dim inherited from its embedding in R^(dim+1).

For dim <= 2, and for dim==3 (when pi/6 <= s_cap <= 5*pi/6), AREA is calculated in closed form, using the analytic solution of the definite integral.

Otherwise, AREA is calculated using the incomplete Beta function ratio.

References

[LeGS01 Lemma 4.1 p255]

See also

sradius_of_cap

Examples

>>> print(f"{area_of_cap(2, pi/2):.4f}")
6.2832
>>> np.set_printoptions(precision=4, suppress=True)
>>> print(area_of_cap(3, np.linspace(0, pi, 5)))
[ 0.      1.7932  9.8696 17.946  19.7392]
eqsp.area_of_collar(dim, a_top, a_bot)[source]

Area of a spherical collar.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • a_top (float or array-like) – Top (smaller) spherical radius/radii, in [0, pi].

  • a_bot (float or array-like) – Bottom (larger) spherical radius/radii, in [0, pi].

Returns:

a – Area(s) of the spherical collar(s).

Return type:

float or ndarray

Notes

a_top and a_bot must have the same shape. The area is defined via the Lebesgue measure on S^dim inherited from its embedding in R^(dim+1).

References

[LeGS01 Lemma 4.1 p255]

See also

area_of_cap

Examples

>>> import numpy as np
>>> np.set_printoptions(precision=4, suppress=True)
>>> area_of_collar(2, np.array([0, 1, 2]), np.array([1, 2, 3]))
array([2.8884, 6.0095, 3.6056])
eqsp.area_of_sphere(dim)[source]

Returns the area of the unit sphere as a manifold: S^dim in R^(dim+1).

Parameters:

dim (int or array-like of int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

Returns:

a – Area(s) of the unit sphere(s).

Return type:

float or np.ndarray

Notes

The area of S^dim is defined via the Lebesgue measure on S^dim inherited from its embedding in R^(dim+1).

The area is calculated as:

a = 2 * pi^((dim+1)/2) / gamma((dim+1)/2)

References

[Mue98] p39.

See also

volume_of_ball

Examples

>>> area_of_sphere(range(1, 8))
array([ 6.2832, 12.5664, 19.7392, 26.3189, 31.0063, 33.0734, 32.4697])
eqsp.cart2polar2(x)[source]

Convert from Cartesian to spherical coordinates on the manifold S^2 in R^3.

Parameters:

x (ndarray) – An array of real numbers of shape (3, N). Each column represents a point in 3D Cartesian coordinates.

Returns:

s – An array of shape (2, N), where for each point: - s[0, :] is the longitude phi in [0, TAU), - s[1, :] is the colatitude theta in [0, pi].

Return type:

ndarray

See also

polar2cart

Notes

This function projects any X in R^3 onto the unit sphere S^2 via a line through the origin [0, 0, 0]’. If X includes the origin, this results in a ValueError exception.

Examples

>>> import numpy as np
>>> x0 = np.array([[ 0., 0.,  0.,  0.],
...                [ 0., 1., -1.,  0.],
...                [ 1., 0.,  0., -1.]])
>>> s0 = cart2polar2(x0)
>>> print(s0)
[[0.     1.5708 4.7124 0.    ]
 [0.     1.5708 1.5708 3.1416]]
>>> x1 = np.array([[ 0., 0.,  0.,  0.],
...                [ 0., 1., -1.,  0.],
...                [ 0., 0.,  0.,  0.],
...                [ 1., 0.,  0., -1.]])
>>> s1 = cart2polar2(x1)
Traceback (most recent call last):
    ...
ValueError: Input x must have shape (3, N)
>>> x2 = np.array([[ 0., 0.,  0.,  0.],
...                [ 0., 0., -1.,  0.],
...                [ 1., 0.,  0., -1.]])
>>> s2 = cart2polar2(x2)
Traceback (most recent call last):
    ...
ValueError: Input x must not contain the origin
eqsp.eq_caps(dim, N, even_collars=False)[source]

Colatitudes of nested spherical caps and the number of regions in the polar caps and each collar of an EQ partition.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int) – The number of regions in the partition.

  • even_collars (bool, optional) – If True, force an even number of collars so the equatorial hyperplane falls exactly on a cap boundary. This enables clean hemisphere splitting for symmetric sampling methods. Requires N to be an even number. Default is False.

Returns:

  • s_cap (ndarray) – Colatitudes of spherical caps, in [0, pi].

  • n_regions (ndarray) – Integers represented as floating point numbers that sum to N. Size is (n_collars+2,).

Raises:

ValueError – If dim or N are not positive integers, or if even_collars is True but N is odd.

Notes

  • s_cap[0] is the colatitude of the North polar cap.

  • s_cap[-2] is pi - c_polar.

  • s_cap[-1] is pi.

  • n_regions[0] is 1 and n_regions[-1] is 1.

  • The sum of n_regions equals N.

Examples

>>> import numpy as np
>>> np.set_printoptions(precision=4)
>>> s_cap, n_regions = eq_caps(2,10)
>>> s_cap
array([0.6435, 1.5708, 2.4981, 3.1416])
>>> n_regions
array([1., 4., 4., 1.])
>>> s_cap, n_regions = eq_caps(3,6)
>>> s_cap
array([0.9845, 2.1571, 3.1416])
>>> n_regions
array([1., 4., 1.])
>>> s_cap, n_regions = eq_caps(2, 10, even_collars=True)
>>> s_cap
array([0.6435, 1.5708, 2.4981, 3.1416])
>>> n_regions
array([1., 4., 4., 1.])
eqsp.eq_diam_bound(dim, N, show_progress=False, even_collars=False)[source]

Upper bound on diameter of regions of an EQ partition.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of regions in the partition.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

diam_bound – Maximum of per-region diameter bound.

Return type:

ndarray

See also

eq_vertex_diam, eq_diam_coeff, eq_regions_property

Examples

>>> np.set_printoptions(precision=4, suppress=True)
>>> print(f"{float(eq_diam_bound(2, 10)):.4f}")
1.6733
>>> eq_diam_bound(3, np.arange(1, 7))
array([2., 2., 2., 2., 2., 2.])
>>> print(f"{float(eq_diam_bound(2, 6, show_progress=True)):.4f}")
1.9437
eqsp.eq_dist_coeff(dim, N, extra_offset=False, show_progress=False, even_collars=False)[source]

Coefficient of minimum distance of an EQ point set.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of points.

  • extra_offset (bool, optional) – Use extra offsets (experimental feature from the original MATLAB toolbox for dim 2-3). Default False.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

coeff – Coefficient(s), same shape as N.

Return type:

array-like

Examples

>>> np.round(eq_dist_coeff(2, np.arange(2, 5)), 4)
array([2.8284, 2.4495, 2.8284])
>>> float(np.round(eq_dist_coeff(2, 6, show_progress=True), 4))
3.4641
eqsp.eq_energy_coeff(dim, N, s=None, extra_offset=False, show_progress=False, even_collars=False)[source]

Coefficient in expansion of energy of an EQ point set.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of points.

  • s (float, optional) – Exponent parameter. Defaults to dim-1.

  • extra_offset (bool, optional) – Use extra offsets (experimental feature from the original MATLAB toolbox for dim 2-3). Default False.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

coeff – Coefficient(s), same shape as N.

Return type:

array-like

Notes

The returned coeff ($C$) relates to the thesis metric $ec_d(mathcal{N})$ as: $ec_d(mathcal{N}) = -2 times C$ (for $s=dim-1$). See Remark on page 198 of [Leo07].

Examples

>>> float(np.round(eq_energy_coeff(2, 4), 4))
-0.5214
>>> float(np.round(eq_energy_coeff(2, 6, show_progress=True), 4))
-0.5453
eqsp.eq_energy_dist(dim, N, s=None, extra_offset=False, show_progress=False, even_collars=False)[source]

Energy and minimum distance of an EQ point set.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of points.

  • s (float, optional) – Exponent parameter. Defaults to dim-1.

  • extra_offset (bool, optional) – Use extra offsets (experimental feature from the original MATLAB toolbox for dim 2-3). Default False.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

  • energy (array-like) – Energy values, same shape as N.

  • dist (array-like, optional) – Minimum Euclidean distance(s), same shape as N.

Examples

>>> energy = eq_energy_dist(2, 6, show_progress=True)
>>> float(np.round(energy, 4))
9.9853
eqsp.eq_min_dist(dim, N, extra_offset=False, show_progress=False, even_collars=False)[source]

Minimum distance between centre points of an EQ partition.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of regions in the partition.

  • extra_offset (bool, optional) – Use extra offsets (experimental feature from the original MATLAB toolbox for dim 2-3). Default False.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

dist – Minimum Euclidean distance(s), same shape as N.

Return type:

array-like

Notes

Exploits the collar structure for efficient calculation.

Examples

>>> float(np.round(eq_min_dist(2, 6, show_progress=True), 4))
1.4142
eqsp.eq_point_set(dim, N, extra_offset=False, even_collars=False)[source]

Centre points of regions of EQ partition, in Cartesian coordinates.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int) – The number of points.

  • extra_offset (bool, optional) – If True, enables experimental extra offsets for dim 2 and 3. This is a feature from the original MATLAB toolbox and is no longer planned for expansion to dim > 3.

  • even_collars (bool, optional) – If True, force an even number of collars. See eq_caps for details.

Returns:

points_x – Array of shape (dim+1, N) containing centre points of each region in Cartesian coordinates. Each column is a point on S^dim.

Return type:

ndarray

Raises:

ValueError – If dim or N are not positive integers.

Notes

Uses the recursive zonal equal area algorithm. The optional argument “offset”, “extra” may be provided and is forwarded to eq_point_set_polar.

Examples

>>> points = eq_point_set(2, 4)
>>> points.shape
(3, 4)
>>> points = eq_point_set(2, 4, even_collars=True)
>>> points.shape
(3, 4)
eqsp.eq_point_set_polar(dim, N, extra_offset=False, even_collars=False)[source]

Centre points of regions of an EQ partition in polar coordinates.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int) – The number of points.

  • extra_offset (bool, optional) – If True, enables experimental extra offsets for dim 2 and 3. This is a feature from the original MATLAB toolbox and is no longer planned for expansion to dim > 3.

  • even_collars (bool, optional) – If True, force an even number of collars. See eq_caps for details.

Returns:

points_s – Array of shape (dim, N) containing centre points in spherical polar coordinates. Each column is a point on S^dim.

Return type:

ndarray

Raises:

ValueError – If dim or N are not positive integers.

Notes

  • If dim > 3, extra offsets are ignored.

  • Points are arranged such that each region centre is the centre of the corresponding product interval in spherical coordinates, except for polar caps where the spherical cap centre is used.

Examples

>>> pts = eq_point_set_polar(2, 4)
>>> pts.shape
(2, 4)
>>> pts = eq_point_set_polar(2, 4, even_collars=True)
>>> pts.shape
(2, 4)
eqsp.eq_regions(dim, N, extra_offset=False, even_collars=False)[source]

Recursive zonal equal area (EQ) partition of sphere.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int) – The number of regions in the partition.

  • extra_offset (bool, optional) – If True, enables experimental extra offsets for dim 2 and 3. This is a feature from the original MATLAB toolbox and is no longer planned for expansion to dim > 3.

  • even_collars (bool, optional) – If True, force an even number of collars. See eq_caps for details.

Returns:

  • regions (ndarray) – An array of shape (dim, 2, N) containing the boundaries of the N regions in spherical polar coordinates. For each region r in 0..N-1: - regions[i, 0, r] is the lower bound of the i-th coordinate, - regions[i, 1, r] is the upper bound of the i-th coordinate.

  • dim_1_rot (list (optional)) – If requested (by caller), a list of N rotation matrices, each of size (dim, dim), describing R^dim rotations needed to place regions when extra offsets are used (only meaningful for dim == 3).

Raises:

ValueError – If dim or N are not positive integers.

See also

eq_point_set, centres_of_regions

Notes

  • For N == 1, the single region is the whole sphere.

  • If extra_offset is used and dim == 3, the returned dim_1_rot describes the rotation applied to sub-spheres.

Examples

>>> regs = eq_regions(2, 4)
>>> regs.shape
(2, 2, 4)
>>> regs = eq_regions(2, 4, even_collars=True)
>>> regs.shape
(2, 2, 4)
eqsp.point_set_dist_coeff(points)[source]

Coefficient of minimum distance of a point set.

Parameters:

points (array-like) – Array of shape (dim+1, N), columns are points in R^(dim+1).

Returns:

coeff – Coefficient value.

Return type:

float

Notes

For details, see calc_dist_coeff.

See also

point_set_min_dist, calc_dist_coeff, eq_dist_coeff, eq_min_dist

Examples

>>> x = np.array([[0, 0, 0, 0], [0, 1, -1, 0], [1, 0, 0, -1]])
>>> float(point_set_dist_coeff(x))
2.8284271247461903
eqsp.point_set_energy_coeff(points, s=None)[source]

Coefficient in expansion of energy of a point set.

Parameters:
  • points (array-like) – Array of shape (dim+1, N), columns are points in R^(dim+1).

  • s (float, optional) – Exponent parameter. Defaults to dim-1.

Returns:

coeff – Coefficient value.

Return type:

float

Notes

For details, see calc_energy_coeff.

See also

point_set_energy_dist, calc_energy_coeff, eq_energy_coeff, eq_energy_dist

Examples

>>> x = np.array([[0, 0, 0, 0], [0, 1, -1, 0], [1, 0, 0, -1]])
>>> point_set_energy_coeff(x)
array([-0.5214, -0.8232])
eqsp.point_set_energy_dist(points, s=None, block_size=2000)[source]

Energy and minimum distance of a point set.

Parameters:
  • points (array-like) – Array of shape (M, N), columns are points in R^M.

  • s (float, optional) – Exponent parameter. Defaults to dim-1.

  • block_size (int, optional) – Maximum number of points to process in a single block. Defaults to 2000, balancing memory usage and vectorization overhead.

Returns:

  • energy (float) – Energy value.

  • min_dist (float) – Minimum Euclidean distance.

Notes

ENERGY for single point is 0. MIN_DIST for single point is 2.

Examples

>>> x = np.array([[0, 0, 0, 0], [0, 1, -1, 0], [1, 0, 0, -1]])
>>> energy, dist = point_set_energy_dist(x, 2)
>>> (float(energy), float(dist))
(2.5, 1.4142135623730951)
>>> energy, dist = point_set_energy_dist(x, 0)
>>> (float(energy), float(dist))
(-2.7725887222397816, 1.4142135623730951)
eqsp.point_set_min_dist(points)[source]

Minimum distance between points of a point set.

Parameters:

points (array-like) – Array of shape (dim+1, N).

Returns:

min_dist – Minimum Euclidean distance.

Return type:

float

Notes

Uses scipy.spatial.KDTree for efficient O(N log N) calculation.

eqsp.polar2cart(s)[source]

Convert spherical polar to Cartesian coordinates.

Parameters:

s (array_like) – Array of real numbers of shape (dim, N) representing N points of the sphere as a manifold: S^dim in R^(dim+1).

Returns:

x – Array of shape (dim+1, N) containing the Cartesian coordinates of the points represented by the spherical polar coordinates s.

Return type:

ndarray

See also

cart2polar2

Examples

>>> import numpy as np
>>> np.set_printoptions(precision=4, suppress=True)
>>> s = np.array([
...     [0, pi/2, 3*pi/2, 0],
...     [0, pi/2, pi/2,   pi]])
>>> x = polar2cart(s)
>>> print(x)
[[ 0.  0. -0.  0.]
 [ 0.  1. -1.  0.]
 [ 1.  0.  0. -1.]]
eqsp.volume_of_ball(dim)[source]

Volume of the unit ball B^dim in R^dim.

Parameters:

dim (int or array-like) – The dimension of the ball B^dim in R^dim.

Returns:

v – Volume(s) of the unit ball(s).

Return type:

float or ndarray

Notes

The volume of B^dim is defined via the Lebesgue measure on R^dim.

References

[WeiMW].

See also

area_of_sphere

Examples

>>> import numpy as np
>>> volume_of_ball(range(1, 8))
array([2.    , 3.1416, 4.1888, 4.9348, 5.2638, 5.1677, 4.7248])

Submodules

eqsp.histograms module

PyEQSP histograms module.

Copyright 2026 Paul Leopardi

eqsp.histograms.eq_count_points_by_s2_region(s_point, N, even_collars=False)[source]

Count points in each of N regions of S^2.

Parameters:
  • s_point (ndarray) – Sequence of points on S^2, as a 2 x n_points array in spherical polar coordinates, with longitude 0 <= s[0, p_idx] <= TAU, colatitude 0 <= s[1, p_idx] <= pi.

  • N (int) – The number of regions in the partition.

  • even_collars (bool, optional) – If True, force an even number of collars for symmetric partitions. Default is False.

Returns:

count_v – Array of length N containing the number of points of s_point contained in each region.

Return type:

ndarray

Examples

>>> import numpy as np
>>> from eqsp.partitions import eq_point_set_polar
>>> points_s = eq_point_set_polar(2, 8)
>>> eq_count_points_by_s2_region(points_s, 8)
array([1, 1, 1, 1, 1, 1, 1, 1])
>>> eq_count_points_by_s2_region(points_s, 5)
array([1, 2, 2, 2, 1])
>>> points_s = eq_point_set_polar(2, 128)
>>> eq_count_points_by_s2_region(points_s, 8)
array([19, 15, 14, 17, 15, 14, 15, 19])
>>> eq_count_points_by_s2_region(points_s, 5)
array([19, 29, 32, 29, 19])
eqsp.histograms.eq_find_s2_region(s_point, N, even_collars=False)[source]

Partition S^2 into N regions and find the index for each point.

Parameters:
  • s_point (ndarray) – Sequence of points on S^2, as a 2 x n_points array in spherical polar coordinates, with longitude 0 <= s[0, p_idx] <= TAU, colatitude 0 <= s[1, p_idx] <= pi.

  • N (int) – The number of regions in the partition.

  • even_collars (bool, optional) – If True, force an even number of collars for symmetric partitions. Default is False.

Returns:

r_idx – Array of length s_point.shape[1] containing the index of the region corresponding to each point.

Return type:

ndarray

See also

eq_count_points_by_s2_region, lookup_s2_region

Examples

>>> from eqsp.partitions import eq_point_set_polar
>>> pts = eq_point_set_polar(2, 8)
>>> eq_find_s2_region(pts, 8)
array([1, 2, 3, 4, 5, 6, 7, 8])
>>> eq_find_s2_region(pts, 5)
array([1, 2, 2, 3, 3, 4, 4, 5])
>>> # Testing even_collars support
>>> pts_even = eq_point_set_polar(2, 8, even_collars=True)
>>> eq_find_s2_region(pts_even, 8, even_collars=True)
array([1, 2, 3, 4, 5, 6, 7, 8])
eqsp.histograms.in_s2_region(s_point, region)[source]

Test if points on S^2 are within a given region.

Parameters:
  • s_point (ndarray) – Sequence of points on S^2, as a 2 x n_points array in spherical polar coordinates, with longitude 0 <= s[0, p_idx] <= TAU, colatitude 0 <= s[1, p_idx] <= pi.

  • region (ndarray) – One region of S^2 as returned by eq_regions(2, N).

Returns:

result – Boolean array of length s_point.shape[1] indicating whether each point is in the region.

Return type:

ndarray

See also

eq_regions, eq_find_s2_region

Examples

>>> from eqsp.partitions import eq_point_set_polar, eq_regions
>>> points_s = eq_point_set_polar(2, 8)
>>> s_regions = eq_regions(2, 5)
>>> region = s_regions[:, :, 2]
>>> in_s2_region(points_s, region)
array([False, False, False,  True,  True, False, False, False])

eqsp.illustrations module

PyEQSP illustrations module.

Copyright 2026 Paul Leopardi

eqsp.illustrations.illustrate_eq_algorithm(dim, N, *, extra_offset=False, fontsize=8, show_title=True, _long_title=False, show_points=True, proj='eqarea', show=True, **_kwargs)[source]

Illustrate the EQ partition algorithm.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int) – Number of equal-area regions to partition the sphere into.

  • extra_offset (bool, optional) – Use extra offsets. Default False.

  • fontsize (int, optional) – Font size. Default 16.

  • show_title (bool, optional) – Show title. Default True.

  • _long_title (bool, optional) – Use long title variant. Default False.

  • show_points (bool, optional) – Show center points of regions. Default True.

  • proj (str, optional) – Projection type (‘stereo’ or ‘eqarea’). Default ‘eqarea’.

  • show (bool, optional) – If True (default), call plt.show().

  • **_kwargs – Passed to underlying plot functions.

Return type:

None

eqsp.illustrations.illustrate_steps_1_2(dim, N, *, fontsize=8, show_title=True, _long_title=False, **_kwargs)[source]

Illustrate steps 1 and 2 of the EQ partition.

eqsp.illustrations.illustrate_steps_3_5(dim, N, *, fontsize=8, show_title=True, _long_title=False, **_kwargs)[source]

Illustrate steps 3 to 5 of the EQ partition.

eqsp.illustrations.illustrate_steps_6_7(dim, N, *, fontsize=8, show_title=True, _long_title=False, **_kwargs)[source]

Illustrate steps 6 and 7 of the EQ partition.

eqsp.illustrations.project_point_set(points, ax=None, proj='stereo', _scale_factor=0.05, color=None, show=None, **_kwargs)[source]

Use projection to illustrate a point set of S^2 or S^3.

Parameters:
  • points (ndarray) – Points in R^3 (S^2) or R^4 (S^3).

  • ax (Axes, optional) – Matplotlib axes (2D or 3D). If None, a new figure is created.

  • proj ({'stereo', 'eqarea'}, optional) – Projection type. Default is ‘stereo’.

  • _scale_factor (float, optional) – Scale factor for points (unused in matplotlib implementation, kept for compatibility/kwargs).

  • color (color spec, optional) – Colour of points. Default is ‘k’ for 2D, ‘r’ for 3D.

  • show (bool or None, optional) – If True, call plt.show(). If None, call plt.show() only if ax was None.

  • **_kwargs – Passed to ax.scatter.

Returns:

ax – The axes object.

Return type:

Axes

Examples

>>> from eqsp.illustrations import project_point_set
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> plt.switch_backend('Agg')
>>> points = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).T
>>> ax = project_point_set(points, proj='eqarea')
>>> len(ax.collections)
1
eqsp.illustrations.project_s2_partition(N, *, extra_offset=False, fontsize=16, title='long', proj='stereo', show_points=False, ax=None, show=None, **_kwargs)[source]

Use projection to illustrate an EQ partition of S^2.

Parameters:
  • N (int) – The number of regions in the partition.

  • extra_offset (bool, optional) – Use extra offsets. Default False.

  • fontsize (int, optional) – Font size for title. Default 16.

  • title ({'long', 'short', 'none'}, optional) – Title mode. Default ‘long’.

  • proj ({'stereo', 'eqarea'}, optional) – Projection type. Default ‘stereo’.

  • show_points (bool, optional) – Show center points of regions. Default False.

  • ax (Axes, optional) – Matplotlib axes to plot on. If None, a new figure is created.

  • show (bool or None, optional) – If True, call plt.show(). If None, call plt.show() only if ax was None.

  • **_kwargs – Passed to underlying plot functions.

Returns:

ax – The axes object.

Return type:

Axes

Examples

>>> from eqsp.illustrations import project_s2_partition
>>> import matplotlib.pyplot as plt
>>> plt.switch_backend('Agg')
>>> ax = project_s2_partition(4, proj='eqarea', title='none', show_points=True)
>>> ax.get_title()
''

eqsp.partitions module

PyEQSP partitions module.

Copyright 2026 Paul Leopardi

eqsp.partitions.eq_caps(dim, N, even_collars=False)[source]

Colatitudes of nested spherical caps and the number of regions in the polar caps and each collar of an EQ partition.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int) – The number of regions in the partition.

  • even_collars (bool, optional) – If True, force an even number of collars so the equatorial hyperplane falls exactly on a cap boundary. This enables clean hemisphere splitting for symmetric sampling methods. Requires N to be an even number. Default is False.

Returns:

  • s_cap (ndarray) – Colatitudes of spherical caps, in [0, pi].

  • n_regions (ndarray) – Integers represented as floating point numbers that sum to N. Size is (n_collars+2,).

Raises:

ValueError – If dim or N are not positive integers, or if even_collars is True but N is odd.

Notes

  • s_cap[0] is the colatitude of the North polar cap.

  • s_cap[-2] is pi - c_polar.

  • s_cap[-1] is pi.

  • n_regions[0] is 1 and n_regions[-1] is 1.

  • The sum of n_regions equals N.

Examples

>>> import numpy as np
>>> np.set_printoptions(precision=4)
>>> s_cap, n_regions = eq_caps(2,10)
>>> s_cap
array([0.6435, 1.5708, 2.4981, 3.1416])
>>> n_regions
array([1., 4., 4., 1.])
>>> s_cap, n_regions = eq_caps(3,6)
>>> s_cap
array([0.9845, 2.1571, 3.1416])
>>> n_regions
array([1., 4., 1.])
>>> s_cap, n_regions = eq_caps(2, 10, even_collars=True)
>>> s_cap
array([0.6435, 1.5708, 2.4981, 3.1416])
>>> n_regions
array([1., 4., 4., 1.])
eqsp.partitions.eq_point_set(dim, N, extra_offset=False, even_collars=False)[source]

Centre points of regions of EQ partition, in Cartesian coordinates.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int) – The number of points.

  • extra_offset (bool, optional) – If True, enables experimental extra offsets for dim 2 and 3. This is a feature from the original MATLAB toolbox and is no longer planned for expansion to dim > 3.

  • even_collars (bool, optional) – If True, force an even number of collars. See eq_caps for details.

Returns:

points_x – Array of shape (dim+1, N) containing centre points of each region in Cartesian coordinates. Each column is a point on S^dim.

Return type:

ndarray

Raises:

ValueError – If dim or N are not positive integers.

See also

eq_point_set_polar, polar2cart, eq_regions

Notes

Uses the recursive zonal equal area algorithm. The optional argument “offset”, “extra” may be provided and is forwarded to eq_point_set_polar.

Examples

>>> points = eq_point_set(2, 4)
>>> points.shape
(3, 4)
>>> points = eq_point_set(2, 4, even_collars=True)
>>> points.shape
(3, 4)
eqsp.partitions.eq_point_set_polar(dim, N, extra_offset=False, even_collars=False)[source]

Centre points of regions of an EQ partition in polar coordinates.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int) – The number of points.

  • extra_offset (bool, optional) – If True, enables experimental extra offsets for dim 2 and 3. This is a feature from the original MATLAB toolbox and is no longer planned for expansion to dim > 3.

  • even_collars (bool, optional) – If True, force an even number of collars. See eq_caps for details.

Returns:

points_s – Array of shape (dim, N) containing centre points in spherical polar coordinates. Each column is a point on S^dim.

Return type:

ndarray

Raises:

ValueError – If dim or N are not positive integers.

See also

eq_point_set, polar2cart, cart2polar2

Notes

  • If dim > 3, extra offsets are ignored.

  • Points are arranged such that each region centre is the centre of the corresponding product interval in spherical coordinates, except for polar caps where the spherical cap centre is used.

Examples

>>> pts = eq_point_set_polar(2, 4)
>>> pts.shape
(2, 4)
>>> pts = eq_point_set_polar(2, 4, even_collars=True)
>>> pts.shape
(2, 4)
eqsp.partitions.eq_regions(dim, N, extra_offset=False, even_collars=False)[source]

Recursive zonal equal area (EQ) partition of sphere.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int) – The number of regions in the partition.

  • extra_offset (bool, optional) – If True, enables experimental extra offsets for dim 2 and 3. This is a feature from the original MATLAB toolbox and is no longer planned for expansion to dim > 3.

  • even_collars (bool, optional) – If True, force an even number of collars. See eq_caps for details.

Returns:

  • regions (ndarray) – An array of shape (dim, 2, N) containing the boundaries of the N regions in spherical polar coordinates. For each region r in 0..N-1: - regions[i, 0, r] is the lower bound of the i-th coordinate, - regions[i, 1, r] is the upper bound of the i-th coordinate.

  • dim_1_rot (list (optional)) – If requested (by caller), a list of N rotation matrices, each of size (dim, dim), describing R^dim rotations needed to place regions when extra offsets are used (only meaningful for dim == 3).

Raises:

ValueError – If dim or N are not positive integers.

See also

eq_point_set, centres_of_regions

Notes

  • For N == 1, the single region is the whole sphere.

  • If extra_offset is used and dim == 3, the returned dim_1_rot describes the rotation applied to sub-spheres.

Examples

>>> regs = eq_regions(2, 4)
>>> regs.shape
(2, 2, 4)
>>> regs = eq_regions(2, 4, even_collars=True)
>>> regs.shape
(2, 2, 4)

eqsp.point_set_props module

PyEQSP point set properties module.

Copyright 2026 Paul Leopardi

eqsp.point_set_props.calc_dist_coeff(dim, N, min_euclidean_dist)[source]

Coefficient of minimum distance.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of points.

  • min_euclidean_dist (array-like) – Minimum Euclidean distance(s), same shape as N.

Returns:

coeff – Coefficient(s), same shape as N.

Return type:

array-like

Notes

The expression for the lower bound on minimum distance of a minimum $r^{-s}$ energy point set on $S^{dim}$ was given by [Rak94] for s == 0, dim = 2, [Dah78] for s == dim-1, [Kui07] for dim-1 <= s < dim, and [Kui98] for s > dim.

Examples

>>> N = np.arange(2, 7)
>>> dist = eq_min_dist(2, N)
>>> np.round(calc_dist_coeff(2, N, dist), 4)
array([2.8284, 2.4495, 2.8284, 3.1623, 3.4641])
eqsp.point_set_props.calc_energy_coeff(dim, N, s, energy)[source]

Coefficient of second term in expansion of energy.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of points.

  • s (float) – Exponent parameter.

  • energy (array-like) – Energy values, same shape as N.

Returns:

coeff – Coefficient(s), same shape as N.

Return type:

array-like

Notes

The returned coefficient coeff (denoted $C$) corresponds to the second term in the energy expansion. In the PhD thesis [Leo07], the “energy coefficient” $ec_d(mathcal{N})$ is defined as: $ec_d(mathcal{N}) := (1 - E/I(d,s)) mathcal{N}^{s/d}$. For $s = dim-1$ (where $I(d,s)=1$ on $S^2$ and higher), this relates to $C$ as: $ec_d(mathcal{N}) = -2 times C$.

The energy expansion is not valid for N == 1, and in particular, eq_energy_coeff(dim, N, 0, energy) := 0.

For s > 0, [Kui98] has E(dim, N, s) == (sphere_int_energy(dim, s)/2) N^2 + COEFF N^(1+s/dim) + …

For s == 0 (logarithmic potential), see [Saf97].

Examples

>>> np.set_printoptions(precision=4, suppress=True)
>>> N = np.arange(2, 7)
>>> energy, dist = eq_energy_dist(2, N, 0)
>>> calc_energy_coeff(2, N, 0, energy)
array([-0.2213, -0.1569, -0.2213, -0.2493, -0.2569])
eqsp.point_set_props.calc_packing_density(dim, N, min_euclidean_dist)[source]

Density of packing given by minimum distance.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of points.

  • min_euclidean_dist (array-like) – Minimum Euclidean distance(s), same shape as N.

Returns:

density – Density values, same shape as N.

Return type:

array-like

Notes

The packing density is defined as the sum of the areas of the spherical caps divided by the area of the unit sphere $S^{dim}$.

The spherical radius of the caps is half the minimum spherical distance. For N == 1, the spherical radius is pi.

See also

eq_min_dist, area_of_cap, area_of_sphere, eq_packing_density

Examples

>>> np.set_printoptions(precision=4, suppress=True)
>>> N = np.arange(2, 7)
>>> dist = eq_min_dist(2, N)
>>> calc_packing_density(2, N, dist)
array([1.    , 0.4393, 0.5858, 0.7322, 0.8787])
eqsp.point_set_props.eq_dist_coeff(dim, N, extra_offset=False, show_progress=False, even_collars=False)[source]

Coefficient of minimum distance of an EQ point set.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of points.

  • extra_offset (bool, optional) – Use extra offsets (experimental feature from the original MATLAB toolbox for dim 2-3). Default False.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

coeff – Coefficient(s), same shape as N.

Return type:

array-like

Examples

>>> np.round(eq_dist_coeff(2, np.arange(2, 5)), 4)
array([2.8284, 2.4495, 2.8284])
>>> float(np.round(eq_dist_coeff(2, 6, show_progress=True), 4))
3.4641
eqsp.point_set_props.eq_energy_coeff(dim, N, s=None, extra_offset=False, show_progress=False, even_collars=False)[source]

Coefficient in expansion of energy of an EQ point set.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of points.

  • s (float, optional) – Exponent parameter. Defaults to dim-1.

  • extra_offset (bool, optional) – Use extra offsets (experimental feature from the original MATLAB toolbox for dim 2-3). Default False.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

coeff – Coefficient(s), same shape as N.

Return type:

array-like

Notes

The returned coeff ($C$) relates to the thesis metric $ec_d(mathcal{N})$ as: $ec_d(mathcal{N}) = -2 times C$ (for $s=dim-1$). See Remark on page 198 of [Leo07].

Examples

>>> float(np.round(eq_energy_coeff(2, 4), 4))
-0.5214
>>> float(np.round(eq_energy_coeff(2, 6, show_progress=True), 4))
-0.5453
eqsp.point_set_props.eq_energy_dist(dim, N, s=None, extra_offset=False, show_progress=False, even_collars=False)[source]

Energy and minimum distance of an EQ point set.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of points.

  • s (float, optional) – Exponent parameter. Defaults to dim-1.

  • extra_offset (bool, optional) – Use extra offsets (experimental feature from the original MATLAB toolbox for dim 2-3). Default False.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

  • energy (array-like) – Energy values, same shape as N.

  • dist (array-like, optional) – Minimum Euclidean distance(s), same shape as N.

Examples

>>> energy = eq_energy_dist(2, 6, show_progress=True)
>>> float(np.round(energy, 4))
9.9853
eqsp.point_set_props.eq_min_dist(dim, N, extra_offset=False, show_progress=False, even_collars=False)[source]

Minimum distance between centre points of an EQ partition.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of regions in the partition.

  • extra_offset (bool, optional) – Use extra offsets (experimental feature from the original MATLAB toolbox for dim 2-3). Default False.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

dist – Minimum Euclidean distance(s), same shape as N.

Return type:

array-like

Notes

Exploits the collar structure for efficient calculation.

Examples

>>> float(np.round(eq_min_dist(2, 6, show_progress=True), 4))
1.4142
eqsp.point_set_props.point_set_dist_coeff(points)[source]

Coefficient of minimum distance of a point set.

Parameters:

points (array-like) – Array of shape (dim+1, N), columns are points in R^(dim+1).

Returns:

coeff – Coefficient value.

Return type:

float

Notes

For details, see calc_dist_coeff.

Examples

>>> x = np.array([[0, 0, 0, 0], [0, 1, -1, 0], [1, 0, 0, -1]])
>>> float(point_set_dist_coeff(x))
2.8284271247461903
eqsp.point_set_props.point_set_energy_coeff(points, s=None)[source]

Coefficient in expansion of energy of a point set.

Parameters:
  • points (array-like) – Array of shape (dim+1, N), columns are points in R^(dim+1).

  • s (float, optional) – Exponent parameter. Defaults to dim-1.

Returns:

coeff – Coefficient value.

Return type:

float

Notes

For details, see calc_energy_coeff.

Examples

>>> x = np.array([[0, 0, 0, 0], [0, 1, -1, 0], [1, 0, 0, -1]])
>>> point_set_energy_coeff(x)
array([-0.5214, -0.8232])
eqsp.point_set_props.point_set_energy_dist(points, s=None, block_size=2000)[source]

Energy and minimum distance of a point set.

Parameters:
  • points (array-like) – Array of shape (M, N), columns are points in R^M.

  • s (float, optional) – Exponent parameter. Defaults to dim-1.

  • block_size (int, optional) – Maximum number of points to process in a single block. Defaults to 2000, balancing memory usage and vectorization overhead.

Returns:

  • energy (float) – Energy value.

  • min_dist (float) – Minimum Euclidean distance.

Notes

ENERGY for single point is 0. MIN_DIST for single point is 2.

Examples

>>> x = np.array([[0, 0, 0, 0], [0, 1, -1, 0], [1, 0, 0, -1]])
>>> energy, dist = point_set_energy_dist(x, 2)
>>> (float(energy), float(dist))
(2.5, 1.4142135623730951)
>>> energy, dist = point_set_energy_dist(x, 0)
>>> (float(energy), float(dist))
(-2.7725887222397816, 1.4142135623730951)
eqsp.point_set_props.point_set_min_dist(points)[source]

Minimum distance between points of a point set.

Parameters:

points (array-like) – Array of shape (dim+1, N).

Returns:

min_dist – Minimum Euclidean distance.

Return type:

float

Notes

Uses scipy.spatial.KDTree for efficient O(N log N) calculation.

eqsp.point_set_props.sphere_int_energy(dim, s)[source]

Energy integral of r^(-s) potential.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • s (float) – Exponent parameter.

Returns:

energy – Energy integral on S^dim of the r^(-s) potential.

Return type:

float

Notes

Ref for s > 0: [Kui98] Ref for s == 0 and dim == 2: [Saf97]

Examples

>>> float(sphere_int_energy(2, 0))
-0.1931471805599453

eqsp.region_props module

PyEQSP region properties module.

Copyright 2026 Paul Leopardi

eqsp.region_props.area_of_region(region)[source]

Area of given region(s).

Parameters:

region (ndarray) – Region(s), typically of shape (dim, 2) or (dim, 2, N).

Returns:

area – Area of the region(s).

Return type:

float or ndarray

See also

area_of_sphere, area_of_collar

Examples

>>> import numpy as np
>>> region = np.array([[0, TAU], [0, np.pi]])
>>> float(area_of_region(region))
12.566370614359172
eqsp.region_props.eq_area_error(dim, N, show_progress=False, even_collars=False)[source]

Total area error and max area error per region of an EQ partition.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like of int) – The number of regions in the partition.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

  • total_error (ndarray) – Absolute difference between total area of all regions and the area of $S^{dim}$. Total error should be near 0.

  • max_error (ndarray) – Maximum absolute difference between the area of any region and the ideal area.

Raises:

ValueError – If arguments are not provided.

See also

eq_regions, area_of_sphere, area_of_ideal_region

Notes

The results will be arrays of the same size as N. Note that both total_error and max_error are returned as native floats if N is a scalar, otherwise as NumPy arrays.

Implementation

To accurately measure the accumulated rounding error of the partitioning algorithm itself, this function computes the area for every single region independently based on the exact geometric boundaries (s_top and s_bot) produced by the algorithm. It does not assume regions within a given collar are strictly identical, nor does it substitute theoretical ideal areas. The calculations are vectorized using NumPy arrays for performance while maintaining strict geometric fidelity to the algorithm’s actual output.

Examples

>>> import numpy as np
>>> np.set_printoptions(precision=4, suppress=True)
>>> total_error, max_error = eq_area_error(2, 10)
>>> np.allclose(total_error, 0)
True
>>> total_error, max_error = eq_area_error(2, 6, show_progress=True)
>>> float(total_error)
0.0
>>> np.allclose(max_error, 0, atol=1e-12)
True
>>> np.allclose(total_error * 1e12, [0, 0, 0, 0, 0, 0], atol=1)
True
>>> np.allclose(max_error * 1e12, [0, 0, 0, 0, 0, 0], atol=1)
True
>>> total_error, max_error = eq_area_error(2, 6, show_progress=True)
>>> np.allclose(total_error, 0)
True
eqsp.region_props.eq_diam_bound(dim, N, show_progress=False, even_collars=False)[source]

Upper bound on diameter of regions of an EQ partition.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of regions in the partition.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

diam_bound – Maximum of per-region diameter bound.

Return type:

ndarray

Examples

>>> np.set_printoptions(precision=4, suppress=True)
>>> print(f"{float(eq_diam_bound(2, 10)):.4f}")
1.6733
>>> eq_diam_bound(3, np.arange(1, 7))
array([2., 2., 2., 2., 2., 2.])
>>> print(f"{float(eq_diam_bound(2, 6, show_progress=True)):.4f}")
1.9437
eqsp.region_props.eq_diam_coeff(dim, N, show_progress=False, even_collars=False)[source]

Coefficient of diameter bound for EQ partitions.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of regions in the partition.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

  • bound_coeff (ndarray) – Diameter bound coefficient.

  • vertex_coeff (ndarray) – Vertex diameter coefficient.

Raises:

ValueError – If arguments are not provided.

Notes

The returned coefficients relate the maximum per-region diameter to the number of regions. Specifically, the coefficients are calculated as: \(C = \text{diam} \times N^{1/d}\) where diam is the maximum diameter bound or vertex diameter.

Unlike the Matlab implementation, this function always returns a 2-tuple. If you only need one coefficient, you can ignore the other during unpacking (e.g., b, _ = eq_diam_coeff(...)).

Examples

>>> np.set_printoptions(precision=4, suppress=True)
>>> bound_coeff, vertex_coeff = eq_diam_coeff(2, 10)
>>> print(f"{float(bound_coeff):.4f}, {float(vertex_coeff):.4f}")
5.2915, 4.4721
>>> b, v = eq_diam_coeff(2, 6, show_progress=True)
>>> print(f"{float(b):.4f}")
4.7610
eqsp.region_props.eq_regions_property(fhandle, dim, N, show_progress=False, even_collars=False)[source]

Property of regions of an EQ partition.

Parameters:
  • fhandle (callable) – Function handle to apply to regions.

  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like of int) – The number of regions in the partition.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

property – Calculated property for each partition.

Return type:

ndarray

See also

eq_regions, eq_diam_bound, eq_vertex_diam

Notes

The function specified by fhandle must accept an array of shape (dim, 2, N_regions) and return a single value.

Examples

>>> def dummy_property(regions): return regions.shape[2]
>>> eq_regions_property(dummy_property, 2, [3, 4]).astype(int)
array([3, 4])
>>> float(eq_regions_property(dummy_property, 2, 6, show_progress=True))
6.0
eqsp.region_props.eq_vertex_diam(dim, N, show_progress=False, even_collars=False)[source]

Maximum vertex diameter of regions of an EQ partition.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of regions in the partition.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

vertex_diam – Maximum vertex diameter over all regions.

Return type:

ndarray

Examples

>>> np.set_printoptions(precision=4, suppress=True)
>>> print(f"{float(eq_vertex_diam(2, 10)):.4f}")
1.4142
>>> eq_vertex_diam(3, np.arange(1, 7))
array([2., 2., 2., 2., 2., 2.])
>>> print(f"{float(eq_vertex_diam(2, 6, show_progress=True)):.4f}")
1.6997
eqsp.region_props.eq_vertex_diam_coeff(dim, N, show_progress=False, even_collars=False)[source]

Coefficient of maximum vertex diameter of regions of an EQ partition.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of regions in the partition.

  • show_progress (bool, optional) – Show progress messages. Default False.

  • even_collars (bool, optional) – Use even number of collars for symmetric partitions. Default False.

Returns:

coeff – Vertex diameter coefficient.

Return type:

ndarray

Examples

>>> np.set_printoptions(precision=4, suppress=True)
>>> print(f"{float(eq_vertex_diam_coeff(2, 10)):.4f}")
4.4721
>>> eq_vertex_diam_coeff(3, np.arange(1, 7))
array([2.    , 2.5198, 2.8845, 3.1748, 3.42  , 3.6342])
>>> print(f"{float(eq_vertex_diam_coeff(2, 6, show_progress=True)):.4f}")
4.1633

eqsp.utilities module

PyEQSP utilities module.

Copyright 2026 Paul Leopardi

eqsp.utilities.area_of_cap(dim, s_cap)[source]

Area of spherical cap on the manifold S^dim in R^(dim+1).

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • s_cap (float or array_like) – Spherical radius/radii of the cap(s), in [0, pi].

Returns:

area – Area(s) of the spherical cap(s).

Return type:

float or ndarray

Notes

The area is defined via the Lebesgue measure on S^dim inherited from its embedding in R^(dim+1).

For dim <= 2, and for dim==3 (when pi/6 <= s_cap <= 5*pi/6), AREA is calculated in closed form, using the analytic solution of the definite integral.

Otherwise, AREA is calculated using the incomplete Beta function ratio.

References

[LeGS01 Lemma 4.1 p255]

See also

sradius_of_cap

Examples

>>> print(f"{area_of_cap(2, pi/2):.4f}")
6.2832
>>> np.set_printoptions(precision=4, suppress=True)
>>> print(area_of_cap(3, np.linspace(0, pi, 5)))
[ 0.      1.7932  9.8696 17.946  19.7392]
eqsp.utilities.area_of_collar(dim, a_top, a_bot)[source]

Area of a spherical collar.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • a_top (float or array-like) – Top (smaller) spherical radius/radii, in [0, pi].

  • a_bot (float or array-like) – Bottom (larger) spherical radius/radii, in [0, pi].

Returns:

a – Area(s) of the spherical collar(s).

Return type:

float or ndarray

Notes

a_top and a_bot must have the same shape. The area is defined via the Lebesgue measure on S^dim inherited from its embedding in R^(dim+1).

References

[LeGS01 Lemma 4.1 p255]

See also

area_of_cap

Examples

>>> import numpy as np
>>> np.set_printoptions(precision=4, suppress=True)
>>> area_of_collar(2, np.array([0, 1, 2]), np.array([1, 2, 3]))
array([2.8884, 6.0095, 3.6056])
eqsp.utilities.area_of_ideal_region(dim, N)[source]

Area of one region of an EQ partition.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of regions in the partition.

Returns:

a – Area(s) of the ideal region(s).

Return type:

float or numpy.ndarray with the same shape as N

See also

area_of_sphere

Examples

>>> area_of_ideal_region(3, range(1, 7))
array([19.7392,  9.8696,  6.5797,  4.9348,  3.9478,  3.2899])
eqsp.utilities.area_of_sphere(dim)[source]

Returns the area of the unit sphere as a manifold: S^dim in R^(dim+1).

Parameters:

dim (int or array-like of int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

Returns:

a – Area(s) of the unit sphere(s).

Return type:

float or np.ndarray

Notes

The area of S^dim is defined via the Lebesgue measure on S^dim inherited from its embedding in R^(dim+1).

The area is calculated as:

a = 2 * pi^((dim+1)/2) / gamma((dim+1)/2)

References

[Mue98] p39.

See also

volume_of_ball

Examples

>>> area_of_sphere(range(1, 8))
array([ 6.2832, 12.5664, 19.7392, 26.3189, 31.0063, 33.0734, 32.4697])
eqsp.utilities.asfloat(x)[source]

Convert from a numpy array to a float when this makes sense.

It checks if the input is a 0-dimensional array (scalar) or a 1-element array, and if so, converts it to a standard Python float. Otherwise, it returns the input as a NumPy array. This ensures that functions return native Python scalars when appropriate (e.g., area of a single region) while still supporting vectorized operations.

Parameters:

x (array_like)

Returns:

a – If x is a (), or (1,) or (1,1) array, then a is returned as a float. Otherwise a is just x as a Numpy array.

Return type:

ndarray or float

Examples

>>> import numpy as np
>>> np.set_printoptions(precision=4, suppress=True)
>>> x0 = 12.789
>>> a0 = asfloat(x0)
>>> print(a0)
12.789
>>> x1 = [[22.546]]
>>> a1 = asfloat(x1)
>>> print(a1)
22.546
>>> x2 = [12.789, 22.546]
>>> a2 = asfloat(x2)
>>> print(a2)
[12.789 22.546]
>>> x3 = np.array([12.789, 22.546])
>>> a3 = asfloat(x3)
>>> print(a3)
[12.789 22.546]
eqsp.utilities.cart2polar2(x)[source]

Convert from Cartesian to spherical coordinates on the manifold S^2 in R^3.

Parameters:

x (ndarray) – An array of real numbers of shape (3, N). Each column represents a point in 3D Cartesian coordinates.

Returns:

s – An array of shape (2, N), where for each point: - s[0, :] is the longitude phi in [0, TAU), - s[1, :] is the colatitude theta in [0, pi].

Return type:

ndarray

See also

polar2cart

Notes

This function projects any X in R^3 onto the unit sphere S^2 via a line through the origin [0, 0, 0]’. If X includes the origin, this results in a ValueError exception.

Examples

>>> import numpy as np
>>> x0 = np.array([[ 0., 0.,  0.,  0.],
...                [ 0., 1., -1.,  0.],
...                [ 1., 0.,  0., -1.]])
>>> s0 = cart2polar2(x0)
>>> print(s0)
[[0.     1.5708 4.7124 0.    ]
 [0.     1.5708 1.5708 3.1416]]
>>> x1 = np.array([[ 0., 0.,  0.,  0.],
...                [ 0., 1., -1.,  0.],
...                [ 0., 0.,  0.,  0.],
...                [ 1., 0.,  0., -1.]])
>>> s1 = cart2polar2(x1)
Traceback (most recent call last):
    ...
ValueError: Input x must have shape (3, N)
>>> x2 = np.array([[ 0., 0.,  0.,  0.],
...                [ 0., 0., -1.,  0.],
...                [ 1., 0.,  0., -1.]])
>>> s2 = cart2polar2(x2)
Traceback (most recent call last):
    ...
ValueError: Input x must not contain the origin
eqsp.utilities.euc2sph_dist(e)[source]

Convert Euclidean to spherical distance.

Parameters:

e (float or array-like) – A real number or array of real numbers, with abs(e) <= 2.

Returns:

s – The spherical distance(s), same shape as e.

Return type:

float or ndarray

Notes

The argument e is assumed to satisfy abs(e) <= 2. The formula is valid for the unit sphere in all dimensions.

Examples

>>> np.set_printoptions(precision=4, suppress=True)
>>> print(f"{euc2sph_dist(2):.4f}")
3.1416
>>> euc2sph_dist(np.array([0, np.sqrt(2), 2.0]))
array([0.    , 1.5708, 3.1416])
>>> print(f"{euc2sph_dist(-2):.4f}")
-3.1416
eqsp.utilities.euclidean_dist(x, y)[source]

Euclidean distance between two points in Cartesian coordinates.

Parameters:
  • x (array_like, shape (M, N)) – Array of shape (M, N), where M = dim+1, and dim is the dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • y (array_like, shape (M, N)) – Array of shape (M, N). The shapes of x and y must be identical.

Returns:

d – The Euclidean distance between corresponding pairs of points in x and y.

Return type:

ndarray, shape (N,)

Examples

>>> x = np.array([[0,     0,      0,     0],
...               [0,     1,     -1,     0],
...               [1,     0,      0,    -1]])
>>> y = np.array([[ 0,    0,      0,     0],
...               [-0.5,  0.866, -0.866, 0.5],
...               [ 0.866,0.5,   -0.5,  -0.866]])
>>> euclidean_dist(x, y)
array([0.5176, 0.5176, 0.5176, 0.5176])
eqsp.utilities.ideal_collar_angle(dim, N)[source]

The ideal angle for spherical collars of an EQ partition.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • N (int or array-like) – The number of regions in the partition.

Returns:

angle – The ideal angle(s).

Return type:

float or np.ndarray

Notes

The ideal collar angle is determined by the side of a dim-dimensional hypercube of the same volume as the area of single region of S^dim.

Examples

>>> print(f"{ideal_collar_angle(2, 10):.4g}")
1.121
>>> np.round(ideal_collar_angle(3, np.arange(1,7)), 4)
array([2.7026, 2.145 , 1.8739, 1.7025, 1.5805, 1.4873])
eqsp.utilities.polar2cart(s)[source]

Convert spherical polar to Cartesian coordinates.

Parameters:

s (array_like) – Array of real numbers of shape (dim, N) representing N points of the sphere as a manifold: S^dim in R^(dim+1).

Returns:

x – Array of shape (dim+1, N) containing the Cartesian coordinates of the points represented by the spherical polar coordinates s.

Return type:

ndarray

See also

cart2polar2

Examples

>>> import numpy as np
>>> np.set_printoptions(precision=4, suppress=True)
>>> s = np.array([
...     [0, pi/2, 3*pi/2, 0],
...     [0, pi/2, pi/2,   pi]])
>>> x = polar2cart(s)
>>> print(x)
[[ 0.  0. -0.  0.]
 [ 0.  1. -1.  0.]
 [ 1.  0.  0. -1.]]
eqsp.utilities.sph2euc_dist(s)[source]

Convert spherical distance to Euclidean distance on the unit sphere.

Parameters:

s (float or array_like) – Spherical distance(s), in radians.

Returns:

e – Euclidean (chord) distance(s), same shape as input.

Return type:

float or ndarray

Examples

>>> from math import pi
>>> import numpy as np
>>> np.set_printoptions(precision=4, suppress=True)
>>> sph2euc_dist(0)
0.0
>>> sph2euc_dist(pi)
2.0
>>> print(sph2euc_dist(np.array([0, pi/4, pi/2, 3*pi/4, pi])))
[0.     0.7654 1.4142 1.8478 2.    ]
>>> print(f"{sph2euc_dist(-pi/2):.4f}")
-1.4142
eqsp.utilities.spherical_dist(x, y)[source]

Spherical distance between two points in Cartesian coordinates.

Parameters:
  • x (array_like, shape (M, N)) – Array of shape (M, N), where M = dim+1, and dim is the dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • y (array_like, shape (M, N)) – Array of shape (M, N). The shapes of x and y must be identical.

Returns:

d – Array of shape (N,), containing spherical distances (in radians) between corresponding pairs.

Return type:

ndarray

Examples

>>> x0 = np.array([[0,     0,      0,     0],
...                [0,     1,     -1,     0],
...                [1,     0,      0,    -1]])
>>> y0 = np.array([[ 0,    0,      0,     0],
...                [-0.5,  0.866, -0.866, 0.5],
...                [ 0.866,0.5,   -0.5,  -0.866]])
>>> print(spherical_dist(x0, y0))
[0.5236 0.5236 0.5236 0.5236]
eqsp.utilities.sradius_of_cap(dim, area)[source]

Spherical radius of a spherical cap of given area.

Parameters:
  • dim (int) – The dimension of the sphere as a manifold: S^dim in R^(dim+1).

  • area (float or array-like) – Area(s) of the cap(s).

Returns:

s_cap – Spherical radius/radii in [0, pi], same shape as area.

Return type:

float or ndarray

Notes

For dim <= 2, the result is exact (closed form). For dim > 2, the result is found numerically.

See also

area_of_cap

Examples

>>> import numpy as np
>>> np.set_printoptions(precision=4, suppress=True)
>>> area = area_of_sphere(2) / 2
>>> print(f"{sradius_of_cap(2, area):.4f}")
1.5708
>>> areas = np.linspace(0, 4, 5) * area_of_sphere(3) / 4
>>> sradius_of_cap(3, areas)
array([0.    , 1.1549, 1.5708, 1.9867, 3.1416])
eqsp.utilities.volume_of_ball(dim)[source]

Volume of the unit ball B^dim in R^dim.

Parameters:

dim (int or array-like) – The dimension of the ball B^dim in R^dim.

Returns:

v – Volume(s) of the unit ball(s).

Return type:

float or ndarray

Notes

The volume of B^dim is defined via the Lebesgue measure on R^dim.

References

[WeiMW].

See also

area_of_sphere

Examples

>>> import numpy as np
>>> volume_of_ball(range(1, 8))
array([2.    , 3.1416, 4.1888, 4.9348, 5.2638, 5.1677, 4.7248])
eqsp.utilities.x2eqarea(x)[source]

Equal area projection of Euclidean points.

Parameters:

x (ndarray) – Points in R^(dim+1), shape (dim+1, N).

Returns:

result – Projected points in R^dim, shape (dim, N).

Return type:

ndarray

eqsp.utilities.x2stereo(x)[source]

Stereographic projection of Euclidean points.

Parameters:

x (ndarray) – Points in R^(dim+1), shape (dim+1, N).

Returns:

result – Projected points in R^dim, shape (dim, N).

Return type:

ndarray

eqsp.visualizations module

PyEQSP Visualizations module. 3D visualizations using Mayavi.

Copyright 2026 Paul Leopardi. For licensing, see COPYING.

eqsp.visualizations.project_point_set(points, proj='stereo', scale_factor=0.1, color=(1, 0, 0), show=True, save_file=None, **kwargs)[source]

Use projection to illustrate a point set of S^2 or S^3.

Parameters:
  • points (ndarray) – Array of shape (dim+1, N) containing centre points of each region in Cartesian coordinates.

  • proj ({'stereo', 'eqarea'}, optional) – Projection type. Default ‘stereo’.

  • scale_factor (float, optional) – Scale factor for points. Default 0.1.

  • color (tuple, optional) – Colour of points in RGB format (0 to 1). Default (1, 0, 0).

  • **kwargs – Passed to Mayavi plotting functions.

Examples

>>> from eqsp.visualizations import project_point_set
>>> import numpy as np
>>> from mayavi import mlab
>>> mlab.options.offscreen = True
>>> points = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).T
>>> try:
...     project_point_set(points, proj='eqarea')
...     print("Success")
... except ImportError:
...     print("Mayavi not installed")
Success
eqsp.visualizations.project_s3_partition(N, *, extra_offset=False, title='long', proj='stereo', show_points=True, show_surfaces=True, show=True, save_file=None, **kwargs)[source]

Use projection to illustrate an EQ partition of S^3.

Parameters:
  • N (int) – Number of regions.

  • extra_offset (bool, optional) – Use extra offsets. Default False.

  • title ({'long', 'short', 'none'}, optional) – Title format. Default ‘long’.

  • proj ({'stereo', 'eqarea'}, optional) – Projection type. Default ‘stereo’.

  • show_points (bool, optional) – Show center points. Default True.

  • show_surfaces (bool, optional) – Show region surfaces. Default True.

  • **kwargs – Passed to Mayavi plotting functions.

Examples

>>> from eqsp.visualizations import project_s3_partition
>>> from mayavi import mlab
>>> mlab.options.offscreen = True
>>> try:
...     project_s3_partition(
...         4, proj='stereo', show_points=True, show_surfaces=False
...     )
...     print("Success")
... except ImportError:
...     print("Mayavi not installed")
Success
eqsp.visualizations.show_r3_point_set(points, show_sphere=False, scale_factor=0.1, save_file=None, **kwargs)[source]

3D illustration of a point set.

eqsp.visualizations.show_s2_partition(N, *, extra_offset=False, show_points=True, show_sphere=True, title='long', title_pos=(0.2, 0.85), show=True, save_file=None, **_kwargs)[source]

3D illustration of an EQ partition of S^2 into N regions.

Parameters:
  • N (int) – Number of regions.

  • extra_offset (bool, optional) – Use extra offsets. Default False.

  • show_points (bool, optional) – Show centre points. Default True.

  • show_sphere (bool, optional) – Show unit sphere. Default True.

  • title (str, optional) – Title text. Special values: ‘long’, ‘short’, ‘none’. ‘long’ uses a default multi-line description. ‘short’ uses ‘EQ(2, N)’. ‘none’ shows no title. Any other string is used as the title text.

  • title_pos (tuple, optional) – (x, y) position of the title in figure coordinates (0 to 1). Default is (0.2, 0.85).

  • **kwargs – Passed to Mayavi functions.

Examples

>>> from eqsp.visualizations import show_s2_partition
>>> from mayavi import mlab
>>> mlab.options.offscreen = True
>>> try:
...     show_s2_partition(4, title='short', show_points=False)
...     print("Success") # Crude check as Mayavi is hard to doctest
... except ImportError:
...     print("Mayavi not installed")
Success
eqsp.visualizations.show_s2_region(region, N, fidelity=32)[source]

Illustrate a region of S^2.

eqsp.visualizations.show_s2_sphere(opacity=0.95, color=(0, 1, 0))[source]

Illustrate the unit sphere S^2.