Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rcpparmadillo: can't call Fortran routine "dgebal"?

Tags:

r

rcpp

lapack

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)
*/
like image 876
aenima Avatar asked Dec 12 '16 05:12

aenima


1 Answers

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
like image 88
aenima Avatar answered Oct 31 '22 10:10

aenima