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