views:

80

answers:

3

Using Matlab, how to generate a net of 3^10 points that are evenly located (or distributed) on the 8-dimensional unit sphere?

Thanks for any helpful answers!

A: 

OK, on Wikipedia we read that

an n-sphere of radius r is defined as the set of points in (n + 1)-dimensional Euclidean space which are at distance r from a central point, where the radius r may be any positive real number

so your problem becomes one of generating 3^10 vectors in 7-space. Without losing anything we can let r = 1. The approach will be to generate random vectors in 7-space and then normalise them to unit length in the usual way

Here's some code I knocked up in a hurry, I know I should have vectorised things and not written loops, I'll leave that to OP. The code shouldn't need any explanation.

pointset = rand(3^10,7);
normset = zeros(3^10,1);
for ix = 1:3^10
  normset(ix) = norm(pointset(ix,:));
end
for ix = 1:3^10
  pointset(ix,:) = pointset(ix,:)/normset(ix);
end

This relies, of course, on Matlab's PRNG produding uniformly distributed numbers to create a uniformly distributed net on the 8-sphere.

High Performance Mark
I think that to get a uniform distribution on the surface, you would need to replace rand with randn (the values need to be gaussian distributed, not uniformly distributed). I'm sure that if you use rand, you at least need to subtract off 1/2, otherwise all your points will be in the first hyperquadrant (x_j > 0 for all x,j).
Marc
+2  A: 

A simple way to get points on the n-d unit sphere is to create an n-d cube, cut away the corners, and normalize the remaining radii to 1. Note that without the cutting, the distribution won't be uniform.

However, since the volume of the hypersphere relative to the enclosing box decreases as the dimensionality goes up, this is not a particularly efficient way.

A better way is to generate an array of n-d normally distributed points (radii), and to normalize them to the radius of the sphere - the n-d normal distribution is radially symmetric, and thus the distribution on the surface will be uniform

%# set-up
nPoints = 3^10;
nDim = 8;

%# create normally distributed variables
points = randn(nPoints,nDim);

%# normalize by dividing by the norm (=square root of sum(points.^2,2) )
points = bsxfun(@rdivide,points,sqrt(sum(points.^2,2)));
Jonas
should be sqrt(sum(points.^2,2))
Marc
@Marc: Thank you for spotting this!
Jonas
A: 

from wikipedia n-sphere

To generate uniformly distributed random points on the (n − 1)-sphere (i.e., the surface of the n-ball), Marsaglia (1972) gives the following algorithm.

Generate an n-dimensional vector of normal deviates (it suffices to use N(0, 1), although in fact the choice of the variance is arbitrary), \mathbf{x}=(x_1,x_2,\ldots,x_n).

Now calculate the "radius" of this point, r=\sqrt{x_1^2+x_2^2+\cdots+x_n^2}.

The vector \frac{1}{r} \mathbf{x} is uniformly distributed over the surface of the unit n-ball.

A matlab code fragment that accomplishes this is:

numdims = 8;
numpts = 3^10;
x = randn([numdims numpts]);
lx = repmat(sqrt(sum(x.^2,1)), [numdims 1]);
x = x./lx;
%x(:,j) is the jth point on the circle)
Marc

related questions