Uma Introdu¸c˜ ao ao Rcpp
5 º Encontro da P´ os-Gradua¸c˜ ao em Estat´ıstica do IME - USP
Jos´ e Augusto Sartori Junior
Instituto de Matem´atica e Estat´ıstica Universidade de S˜ao Paulo
19 de Novembro de 2021
Overview
1. Introdu¸c˜ ao e C++
2. Estruturas de Dados e Exemplo
Introdu¸c˜ ao
R ´ e uma linguagem maravilhosa para lidar com dados:
m y d a t a < - r e a d . t a b l e ()
fit < - lm ( y ~ x , d a t a = m y d a t a ) p l o t ( fit )
Com seus pacotes ent˜ ao...
r e a d _ c s v () % >% f i l t e r () % >% g r o u p _ b y () % >% s u m m a r i s e () % >% g g p l o t () + g e o m _ c o l ()
Introdu¸c˜ ao
R ´ e uma linguagem maravilhosa para lidar com dados:
m y d a t a < - r e a d . t a b l e ()
fit < - lm ( y ~ x , d a t a = m y d a t a ) p l o t ( fit )
Com seus pacotes ent˜ ao...
r e a d _ c s v () % >%
f i l t e r () % >%
g r o u p _ b y () % >%
s u m m a r i s e () % >%
g g p l o t () + g e o m _ c o l ()
Introdu¸c˜ ao
Tamb´ em ´ e muito boa para escrever prot´ otipos de c´ odigo:
• alto n´ıvel
• interpretada
• tipagem dinˆ amica
Benef´ıcios adicionais: a comunidade e o RStudio!
Introdu¸c˜ ao
Tamb´ em ´ e muito boa para escrever prot´ otipos de c´ odigo:
• alto n´ıvel
• interpretada
• tipagem dinˆ amica
Benef´ıcios adicionais: a comunidade e o RStudio!
Introdu¸c˜ ao
R ´ e um programa escrito em C que incorpora bibliotecas super otimizadas do Fortran.
Est´ a fadado a ser mais lento que C ou Fortran (ou C++ ou Assembly ou...) O que importa mais, velocidade de execu¸ c˜ ao ou velocidade de implementa¸ c˜ ao? Depende! Vocˆ e usaria R se o c´ odigo abaixo:
• demorasse 3 horas para rodar...
• mas fosse seu e estivesse em fase de testes?
m y d a t a < - r e a d . t a b l e ()
fit < - lm ( y ~ x , d a t a = m y d a t a ) p l o t ( fit )
Introdu¸c˜ ao
R ´ e um programa escrito em C que incorpora bibliotecas super otimizadas do Fortran.
Est´ a fadado a ser mais lento que C ou Fortran (ou C++ ou Assembly ou...)
O que importa mais, velocidade de execu¸ c˜ ao ou velocidade de implementa¸ c˜ ao? Depende! Vocˆ e usaria R se o c´ odigo abaixo:
• demorasse 3 horas para rodar...
• mas fosse seu e estivesse em fase de testes?
m y d a t a < - r e a d . t a b l e ()
fit < - lm ( y ~ x , d a t a = m y d a t a ) p l o t ( fit )
Introdu¸c˜ ao
R ´ e um programa escrito em C que incorpora bibliotecas super otimizadas do Fortran.
Est´ a fadado a ser mais lento que C ou Fortran (ou C++ ou Assembly ou...) O que importa mais, velocidade de execu¸ c˜ ao ou velocidade de implementa¸ c˜ ao?
Depende! Vocˆ e usaria R se o c´ odigo abaixo:
• demorasse 3 horas para rodar...
• mas fosse seu e estivesse em fase de testes?
m y d a t a < - r e a d . t a b l e ()
fit < - lm ( y ~ x , d a t a = m y d a t a ) p l o t ( fit )
Introdu¸c˜ ao
R ´ e um programa escrito em C que incorpora bibliotecas super otimizadas do Fortran.
Est´ a fadado a ser mais lento que C ou Fortran (ou C++ ou Assembly ou...) O que importa mais, velocidade de execu¸ c˜ ao ou velocidade de implementa¸ c˜ ao?
Depende! Vocˆ e usaria R se o c´ odigo abaixo:
• demorasse 3 horas para rodar...
• mas fosse seu e estivesse em fase de testes?
m y d a t a < - r e a d . t a b l e ()
fit < - lm ( y ~ x , d a t a = m y d a t a ) p l o t ( fit )
Rcpp
Pacote do R que permite f´ acil integra¸ c˜ ao de c´ odigos escritos em C++.
N˜ ao seria mais f´ acil integrar com C ou Fortran mesmo?
. C ()
. F o r t r a n () . C a l l ()
Muito do C que importa para n´ os ´ e entendido pelo compilador do C++.
C++ vivenciou uma renascen¸ ca com o padr˜ ao C++11.
Rcpp
Pacote do R que permite f´ acil integra¸ c˜ ao de c´ odigos escritos em C++.
N˜ ao seria mais f´ acil integrar com C ou Fortran mesmo?
. C ()
. F o r t r a n () . C a l l ()
Muito do C que importa para n´ os ´ e entendido pelo compilador do C++.
C++ vivenciou uma renascen¸ ca com o padr˜ ao C++11.
Rcpp
Pacote do R que permite f´ acil integra¸ c˜ ao de c´ odigos escritos em C++.
N˜ ao seria mais f´ acil integrar com C ou Fortran mesmo?
. C ()
. F o r t r a n () . C a l l ()
Muito do C que importa para n´ os ´ e entendido pelo compilador do C++.
C++ vivenciou uma renascen¸ ca com o padr˜ ao C++11.
Rcpp
Pacote do R que permite f´ acil integra¸ c˜ ao de c´ odigos escritos em C++.
N˜ ao seria mais f´ acil integrar com C ou Fortran mesmo?
. C ()
. F o r t r a n () . C a l l ()
Muito do C que importa para n´ os ´ e entendido pelo compilador do C++.
C++ vivenciou uma renascen¸ ca com o padr˜ ao C++11.
Rcpp
Pacote do R que permite f´ acil integra¸ c˜ ao de c´ odigos escritos em C++.
N˜ ao seria mais f´ acil integrar com C ou Fortran mesmo?
. C ()
. F o r t r a n () . C a l l ()
Muito do C que importa para n´ os ´ e entendido pelo compilador do C++.
C++ vivenciou uma renascen¸ ca com o padr˜ ao C++11.
Instala¸c˜ ao
• Linux
i n s t a l l . p a c k a g e s (" R c p p ")
• Windows
# B a i x e e i n s t a l e R t o o l s
# h t t p s :// c r a n . r - p r o j e c t . org / bin / w i n d o w s / R t o o l s / i n d e x . h t m l i n s t a l l . p a c k a g e s (" R c p p ")
• Mac
# I n s t a l e X c o d e no t e r m i n a l :
# xcode - s e l e c t - - i n s t a l i n s t a l l . p a c k a g e s (" R c p p ")
• Para testar a instala¸ c˜ ao:
l i b r a r y ( R c p p ) e v a l C p p ( " 2 + 2 " )
Instala¸c˜ ao
• Linux
i n s t a l l . p a c k a g e s (" R c p p ")
• Windows
# B a i x e e i n s t a l e R t o o l s
# h t t p s :// c r a n . r - p r o j e c t . org / bin / w i n d o w s / R t o o l s / i n d e x . h t m l i n s t a l l . p a c k a g e s (" R c p p ")
• Mac
# I n s t a l e X c o d e no t e r m i n a l :
# xcode - s e l e c t - - i n s t a l i n s t a l l . p a c k a g e s (" R c p p ")
• Para testar a instala¸ c˜ ao:
Bacana, mas eu n˜ ao sei C++!
C++ ´ e totalmente o oposto do que falamos sobre o R:
• baixo n´ıvel
• compilada
• tipagem est´ atica
Declara¸ c˜ oes mais comuns:
// S c a l a r
int k ; d o u b l e x ; c o n s t int c ; l o n g int n ; // A r r a y
int a [ n ]; d o u b l e v [ n ]; int A [ n ][ m ]; d o u b l e Y [ n ][ m ]
Os ´ındices em C++ come¸ cam em zero e n˜ ao em um!
Bacana, mas eu n˜ ao sei C++!
C++ ´ e totalmente o oposto do que falamos sobre o R:
• baixo n´ıvel
• compilada
• tipagem est´ atica Declara¸c˜ oes mais comuns:
// S c a l a r
int k ; d o u b l e x ; c o n s t int c ; l o n g int n ; // A r r a y
int a [ n ]; d o u b l e v [ n ]; int A [ n ][ m ]; d o u b l e Y [ n ][ m ]
Os ´ındices em C++ come¸ cam em zero e n˜ ao em um!
Bacana, mas eu n˜ ao sei C++!
C++ ´ e totalmente o oposto do que falamos sobre o R:
• baixo n´ıvel
• compilada
• tipagem est´ atica Declara¸c˜ oes mais comuns:
// S c a l a r
int k ; d o u b l e x ; c o n s t int c ; l o n g int n ; // A r r a y
int a [ n ]; d o u b l e v [ n ]; int A [ n ][ m ]; d o u b l e Y [ n ][ m ]
Os ´ındices em C++ come¸ cam em zero e n˜ ao em um!
Bacana, mas eu n˜ ao sei C++!
# i n c l u d e < i o s t r e a m >
u s i n g n a m e s p a c e std ; int m a i n () {
d o u b l e x [4] = {1.0 , -1.0 , 2.0 , -2.0};
for ( int i = 0; i < 4; i ++) { if ( x [ i ] < 0) {
x [ i ] = - x [ i ];
} e l s e {
x [ i ] = 2 * x [ i ];
} }
int j = 0;
w h i l e ( j < 4) {
c o u t < < x [ j ] < < e n d l ; j ++;
Show me!
Sequˆ encia de Fibonnaci: f
n= f
n−1+ f
n−2• f
0= 0, f
1= 1, f
2= 1, f
3= 2, ...
Implementa¸c˜ ao recursiva em R:
f i b R < - f u n c t i o n ( n ) { if ( n == 0) r e t u r n (0) if ( n == 1) r e t u r n (1)
r e t u r n ( f i b R ( n -1) + f i b R ( n -2) ) }
Implementa¸c˜ ao recursiva em C++:
int f i b C ( int n ) {
if ( n == 0) r e t u r n 0; if ( n == 1) r e t u r n 1;
r e t u r n f i b C ( n -1) + f i b C ( n -2) ; }
Show me!
Sequˆ encia de Fibonnaci: f
n= f
n−1+ f
n−2• f
0= 0, f
1= 1, f
2= 1, f
3= 2, ...
Implementa¸c˜ ao recursiva em R:
f i b R < - f u n c t i o n ( n ) { if ( n == 0) r e t u r n (0) if ( n == 1) r e t u r n (1)
r e t u r n ( f i b R ( n -1) + f i b R ( n -2) ) }
Implementa¸c˜ ao recursiva em C++:
int f i b C ( int n ) {
if ( n == 0) r e t u r n 0;
if ( n == 1) r e t u r n 1;
r e t u r n f i b C ( n -1) + f i b C ( n -2) ; }
Show me!
A fun¸ c˜ ao do R vai funcionar de imediato, mas a do C++ precisa ser compilada.
J´ a vimos a fun¸c˜ ao evalCpp(). Agora vamos usar uma mais flex´ıvel:
R c p p :: c p p F u n c t i o n ("
int f i b C ( int n ) {
if ( n == 0) r e t u r n 0;
if ( n == 1) r e t u r n 1;
r e t u r n f i b C ( n -1) + f i b C ( n -2) ; }")
Vamos fazer alguns testes:
f i b R (0) ; f i b C (0) f i b R (1) ; f i b C (1)
Estruturas de Dados
O Rcpp e os pacotes que o usam tˆ em muitas estruturas de dados.
As mais usuais s˜ ao:
R c p p :: I n t e g e r V e c t o r ; R c p p :: I n t e g e r M a t r i x ; R c p p :: N u m e r i c V e c t o r ; R c p p :: N u m e r i c M a t r i x ; R c p p :: L o g i c a l V e c t o r ; R c p p :: C h a r a c t e r V e c t o r R c p p :: L i s t ; R c p p :: D a t a F r a m e ;
Vamos focar aqui nos vetores, matrizes e listas, mas o resto quase que praticamente igual! Tamb´ em vamos remover os Rcpp:: come¸ cando o c´ odigo com
# i n c l u d e < R c p p . h > u s i n g n a m e s p a c e R c p p ;
Estruturas de Dados
O Rcpp e os pacotes que o usam tˆ em muitas estruturas de dados.
As mais usuais s˜ ao:
R c p p :: I n t e g e r V e c t o r ; R c p p :: I n t e g e r M a t r i x ; R c p p :: N u m e r i c V e c t o r ; R c p p :: N u m e r i c M a t r i x ; R c p p :: L o g i c a l V e c t o r ; R c p p :: C h a r a c t e r V e c t o r R c p p :: L i s t ; R c p p :: D a t a F r a m e ;
Vamos focar aqui nos vetores, matrizes e listas, mas o resto quase que praticamente igual! Tamb´ em vamos remover os Rcpp:: come¸ cando o c´ odigo com
# i n c l u d e < R c p p . h > u s i n g n a m e s p a c e R c p p ;
Estruturas de Dados
O Rcpp e os pacotes que o usam tˆ em muitas estruturas de dados.
As mais usuais s˜ ao:
R c p p :: I n t e g e r V e c t o r ; R c p p :: I n t e g e r M a t r i x ; R c p p :: N u m e r i c V e c t o r ; R c p p :: N u m e r i c M a t r i x ; R c p p :: L o g i c a l V e c t o r ; R c p p :: C h a r a c t e r V e c t o r R c p p :: L i s t ; R c p p :: D a t a F r a m e ;
Vamos focar aqui nos vetores, matrizes e listas, mas o resto quase que praticamente igual!
Tamb´ em vamos remover os Rcpp:: come¸ cando o c´ odigo com
# i n c l u d e < R c p p . h > u s i n g n a m e s p a c e R c p p ;
Estruturas de Dados
O Rcpp e os pacotes que o usam tˆ em muitas estruturas de dados.
As mais usuais s˜ ao:
R c p p :: I n t e g e r V e c t o r ; R c p p :: I n t e g e r M a t r i x ; R c p p :: N u m e r i c V e c t o r ; R c p p :: N u m e r i c M a t r i x ; R c p p :: L o g i c a l V e c t o r ; R c p p :: C h a r a c t e r V e c t o r R c p p :: L i s t ; R c p p :: D a t a F r a m e ;
Vamos focar aqui nos vetores, matrizes e listas, mas o resto quase que praticamente igual!
Tamb´ em vamos remover os Rcpp:: come¸ cando o c´ odigo com
# i n c l u d e < R c p p . h >
Vetores
Inicializa¸ c˜ ao:
// x < - c (0 , 0) I n t e g e r V e c t o r x (2) ; // y < - rep (1 , 3)
N u m e r i c V e c t o r y (3 , 1 . 0 ) ; // z < - c ( TRUE , FALSE , T R U E )
L o g i c a l V e c t o r z = { true , false , t r u e };
Acessando os elementos:
// a < - 0 e b < - 1.0
int a = x [ 0 ] ; d o u b l e b = y (0) ; // z [1] < - F A L S E
z [0] = f a l s e ;
Vetores
Inicializa¸ c˜ ao:
// x < - c (0 , 0) I n t e g e r V e c t o r x (2) ; // y < - rep (1 , 3)
N u m e r i c V e c t o r y (3 , 1 . 0 ) ; // z < - c ( TRUE , FALSE , T R U E )
L o g i c a l V e c t o r z = { true , false , t r u e };
Acessando os elementos:
// a < - 0 e b < - 1.0
int a = x [ 0 ] ; d o u b l e b = y (0) ; // z [1] < - F A L S E
Matrizes (com exerc´ıcios)
Inicializa¸ c˜ ao:
// q u a i s os e q u i v a l e n t e s do R ? I n t e g e r M a t r i x Z (100 , 1 0 0 ) ; N u m e r i c M a t r i x Y (10 ,2) ; Y . f i l l ( 1 . 0 ) ;
N u m e r i c M a t r i x X (2 ,2) ; X . f i l l _ d i a g ( 1 . 0 ) ;
Acessando os elementos:
int z = Z (0 ,0) ;
N u m e r i c V e c t o r x = X (1 , _ ) ;
N u m e r i c V e c t o r y = Y ( _ ,2) ; // C u i d a d o !
Matrizes (com exerc´ıcios)
Inicializa¸ c˜ ao:
// q u a i s os e q u i v a l e n t e s do R ? I n t e g e r M a t r i x Z (100 , 1 0 0 ) ; N u m e r i c M a t r i x Y (10 ,2) ; Y . f i l l ( 1 . 0 ) ;
N u m e r i c M a t r i x X (2 ,2) ; X . f i l l _ d i a g ( 1 . 0 ) ;
Acessando os elementos:
int z = Z (0 ,0) ;
N u m e r i c V e c t o r x = X (1 , _ ) ;
Listas
Inicializa¸ c˜ ao:
L i s t X = L i s t :: c r e a t e ( x1 , x2 ) ; // x1 v e t o r e x2 escalar , por e x e m p l o L i s t Y = L i s t :: c r e a t e ( N a m e d (" y1 ") = x1 , N a m e d (" y2 ") = x2 ) ;
L i s t Z ;
Z [" z1 "] = x1 ; Z [" z2 "] = x2 ;
Acessando os elementos:
N u m e r i c V e c t o r x = X [ 0 ] ; d o u b l e y = Y [" y2 "];
Listas
Inicializa¸ c˜ ao:
L i s t X = L i s t :: c r e a t e ( x1 , x2 ) ; // x1 v e t o r e x2 escalar , por e x e m p l o L i s t Y = L i s t :: c r e a t e ( N a m e d (" y1 ") = x1 , N a m e d (" y2 ") = x2 ) ;
L i s t Z ;
Z [" z1 "] = x1 ; Z [" z2 "] = x2 ;
Acessando os elementos:
N u m e r i c V e c t o r x = X [ 0 ] ; d o u b l e y = Y [" y2 "];
Exemplo 1: Simulando um processo AR(1)
Processo AR(1) com erros normais: Y
t= ϕY
t−1+ e
t.
Algoritmo iterativo no R:
a r 1 R < - f u n c t i o n ( n , phi , s i g m a ) { y <- n u m e r i c ( n )
for ( t in 2: n ) {
y [ t ] < - phi * y [ t -1] + r n o r m (1 , 0 , s i g m a ) }
r e t u r n ( y ) }
Exemplo 1: Simulando um processo AR(1)
Processo AR(1) com erros normais: Y
t= ϕY
t−1+ e
t. Algoritmo iterativo no R:
a r 1 R < - f u n c t i o n ( n , phi , s i g m a ) { y <- n u m e r i c ( n )
for ( t in 2: n ) {
y [ t ] < - phi * y [ t -1] + r n o r m (1 , 0 , s i g m a ) }
r e t u r n ( y ) }
Exemplo: Simulando um processo AR(1)
Algoritmo iterativo no C++ (agora completinho!):
# i n c l u d e < R c c p . h >
u s i n g n a m e s p a c e R c p p ; // [[ R c p p :: e x p o r t ]]
N u m e r i c V e c t o r ar 1 C ( int n , d o u b l e phi , d o u b l e s i g m a ) { N u m e r i c V e c t o r y ( n ) ;
for ( int t = 1; t < n ; t ++) {
y [ t ] = phi * y [ t -1] + r n o r m (1 , 0 , s i g m a ) [ 0 ] ; }
r e t u r n y ; }
Vamos salvar como .cpp e compilar pelo R mesmo:
Exemplo: Simulando um processo AR(1)
Quem ser´ a o vencedor? Vamos comparar usando o pacote microbenchmark:
m i c r o b e n c h m a r k (
a r 1 R ( n = 1000 , phi = 0.8 , s i g m a = 1) , # M e d i a n a : 1 3 4 0 m i c r o s e g u n d o s a r 1 C ( n = 1000 , phi = 0.8 , s i g m a = 1) , # M e d i a n a : 90 m i c r o s e g u n d o s t i m e s = 100
)