2017-05-11 39 views
1

我正在學習Rcpp並編寫以下兩個函數。第二個函數簡單計算sum(log_gamma(x)) - log_gamma(sum(x)),其中x是一個向量。使用Rcpp時的數據類型轉換錯誤

返回三個數據類型轉換錯誤,我無法解決所有這些錯誤。有人可以幫我糾正這些代碼嗎?謝謝。

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

這裏有兩個明顯的錯誤。第一個問題是當它不應該是C++作爲常規函數(例如sum_cpp)時使用的函數。第二個問題是lgamma是返回Rcpp::NumericVector而不是標量(例如double)的糖表達式。


的第一個問題來了,因爲你正在使用cppFunction(),有其爲主要手段的使用原型C++代碼。對於更多擴展C++的用法,最好使用sourceCpp()sourceCpp()的使用給Rcpp屬性帶來了光線,這提供了將C++函數表示爲R的手段。具體而言,在腳本中,應該使用高於所需功能的// [[Rcpp::exports]]腳本。另外,如果您需要在另一箇中使用功能,則必須在其使用之前對其進行定義。因此,在C++文件中的LogB_cpp之前定義sum_cpp。有關此示例,請參閱Rcpp Quick Reference指南。


關於第二個問題,這是很容易選擇保存它作爲NumericVector或使用[0]以獲得第一結果作爲雙校正。

此外,由於某種原因,您最初保存爲SEXP,然後轉換爲NumericVector該步驟不需要,並且從下面省略。

例如,將以下成gamma_source.cpp

#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」的位置相同。否則,追加路徑)


例:

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

謝謝!這很有道理。 –