@ginko's comment is correct - you can fix the algorithm by throwing out any points that lie outside the sphere before normalizing.
One of the advantages of the normal-sampling route over @ginko's rejection-based method is that in high dimensions almost all of the volume of the unit cube is situated outside of the unit sphere (the volume of the unit cube is always 1, whereas the volume of the unit sphere decreases exponentially with dimension). So the rejection method becomes exponentially slow in high dimensions, while the Gaussian method still works just fine.
Other simple distributions tend to give biases towards the corners or axis. Perhaps the Gaussian is unique in this regard? I'm not sure.
I think I found one, but I'm not sure:
Without loss of generality, take f(xi) = k1 * exp(-g(xi)) [1], for some g. Then we need the joint pdf to satisfy f(x1,...,xn) = k2 * exp(-h(R^2)), R=sum(xi^2)^1/2 (the R^2 and h(.) is w.l.g. too). So we get g(x1)+g(x2)=h(x1^2+x2^2). Then assuming the functions g and h analytic we end up needing g(x)= k * x^2, otherwise we get cross terms in the Taylor expansion that can't be cancelled out for all xi. Sounds good?
[1] The function f trivially needs to be symmetric, justifying no loss of generality.
I wanted to make sure I got a proof, since I didn't really find this elsewhere.
But that pdf is also the joint pdf of N i.i.d. gaussians, evident by decomposing f=a * exp(-x1^2) * ... * exp(-xN^2) [2], which is the joint pdf x1,...xN s.t. fx1=c * exp(-x1^2), ..., fxn=c * exp(-xN^2).
[1] Since exp(-R^2) does not depend on direction but only on distance from the origin
[2] The fact that f(x1,...xN)=f1 * ... * fN if x1,...xN are independent follows directly from the fact that P(A & B) = P(A)*P(B) if A and B are independent events.
So your solution ends up pretty much using the same math (while probably calling cos a few more times) and throwing away at least one random number and possibly half of them (depending on the implementation of randn).
For example:
https://www.gnu.org/software/gsl/manual/html_node/Spherical-...
[0] http://mathworld.wolfram.com/SpherePointPicking.html [1] http://stats.stackexchange.com/questions/7977/how-to-generat...
You need to work harder than that, as most of the other comments are pointing out.
V_{2k} = pi^k/k!
For 10 dimensions, the hypersphere is of volume 2.55, but the enclosing box is of volume 2^10 = 1024. So roughly one in 400 trials gets you a point inside the sphere. Not good odds.In terms of CPU power, calculating the length of the vector and doing a branch, I think, is going to be slower then the proper way to do it.
This works because the normal distribution is rotationally symmetric, so each sample is essentially a random unit vector scaled by a random (normally distributed) radius. Once you remove the variation in radius you just get back the random unit vector, i.e. a point on the unit sphere.