Solución:
Si desea un vector aleatorio solo porque necesita un vector arbitrario y realmente no le importa cuál es, entonces el método del Sr.Wizard para elegir tres coordenadas aleatorias en [-1,1] trabajará. Pero si te preocupan las propiedades estadísticas de tu vector y, en particular, si quieres que se extraiga de una distribución uniforme sobre la superficie de la esfera, tendrás que hacer algo un poco más complicado. La razón se explica en esta página de MathWorld, pero básicamente las direcciones de las esquinas del cubo tienen más puntos para elegir, por lo que serán más probables.
La misma página sugiere varios métodos para elegir un vector distribuido uniformemente sobre la superficie de la esfera. Una forma sería transformar números aleatorios distribuidos uniformemente $ u in[0,1], v in[-1,1]$ en los ángulos de coordenadas esféricas como
$$ begin {align} theta & = 2 pi u & phi & = cos ^ {- 1} v end {align} $$
y luego calcular los componentes del vector unitario correspondiente como
$$ begin {align} x & = cos theta sin phi & y & = sin theta sin phi & z & = cos phi end {align} $$
Podrías resumir esto en una función como
randomVec[r_] := With[{theta=2*Pi*RandomReal[],[email protected][{-1,1}]},
r*{Cos[theta]Sin[phi],Sin[theta]Sin[phi],Cos[phi]}]
Puede notar que $ z = v $ con este método, por lo que podría intentar “optimizar” el cálculo estableciendo directamente $ z = v $ y calculando $ sin phi = sqrt {1 – z ^ 2} $, pero no creo que eso vaya a ahorrar mucho tiempo en el cálculo; de todos modos, Mathematica no es un lenguaje de programación particularmente optimizado para la velocidad. (Y en realidad podría hacer esa optimización por sí solo, no estoy seguro).
Un método diferente es elegir tres números aleatorios gaussianos y normalizar el vector resultante:
randomVec[r_] := r * [email protected][NormalDistribution[], 3]
La respuesta de David ha dado los métodos para producir puntos aleatorios que se distribuyen uniformemente sobre la superficie de la esfera. Por supuesto, existen otras distribuciones de probabilidad en la esfera que son de interés, así como una serie de métodos para generarlas. Por ejemplo, aquí se explica cómo generar un vector unitario aleatorio que sigue la distribución de von Mises-Fisher, según la propuesta que se presenta aquí:
vonMisesFisherRandom[μ_?VectorQ, κ_?NumericQ] := Module[{ξ = RandomReal[], w},
w = 1 + (Log[ξ] + Log[1 + (1 - ξ) Exp[-2 κ]/ξ])/κ;
RotationTransform[{{0, 0, 1}, Normalize[μ]}][
Append[Sqrt[1 - w^2] Normalize[RandomVariate[NormalDistribution[], 2]], w]]]
(Anteriormente había usado este generador para esta respuesta).
La distribución seguida por el generador dado arriba es completamente análoga a la incorporada VonMisesDistribution[μ, κ]
; $ mu $ aquí es la llamada “dirección media”, y $ kappa $ es el “parámetro de concentración”. Los valores grandes de $ kappa $ producen puntos que están más agrupados en la dirección $ mu $.
Este artículo también puede ser de interés.
Como demostración de la distribución de von Mises-Fisher, aquí está el resultado de generar $ 10 ^ 4 $ vectores unitarios aleatorios a partir de esta distribución, con respecto a la dirección media fija $ mu = left (- tfrac1 { sqrt 8} ; – sqrt { tfrac38} ; frac1 { sqrt 2} right) ^ top $ y parámetro de concentración variable $ kappa $. Tenga en cuenta la agrupación alrededor de $ mu $ que mencioné anteriormente como $ kappa $ aumenta.
Código de la imagen:
With[{μ = {-1/Sqrt[8], -Sqrt[3/8], 1/Sqrt[2]}},
GraphicsGrid[Partition[
Table[Graphics3D[{AbsolutePointSize[1],
Point[Table[vonMisesFisherRandom[μ, κ], {10^4}]]},
PlotLabel -> StringForm["κ=`1`", κ]],
{κ, {1/2, 1, 4, 8}}], 2]]]
Como otro ejemplo de una distribución esférica no trivial, aquí hay rutinas para generar un vector unitario aleatorio que sigue la distribución de Dimroth-Watson, utilizando el método propuesto en este artículo:
(* special case; κ = 0 is the uniform distribution *)
dimrothWatsonRandom[μ_?VectorQ, κ_ /; κ == 0] :=
Normalize[RandomVariate[NormalDistribution[], 3]]
dimrothWatsonRandom[μ_?VectorQ, κ_ /; NumericQ[κ] && Positive[κ]] := Module[{c, u, v, w},
c = Exp[-κ/2] Csch[κ/2]/2;
While[
{u, v} = RandomReal[1, 2]; w = Log[1 + u/c]/κ;
v > Exp[κ w (w - 1)]];
RotationTransform[{{0, 0, 1}, Normalize[μ]}][Append[
Sqrt[1 - w^2] Normalize[RandomVariate[NormalDistribution[], 2]], RandomChoice[{-1, 1}] w]]]
dimrothWatsonRandom[μ_?VectorQ, κ_ /; NumericQ[κ] && Negative[κ]] := Module[{c, d, u, v, w},
c = Sqrt[-κ]; d = ArcTan[c];
While[
{u, v} = RandomReal[1, 2]; w = Tan[d u]/c;
v > (1 - κ w^2) Exp[κ w^2]];
RotationTransform[{{0, 0, 1}, Normalize[μ]}][Append[
Sqrt[1 - w^2] Normalize[RandomVariate[NormalDistribution[], 2]], RandomChoice[{-1, 1}] w]]]
Al igual que con la distribución de von Mises-Fisher, $ mu $ es una dirección media y $ kappa $ es un parámetro de concentración; aquí, sin embargo, el comportamiento de agrupamiento de las variantes depende del signo de $ kappa $. Para $ kappa> 0 $, la distribución de Dimroth-Watson se denomina bipolar, con las variables agrupadas alrededor del eje determinado por $ mu $, mientras que para $ kappa <0 $, la distribución se denomina faja, con las variantes agrupadas alrededor del gran círculo perpendicular al eje determinado por $ mu $.
Aquí está el resultado de generar $ 10 ^ 4 $ vectores unitarios aleatorios a partir de la distribución de Dimroth-Watson, con dirección media $ mu = (0 ; 0 ; 1) ^ top $ y varios valores de $ kappa $:
RandomPoint
hace que este sea un trazador de líneas (a partir de la versión 10.2):
RandomPoint[Sphere[{0, 0, 0}, 4]]
{1.80874, 3.43311, -0.970669}
O consiga varios puntos a la vez:
RandomPoint[Sphere[{0, 0, 0}, 4], 10]
{{-2.15717, -0.871558, -3.25377}, {1.65153, 2.06714, -2.99989}, {-0.798, 3.91915, -0.0591287}, {-2.19946, 3.2677, 0.696074}, {3.21113, 2.00556, 1.29087}, {1.13529, -0.792109, 3.75282}, {3.51176, -1.82698, 0.574145}, {-1.25466, -2.03064, 3.20972}, {3.9609, 0.552069, 0.0803608}, {1.81014, 1.09316, 3.39535}}
Además, hay una buena publicación en el blog sobre esta función.