RCPP 中的模板化矩阵

Templated Matrix in RCPP

本文关键字:RCPP      更新时间:2023-10-16

我正在使用 Rcpp 制作一个接受矩阵和向量的函数,我希望它们都是相同的模板化类型。有没有办法这样做?似乎您必须在使用矩阵之前将其声明为数字或其他东西。

//[[Rcpp::export]]
void MyFunc(Matrix<T> templated_matrix, std::vector<T> set_row)
{
    templated_matrix(0, _) = row;
}

这里有几个问题交织在一起。特别是,Rcpp 属性不处理模板函数的导出,因此您无法编写:

// [[Rcpp::export]]
template <typename T>
void MyFunc(T object) { ... }

这是因为在 R 中键入是动态的(在运行时完成并存储(,C++键入是静态的(在编译时必须知道所有内容(。您需要手动生成动态和静态世界之间的桥梁。

一种常见的方法是制作模板函数和"调度"函数,例如

template <typename T>
void MyFuncImpl(T object) { .... }
// [[Rcpp::export]]
void MyFunc(SEXP object)
{
    switch (TYPEOF(object))
    {
    case INTSXP: return MyFuncImpl<IntegerVector>(object);
    case REALSXP: return MyFuncImpl<NumericVector>(object);
    ...
    }
}

在您的情况下,您可能需要根据传入的对象是否是矩阵来分离调度,例如 if (Rf_isMatrix(object)) { ... } else { .... } .

您可能会发现 Rcpp 库中的这些文章很有帮助:

  • http://gallery.rcpp.org/articles/rcpp-wrap-and-recurse/
  • http://gallery.rcpp.org/articles/dynamic-dispatch-for-sparse-matrices/

另外,如果要直接在 R 对象的基础类型上模板化,还可以编写:

template <int RTYPE>
void MyFuncImpl(Vector<RTYPE> object) { .... }

根据您的需求,这可能更有用,也可能不更有用。