Понимание передачи матриц броненосца в R-функции через RInside

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

    #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);
}

4

Решение

Как мы реализовали 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
5

Другие решения

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

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

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

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

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

  5. Отнеси это Rcpp.

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

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

4