2012-11-14 1 views
4

Я пытаюсь использовать R внутри C++ через RInside. У меня возникли проблемы с передачей армадильо-матриц в R и возвратом результата. Ниже я могу вернуть результаты из функции библиотеки R, однако я получаю неправильный результат. Я использую функцию асимметрии из пакета моментов в качестве примера, который работает так же, как и в R. Я проверил примеры из RInside, и я все еще не уверен, как использовать RcppArmadillo. Как правильно передать матрицу броненосца в C++ на R?Понимание прохождений армадильо-матриц к функциям R через RInside

#include <RInside.h>     
    #include <RcppArmadillo.h> 

    using namespace std; 
    using namespace arma; 

    int main(int argc, char *argv[]) { 
     RInside R(argc, argv); 


     string R_libs = "suppressMessages(library(moments));"; 

     R.parseEvalQ(R_libs); 

     mat A = randu<mat>(5,5); 

     R["A"] = A; 

     string R_skewness = "B <- skewness(A);"; 
     //this fails 
     mat B = Rcpp::as<mat>(R.parseEval(R_skewness)); //terminate called after throwing an instance of 'Rcpp::not_a_matrix' 

     //this works but wrong 
     mat B = Rcpp::as<vec>(R.parseEval(R_skewness)); // returns only 1 number, should be 5 (1 for each columnn), same result if i change mat B to vec B 
     exit(0); 
} 

ответ

5

Способ, которым мы реализовали as<mat>, требует, чтобы объект R, который вы проходили, является матрицей. А в вашем примере B вектор:

> A <- matrix(runif(25), ncol = 5) 
> A 
      [,1]  [,2]  [,3]  [,4]  [,5] 
[1,] 0.19215339 0.5857249 0.14345222 0.32154176 0.6162155 
[2,] 0.95753898 0.9618379 0.06239842 0.06200197 0.7044018 
[3,] 0.33575790 0.1372804 0.03027635 0.62662467 0.9778451 
[4,] 0.16504957 0.1919765 0.49176372 0.94841456 0.2914772 
[5,] 0.01570709 0.8055231 0.51218581 0.79562809 0.6939380 
> B <- skewness(A) 
> B 
[1] 1.15196587 -0.04547576 0.32186257 -0.30788111 -0.29251009 

Для преобразования в arma::vec я не воспроизводят поведение, которое вы видите. arma::vec имеет 3 элемента:

require(RcppArmadillo) ## and make sure you have Rcpp 0.10.0 or later 

sourceCpp(code = ' 
// [[Rcpp::depends("RcppArmadillo")]] 

#include <RcppArmadillo.h> 

using namespace arma ; 
using namespace Rcpp ; 

// [[Rcpp::export]] 
List foo(NumericVector x){ 
    vec B = Rcpp::as<vec>(x); 

    return List::create( 
     _["nrows"] = B.n_rows, 
     _["ncols"] = B.n_cols 
    ) ; 

} 
') 
foo(c(1, 2, 3)) 
# $nrows 
# [1] 3 
# 
# $ncols 
# [1] 1 
+1

Три ура для первого официального 'sourceCpp()' -using ответа :) –

+0

Не удалось устоять –

+1

Пролито в небольшом разъяснении. –

4

Вы пытаетесь выполнить сложное выражение с участием нескольких сильно затененных библиотек. Это может пойти не так. Я, г рекомендуется делать это в кусках:

  1. Убедитесь, что матрица A вы ожидаете передается вниз к встраиваемой R

  2. Убедитесь, что вызовы функции работали правильно, проверьте результат.

  3. Важно: проверьте тип результата. Матрица должна восстановиться.

  4. Получите результат обратно на C++.

  5. Получить его в Rcpp.

  6. Использование RcppArmadillo для маршалинга, чтобы добраться до Armadillo.

В принципе, это должно сработать. Дьявол в деталях, как всегда.

+0

ах большое предложение х, я уже проверил тип результата с 'R.parseEval («ули (A)»);' и обнаружил, что он прочитал мою матрицу как вектор! 'num [1:25]' – pyCthon

+0

А между тем Ромен доказывает, что моя догадка в 3 была правильной. C++ остается по-прежнему строго типизированным языком ... –

 Смежные вопросы

  • Нет связанных вопросов^_^