vendredi 2 octobre 2020

Differences between vectorized and non-vectorized code in R

everything good?

I am starting to program in R and I am vectorizing a code.

However, they are returning different values ​​for mean (SAg) and sd (SAg), even choosing the same seed and running on the same version of R.

This is the non-vectorized code:

set.seed(42)
#n: tamanho da carteira (quantidade de segurados
tamanho = 10000
# prob_sin é a probabilidade esperada de ocorrência de sinistros com um segurado (1_i)
prob_sin = 0.02
# "cenarios" são as quantidades de simulações de atribuição de valor para o SAg
cenarios = 100
# sev_media é o valor esperado da indenização em caso de materialização do sinistro com a i-ésima apólice
sev_media = 10000

replicacoes_ind = matrix(NA, tamanho, cenarios) # 0 e 1
replicacoes_sev = matrix(NA, tamanho, cenarios) # se a matriz anterior tiver 1, então terá entrada diferente de zero

SAg = array(NA, cenarios)

# quant_sin é um vetor que armazena a quantidade de sinistros ocorridos em cada simulação/cenário
quant_sin = array(NA, cenarios)

for (j in 1:cenarios){ ### cria todos os cenários possíveis de ocorrência
  for (i in 1:tamanho){ ### percorre toda a carteira
    u <- runif(1,0,1) # gera um número aleatório entre 0 e 1
    ifelse(u <= prob_sin, replicacoes_ind[i,j] <- 1, replicacoes_ind[i,j] <- 0)
    ifelse(u <= prob_sin, replicacoes_sev[i,j] <- rexp(1,rate=1/sev_media), replicacoes_sev[i,j] <- 0)
  }
  quant_sin[j] <- sum(replicacoes_ind[,j])
  SAg[j] <- sum(replicacoes_sev[,j])
}

mean(SAg); sd(SAg)

And this is the vectorized code:

simulate_uniform = function(tamanho, cenarios){
  return(matrix(data=runif(tamanho*cenarios, 0, 1), nrow=tamanho, ncol=cenarios))
}

fill_sev = function(p, u, dist, media, tamanho, cenarios){
  # Matriz que armazena as indenizacoes ($) associadas a cada sinistro
  matriz = matrix(NA, tamanho, cenarios)
  
  # Indices aos quais houve sinistros
  ind <- which(u <= p, arr.ind = TRUE)
  
  # Usamos os indices acima para preencher as posicoes com a distribuicao escolhida
  if(dist == "Exponencial"){
    matriz[ind] = rexp(nrow(ind), rate = 1/media)
  } else if(dist == "Uniforme"){
    matriz[ind] = runif(nrow(ind), min = 0, max = 20000)
  } else {
    return(NULL)
  }
  
  # Para os indices restantes, substituimos por zero
  matriz[is.na(matriz)] = 0
  
  return(matriz)
}

set.seed(42)

cenarios = 100 # Numero de simulacoes
tamanho = 10000 # Carteira
prob_sin = 0.02 # Probabilidade de ocorrência de sinistros
sev_med = 10000 # Severidade média individual
distribuicao = "Exponencial" # Entre a distribuicao exponencial ou uniforme

SAg = array(NA, cenarios)

# Armazena a qtd de sinistros ocorridos em cada cenario
quant_sin = array(NA, cenarios)

u = simulate_uniform(tamanho, cenarios)

replicacoes_sev = fill_sev(prob_sin, u, distribuicao, sev_med, tamanho, cenarios)

if(is.null(replicacoes_sev)){
  stop("Somente sao permitidas as ditribuicoes exponencial e uniforme.")
} else{
  # Quantidade de sinistros em cada simulacao
  quant_sin = colSums(replicacoes_sev != 0)
  
  # Sinistro agregado em cada simulacao
  SAg = colSums(replicacoes_sev)
  
  # Media de SAg
  mean(SAg)
  
  # Desvio padrao de SAg
  sd(SAg)
}

Can someone help me please?




Aucun commentaire:

Enregistrer un commentaire