我对Rcpp是一个相当新的学习者,主要是因为循环迭代中的依赖性而需要它来加速不易并行化的慢速R代码。
我希望将以下R代码转换为C ++代码,以便通过Rcpp直接使用。
migrate_r <- function(pop) {
if (m != 0) {
if (model == "Step") {
for (i in 1:K) {
for (j in 1:K) {
for (k in 2:(K - 1)) {
i <- sample(perms, size = ceiling(perms * m/2), replace = FALSE)
j <- sample(perms, size = ceiling(perms * m/2), replace = FALSE)
tmp <- pop[i,, sample(k)]
pop[i,, sample(k)] <- pop[j,, sample(k)]
pop[j,, sample(k)] <- tmp
}
}
}
}
}
pop
}
我的尝试如下:
// [[Rcpp::depends(RcppArmadillo)]]
#define ARMA_DONT_PRINT_OPENMP_WARNING
#include <RcppArmadillo.h>
#include <RcppArmadilloExtensions/sample.h>
#include <set>
using namespace Rcpp;
// [[Rcpp::export]]
arma::Cube<int> migrate_cpp(arma::Cube<int> pop) {
String model;
int i, j, k, K, perms, tmp;
double m;
if (m != 0) {
if (model == "Step") {
for (i = 0; i < K; i++) {
for (j = 0; j < K; j++) {
for(k = 1; k < (K - 1); k++) {
i = RcppArmadillo::sample(perms, ceil(perms * m / 2), false);
j = RcppArmadillo::sample(perms, ceil(perms * m / 2), false);
tmp = pop[i, RcppArmadillo::sample(k, K, true)];
pop[i, RcppArmadillo::sample(k, K, true)] = pop[j, RcppArmadillo::sample(k, K, true)];
pop[j, RcppArmadillo::sample(k, K, true)] = tmp;
}
}
}
}
}
return pop;
}
基本上两个函数都通过临时变量交换三维数组('pop')中的随机行。 C ++代码无法运行。
我知道我接近使用C ++代码,与R for循环相比,这将导致大量的加速。
我在这里缺少什么吗?非常感谢任何帮助,并热烈欢迎。
可重复的示例
##### Load packages #####
library(Rcpp)
library(RcppArmadillo)
### Set parameters ###
K <- 2
N <- 6
Hstar <- 5
probs <- rep(1/Hstar, Hstar)
m <- 0.20
perms <- 2 # number of permutations
num.specs <- ceiling(N / K)
haps <- 1:Hstar
specs <- 1:num.specs
gen.perms <- function() {
sample(haps, size = num.specs, replace = TRUE, prob = probs)
}
pop <- array(dim = c(perms, num.specs, K))
for (i in 1:K) {
pop[,, i] <- replicate(perms, gen.perms())
}
pop
, , 1
[,1] [,2] [,3]
[1,] 3 5 1
[2,] 2 3 3
, , 2
[,1] [,2] [,3]
[1,] 2 5 3
[2,] 3 5 3
migrate_r(pop) # notice rows have been swapped between subarrays
, , 1
[,1] [,2] [,3]
[1,] 3 5 1
[2,] 2 5 3
, , 2
[,1] [,2] [,3]
[1,] 3 5 3
[2,] 2 3 3