使用Rcpp时的数据类型转换错误

时间:2017-05-11 07:25:11

标签: r rcpp

我正在学习Rcpp并编写以下两个函数。第二个函数只计算sum(log_gamma(x)) - log_gamma(sum(x)),其中x是向量。

返回三个数据类型转换错误,所有这些都无法解决。有人可以帮我纠正代码吗?感谢。

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;}')

1 个答案:

答案 0 :(得分:2)

这里有两个明显的错误。第一个问题是在不应该使用C ++作为常规 R 函数时(例如lgamma)。第二个问题是Rcpp::NumericVector是一个糖表达式,返回double而不是标量(例如cppFunction())。

第一个问题出现是因为您正在使用sourceCpp(),它将其用作构建 C ++ 代码的主要方法。对于更广泛的 C ++ 用法,最好使用sourceCpp()// [[Rcpp::exports]]的使用为Rcpp属性带来了光明,它提供了将 C ++ 函数表示为 R 的方法。具体来说,在 C ++ 脚本中,应该在所需的 C ++ 函数之上使用sum_cpp。此外,如果您需要在另一个中使用 C ++ 函数,则必须在使用之前定义它。因此,在 C ++ 文件中的LogB_cpp之前定义NumericVector。有关此示例,请参阅Rcpp Quick Reference指南。

关于第二个问题,可以通过将其另存为[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; } 该步骤并不需要,并且已从下面省略。

例如,将以下内容放入 gamma_source.cpp

sourceCpp("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 。这假设工作目录与&#34; gamma_source.cpp&#34;是。否则,请追加路径。)

示例:

origin/master