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)
*/
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With