4

I'm looking for an analogue of SpherePoints that works in dimensions higher than 3, has this been created already?

A random sample from unit ball will be approximately evenly spaced already, so was looking for something that's more evenly spaced than a typical random sample. Such sample gives a slightly lower variance estimator when estimating a directional statistic.

Yaroslav Bulatov
  • 7,793
  • 1
  • 19
  • 44
  • 3
    For 100 points uniformly distributed on a unit sphere in R^5: RandomPoint[Sphere[5], 100] – Bob Hanlon Jul 06 '21 at 18:33
  • I tried using a HardcorePointProcess in a thin $d$-spherical shell and this works to produce equidistant looking distributions in 3d and 2d, but unfortunately this only reduces the left tail of the distance histogram (i.e prevents clumping but doesn't prevent gaps) and it looks good in 2d and 3d but not sure if it produces what you need - nowhere near as tight as SpherePoints - I could show this in an answer if you want but it's not really a solution. It also doesn't let you generate n points because it's based on point intensity. – flinty Jul 06 '21 at 21:36
  • 1
    Perhaps this answer, particularly Thomas Ahle 's comment, could be of use? – flinty Jul 06 '21 at 21:39

1 Answers1

2

No, Mathematica doesn't have a built in function for equidistant points on hyperspheres so you'll have to do it yourself. This simulates the 'electrostatic repulsion' of points and is unfortunately very slow for many points - it's a $\mathcal{O}(n^2)$ algorithm.

update[points_] :=
 Normalize /@ (Total[
    Outer[Subtract, points, points, 
      1]/(DistanceMatrix[points, 
          DistanceFunction -> SquaredEuclideanDistance] + 
          IdentityMatrix[Length@points])])

(** measure the standard deviation of nearest point distance

  • lower means more equidistant **)

stdev[points_] := With[{nf = Nearest@points}, StandardDeviation[EuclideanDistance[#, Last@nf[#, 2]] & /@ points]]

SeedRandom[1]; dimensions = 5; iterations = 8; init = RandomPoint[Sphere[dimensions], 500]; result = Nest[update, init, iterations]; stdev[init] (* 0.0824725 ) stdev[result] ( 0.0389372 *)

flinty
  • 25,147
  • 2
  • 20
  • 86
  • BTW, just discovered built-in HardcorePointProcess which uses "birth-death point process" to randomly sample points not close to each other. However, it's for Euclidian space, not sphere. One of their examples samples from surface of the Earth, but this feels incorrect https://wolfram.com/xid/0g38do4fqet8yf872-h6txtp – Yaroslav Bulatov Aug 26 '21 at 13:10
  • 1
    @YaroslavBulatov yeah I tried this (in the comment) by using a region (intersection of a Ball and a slightly smaller ball as the region (a thin shell so that the region has enough volume to sample from). Unfortunately, while it looks equidistant, the distribution only limits the min distance tail - the max distance tail will be really long, and you can see this because the distribution of points has unpopulated areas / 'holes' in it. The variance reduction effect is only slight. – flinty Aug 26 '21 at 13:21