代码之家  ›  专栏  ›  技术社区  ›  thc

有没有办法将ALTREP与Rcpp一起使用?

  •  3
  • thc  · 技术社区  · 7 年前

    例子:

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

    x <- seq(1,1e10)
    z1(x)
    [1] 1e+10
    
    z2(x)
    # computer hard crash
    

    假设作为示例,我只想取ALTREP向量的前10个元素。在C++中,最好的方法是什么?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Ralf Stubner    7 年前

    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/ .

    推荐文章