我使用 Rcpp::sourceCpp("test.cpp") 并输出以下错误信息。请注意, check1() 有效,而 check2 失败。区别在于“arma::vec”和“arma::fvec”。当我在 Windows 上尝试时发生错误。当我在linux上尝试它时,它可以工作。
(编辑:我在 Linux 上添加了我的 R 环境。PS:Linux 上的结果表明 float 比 double 快,这就是我更喜欢使用 float 的原因)
C:/RBuildTools/3.5/mingw_64/bin/g++ -std=gnu++11 -I"C:/PROGRA~1/R/R-36~1.1/include" -DNDEBUG -I../inst/include -fopenmp -I"C:/Users/wenji/OneDrive/Documents/R/win-library/3.6/Rcpp/include" -I"C:/Users/wenji/OneDrive/Documents/R/win-library/3.6/RcppArmadillo/include" -I"Y:/" -O2 -Wall -mtune=generic -c check.cpp -o check.o
C:/RBuildTools/3.5/mingw_64/bin/g++ -shared -s -static-libgcc -o sourceCpp_3.dll tmp.def check.o -fopenmp -LC:/PROGRA~1/R/R-36~1.1/bin/x64 -lRlapack -LC:/PROGRA~1/R/R-36~1.1/bin/x64 -lRblas -lgfortran -lm -lquadmath -LC:/PROGRA~1/R/R-36~1.1/bin/x64 -lR
check.o:check.cpp:(.text+0xa18): undefined reference to `sdot_'
collect2.exe: error: ld returned 1 exit status
下面是Windows上的R环境
R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18362)
Matrix products: default
Random number generation:
RNG: Mersenne-Twister
Normal: Inversion
Sample: Rounding
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_3.6.1 tools_3.6.1 RcppArmadillo_0.9.850.1.0
[4] Rcpp_1.0.3
下面是Linux上的R环境
R version 3.6.3 (2020-02-29)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 16.04.6 LTS
Matrix products: default
BLAS: /usr/lib/openblas-base/libblas.so.3
LAPACK: /usr/lib/libopenblasp-r0.2.18.so
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_3.6.3 tools_3.6.3
[3] RcppArmadillo_0.9.850.1.0 Rcpp_1.0.4
以下是“test.cpp”的代码
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector timesTwo(NumericVector x) {
return x * 2;
}
// [[Rcpp::export]]
arma::vec check1(arma::vec x1, arma::vec x2, int rep){
int n = x1.size();
arma::vec y(n);
y.fill(0);
for(int i = 0; i < rep; i ++){
y += x1 * arma::dot(x1, x2);
}
return y;
}
// [[Rcpp::export]]
arma::fvec check2(arma::fvec x1, arma::fvec x2, int rep){
int n = x1.size();
arma::fvec y(n);
y.fill(0);
for(int i = 0; i < rep; i ++){
y += x1 * arma::dot(x1, x2);
}
return y;
}
// You can include R code blocks in C++ files processed with sourceCpp
// (useful for testing and development). The R code will be automatically
// run after the compilation.
//
/*** R
timesTwo(42)
n = 100000
x1 = rnorm(n)
x2 = rnorm(n)
rep = 1000
system.time(y1 <- check1(x1, x2, rep))
system.time(y2 <- check2(x1, x2, rep))
head(y1)
head(y2)
*/
以下是 Linux 上的输出
> system.time(y1 <- check1(x1, x2, rep))
user system elapsed
0.156 0.000 0.160
> system.time(y2 <- check2(x1, x2, rep))
user system elapsed
0.088 0.000 0.100