假设
我有以下代码用于实矩阵,可以在
A
是一个复矩阵。我想要高效地计算在R
中的A%*%Conj(t(A))
乘积。据我所知,使用C++可以显著加快速度,所以这就是我想要做的。我有以下代码用于实矩阵,可以在
R
中使用。library(Rcpp);
library(inline);
library(RcppEigen);
crossprodCpp <- '
using Eigen::Map;
using Eigen::MatrixXd;
using Eigen::Lower;
const Map<MatrixXd> A(as<Map<MatrixXd> >(AA));
const int m(A.rows());
MatrixXd AAt(MatrixXd(m, m).setZero().selfadjointView<Lower>().rankUpdate(A));
return wrap(AAt);
'
fcprd <- cxxfunction(signature(AA = "matrix"), crossprodCpp, "RcppEigen")
A<-matrix(rnorm(100^2),100)
all.equal(fcprd(A),tcrossprod(A))
fcprd(A)
在我的笔记本电脑上比 tcrossprod(A)
运行得快得多。这是我在 A<-matrix(rnorm(1000^2),1000)
上得到的结果:
microbenchmark::microbenchmark('tcrossprod(A)'=tcrossprod(A),'A%*%t(A)'=A%*%t(A),fcprd=fcprd(A))
Unit: milliseconds
expr min lq mean median uq max neval
tcrossprod(A) 428.06452 435.9700 468.9323 448.8168 504.2628 618.7681 100
A%*%t(A) 722.24053 736.6197 775.4814 767.7668 809.8356 903.8592 100
fcprd 95.04678 100.0733 111.5021 103.6616 107.2551 197.4479 100
然而,这段代码仅适用于具有双精度条目的矩阵。我该如何修改此代码以使其适用于复杂矩阵?
我对编程了解非常有限,但我正在努力学习。任何帮助都将不胜感激!
fcprd
大约需要0.4秒来乘以1000x1000复杂矩阵,而A%*%Conj(t(A))
则需要大约1.6秒才能完成相同的操作。在我的笔记本电脑上,使用Eigen库的代码运行速度更快。 - Cm7F7BbRcpp::traits::Exporter<Eigen::Map<Eigen::Matrix<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic>>>
的专业化并在get()
方法中执行reinterpret_cast
来使地图正常工作(R和std都具有C99兼容的复杂类型,因此应该是安全的)。在centos7 / gcc 8.3中使用-O3 -DNDEBUG -flto -march = generic
计算(mat * mat.adjoint()).real()
,我发现Eigen需要1.20565秒,而vanilla R需要2.95519秒。 - Jean-Mathieu Vermosen