Esto se llama distribución normal truncada:
http://en.wikipedia.org/wiki/Truncated_normal_distribution
Christian Robert escribió sobre un enfoque para hacerlo en una variedad de situaciones (usando diferentes dependiendo de dónde estaban los puntos de truncamiento) aquí:
Robert, CP (1995) "Simulación de variables normales truncadas",
Estadística e informática, Volumen 5, Número 2, junio, pp 121-125
Documento disponible en http://arxiv.org/abs/0907.4010
Esto discute una serie de ideas diferentes para diferentes puntos de truncamiento. No es la única forma de abordarlos de ninguna manera, pero generalmente tiene un rendimiento bastante bueno. Si desea hacer muchas normales truncadas diferentes con varios puntos de truncamiento, sería un enfoque razonable. Como notó, msm::tnorm
se basa en el enfoque de Robert, mientras truncnorm::truncnorm
implementa el muestreador de aceptación / rechazo de Geweke (1991); Esto está relacionado con el enfoque en el artículo de Robert. Tenga en cuenta que msm::tnorm
incluye las funciones de densidad, cdf y cuantil (cdf inverso) de la R
manera habitual .
Una referencia más antigua con un enfoque es el libro de Luc Devroye ; desde que se agotó, recuperó los derechos de autor y lo puso a disposición como descarga.
Su ejemplo particular es lo mismo que muestrear un estándar normal truncado en 1 (si es el punto de truncamiento, ), y luego escalar el resultado (multiplicar por y agregar ).t( t - μ ) / σ= ( 5 - 3 ) / 2 = 1σμ
En ese caso específico, Robert sugiere que su idea (en la segunda o tercera encarnación) es bastante razonable. Obtiene un valor aceptable aproximadamente el 84% del tiempo y, por lo tanto, genera aproximadamente normales en promedio (puede calcular límites para generar suficientes valores usando un algoritmo vectorizado, digamos el 99.5% del tiempo, y luego de vez en cuando generar los últimos menos eficientemente, incluso uno a la vez).1.19 n
También se discute una implementación en el código R aquí (y en Rccp en otra respuesta a la misma pregunta, pero el código R allí es en realidad más rápido). El código R simple allí genera 50000 normales truncadas en 6 milisegundos, aunque esa normal truncada en particular solo corta las colas extremas, por lo que un truncamiento más sustancial significaría que los resultados fueron más lentos. Implementa la idea de generar "demasiados" calculando cuántos debería generar para estar seguro de obtener suficiente.
Si necesitara un tipo particular de normal truncado muchas veces, probablemente buscaría adaptar una versión del método zigurat, o algo similar, al problema.
De hecho, parece que Nicolas Chopin ya lo hizo, así que no soy la única persona que se le ocurrió:
http://arxiv.org/abs/1201.6140
Analiza varios otros algoritmos y compara el tiempo para 3 versiones de su algoritmo con otros algoritmos para generar 10 ^ 8 normales al azar para varios puntos de truncamiento.
Quizás, como era de esperar, su algoritmo resulta ser relativamente rápido.
Del gráfico en el documento, incluso el algoritmo más lento con el que se compara en (para ellos) los peores puntos de truncamiento están generando valores en aproximadamente 3 segundos, lo que sugiere que cualquiera de los algoritmos discutidos allí puede ser aceptable si es razonable Bien implementado.108
Editar: Uno que no estoy seguro se menciona aquí (pero tal vez está en uno de los enlaces) es transformar (a través de cdf normal inverso) un uniforme truncado, pero el uniforme se puede truncar simplemente generando un uniforme dentro de los límites de truncamiento . Si el cdf normal inverso es rápido, esto es rápido y fácil y funciona bien para una amplia gama de puntos de truncamiento.