//styles, look here: https://cdnjs.com/libraries/highlight.js/9.12.0

February 9, 2020

420 palavras 2 mins

Gerando um padrão de difusão com soma de um termo gaussiano

Dia desses eu fui informado por um amigo de que um padrão bonitinho de difusão acontece somando um termo gaussiano acumuladamente a um conjunto. O que o amigo versado em Física me relatou como um “padrão de difusão”, na minha intuição mais econométrica vem como uma random walk no \(\mathbb{R}^2\).

Bem, vamos usar o purrr e o dplyr para gerar de maneira concisa um tibble pronto para ser passado ao ggplot2. A parte mais interessante desse post é mostrar como a abordagem funcional gera código mais compreensível. Compare o código deste post com os do Teorema de Perron-Frobenius, que se baiseam em iteração, por exemplo.

Geraremos um conjunto de vetores representando a random walk, que por simplicidade terá os choques independentes. Matematicamente temos uma operação de aplicação acumulada de uma soma em uma sequência de matrizes. Teremos um conjunto de matrizes \(\Lambda\), começamos com \(\Lambda_1 = A\), onde \(A_{ij} \sim U(a, b)\) e a partir daí:

\[ \Lambda_{i \, > \, 1} := B\,\Lambda_{i-1} \]

\[ B \sim N(\mu, \Sigma) \]

\[ \Sigma = \pmatrix{\sigma & 0 \\ 0 & \sigma} \]

library(dplyr)
library(purrr)
library(ggplot2)
library(gganimate)

n <- 500
t <- 500

data <- matrix(runif(n = 2*n),
                   ncol = 2) %>%
  list() %>%
  rep(t) %>%
  accumulate(~ .x + matrix(rnorm(n = 2*n , sd = .02),
                           ncol = 2)) %>% # gera uma lista que aplica cumulativamente a soma dos termos gaussianos
  invoke(.f = rbind) %>% # empilha tudo em um dataframe
  as_tibble() %>% # converte em um tibble
  rename(x = V1, y = V2) %>% # renomeia as colunas
  mutate(time = sort(rep(1:n, t)), # adiciona um termo de passagem do "tempo"
         walk = factor(rep(1:n, t)))  # identifica a caminhada
data %>%
  ggplot(aes(x = x, y = y, color = time)) +
  geom_point(size = 2, alpha = .7) +
  lims(x = c(-1, 2),
       y = c(-1.5, 2.5)) +
  labs(title = "Vetores Aleatórios com Distribuição Uniforme em Difusão",
       x = "",
       y = "")

data %>%
  ggplot(aes(x = x, y = y)) +
  geom_point(size = 2) +
  lims(x = c(-1, 2),
       y = c(-1.5, 2.5)) +
  labs(title = "Vetores Aleatórios com Distribuição Uniforme em Difusão",
       subtitle = "Difusão ocorre com a soma de termos gaussianos",
       x = "",
       y = "") +
  transition_time(time) +
  shadow_trail()

data %>%
  ggplot(aes(x = x, y = y)) +
  geom_point(size = 2, color = "light blue") +
  lims(x = c(-1, 2),
       y = c(-1.5, 2.5)) +
  labs(title = "Vetores Aleatórios com Distribuição Uniforme em Difusão",
       subtitle = "Caminhadas individuais",
       x = "",
       y = "") +
  transition_states(walk)