Está bien, parecen ser bastante confundido acerca de varias cosas. Comencemos por el principio: mencionaste una "función multidimensional", pero luego pasas a discutir la curva gaussiana usual de una variable. Esto es no una función multidimensional: cuando la integra, solo integra una variable (x). Es importante hacer la distinción, porque es un monstruo llamado "distribución gaussiana multivariante" que es una verdadera función multidimensional y, si está integrada, requiere integrar más de dos o más variables (que usa la costosa técnica de Monte Carlo que mencioné antes)) Pero parece que solo estás hablando del Gaussiano regular de una variable, que es mucho más fácil de trabajar, integrar y todo eso.
La distribución de Gauss de una variable tiene dos parámetros, sigma
y mu
, y es una función de una sola variable que vamos a denotamos x
. También parece llevar un parámetro de normalización n
(que es útil en un par de aplicaciones). Los parámetros de normalización generalmente son no incluidos en los cálculos, ya que puede volverlos a conectar al final (recuerde, la integración es un operador lineal: int(n*f(x), x) = n*int(f(x), x)
). Pero podemos llevarlo a cabo si lo desea; la notación me gusta para una distribución normal es entonces
N(x | mu, sigma, n) := (n/(sigma*sqrt(2*pi))) * exp((-(x-mu)^2)/(2*sigma^2))
(leído que como "la distribución normal de x
dado sigma
, mu
y n
está dada por ...") Hasta ahora, todo va bien; esto coincide con la función que tienes. Observe que la única verdadera variable aquí es x
: los otros tres parámetros son fijo para cualquier gaussiano en particular.
Ahora, por un hecho matemático: es probable que todas las curvas de Gauss tengan la misma forma, simplemente se desplazan un poco. Entonces podemos trabajar con N(x|0,1,1)
, llamado "distribución normal estándar", y simplemente traducimos nuestros resultados a la curva general de Gauss. Entonces, si tiene la integral de N(x|0,1,1)
, puede calcular trivialmente la integral de cualquier gaussiano. Esta integral aparece con tanta frecuencia que tiene un nombre especial: la función de error erf
. Debido a algunas convenciones antiguas, no es exactamenteerf
; hay un par de factores aditivos y multiplicativos que también se transportan.
Si Phi(z) = integral(N(x|0,1,1), -inf, z)
; es decir, Phi(z)
es la integral de la distribución normal estándar de menos infinito hasta z
, entonces es cierto por la definición de la función de error que
Phi(z) = 0.5 + 0.5 * erf(z/sqrt(2))
.
Del mismo modo, si Phi(z | mu, sigma, n) = integral(N(x|sigma, mu, n), -inf, z)
; es decir, Phi(z | mu, sigma, n)
es la integral de los parámetros de distribución normal dadas mu
, sigma
, y n
de menos infinito hasta z
, entonces es cierto por la definición de la función de error que
Phi(z | mu, sigma, n) = (n/2) * (1 + erf((x - mu)/(sigma * sqrt(2))))
.
Eche un vistazo a the Wikipedia article on the normal CDF si quiere más detalles o una prueba de esto.
Bueno, eso debería ser suficiente explicación de fondo. De vuelta a su publicación (editada). Usted dice "El erf (z) en scipy.special requeriría que defina exactamente qué t es inicialmente". No tengo idea de lo que quieres decir con esto; ¿dónde entra t
(¿tiempo?) en esto? Afortunadamente, la explicación anterior ha desmitificado un poco la función de error y ahora está más claro por qué la función de error es la función correcta para el trabajo.
Su código Python está bien, pero yo preferiría un cierre sobre una lambda:
def make_gauss(N, sigma, mu):
k = N/(sigma * math.sqrt(2*math.pi))
s = -1.0/(2 * sigma * sigma)
def f(x):
return k * math.exp(s * (x - mu)*(x - mu))
return f
Usando un cierre permite precomputation de constantes k
y s
, por lo que la función devuelta tendrá que hacer menos trabajo cada vez se llama (lo cual puede ser importante si lo está integrando, lo que significa que será llamado muchas veces). Además, he evitado el uso del operador de exponenciación **
, que es más lento que solo escribir la cuadratura, y he levantado la división del ciclo interno y la he reemplazado por una multiplicación. No he visto en absoluto su implementación en Python, pero desde la última vez que sintonicé un bucle interno para velocidad pura usando el ensamblaje x87 sin procesar, me parece recordar que agrega, resta o multiplica toma alrededor de 4 ciclos de CPU cada uno, se divide sobre 36, y exponenciación de aproximadamente 200. Eso fue hace un par de años, así que tome esos números con un grano de sal; aún así, ilustra su complejidad relativa. Además, calcular exp(x)
el modo de fuerza bruta es una muy mala idea; hay trucos que puede tomar al escribir una buena implementación de exp(x)
que lo hacen significativamente más rápido y más preciso que una exponenciación de estilo general a**b
.
Nunca he usado la versión numpy de las constantes pi y e; Siempre me he quedado con las versiones simples del módulo de matemáticas. No sé por qué podrías preferir cualquiera de los dos.
No estoy seguro de lo que está buscando con la llamada quad()
. quad(gen_gauss, -inf, inf, (10,2,0))
debe integrar un gaussiano renormalizado de menos infinito a más infinito, y siempre debe escupir 10 (su factor de normalización), ya que Gaussian se integra a 1 sobre la línea real. Cualquier respuesta lejos de 10 (no esperaría que exactamente 10 ya que quad()
es sólo una aproximación) significa que algo está arruinado en algún lado ... es difícil decir lo que se estropeó sin conocer el valor de retorno real y posiblemente el valor interno funcionamientos de quad()
.
Esperemos que esto haya desmitificado parte de la confusión y haya explicado por qué la función de error es la respuesta correcta a su problema, y cómo hacerlo todo usted mismo si tiene curiosidad. Si alguna de mis explicaciones no estaba clara, sugiero echar un vistazo rápido a Wikipedia primero; si todavía tiene preguntas, no dude en preguntar.
una distribución gaussiana de números o de datos. Parece un bache o "curva de campana" si se traza. – physicsmichael
Coloquialmente, gaussian se usa como sustantivo para representar una curva o distribución gaussiana (es algo común en la entrada de Wikipedia, por ejemplo). Supongo que deberíamos escribir con mayúsculas también, pero SO es un lugar bastante coloquial, ¿no? – physicsmichael
Un gaussiano es un gaussiano es un gaussiano, no importa qué nombre modifique. Salga con los estúpidos argumentos semánticos que no agregan nada. – temp2290