Rcpparmadillo:不能打电话给Fortran例程" dgebal"?

时间:2016-12-12 05:51:01

标签: r rcpp lapack

我需要在我的Rcpparmadillo代码中使用名为dgebal的Fortran例程(文档here)。我已经包含以下标题:

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

但是,当我尝试使用sourceCpp()编译代码时,出现以下错误:

error: 'dgebal_' was not declared in this scope

如果我进一步包含<R_ext/Lapack.h><R_ext/BLAS.h>,则代码编译时没有错误并且运行正常。但是编译器会抛出一堆这样的警告:

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]

还有更多类似的警告。我是否正确地认为这是由Rcpparmadillo附带的LAPACK库引起的,不包括dgebal,但是它包含在R&L的LAPACK库中?我应该关注这些警告吗?最后,有没有办法在没有编译警告的情况下在我的Rcpparmadillo代码中使用dgebal? Rcpp和Rcpparmadillo都是最新的。操作系统是Windows 8.1 64位。

编辑: 感谢@coatless和@Dirk Eddelbuettel指出这不是Rcpparmadillo问题。不过我的问题仍然存在,我想就如何解决这个问题提出建议。下面是一个说明我的问题的工作示例代码。它编译得很好但会产生很多上述警告,这似乎不会影响预期的功能,至少根据我的有限测试。如果我删除了两个标头R_ext/Lapack.hR_ext/BLAS.h,编译器会抛出上述错误。

#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 个答案:

答案 0 :(得分:9)

我已经弄明白了。我刚刚创建了一个带有以下行的本地头文件,并在我的.cpp文件中包含#included。编译正常,没有任何警告或错误。

public class Playground {

    public static void main(String[] args) {
        String testInput = "http://abc-xyz.com/AppName/service?id=1234&isStudent&stream&shouldUpdateRecord=Y&courseType";

        String[] tokens = testInput.split("\\?");
        String   urlPrefix = tokens[0];
        String   paramString = tokens[1];

        String[] params = paramString.split("&");

        StringBuilder sb = new StringBuilder();
        sb.append(urlPrefix + "?");
        String keyValueRegex = "(\\w+)=(\\w+)";
        String amp = "";    // first time special
        for (String param : params) {
            if (param.matches(keyValueRegex)) {
                sb.append(amp + param);
                amp = "&";  // second time and onwards
            }
        }

        System.out.println(sb.toString());

    }

}