使用Rcpp进行矢量回收

时间:2019-03-28 17:23:04

标签: c++ r vector vectorization rcpp

我正在尝试使向量回收在Rcpp中工作。

> recycle_and_add <- Rcpp::cppFunction("
+ NumericVector recycle_and_add(NumericVector x, NumericVector y) {
+     return x + y;
+ }")
> recycle_and_add(42, 1:5)
[1] 43

我希望它返回类似

的内容
> 42 + 1:5
[1] 43 44 45 46 47

经过一番分析,我发现Rcpp函数中的x.size()1y.size()5,因此显然矢量循环并不能解决问题盒子。

虽然我可以手动找到xy中最长的一个,然后回收较短的while (fread(&s, sizeof(s), 1, f)) { int g=0; char nume[30]; //size of nume here should be same as that of structure if (grupa == s.grupa) { g = 1; printf("Numele initial este:%s\n", s.nume); printf("Noul nume este:"); getchar(); gets(nume); fseek(f,-sizeof(s), SEEK_CUR)) ; //Using macros helps clarify code fwrite(&s, sizeof(s), 1, f); break; //break after modifying content } if (feof(f)) break; @GetMapping(produces = {MediaType.APPLICATION_JSON_VALUE}) public ResponseEntity< List<Producto> > productoGet(){ Iterable<Producto> prods = prodDao.findAll(); List<Producto> lista = new ArrayList<>(); prods.forEach(lista::add); if(lista.isEmpty()) { return new ResponseEntity<List<Producto>>(HttpStatus.NOT_FOUND); }else { return new ResponseEntity<List<Producto>>(lista, HttpStatus.OK); } } ,但在实际应用中有3或4个需要回收的参数,因此我可以想象手动展开会导致许多指向不同向量的变量将代码转换成一堆意大利面条。

Rcpp是否有对矢量循环的内置支持,例如与一些糖一样?

1 个答案:

答案 0 :(得分:4)

从策略角度来讲,在 R 中进行回收再转移到 C ++ 中几乎总是容易的。

如果必须在 C ++ 中完成 ,则以下设计模式应该有效:

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::NumericVector recycle_vector(Rcpp::NumericVector x, 
                             Rcpp::NumericVector y) {

    // Obtain vector sizes
    int n_x = x.size();
    int n_y = y.size(); 

    // Check both vectors have elements
    if(n_x <= 0 || n_y <= 0) {
        Rcpp::stop("Both `x` and `y` vectors must have at least 1 element.");
    }

    // Compare the three cases that lead to recycling... 
    if(n_x == n_y) {
        return x + y;
    } else if (n_x > n_y) {
        return Rcpp::rep_len(y, n_x) + x;
    }

    return Rcpp::rep_len(x, n_y) + y; 
}

测试用例:

recycle_vector(1:3, 1:3)
# [1] 2 4 6
recycle_vector(4, 1:3)
# [1] 5 6 7
recycle_vector(10:12, -2:-1)
# [1] 8 10 10