EJERCICIOS PROPUESTOS

  1. Dar un algoritmo para simular la variable aleatoria continua con densidad \[ f(x)=\left(\frac{2x}{e^x}\right)^2, \space si \space x\geq0, \] utlizando, de forma auxiliar, el generador de una exponencial de parámetro uno. Comentar su eficiencia.
# Densidad ejercicio 1
f <- function(x){
  ((2*x)/(exp(x)))^2
}

c <- optimize(f=function(x){f(x)/dexp(x)}, maximum=TRUE, interval=c(0,4))
c.opt <- c$objective

cat("c óptimo = ", c.opt)
## c óptimo =  2.165365
curve(c.opt * dexp(x), xlim = c(0, 4), col='red',lwd=2, lty = 2)
curve(f(x), col='blue', lwd=2, add = TRUE)

#definimos las siguientes funciones basadas en el método de aceptacion-rechazo

lambda.opt <- 1
rfR <- function() {
  # Simulación por aceptación-rechazo
  # f a partir de una exponencial
  while (TRUE) {
    U <- runif(1)
    X <- rexp(1)
    ngen <<- ngen+1 
    if (c.opt * U * dexp(X, lambda.opt) <= f(X)) return(X)
  }
}

rfRn <- function(n=1000) {
  # Simulación n valores 
  x <- numeric(n)
  for(i in 1:n) x[i]<-rfR()
  return(x)
}

set.seed(500)
ngen <- 0
system.time(w <- rfRn(10^4))
##    user  system elapsed 
##    0.62    0.13    1.20
hist(w, breaks="FD", freq=FALSE)
curve(f(x), col='red',add=TRUE)

cat("Nº de generaciones = ", ngen)
## Nº de generaciones =  21598
cat("\nNº medio de comparaciones = ", ngen/10^4)
## 
## Nº medio de comparaciones =  2.1598
cat("\nProporción de rechazos = ", 1-10^4/ngen, "\n")
## 
## Proporción de rechazos =  0.5369942

Notemos que el numero medio de comparaciones no es ediciente pues este no se acerca tanto a 1 como se esperaria.

  1. Dada una variable aleatoria continua con funcion de densidad \[ F(x)= \left\{ \begin{array}{lcc} 6x(1-x) & si & x \in [0,1] \\ \\ 0 & si & en\space otro\space caso \end{array} \right. \] dar un algoritmo para simular valores de la misma. Analizar la eficiencia de dicho algoritmo.
# Densidad ejercicio 2
f2 <- function(x){
  if (x>=0 && x<=1)
  {
    6*x*(1-x)
  }
  else
  {
    0
  }
}

c <- optimize(f=function(x){f2(x)/dunif(x,0,1)}, maximum=TRUE, interval=c(0,1))
c.opt <- c$objective

cat("c Óptimo = ", c.opt)
## c Óptimo =  1.5
curve(c.opt * dunif(x,0,1), xlim = c(0, 1), col='red',lwd=2, lty = 2)
curve(f2(x),col='blue',lwd=2, add = TRUE)

#Basandonos en el método de aceptacion-rechazo (a partir de una U(0,1) consideramos

rfR <- function() {
  while (TRUE) {
    U <- runif(1)
    X <- runif(1,0,1)
    ngen <<- ngen+1 
    if (c.opt * U * dunif(X,0,1) <= f2(X)) return(X)
  }
}

rfRn <- function(n=1000) {
  # Simulación n valores 
  x <- numeric(n)
  for(i in 1:n) x[i]<-rfR()
  return(x)
}

#verificando la eficiencia del algoritmo
set.seed(500)
ngen <- 0

system.time(x <- rfRn(10^4))
##    user  system elapsed 
##    0.42    0.00    0.70
hist(x, breaks="FD", freq=FALSE)
curve(f2(x), col='red',lwd=2,add=TRUE)

cat("Nº de generaciones = ", ngen)
## Nº de generaciones =  15034
cat("\nNº medio de generaciones = ", ngen/10^4)
## 
## Nº medio de generaciones =  1.5034
cat("\nProporción de rechazos = ", 1-10^4/ngen, "\n")
## 
## Proporción de rechazos =  0.334841
cat( ngen/10^4)
## 1.5034

Notemos que es considerablemente eficiente pues su numero medio de generaciones es cercano a 1.

  1. Al bombardear una lámina circular de radio 1cm, hecha de plata, con partículas \(\alpha\), la distancia de cada impacto al centro del círculo resulta ser una variable aleatoria continua con función de densidad dada por \(f(x)=3x^2\), si \(0\leq x\leq1\). Detallar un algoritmo, lo mas sencillo posible, para simular la distancia al centro de la lámina en sucesivos impactos.

Considerando \(F\) como la funcion de distribucion

\[ F(x) = \int_{0}^{x}f(t)dt\ = \int_{0}^{x} 3t^{2}dt\ = 3 \left.\left(\frac{t^{3}}{3}\right)\right|^{x}_{0}\ = x^{3} \]

Notemos que es inversible en \([0,1]\), asi.

\[ F(x)= \left\{ \begin{array}{lcc} 0 & \text{si } x < 0 \\ x^{3} & \text{si } x \in [0,1] \\ 1 & \text{si } x>1 \end{array} \right.. \]

# Densidad ejercicio 3
f3 <- function(x){
  if (x>=0 && x<=1)
  {
    3*(x^2)
  }
  
}

pF <- function(x){
  ifelse((x<0),0,
         ifelse((x<=1),x^{3},0))
}

#Usando el método de inversion

rfR <- function(){
  U <- runif(1)
  return((U)^(1/3))
  
}

rfRn <- function(n = 1000) {
  # Simulación n valores 
  x <- numeric(n)
  for(i in 1:n) x[i]<-rfR()
  return(x)
}

#verificando la eficiencia del algoritmo
set.seed(500)
system.time(x <- rfRn(10^4))
##    user  system elapsed 
##    0.13    0.00    0.22
hist(x, breaks = "FD", freq = FALSE)
curve(f3(x),col='red',lwd=2, add = TRUE)

#Notemos que sigue una distribucion F.
#Usando el test de Kolmogorov

ks.test(x,'pF')
## 
##  One-sample Kolmogorov-Smirnov test
## 
## data:  x
## D = 0.0072051, p-value = 0.6769
## alternative hypothesis: two-sided

De donde concluimos que los datos siguen una distribucion F.

  1. El tiempo de respuesta (en centésimas de segundo) de un servidor informático es una variable con función de distribucion dada por \(F(x)=1-(x+1)e^{-x}\), si \(x\geq0\) y cero en otro caso. Dar un algoritmo, lo más detallado posible, para simular valores de dicho tiempo de respuesta.

Notemos que \(F\) no es inversible en \([0,\infty]\), por tanto usaremos el método de aceptacion-rechazo por tanto, determinamos la funsion de densidad de f, a partir de F.

\[ f(x) = \frac{d}{dx} F(x)\ = \frac{d}{dx} 1-(x+1)e^{-x}\ = -e^{-x} +(x+1)e^{-x}\\ = -e^{-x} +xe^{-x}+e^{-x}\ = xe^{-x} \]

Así

[ f(x)= { \[\begin{array}{lcc} xe^{-x} & \text{si } x \geq 0 \\ 0 & \text{caso contrario } \\ \end{array}\]

..
]

Debemos encontrar los valores de lambda y c que cumplan \[ f(x) \leq c*dgamma(2,lambda.opt) \]

df <- function(x){
  ifelse((x>=0),x*exp(-x),0)
  }
  
pF <- function(x){
  ifelse((x>=0),(1-((x+1)*exp(-x))),0)
}

fopt <- function(sc) {
# Obtiene c fijado k
optimize(f = function(x){df(x)/dgamma(x,2,sc)},
         maximum=TRUE, interval=c(0,10))$objective
}
# Encontar lambda que minimiza
res <- optimize(f=function(x){fopt(x)}, interval=c(0,10))  
sc.opt <- res$minimum
c.opt <- res$objective

cat("c optimo =", c.opt)
## c optimo = 1.000021
cat("\n lamda optimo=",sc.opt)
## 
##  lamda optimo= 0.9999895
curve(c.opt*dgamma(x, 2, sc.opt), xlab = "x", 0, 10, col = 3, lwd = 3)
curve(df(x),col='red',lwd=3,lty=2,add=TRUE)

#Definimos

rfR <- function() {
  # Simulación por aceptación-rechazo
  while (TRUE) {
    U <- runif(1)
    X <- rgamma(1,2,sc.opt)
    ngen <<- ngen+1 
    if (c.opt * U * dgamma(X,2,sc.opt) <= df(X)) return(X)
  }
}

rfRn <- function(n=1000) {
  # Simulación n valores N(0,1)
  x <- numeric(n)
  for(i in 1:n) x[i]<-rfR()
  return(x)
}

set.seed(500)
ngen <- 0
system.time(x <- rfRn(10^4))
##    user  system elapsed 
##    0.55    0.01    1.00
hist(x, breaks="FD", freq=FALSE)
curve(df(x), col='red', add=TRUE)

#Notemos ue X sigue una distribucion F.

cat("Nº de generaciones = ", ngen)
## Nº de generaciones =  10000
cat("\nNº medio de generaciones = ", ngen/10^4)
## 
## Nº medio de generaciones =  1
cat("\nProporción de rechazos = ", 1-10^4/ngen, "\n")
## 
## Proporción de rechazos =  0
#Por último para el análisis de funcionamiento

ks.test(x,'pF')
## 
##  One-sample Kolmogorov-Smirnov test
## 
## data:  x
## D = 0.008159, p-value = 0.5185
## alternative hypothesis: two-sided
#Donde podemos notar que sigue una distribucion F.
  1. La densidad de probabilidad de una variable aleatoria viena dada por \[ f(x)= \left\{ \begin{array}{lcc} (2x^2+1)e^{-2x} & si & x\geq0 \\ \\ 0 & si & en\space otro\space caso \end{array} \right. \] Encontrar un algoritmo para simular valores procedentes de dicha distribución y comentar su eficiencia.

Definimos F, tal que

\[\begin{align*} F(x)= \left\{ \begin{array}{lcc} -x^{2}e^{-2x} - x^{-2x}-e^{-2x}+1 & si & x \geq 0 \\ \\ 0 & \text{Caso contrario} & \\ \end{array} \right.. \end{align*}\]
df <- function(x)
{
  ifelse((x >= 0),((2*(x^2))+1)*exp(-2*x),0 )
}

pF <- function(x)
{
    ifelse((x>=0),((-(x^{2})*(exp(-2*x)))-(x*(exp(-2*x)))-(exp(-2*x))+1),0)
}

fopt <- function(lambda) {
  # Obtiene c fijado lambda
  optimize(f = function(x){df(x)/dexp(x,lambda)},
           maximum=TRUE, interval=c(0,10))$objective
}

# Encontar lambda que minimiza
res <- optimize(f=function(x){fopt(x)}, interval=c(0,10))
lambda.opt <- res$minimum
c.opt <- res$objective

cat("c óptimo = ", c.opt)
## c óptimo =  1.150589
cat("\n lambda óptimo =", lambda.opt)
## 
##  lambda óptimo = 0.7932166
curve(c.opt * dexp(x),col='red',lwd=2, xlim = c(0, 10), lty = 2)
curve(df(x),col='blue',lwd=2,add=TRUE)

#Así definimos
rfR <- function() {
  # Simulación por aceptación-rechazo
  # f a partir de la exponencial
  while (TRUE) {
    U <- runif(1)
    X <- rexp(1,lambda.opt)
    ngen <<- ngen+1 
    if (c.opt * U * dexp(X, lambda.opt) <= df(X)) return(X)
  }
}


rfRn <- function(n=1000) {
  # Simulación n valores
  x <- numeric(n)
  for(i in 1:n) x[i]<-rfR()
  return(x)
}

set.seed(500)
ngen <- 0

system.time(x <- rfRn(10^4))
##    user  system elapsed 
##    0.41    0.00    1.06
hist(x, breaks="FD", freq=FALSE)
curve(df(x),col='red',lwd=2, add=TRUE)

#Notemos que x sigue una distribucion F

cat("Nº de generaciones = ", ngen)
## Nº de generaciones =  11596
cat("\nNº medio de generaciones = ", ngen/10^4)
## 
## Nº medio de generaciones =  1.1596
cat("\nProporción de rechazos = ", 1-10^4/ngen, "\n")
## 
## Proporción de rechazos =  0.1376337
#Por último para ver su eficiencia
ks.test(x,'pF')
## 
##  One-sample Kolmogorov-Smirnov test
## 
## data:  x
## D = 0.011173, p-value = 0.1646
## alternative hypothesis: two-sided
#Con lo cual tenemos que x sigue una distribución dada por F.
  1. Dada la función de densidad \(f(x)=\frac{x^3-12x+20}{48}\), si\(\in [0,4]\) y cero en el resto, detallar un algoritmo que permita simular valores de la misma.

Comenzamos determinando \(F\), la funcion de distribución, tal que:

\[\begin{align*} F(x) &= \int_{0}^{x} f(t)dt\\ &= \int_{0}^{x} \frac{t^{3} -12t+20}{48}dt\\ &= \frac{1}{48} \left.\left(\frac{t^{4}}{4} -6t^{2} + 20t \right)\right|^{x}_{0}\\ &=\frac{1}{48}\left(\frac{x^{4}}{4} -6x^{2} + 20x \right) \end{align*}\]

Asi pues definimos:

\[\begin{align*} F(x)= \left\{ \begin{array}{lcc} 0 & \text{si } x<0 \\ \\ \frac{1}{48}\left(\frac{x^{4}}{4} -6x^{2} + 20x \right) & \text{si } \in [0,4] \\ \\ 1 & \text{si } x>4 \end{array} \right.. \end{align*}\]
df <- function(x)
{
  ifelse((x<0),0,
         ifelse((x<=4),(((x^3) - (12*x)+ 20)/48),0))
}

pf <- function(x)
{
  ifelse((0<=x && x<=4),(1/48)*(((x^4)/4)- ((12*x^2)/2) +20*x ),ifelse((x<0),0,1))  
}

c <- optimize(f=function(x){df(x)/dunif(x,0,4)}, maximum=TRUE, interval=c(0,4))
c.opt <- c$objective

cat("c óptimo = ", c.opt)
## c óptimo =  2.999819
curve(c.opt * dunif(x,0,4), xlim=c(0,4),ylim=c(0,0.8),col='blue',lwd=2,lty = 2)
curve(df(x),col='red',add=TRUE)

rfR <- function() {
  # Simulación por aceptación-rechazo
  # F a partir de la U(0,4)
  while (TRUE) {
    U <- runif(1)
    X <- runif(1,0,4)
    ngen <<- ngen+1 
    if (c.opt * U * dunif(X,0,4) <= df(X)) return(X)
  }
}

rfRn <- function(n=1000) {
  # Simulación n valores
  x <- numeric(n)
  for(i in 1:n) x[i]<-rfR()
  return(x)
}

set.seed(500)
ngen <- 0

system.time(x <- rfRn(10^4))
##    user  system elapsed 
##    1.52    0.00    4.51
hist(x, breaks="FD", freq=FALSE)
curve(df(x),col='blue', add=TRUE)

#Notemos que x sigue una distribución F

cat("Nº de generaciones = ", ngen)
## Nº de generaciones =  29570
cat("\nNº medio de generaciones = ", ngen/10^4)
## 
## Nº medio de generaciones =  2.957
cat("\nProporción de rechazos = ", 1-10^4/ngen, "\n")
## 
## Proporción de rechazos =  0.6618194
#Notemos que el algoritmo no es muy eficiente

ks.test(x,pf(x),min=0,max=4)
## 
##  Two-sample Kolmogorov-Smirnov test
## 
## data:  x and pf(x)
## D = 0.7413, p-value = 0.6419
## alternative hypothesis: two-sided
#X sigue una funcion de densidad f.
  1. El tiempo (en años) entre dos inspecciones discales a una empresa es una variable aleatoria con densidad dada por \[ f(x)= \left\{ \begin{array}{lcc} 0.11-0.0018x-0.00003x^2 & si & x\in [0,10] \\ \\ 0 & si & x \notin [0,10] \end{array} \right. \] Dar un algoritmo, lo más sencillo posible, que permita simular valores de esta variable. Comentar el grado de eficiencia de dicho algoritmo frente a otras alternativas posibles para conseguir el mismo fin. Utilizando un generador congruencial con parámetros \(a=5\), \(c=33\) y \(m=1024\) y semilla \(x_0=27\), simular tres tiempos entre inspecciones, por medio del algoritmo encontrado. Describir un método para simular el número de inspecciones realizadas desde una dada hasta dentro de veinte años.
df <- function(x)
{
  ifelse((x<0),0,
         ifelse((x<=10),(0.11-(0.0018*x)-(0.00003*x^2)),0))
}

pf <- function(x){
  ifelse((x<0),0,
         ifelse((x<=10),(0.11*x - (0.0018/2)*x^2 - (0.00003/3)*x^3),0))
}

c <- optimize(f=function(x){df(x)/dunif(x,0,10)}, maximum=TRUE, interval=c(0,10))
c.opt <- c$objective

cat("c óptimo =", c.opt)
## c óptimo = 1.099999
curve(c.opt * dunif(x,0,10), xlim = c(0,10),ylim=c(0,0.12) ,col=3 ,lwd=2,lty = 2)
curve(df(x),col='red',lwd=2,add=TRUE)

rfR <- function() {
  # Simulación por aceptación-rechazo
  # f a partir de una U(0,10)
  while (TRUE) {
    U <- runif(1)
    X <- runif(1,0,10)
    ngen <<- ngen+1 
    if (c.opt * U * dunif(X,0,10) <= df(X)) return(X)
  }
}


rfRn <- function(n=1000) {
  # Simulación n valores N(0,1)
  x <- numeric(n)
  for(i in 1:n) x[i]<-rfR()
  return(x)
}

set.seed(500)
ngen <- 0

system.time(x <- rfRn(10^4))
##    user  system elapsed 
##    0.52    0.00    1.48
hist(x, breaks="FD", freq=FALSE)
curve(df(x),col='red',lwd=2, add=TRUE)

cat("Nº de generaciones = ", ngen)
## Nº de generaciones =  11009
cat("\nNº medio de generaciones = ", ngen/10^4)
## 
## Nº medio de generaciones =  1.1009
cat("\nProporción de rechazos = ", 1-10^4/ngen, "\n")
## 
## Proporción de rechazos =  0.09165228
ks.test(x,'pf')
## 
##  One-sample Kolmogorov-Smirnov test
## 
## data:  x
## D = 0.0072611, p-value = 0.6675
## alternative hypothesis: two-sided
  1. El tiempo, en milisegundos, de anticipación (o retraso) de una señal respecto de otra en un sistema de comunicaciones puede considerarse una variable aleatoria con funcion de distribución dada por \(F(x)=\frac{e^x}{1+e^x}\). Dar un algoritmo, lo más detallado y simple posible, para simular valores de dicho tiempo de respuesta.Comparar la eficiencia computacional del método con la del algoritmo clásico para simular la distribucion exponencial.
df <- function(x)
{
  exp(x)/(1+exp(x))^2
}

pf <- function(x){
  exp(x)/(1+exp(x))
}

# Obtención de valores c y sd óptimos aproximados
fopt <- function(sd) {
  # Obtiene c fijado u
  optimize(f = function(x){df(x)/dnorm(x,0,sd)},
           maximum=TRUE, interval=c(-10,10))$objective
}

# Encontar sd que minimiza
res <- optimize(f=function(x){fopt(x)},interval=c(-10,10))
sd.opt <- res$minimum
c.opt <- res$objective

cat("c óptimo = ", c.opt)
## c óptimo =  1.262126
cat("\n sd.optimo = ", sd.opt)
## 
##  sd.optimo =  2.014062
curve(c.opt * dnorm(x,0,sd.opt), col='blue',lwd=2, xlim = c(-10, 10), lty = 2)
curve(df(x),col='red',lwd=2,add=TRUE)

rfR <- function() {
  # Simulación por aceptación-rechazo
  # F a partir de la normal(0,sd)
  while (TRUE) {
    U <- runif(1)
    X <- rnorm(1,0,sd.opt)
    ngen <<- ngen+1 
    if (c.opt * U * dnorm(X,0, sd.opt) <= df(X)) return(X)
  }
}


rfRn <- function(n=1000) {
  # Simulación n valores N(0,1)
  x <- numeric(n)
  for(i in 1:n) x[i]<-rfR()
  return(x)
}

set.seed(500)
ngen <- 0

system.time(x <- rfRn(10^4))
##    user  system elapsed 
##    0.42    0.00    0.68
hist(x, breaks="FD", freq=FALSE)
curve(df(x),col='red',lwd=2, add=TRUE)

cat("Nº de generaciones = ", ngen)
## Nº de generaciones =  12727
cat("\nNº medio de generaciones = ", ngen/10^4)
## 
## Nº medio de generaciones =  1.2727
cat("\nProporción de rechazos = ", 1-10^4/ngen, "\n")
## 
## Proporción de rechazos =  0.2142689
ks.test(x,'pf')
## 
##  One-sample Kolmogorov-Smirnov test
## 
## data:  x
## D = 0.010478, p-value = 0.2222
## alternative hypothesis: two-sided
  1. El número de horas diarias durante las cuales un terminal (de tipo A) de un laboratorio está siendo utilizado es una variable con función de desitribución: \[ F(x)= \left\{ \begin{array}{lcc} \frac{e^{x-2}}{1+e^{x-2}} & si & x\geq0 \\ \\ 0 & si & en\space otro\space caso \end{array} \right. \] Se pide:
  1. Dar un algoritmo para simular dicha variable.
  2. Si para otro tipo de terminales (el tipo B) el tiempo de utilización tiene distribución \(exp(\frac{1}{2}\), detallar un algoritmo para aproximar, por simulación, la probabilidad de que un terminal de tipo B sea más utilizado que uno de tipo A.
df <- function(x)
{
  ifelse((x>=0), exp(x-2)/(1+exp(x-2))^2,0) 
  
}

pf <- function(x)
{
  ifelse((x>=0),(exp(x-2)/(1+exp(x-2))),0)
}

# Obtencion de valores c y sd óptimos aproximados
fopt <- function(lambda) {
  # Obtiene c fijado lambda
  optimize(f = function(x){df(x)/dexp(x,lambda)}, maximum=TRUE, interval=c(0,10))$objective
}

# Encontar lambda que minimiza
res <- optimize(f=function(x){fopt(x)}, interval=c(0,10))
lambda.opt <- res$minimum
c.opt <- res$objective

curve(c.opt * dexp(x,lambda.opt),col='red',lwd=2, xlim = c(0, 10), lty = 2)
curve(df(x),col='7',add=TRUE)

rfR <- function() {
  # Simulación por aceptación-rechazo
  # Normal estandar a partir de la normal
  while (TRUE) {
    U <- runif(1)
    X <- rexp(1,lambda.opt)
    ngen <<- ngen+1 
    if (c.opt * U * dexp(X,lambda.opt) <= df(X)) return(X)
  }
}


rfRn <- function(n=1000) {
  # Simulación n valores 
  x <- numeric(n)
  for(i in 1:n) x[i]<-rfR()
  return(x)
}

set.seed(500)
ngen <- 0

system.time(x <- rfRn(10^4))
##    user  system elapsed 
##    0.79    0.00    1.33
hist(x, breaks="FD", freq=FALSE)
curve(df(x),col='red',lwd=2, add=TRUE)

cat("Nº de generaciones = ", ngen)
## Nº de generaciones =  18493
cat("\nNº medio de generaciones = ", ngen/10^4)
## 
## Nº medio de generaciones =  1.8493
cat("\nProporción de rechazos = ", 1-10^4/ngen, "\n")
## 
## Proporción de rechazos =  0.4592549
ks.test(x,'pf')
## 
##  One-sample Kolmogorov-Smirnov test
## 
## data:  x
## D = 0.11948, p-value < 2.2e-16
## alternative hypothesis: two-sided
#Rechazamos que x siga una distribucion F.
#Notemos que existe un punto de discontinuidad en x=0

set.seed(500)
n <- 50
estadistico <- numeric(100)
pvalor <- numeric(100)

# Realizar contrastes
for(i in 1:100) {
  u <- rfRn(100) 
  v <- rexp(100,0.5)  # Generar
  tmp <- ks.test(u,v,alternative = 'less',min=0,max=10)
  estadistico[100] <- tmp$statistic
  pvalor[100] <- tmp$p.value
}
plot(1:100, cumsum(pvalor)/(1:100),col='red', type="l", ylab="Media muestral", xlab="Nº de simulaciones")