2017-05-11 6 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++을 일반적인 R 함수로 사용해서는 안되는 경우 (예 : sum_cpp)입니다. 두 번째는 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로 저장하거나 두으로서 제 1 결과를 얻기 위해 어느 [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

감사합니다! 그것은 많은 의미가 있습니다. –