Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果矩阵尺寸增加,使用C++特征包的矩阵乘法似乎不稳定。_C++_R_Matrix_Eigen_Rcpp - Fatal编程技术网

如果矩阵尺寸增加,使用C++特征包的矩阵乘法似乎不稳定。

如果矩阵尺寸增加,使用C++特征包的矩阵乘法似乎不稳定。,c++,r,matrix,eigen,rcpp,C++,R,Matrix,Eigen,Rcpp,我必须执行许多矩阵计算来执行潮流计算。我使用R和C++来计算昂贵的步骤。计算成本最高的部分是两次矩阵乘法+转置,以及一次求解方程Ax=b。我开始使用稀疏矩阵,但因为我设法减小了矩阵的大小,所以这似乎不再是可行的方法。切换到稠密矩阵节省了我构建稀疏矩阵的成本,而且求解步骤快得多~20倍。乘法速度稍微慢一点,但与稀疏矩阵相比,我的速度提高了3到6倍 为了进一步提高速度,我尝试了会议上建议的方法 我包括了一个C++代码的额外部分,它同时执行我所有的计算。 // [[Rcpp::export]] SEX

我必须执行许多矩阵计算来执行潮流计算。我使用R和C++来计算昂贵的步骤。计算成本最高的部分是两次矩阵乘法+转置,以及一次求解方程Ax=b。我开始使用稀疏矩阵,但因为我设法减小了矩阵的大小,所以这似乎不再是可行的方法。切换到稠密矩阵节省了我构建稀疏矩阵的成本,而且求解步骤快得多~20倍。乘法速度稍微慢一点,但与稀疏矩阵相比,我的速度提高了3到6倍

为了进一步提高速度,我尝试了会议上建议的方法

我包括了一个C++代码的额外部分,它同时执行我所有的计算。

// [[Rcpp::export]]
SEXP eigenMapNodeAdm(const Eigen::Map<Eigen::MatrixXd> I, Eigen::Map<Eigen::MatrixXd> A){
  Eigen::MatrixXd Y = I * A * I.transpose() ;

  return Rcpp::wrap(Y);
}

A确保您的cpp文件在-O3上通过编译器优化进行了正确编译,并且完全支持您的CPU-march=nativeDid您告诉Egen使用您的BLAS库吗?@ggael这可能是导致此问题的原因吗?目前,我的编译器使用O2,但不允许我更改正在使用的服务器上的Makeconf文件。是否可以手工编译此函数并在R中使用?@DaBookshah我如何检查?我包括了sourceCpp的详细输出,它显示了完整的编译器设置。是的,看起来你没有。组织添加本征值并使用本征值作为定义。这与您的性能描述一致。请确保您的cpp文件在-O3上通过编译器优化正确编译,并且完全支持您的CPU-march=nativeDid您告诉Egen使用您的BLAS库吗?@ggael这可能是导致此问题的原因吗?目前,我的编译器使用O2,但不允许我更改正在使用的服务器上的Makeconf文件。是否可以手工编译此函数并在R中使用?@DaBookshah我如何检查?我包括了sourceCpp的详细输出,它显示了完整的编译器设置。是的,看起来你没有。组织添加本征值并使用本征值作为定义。这与您的性能描述一致。
library(microbenchmark)
library(Rcpp)
library(RcppEigen)

sourceCpp("MatrixMtp.cpp") # From https://stackoverflow.com/questions/35923787/fast-large-matrix-multiplication-in-r
                           # but with own method added
microbenchmark(I %*% A %*% Matrix::t(I),
               I %*% tcrossprod(A, I),
               armaMatMult(armaMatMult(I, A),Matrix::t(I)),
               eigenMatMult(eigenMatMult(I, A),Matrix::t(I)),
               eigenMapMatMult(eigenMapMatMult(I, A), Matrix::t(I)),
               eigenMapNodeAdm(I,A),
               times=100, check = "equivalent")

Unit: microseconds
                                                 expr       min         lq      mean    median        uq       max neval
                             I %*% A %*% Matrix::t(I)   743.334   960.5095  1802.524  1187.911  1459.810 35053.930   100
                               I %*% tcrossprod(A, I)   671.096   911.5160  1202.167  1163.660  1369.427  2052.610   100
         armaMatMult(armaMatMult(I, A), Matrix::t(I))   820.778  1345.8945  1996.141  1639.704  2437.173  4237.511   100
       eigenMatMult(eigenMatMult(I, A), Matrix::t(I)) 35358.135 43384.3715 49053.363 47713.833 53511.026 76970.653   100
 eigenMapMatMult(eigenMapMatMult(I, A), Matrix::t(I)) 33974.205 44098.6550 49799.859 49723.058 54936.584 76038.817   100
                                eigenMapNodeAdm(I, A) 30565.759 44404.1400 49241.233 48834.046 53759.213 72884.721   100
microbenchmark(Isub %*% Asub %*% Matrix::t(Isub),
               Isub %*% tcrossprod(Asub, Isub),
               armaMatMult(armaMatMult(Isub, Asub),Matrix::t(Isub)),
               eigenMatMult(eigenMatMult(Isub, Asub),Matrix::t(Isub)),
               eigenMapMatMult(eigenMapMatMult(Isub, Asub), Matrix::t(Isub)),
               eigenMapNodeAdm(Isub, Asub),times=1000, check = "equivalent")
Unit: microseconds
                                                      expr     min       lq     mean   median       uq       max neval
                               Isub %*% Asub %*% Matrix::t(Isub) 341.197 376.6945 556.0409 519.2540 535.0250 27024.769  1000
                                 Isub %*% tcrossprod(Asub, Isub) 294.895 346.8450 456.7293 471.9845 486.3635 15247.886  1000
           armaMatMult(armaMatMult(Isub, Asub), Matrix::t(Isub)) 362.011 417.8405 566.1201 521.3710 569.3060 12531.499  1000
         eigenMatMult(eigenMatMult(Isub, Asub), Matrix::t(Isub)) 322.220 440.7020 532.7970 475.2170 519.2595 14328.881  1000
   eigenMapMatMult(eigenMapMatMult(Isub, Asub), Matrix::t(Isub)) 263.116 376.5190 502.5597 407.7840 450.3955 20956.507  1000
                                     eigenMapNodeAdm(Isub, Asub) 197.265 291.4280 330.9622 306.5935 320.9700  7650.685  1000
// [[Rcpp::depends(RcppArmadillo, RcppEigen)]]

#include <RcppArmadillo.h>
#include <RcppEigen.h>

// [[Rcpp::export]]
SEXP armaMatMult(arma::mat A, arma::mat B){
  arma::mat C = A * B;

  return Rcpp::wrap(C);
}

// [[Rcpp::export]]
SEXP eigenMatMult(Eigen::MatrixXd A, Eigen::MatrixXd B){
  Eigen::MatrixXd C = A * B;

  return Rcpp::wrap(C);
}

// [[Rcpp::export]]
SEXP eigenMapMatMult(const Eigen::Map<Eigen::MatrixXd> A, Eigen::Map<Eigen::MatrixXd> B){
  Eigen::MatrixXd C = A * B;

  return Rcpp::wrap(C);
}

// [[Rcpp::export]]
SEXP eigenMapNodeAdm(const Eigen::Map<Eigen::MatrixXd> I, Eigen::Map<Eigen::MatrixXd> A){
  Eigen::MatrixXd Y = I * A * I.transpose() ;

  return Rcpp::wrap(Y);
}
> sourceCpp("inst/extdata/MatrixMtp.cpp", verbose = TRUE) # call the C++ file and we have three functions as armaMatMult,eigenMatMult,eigenMapMatMult.

Generated extern "C" functions 
--------------------------------------------------------


#include <Rcpp.h>
// armaMatMult
SEXP armaMatMult(arma::mat A, arma::mat B);
RcppExport SEXP sourceCpp_1_armaMatMult(SEXP ASEXP, SEXP BSEXP) {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    Rcpp::traits::input_parameter< arma::mat >::type A(ASEXP);
    Rcpp::traits::input_parameter< arma::mat >::type B(BSEXP);
    rcpp_result_gen = Rcpp::wrap(armaMatMult(A, B));
    return rcpp_result_gen;
END_RCPP
}
// eigenMatMult
SEXP eigenMatMult(Eigen::MatrixXd A, Eigen::MatrixXd B);
RcppExport SEXP sourceCpp_1_eigenMatMult(SEXP ASEXP, SEXP BSEXP) {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    Rcpp::traits::input_parameter< Eigen::MatrixXd >::type A(ASEXP);
    Rcpp::traits::input_parameter< Eigen::MatrixXd >::type B(BSEXP);
    rcpp_result_gen = Rcpp::wrap(eigenMatMult(A, B));
    return rcpp_result_gen;
END_RCPP
}
// eigenMapMatMult
SEXP eigenMapMatMult(const Eigen::Map<Eigen::MatrixXd> A, Eigen::Map<Eigen::MatrixXd> B);
RcppExport SEXP sourceCpp_1_eigenMapMatMult(SEXP ASEXP, SEXP BSEXP) {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    Rcpp::traits::input_parameter< const Eigen::Map<Eigen::MatrixXd> >::type A(ASEXP);
    Rcpp::traits::input_parameter< Eigen::Map<Eigen::MatrixXd> >::type B(BSEXP);
    rcpp_result_gen = Rcpp::wrap(eigenMapMatMult(A, B));
    return rcpp_result_gen;
END_RCPP
}
// eigenMapNodeAdm
SEXP eigenMapNodeAdm(const Eigen::Map<Eigen::MatrixXd> I, Eigen::Map<Eigen::MatrixXd> A);
RcppExport SEXP sourceCpp_1_eigenMapNodeAdm(SEXP ISEXP, SEXP ASEXP) {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    Rcpp::traits::input_parameter< const Eigen::Map<Eigen::MatrixXd> >::type I(ISEXP);
    Rcpp::traits::input_parameter< Eigen::Map<Eigen::MatrixXd> >::type A(ASEXP);
    rcpp_result_gen = Rcpp::wrap(eigenMapNodeAdm(I, A));
    return rcpp_result_gen;
END_RCPP
}
// eigenMapCalcCurrents
SEXP eigenMapCalcCurrents(const Eigen::Map<Eigen::MatrixXd> I, Eigen::Map<Eigen::MatrixXd> A, Eigen::Map<Eigen::MatrixXd> U);
RcppExport SEXP sourceCpp_1_eigenMapCalcCurrents(SEXP ISEXP, SEXP ASEXP, SEXP USEXP) {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    Rcpp::traits::input_parameter< const Eigen::Map<Eigen::MatrixXd> >::type I(ISEXP);
    Rcpp::traits::input_parameter< Eigen::Map<Eigen::MatrixXd> >::type A(ASEXP);
    Rcpp::traits::input_parameter< Eigen::Map<Eigen::MatrixXd> >::type U(USEXP);
    rcpp_result_gen = Rcpp::wrap(eigenMapCalcCurrents(I, A, U));
    return rcpp_result_gen;
END_RCPP
}

Generated R functions 
-------------------------------------------------------

`.sourceCpp_1_DLLInfo` <- dyn.load('/data/tmp/R/RtmpPJH0wY/sourceCpp-x86_64-redhat-linux-gnu-1.0.2.3/sourcecpp_620a5c2e111b/sourceCpp_8.so')

armaMatMult <- Rcpp:::sourceCppFunction(function(A, B) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_armaMatMult')
eigenMatMult <- Rcpp:::sourceCppFunction(function(A, B) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_eigenMatMult')
eigenMapMatMult <- Rcpp:::sourceCppFunction(function(A, B) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_eigenMapMatMult')
eigenMapNodeAdm <- Rcpp:::sourceCppFunction(function(I, A) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_eigenMapNodeAdm')
eigenMapCalcCurrents <- Rcpp:::sourceCppFunction(function(I, A, U) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_eigenMapCalcCurrents')

rm(`.sourceCpp_1_DLLInfo`)

Building shared library
--------------------------------------------------------

DIR: /data/tmp/R/RtmpPJH0wY/sourceCpp-x86_64-redhat-linux-gnu-1.0.2.3/sourcecpp_620a5c2e111b

/usr/lib64/R/bin/R CMD SHLIB -o 'sourceCpp_8.so'  'MatrixMtp.cpp'  
g++ -m64 -std=gnu++11 -I"/usr/include/R" -DNDEBUG -I../inst/include -fopenmp  -I"/data/users/al5696/Rlib/Rcpp/include" -I"/data/common/R/library/RcppArmadillo/include" -I"/data/common/R/library/RcppEigen/include" -I"/data/users/al5696/ms_n_min_1_berekening3/inst/extdata" -I/usr/local/include   -fpic  -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic -c MatrixMtp.cpp -o MatrixMtp.o
g++ -m64 -std=gnu++11 -shared -L/usr/lib64/R/lib -Wl,-z,relro -o sourceCpp_8.so MatrixMtp.o -fopenmp -L/usr/lib64/R/lib -lRlapack -L/usr/lib64/R/lib -lRblas -lgfortran -lm -lquadmath -L/usr/lib64/R/lib -lR