Python Distribución uniforme de puntos en esfera 4 dimensional.

Necesito una distribución uniforme de puntos en una esfera de 4 dimensiones. Sé que esto no es tan trivial como escoger 3 angularjs y usar coordenadas polares.

En 3 dimensiones utilizo

from random import random u=random() costheta = 2*u -1 #for distribution between -1 and 1 theta = acos(costheta) phi = 2*pi*random x=costheta y=sin(theta)*cos(phi) x=sin(theta)*sin(phi) 

Esto da una distribución uniforme de x, y y z.

¿Cómo puedo obtener una distribución similar para 4 dimensiones?

    Sin embargo, una forma estándar , quizás no sea la más rápida , es usar el método de Muller para generar puntos distribuidos uniformemente en una N-esfera:

     import numpy as np import matplotlib.pyplot as plt import mpl_toolkits.mplot3d.axes3d as axes3d N = 600 dim = 3 norm = np.random.normal normal_deviates = norm(size=(dim, N)) radius = np.sqrt((normal_deviates**2).sum(axis=0)) points = normal_deviates/radius fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) ax.scatter(*points) ax.set_aspect('equal') plt.show() 

    introduzca la descripción de la imagen aquí

    Simplemente cambie dim = 3 a dim = 4 para generar puntos en una 4 esfera.

    Toma cualquier punto al azar en el espacio 4D y calcula su vector unitario. Esto estará en la unidad de 4 esferas.

     from random import random import math x=random.normalvariate(0,1) y=random.normalvariate(0,1) z=random.normalvariate(0,1) w=random.normalvariate(0,1) r=math.sqrt(x*x + y*y + z*z + w*w) x/=r y/=r z/=r w/=r print (x,y,z,w) 

    Me gusta la respuesta de @unutbu si el muestreo gaussiano realmente crea una distribución esférica espaciada uniformemente (a diferencia del muestreo de un cubo), pero para evitar el muestreo en una distribución gaussiana y tener que probar eso, hay una solución simple: muestrear en un uniforme Distribución en una esfera (no en un cubo).

    1. Generar puntos en una distribución uniforme .
    2. Calcule el radio al cuadrado de cada punto (evite la raíz cuadrada).
    3. Puntos de descarte :
      • Puntos de descarte para los cuales el radio al cuadrado es mayor que 1 (por lo tanto, para el cual el radio sin cuadrar es mayor que 1).
      • Descarte los puntos demasiado cerca de un radio de cero para evitar inestabilidades numéricas relacionadas con la división en el siguiente paso.
    4. Para cada punto muestreado mantenido, divida el punto muestreado por la norma para volver a normalizarlo el radio de la unidad.
    5. Lavar y repetir para obtener más puntos debido a las muestras desechadas.

    Obviamente, esto funciona en un espacio n-dimensional, ya que el radio es siempre la norma L2 en dimensiones más altas.

    Es rápido para evitar una raíz cuadrada y muestrear en una distribución gaussiana, pero no es un algoritmo vectorizado.

    Encontré una buena solución para el muestreo de la esfera N-dim. La idea principal es:

    Si Y se extrae de la distribución normal multivariable no correlacionada, entonces S = Y / || Y || Tiene la distribución uniforme en la unidad d-esfera. Al multiplicar S por U 1 / d , donde U tiene la distribución uniforme en el intervalo unitario (0,1), se crea la distribución uniforme en la bola d-dimensional de la unidad.

    Aquí está el código de python para hacer esto:

     Y = np.random.multivariate_normal(mean=[0], cov=np.eye(1,1), size=(n_dims, n_samples)) Y = np.squeeze(Y, -1) Y /= np.sqrt(np.sum(Y * sample_isotropic, axis=0)) U = np.random.uniform(low=0, high=1, size=(n_samples)) ** (1/n_dims) Y *= distr * radius # in my case radius is one 

    Esto es lo que obtengo para la esfera:

    esfera