2017-05-11 15 views
1

Rcppを学習し、次の2つの関数を記述しています。 2番目の関数は単にsum(log_gamma(x)) - log_gamma(sum(x))を計算します。ここでxはベクトルです。Rcppを使用した場合のデータ型変換エラー

3つのデータ型変換エラーが返されますが、すべて解決できません。誰かがコードを修正するのを助けることができますか?ありがとう。

file330c72cf6532.cpp:8:37: error: cannot convert 'Rcpp::sugar::Vectorized<Rf_lgammafn, true, Rcpp::Vector<14, Rcpp::PreserveStorage> >' to 'SEXP' in initialization 
      SEXP lgamma_x = lgamma(x); 
            ^
file330c72cf6532.cpp:10:45: error: cannot convert 'SEXP' to 'double' in initialization 
      double up = sum_cpp(lgamma_x_vec); 
              ^
file330c72cf6532.cpp:11:44: error: cannot convert 'Rcpp::sugar::Vectorized<Rf_lgammafn, true, Rcpp::Vector<14, Rcpp::PreserveStorage> >' to 'double' in initialization 
      double down = lgamma(sum_cpp(x)); 
              ^

cppFunction(
    'double sum_cpp(NumericVector x){ 
    double tmp = 0; 
    int n = x.size(); 
    for(int j = 0; j<n; j++){ 
     tmp = tmp + x[j]; 
    } 
    return tmp; 
    }') 

cppFunction('double LogB_cpp(NumericVector x){ 
      Function sum_cpp("sum_cpp") ; 
      SEXP lgamma_x = lgamma(x); 
      NumericVector lgamma_x_vec(lgamma_x); 
      double up = sum_cpp(lgamma_x_vec); 
      double down = lgamma(sum_cpp(x)); 
      return up - down;}') 

答えて

2

ここでは2つの目立ったエラーがあります。最初の問題は、通常のR関数としてC++を使用しない場合(例:sum_cpp)です。第2は、lgammaRcpp::NumericVectorを返す糖式であり、スカラー(例えば、double)ではないという問題です。


あなたはC++コードのプロトタイプを作成するための主要な手段として、その使用法を持っているcppFunction()を、使用しているので、最初の問題がアップします。 のC++をさらに拡張するためには、sourceCpp()が使用されることが好ましい。 sourceCpp()を使用すると、Rcpp属性が明示されます。この属性は、サーフェスする手段を提供しますC++の関数はRになります。具体的には、のC++スクリプト内では、// [[Rcpp::exports]]を希望のC++機能より上に使用する必要があります。さらに、C++関数を別の関数内で使用する必要がある場合は、その関数を使用する前に定義する必要があります。したがって、C++ファイルにLogB_cppの前にsum_cppを定義してください。その例については、Rcpp Quick Referenceガイドをご覧ください。第二の問題について


、これは簡単にNumericVectorとして保存するか、doubleとして最初の結果を得るために[0]のいずれかを使用することによって補正されます。

また、何らかの理由で最初にSEXPに保存してから、ステップが不要であり、以下で省略されたNumericVectorに変換していました。

#include <Rcpp.h> 

// [[Rcpp::export]] 
double sum_cpp(Rcpp::NumericVector x){ 
    double tmp = 0; 
    int n = x.size(); 
    for(int j = 0; j<n; j++){ 
     tmp = tmp + x[j]; 
    } 
    return tmp; 
} 

// [[Rcpp::export]] 
double LogB_cpp(Rcpp::NumericVector x){ 
    Rcpp::NumericVector calc_lgamma = lgamma(x); 
    double up = sum_cpp(calc_lgamma); 

    Rcpp::NumericVector sum_lgamma = lgamma(sum_cpp(x)); 
    double down = sum_lgamma[0]; 

    // Alternatively, you could do: 
    // double down = lgamma(sum_cpp(x))[0]; 

    return up - down; 
} 

は、次のように入力します:sourceCpp("gamma_source.cpp")

は例えば、gamma_source.cppに次のように配置します。これは、作業ディレクトリが "gamma_source.cpp"の場所と同じであることを前提としています。 。それ以外の場合は、パスを追加)


例:

library("Rcpp") 
sourceCpp("gamma_source.cpp") 
x = c(1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5) 
LogB_cpp(x) 
## [1] 9.481571 
+0

ありがとうございます!それは多くの意味があります。 –

関連する問題