Есть ли способ использовать ALTREP с Rcpp? - PullRequest
0 голосов
/ 14 ноября 2018

Пример:

// [[Rcpp::export]]
size_t z1(SEXP x) {
  return Rf_xlength(x);
}

// [[Rcpp::export]]
size_t z2(NumericVector x) {
  // do anything or nothing
  return 1;
}

R:

x <- seq(1,1e10)
z1(x)
[1] 1e+10

z2(x)
# computer hard crash

Предположим, в качестве примера, я просто хотел взять первые 10 элементов вектора ALTREP.Что было бы лучшим способом сделать это в C ++?

1 Ответ

0 голосов
/ 01 марта 2019

Rcpp в настоящее время не знает ALTREP. Поэтому преобразование из ALTREP SEXP в NumericVector осуществит его. В моем случае R перестает говорить мне, что не может выделить требуемую память, но это небольшая разница.

Пока что вы должны обрабатывать объект ALTREP без тонкостей Rcpp, например, для вашего последнего вопроса:

#include <Rcpp.h>

// [[Rcpp::export]]
SEXP get_region(SEXP x, R_xlen_t i, R_xlen_t n) {
  SEXP result;
  switch (TYPEOF(x)) {
    case INTSXP: {
      result = PROTECT(Rf_allocVector(INTSXP, n));
      INTEGER_GET_REGION(x, i, n, INTEGER(result));
      UNPROTECT(1);
      break;
    }
    case REALSXP: {
      result = PROTECT(Rf_allocVector(REALSXP, n));
      REAL_GET_REGION(x, i, n, REAL(result));
      UNPROTECT(1);
      break;
    }
    default: {
      Rcpp::stop("Invalid SEXPTYPE %d (%s).\n", TYPEOF(x), Rcpp::type2name(x));
    }
  }
  return result;
}

/*** R
x <- seq(1,1e10)
.Internal(inspect(x)) # @5623ba0b65f0 14 REALSXP g0c0 [NAM(3)]  1 : 10000000000 (compact)
get_region(x, 0, 10)  # [1]  1  2  3  4  5  6  7  8  9 10

x <- seq(1,1e9)
.Internal(inspect(x)) # @5623ba143ff0 13 INTSXP g0c0 [NAM(3)]  1 : 1000000000 (compact)
get_region(x, 0, 10)  # [1]  1  2  3  4  5  6  7  8  9 10
*/

При этом используется полиморфизм времени исполнения от http://gallery.rcpp.org/articles/rcpp-wrap-and-recurse/.

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...