将R%的%转换为C ++

时间:2017-07-25 21:57:34

标签: c++ r rcpp

我正在尝试将一段R代码翻译成使用%in%运算符的C ++(通过Rcpp)。我知道Rcpp有糖in(),但我不明白它是如何相关的。关于%in%还有另一个SO question,但我也无法理清这个问题。 Rcpp gallery很棒,但是当我搜索in()时,我找不到任何帖子。

这是一个简单的问题示例。假设您要创建一个单位矩阵,但将对角线上的某些元素约束为零。 (这显然不再是一个单位矩阵,但你明白我的意思。)你可以用R这样的函数在R中做到这一点:

r_eye <- function(n, v) {
  A <- matrix(data = 0, nrow = n, ncol = n)
  for(i in 1:n) {
    for(j in 1:n) {
      if(i==j & !(i %in% v)) {
        A[i,j] <- 1
      }
    }
  }
  return(A)
}

其中n是一个确定方阵大小的整数,v是&#34;约束&#34;的整数向量。从零的矩阵开始,循环遍历行和列。如果row等于列,并且如果row不在约束中,则将值1分配给矩阵条目。例如,如果您运行r_eye(n=6, v=c(1,2,3)),则会获得一个&#34;身份&#34;矩阵,其中前三个对角元素为零,其余为一:

> r_eye(n = 6, v = c(1,2,3))
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    0    0    0    0    0    0
[2,]    0    0    0    0    0    0
[3,]    0    0    0    0    0    0
[4,]    0    0    0    1    0    0
[5,]    0    0    0    0    1    0
[6,]    0    0    0    0    0    1

将其转换为C ++的瓶颈是&#34; if&#34;的第二部分。条件:!(i %in% v)。我可以用

创建一个单位矩阵
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericMatrix cpp_eye(int n) {
  NumericMatrix A(n,n);
  for(int i = 0; i <= n; i++) {
    for(int j = 0; j <= n; j++) {
      if(i==j) {
          A(i,j) = 1;
        } 
      }
    }
  return A;
}

但是有可能挤进第二个&#34;如果&#34;像R函数那样的条件呢?或者我是否必须考虑不同的方法?

2 个答案:

答案 0 :(得分:0)

据我所知,R向量作为Rcpp::NumericVector传递,它提供begin()end(),如std::vector。所以我会尝试这个:

#include <algorithm>

bool in(int value, const NumericVector & vec) {
    return vec.end() != std::find(vec.begin(), vec.end(), value);
}


NumericMatrix cpp_eye(int n, NumericVector v) {
    NumericMatrix A(n,n);
    for(int i = 0; i <= n; i++) {
        for(int j = 0; j <= n; j++) {
            if((i==j) && in(i, v)) {
               A(i,j) = 1;
            } 
        }
    }
    return A;
}

答案 1 :(得分:0)

我不明白为什么你要在这种情况下使用%in%。即使对于一个更复杂的问题,你应该遍历v而不是遍及指数并测试它们是否属于v

对于此示例,您可以执行以下操作:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericMatrix cpp_eye(int n, const IntegerVector& v) {

  int i, j;

  NumericMatrix A(n, n);
  for (i = 0; i < n; i++) A(i, i) = 1;

  for (j = 0; j < v.size(); j++) {
    i = v[j] - 1; // we are in C++
    A(i, i) = 0;
  }

  return A;
}