For a user specified magnitude, is there a way to have Mathematica produce any 3D vector that fits that magnitude?
|
migrated from stackoverflow.com Oct 14 '12 at 16:45
|
If you want a random vector just because you need some arbitrary vector and you don't really care what it is, then Mr.Wizard's method of picking three random coordinates in [-1,1] will work. But if you care about the statistical properties of your vector, and in particular if you want it drawn from a uniform distribution over the surface of the sphere, then you'll have to do something a little more complicated. The reason is explained on this MathWorld page, but basically the directions of the corners of the cube have more points to pick from, so they're going to be more likely. The same page suggests several methods of picking a vector uniformly distributed over the sphere's surface. One way would be to transform uniformly distributed random numbers $u\in[0,1],v\in[-1,1]$ into the spherical coordinate angles as $$\begin{align}\theta &= 2\pi u & \phi &= \cos^{-1}v\end{align}$$ and then compute the components of the corresponding unit vector as $$\begin{align} x &= \cos\theta\sin\phi & y &= \sin\theta\sin\phi & z &= \cos\phi \end{align}$$ You could wrap this up into a function as
You may notice that $z = v$ with this method, so you could try to "optimize" the calculation by directly setting $z = v$ and calculating $\sin\phi = \sqrt{1 - z^2}$, but I don't think that's going to save much time in the computation - it's not like Mathematica is a particularly speed-optimized programming language anyway. (And it might actually make that optimization on its own, I'm not sure.) A different method is to choose three Gaussian random numbers and normalize the resulting vector:
|
|||||||||||
|
|
David's answer has given the methods for producing random points that are uniformly distributed over the surface of the sphere. Of course, there are other probability distributions on the sphere that are of interest, as well as a number of methods for generating them. For instance, here is how to generate a random unit vector which follows the von Mises-Fisher distribution, based on the proposal given here:
(I had previously used this generator for this answer.) The distribution followed by the generator given above is completely analogous to the built-in This paper might also be of interest. As a demonstration of the von Mises-Fisher distribution, here is the result of generating $10^4$ random unit vectors from this distribution, with respect to the fixed mean direction $\mu=\left(-\tfrac1{\sqrt 8}\;-\sqrt{\tfrac38}\;\frac1{\sqrt 2}\right)^\top$ and varying concentration parameter $\kappa$. Note the clustering around $\mu$ that I mentioned earlier as $\kappa$ increases.
Code for the image:
As another example of a nontrivial spherical distribution, here are routines for generating a random unit vector which follows the Dimroth-Watson distribution, using the method proposed in this paper:
As with the von Mises-Fisher distribution, $\mu$ is a mean direction, and $\kappa$ is a concentration parameter; here, however, the clustering behavior of the variates depends on the sign of $\kappa$. For $\kappa > 0$, the Dimroth-Watson distribution is termed bipolar, with the variates clustering about the axis determined by $\mu$, while for $\kappa < 0$, the distribution is termed girdle, with the variates clustered about the great circle perpendicular to the axis determined by $\mu$. Here is the result of generating $10^4$ random unit vectors from the Dimroth-Watson distribution, with mean direction $\mu=(0\;0\;1)^\top$ and various values of $\kappa$:
|
|||||
|
|
I think kunkelwe's answer is on the right track but not quite there. This seems better to me:
Test:
David Zaslavsky shows that this too is incomplete. I shall graphically compare my incorrect result with his:
|
|||||||
|
|
A very simple way to get over the corner problem is to generate random points in the cube and throw away any that are outside the sphere.
|
|||||
|
|
This should work:
A 3-dimensional vector in Mathematica is just a 3-element list of the components, so we make a random 3-element list, normalize it to a unit vector, and then multiply it by the desired magnitude. |
|||||
|






