2016-12-12 5 views
1

Rcpparmadilloコードにdgebalという名前のFortranルーチン(文書here)を使用する必要があります。私はさらに<R_ext/Lapack.h><R_ext/BLAS.h>が含まれている場合Rcpparmadillo:Fortranルーチン "dgebal"を呼び出せませんか?

error: 'dgebal_' was not declared in this scope 

、コードはなしでコンパイル:私は、私は次のエラーを取得するsourceCpp()を使用して、私のコードをコンパイルしようとすると、しかし

# include <RcppArmadillo.h> 
# include <math.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] 

警告はこれに類似しています。これは、RのLAPACKライ​​ブラリに含まれているdgebalを含まないRcpparmadilloに同梱されているLAPACKライ​​ブラリが原因であると想定するのは正しいですか?私はこれらの警告に心配すべきでしょうか?最後に、私のRcpparmadilloコードにコンパイルの警告なしでdgebalを使用する方法はありますか? RcppとRcpparmadilloの両方が最新です。オペレーティングシステムはWindows 8.1 64bitです。

EDIT: これはRcpparmadilloの問題ではないことを指摘してくれた@coatlessと@Dirk Eddelbuettel。それにもかかわらず、私の問題は解決しません。以下は私の問題を示す実例のコードです。それはうまくコンパイルされますが、私の限られたテストによれば、意図した機能に影響を与えないような前述の警告がたくさん出ます。 R_ext/Lapack.hR_ext/BLAS.hの2つのヘッダーを削除すると、コンパイラは上記のエラーをスローします。

#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) 
*/ 
+2

RcppArmadilloはRのLAPACKインストールを使用します。なぜあなたはfortranルーチンにアクセスしようとしていますか? – coatless

+2

_ "RAPPARMADILLOに同梱されたLAPACKライ​​ブラリ" _完全に間違っています。 RcppArmadilloは決して* LAPACKを出荷しませんが、LAPACK Rはローカルコピーであることを知っています。これは何百万回も議論されており、GHのレポ(issue)とリストに掲載されています。 _complete_の例を提供する場合、OS XとLinuxでテストできます。 –

+0

@ coatless:私は行列のバランスをとる必要があるので、armadilloではすぐに利用できません。 Fortranルーチン 'dgebal'がこれを行います。 – aenima

答えて

5

私はこれを理解しました。私はちょうど次の行でローカルヘッダファイルを作成し、#.cppファイルに#includeしました。警告やエラーがなくコンパイルがうまくいきます。

#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 
+3

おめでとう、あなたはArmadilloがフレームワークを使ってまだアクセスしていないLapackでFortranルーチンを呼び出す方法を工夫しました。それがここにあるのは便利なので、私はただそれを上書きしました。 –

+0

@DirkEddelbuettel:upvoteに感謝します。私はこれがおそらく非常によく見られる問題ではないと考えていますが、他の人がそれを必要とする場合に備えてシンプルで一般化可能な解決策を用意することはうれしいでしょう。 – aenima

関連する問題