interfaces R/C++ - wiki DPI

Transcrição

interfaces R/C++ - wiki DPI
Ambientes integrados para análise estatı́stica em
SIG – interfaces R/C++
Leonardo Bacelar Lima Santos
04 de abril de 2012
1
Introdução e motivação
Interfaces entre ambientes Sistemas de Informações Geográficas (SIG) e ambientes estatı́sticos desempenham papel fundamental na análise de dados espaciais
e espaço-temporais. Há na literatura algumas iniciativas nesta linha [1, 2].
O R [3] é um ambiente estatı́stico de linguagem própria e código aberto muito
utilizado atualmente. Nele existem e são desenvolvidos a cada dia inúmeros
pacotes para o cálculo das mais diversas funções, tanto no domı́nio espacial
quanto no temporal e espaço-temporal.
A TerraLib [4] é um produto do INPE de reconhecido sucesso no tratamento
de dados geoespaciais, baseada na linguagem C++. Com a versao 5.0, a TerraLib ganha tambem funções para representação de dados espaço-temporais [5].
Uma pergunta que emerge neste contexto é: ambientes SIG que usam como
base a biblioteca TerraLib precisam ter nativamente códigos para funções de
análise estatı́stica ou podem ganhar inteligência estatı́stica por outros meios,
ex. via R?
O objetivo deste trabalho é mostrar que:
1. Um usuário R pode fazer uso de códigos em C/C++.
2. Um usuário C/C++ pode fazer uso de funções do R.
No contexto da TerraLib já se tem iniciativas no caminho da integração
com ambientes estatı́sticos, em especial com o R [6], seja do ponto de vista de
usuários C++ [7], seja de usuários R [8].
Duas motivações norteiam as interfaces que este artigo discute:
• Evitar tediosas e perigosas re-escritas de códigos ou funções por um usuário
R (ou TerraLib) interessado em um código C/C++ (ou função do R).
• Com a versão 5.0 da TerraLib as iniciativas anteriores para interface com
o R devem ser atualizadas, não só para conseguir dar suporte às novas
funcionalidades da TerraLib mas também para poder fazer uso dos novos
e mais poderosos recursos R para interface com outras linguagens de programação.
1
Este artigo está assim organizado: na seção de Metodologia são discutidos
os aspectos fundamentais para criação de um pacote R geral e especificamente
usando dependências para os pacotes Rcpp [9], que facilita a chamada em R de
códigos C/C++ compilados e então linkados a uma dll, e RInside [10], que permite a chamada de funções R dentro de programas escritos em C++. Na seção
de resultados são dados exemplos com ambos pacotes em problemas estatı́sticos
ilustativos. Por fim, na seção de conclusões e perspectivas são avaliadas as
possibilidades que o presente trabalho abre e os próximos passos.
2
Metodologia
2.1
Criando pacotes em R
Para criar pacotes R no windows é preciso ter instalado o pacote de ferramentas
R-tools, com os compiladores gcc e g++ disponı́veis, por exemplo, no Gygwin.
É preciso também colocar o R e o R-tools no PATH do sistema operacional.
O pacote Rcpp.package.skeleton traz o formato no qual as pastas e os arquivos
devem ser organizados, sendo um bom primeiro passo para o desenvolvimento
de um novo pacote.
Para instalar o pacote, uma vez que todos os cógidos já estejam devidamente escritos e nas devidas pastas, é preciso compilar todos os códigos fontes
envolvidos e agregá-los à dll correspondente ao novo pacote – para isso: digitar
no prompt R CMD INSTALL NomePacote.
Uma vez dentro do R o usuário pode carregar o novo pacote apenas executando um require (NomePacote).
2.2
Usando o pacote Rcpp
O pacote Rcpp facilita a interface entre códigos C/C++ e o R. Dentre as maiores
vantagens do Rcpp frente a outras iniciativas nesse contexto estão:
• Sintaxe das aplicações compatı́veis com o Rcpp bastante semelhante à
sintaxe do C/C++ nativo;
• Ausência da necessidade de preocupação com a proteção das variáveis
(espaços de memória);
• Ausência da necessidade de construtores e destrutores e da preocupação
com o coletor de lixo.
Todo objeto R é do tipo SEXP. O Rcpp automaticamente transforma todos
os dados de saı́da do código C/C++ no tipo SEXP. Já em relação aos dados de
entrada é necessário dentro do código fazer a assinatura de cada função já ser
com o tipo SEXP.
2
Figura 1: it Snapshot do arquivo de classes C++ do código a ser chamado
dentro do R.
2.3
Usando o pacote RInside
O pacote RInside traz classes C++ que possibilitam a chamada do R dentro
de códigos C++. A passagem é por strings, as funções em C++ devem usar os
tipos de dados do Rcpp e o resultado das operações em R pode ser retornado ao
programa C++.
Neste caso não é preciso criar um novo pacote para o R, apenas usar o pacote
já compilado RInside. O procedimento é compilar o código do programa C++
incluindo o arquivo RInside.h. Tal conjunto de tarefas pode ser simplificado
executando o arquivo Makefile presente no diretorio de exemplos do RInside.
3
Resultados: alguns exemplos ilustrativos
A seguir serão expostos estudos de casos simples que testaram o funcionamento
da interface R-C++ tanto do ponto de vista de um usuário R quanto de um
usuário C++.
3.1
Em R usando C++
Nas figuras 1 e 2 são representados os arquivos relacionados aos códigos C++
utilizados (o primeiro é o arquivo de classes, o .h, e o segundo o código da função,
o .cpp). O exemplo traz o cálculo da correlação entre duas séries temporais. A
função recebe duas séries temporais e retorna o valor do coeficiente de correlação
(de Pearson) entre elas.
Na figura 3 é exibido o script R que representa a função a ser chamada dentro
do ambiente R e que internamente funcionará segundo o código C++. Já a figura
4 mostra o manual do pacote R criado (chamado LeoAE), um documento .pdf
que traz as informações básicas do pacote.
Um exemplo de uso do pacote criado é apresentado na figura 5. São criadas
duas séries temporais, segundo o tipo série temporal do R, com base em um
3
Figura 2: it Snapshot parcial do arquivo da função C++ do código a ser chamado
dentro do R. Destaque para a assinatura da função e os tipos de dados.
Figura 3: it Snapshot do script R que representa a função do código C++.
Destaque para a chamada da função interna ao R .Call.
4
Figura 4: it Snapshot da manual .pdf criado ao se compilar o pacote.
conjunto inicial de valores. A chamada da função para o cálculo da correlação,
LeoCorrelation, aparece na figura 6. Destaque para as mensagens de erro quando
a chamada da função é feita com assinatura incorreta.
3.2
Em C++ usando R
Os resultados do exemplo de uso do pacote RInside para que seja possı́vel dentro
de um programa C++ chamar funções do R estão representados nas próximas
figuras. Na figura 7 aparece o código C++ que chama o R, graças à inclusão
do arquivo RInside.h e do comando RInside R(argc, argv). A chamada do R
é feita por strings e os tipos de dados envolvidos são compatı́veis com os da
sintaxe do Rcpp. O resultado da operação feita no R pode ser retornado ao
próprio programa C++, como é o caso da média dos elementos do conjunto
de amostras – o resultado da operação. Na figura 8 é representada a saı́da do
programa C++ em questão.
4
Conclusões e perspectivas
No presente trabalho foi demonstrado que um usuário R pode fazer uso de
códigos em C/C++, via pacote Rcpp, e um usuário C/C++ pode fazer uso de
funções do R, pelo pacote RInside.
5
Figura 5: it Snapshot da sequência de comandos R pré-chamada da função do
código C++.
Figura 6: it Snapshot da sequência de comandos R que chama a função do código
C++. Destaque para as mensagens de erro quando a assinatura da função não
é a correta.
6
Figura 7: it Snapshot de parte do código C++ que chama comandos do R.
Figura 8: it Snapshot da saı́da do programa C++ que chama comandos do R.
7
O trabalho representa um primeiro passo para a interface com o R na nova
versão da TerraLib, a 5.0. Graças os pacotes testados neste trabalho não será
preciso implementar em TerraLib operações para análises espaço-temporais, e o
usuário TerraLib poderá, de forma transparente, sem nem perceber que o está
fazendo, usar funções do R.
Iniciativas anteriores nesta linha foram propostas, como o myR [7] e o aRT
[8]. Dentre os próximos passos deste trabalho estão o desenvolvimento das
novas versões destas iniciativas, agora criando suporte para análises espaçotemporais e com implementações mais limpas e eficientes, graças aos pacotes
Rcpp e RInside.
Referências
[1] Bao, S. et. al. (2000) Seamless integration of spatial statistics and GIS:
The S-PLUS for ArcView and the SBGrassland Links. J Geog Systems,
2:287-306
[2] Anselin,
Luc.
(2011)
From
SpaceStat
to
CyberGIS:
Twenty
Years
of
Spatial
Data
Analysis
Software.
Disponı́vel
em
http://geodacenter.asu.edu/drupalf iles/2011 −
06.pdf, acessadoem05/12/2011.
[3] R Development Core Team. An Introduction to R. R Foundation for Statistical
Computing, 2003. Disponı́vel em http://www.r-project.org/, acessado em
04/12/2011.
[4] Câmara, G. et al. (2000) Terralib: Technology in support of gis innovation. Em
II Workshop Brasileiro de Geoinformática, GeoInfo2000, São Paulo, Brasil.
[5] Ferreira, K. R., Camara C., Monteiro A. M. V. (2011). An Extension of OGC
SFA-SQL Schema for Spatiotemporal Observations. Pre-print.
[6] Andrade Neto, P. et. al. (2005) Integration of Statistics and Geographic Information Systems: the R/TerraLib case. Disponı́vel em http://www.leg.ufpr.br/ pedro/aRT/docs/P74.pdf, acessado em 05/12/2011.
[7] Disponı́vel em http://leg.ufpr.br/myR/myR.pdf, acessado em 04/12/2011.
[8] Disponı́vel em http://www.leg.ufpr.br/doku.php/software:art, acessado em
04/12/2011.
[9] Disponı́vel em http://cran.r-project.org/web/packages/Rcpp/Rcpp.pdf, acessado em 04/12/2011.
[10] Disponı́vel em http://cran.r-project.org/web/packages/RInside/RInside.pdf,
acessado em 04/12/2011.
8