Rcpparmadillo: can't call Fortran routine “dgebal”?

折月煮酒 提交于 2019-12-19 04:07:20

问题


I need to use a Fortran routine called dgebal (documentation here) in my Rcpparmadillo code. I have included the following headers:

# include <RcppArmadillo.h>
# include <math.h>

However, when I try to compile my code using sourceCpp() I get the following error:

error: 'dgebal_' was not declared in this scope

If I further include <R_ext/Lapack.h> and <R_ext/BLAS.h>, the code compiles without error and runs fine. However the compiler throws a bunch of warnings like this:

C:/PROGRA~1/R/R-32~1.3/include/R_ext/BLAS.h:49:64: warning: declaration of 'double dasum_(const int*, const double*, const int*)' with C language linkage [enabled by default]
C:/PROGRA~1/R/R-32~1.3/library/RCPPAR~1/include/armadillo_bits/def_blas.hpp:76:1: warning: conflicts with previous declaration 'double arma::dasum_(arma::blas_int*, const double*, arma::blas_int*)' [enabled by default]

There are many more warnings similar to this. Am I correct to assume this is caused by the LAPACK library shipped with Rcpparmadillo not including dgebal, which is however included with R's LAPACK library? Should I be concerned with these warnings? And finally, is there any way to use dgebal in my Rcpparmadillo code without compilation warnings? Both Rcpp and Rcpparmadillo are up to date. Operating system is Windows 8.1 64bit.

EDIT: Thanks @coatless and @Dirk Eddelbuettel for pointing out that this is not an Rcpparmadillo issue. Nevertheless my problem persists and I would like suggestions on how to get around this. Below is a working example code illustrating my problem. It compiles fine but produces a lot of the aforementioned warnings, which does not seem to affect the intended functionality, at least according to my limited testing. If I remove the two headers R_ext/Lapack.h and R_ext/BLAS.h, the compiler throws the aforementioned error.

#include <RcppArmadillo.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <R.h>
#include <Rinternals.h>
#include <Rmath.h>
#include <R_ext/Lapack.h>
#include <R_ext/BLAS.h>


// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;

// [[Rcpp::export]]
List R_dgebal2(SEXP x)
{
  SEXP dims, z, Scale, i_1, i_2;
  int n, info;

  dims = Rf_getAttrib(x, R_DimSymbol);
  n = INTEGER(dims)[0];


  z = Rf_duplicate(x); Scale = Rf_allocVector(REALSXP, n);
  i_1 = Rf_allocVector(INTSXP, 1); i_2 = Rf_allocVector(INTSXP, 1);

  F77_CALL(dgebal)("B", &n, REAL(z), &n, INTEGER(i_1), INTEGER(i_2),
           REAL(Scale), &info);

  arma::mat zz = as<arma::mat>(wrap(z));
  arma::vec scale2 = as<arma::vec>(wrap(Scale));
  int i1=as<int>(wrap(i_1)), i2=as<int>(wrap(i_2));
  return List::create(_["z"]=zz, _["scale"]=scale2, _["i1"]=i1, _["i2"]=i2);

}

// Test in R
/*** R
Q <- matrix(c(-1.918206e-01,5.999147e-01,0.000000e+00,0.000000e+00,0.000000e+00,1.106148e-01,
              -1.152574e+00,5.716490e-01,0.000000e+00,0.000000e+00,0.000000e+00,5.526595e-01,
              -1.256864e+00,3.905685e+04,0.000000e+00,0.000000e+00,0.000000e+00,1.929101e-01,
              -3.905721e+04,0.000000e+00,8.120577e-02,0.000000e+00,4.923053e-01,3.572873e-01,0.000000e+00),
              nrow = 5, byrow = T)
R_dgebal2(Q)
*/

回答1:


I have figured this out. I just created a local header file with the following lines and #included it in my .cpp file. Compiles fine with no warnings or errors.

#ifdef ARMA_USE_LAPACK

#if !defined(ARMA_BLAS_CAPITALS)

 #define arma_dgebal dgebal

#else
 #define arma_dgebal DGEBAL

#endif

extern "C"
void arma_fortran(arma_dgebal)(char* job, int* n, double* a, int* lda,
                  int* ilo, int* ihi, double* scale, int* info);

#endif


来源:https://stackoverflow.com/questions/41094867/rcpparmadillo-cant-call-fortran-routine-dgebal

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!