我正在開發中Rcpp
是從bigmemory
包big.matrix
對象進行操作某些功能的不同類型的變量。這些對象被傳遞到作爲Rcpp
對象SEXP
我然後必須強制轉換爲XPtr<BigMatrix>
,然後到一個MatrixAccessor
對象來訪問矩陣的元素。初始化基於switch語句
例如,如果我想要實現的是得到一個功能就是對角線:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::depends(BH, bigmemory)
#include <bigmemory/MatrixAccessor.hpp>
#include <numeric>
// [[Rcpp::export]]
NumericVector GetDiag(SEXP pmat) {
XPtr<BigMatrix> xpMat(pMat); // allows you to access attributes
MatrixAccessor<double> mat(*xpMat); // allows you to access matrix elements
NumericVector diag(xpMat->nrow()); // Assume matrix is square
for (int i = 0; i < xpMat->nrow(); i++) {
diag[i] = mat[i][i];
}
return diag;
}
此功能精美,提供R中的big.matrix
對象充滿了一倍。
但是,如果您在整數矩陣(例如diag(as.big.matrix(matrix(1:9, 3))@address)
)上調用此函數,則會因此導致垃圾回收,因爲MatrixAccessor
已被初始化爲<double>
。
內部,big.matrix
對象可以有四種類型:
void typeof(SEXP pMat) {
XPtr<BigMatrix> xpMat(pMat);
int type = xpMat->matrix_type();
type == 1 // char
type == 2 // short
type == 4 // int
type == 8 // double
}
由於所有我們正在做的是訪問矩陣的元素,在diag
功能應該能夠處理這些類型。但是現在,由於我們的函數簽名是NumericVector
,我會忽略字符矩陣。
爲了解決這個問題,我想我可能只是扔在一個switch語句,在運行時使用合適的類型初始化相應mat
:
// [[Rcpp::export]]
NumericVector GetDiag(SEXP pmat) {
XPtr<BigMatrix> xpMat(pMat);
// Determine the typeof(pmat), and initialize accordingly:
switch(xpMat->matrix_type()) {
case == 1:
{
// Function expects to return a NumericVector.
throw;
}
case == 2:
{
MatrixAccessor<short> mat(*xpMat);
break;
}
case == 4:
{
MatrixAccessor<int> mat(*xpMat);
break;
}
case == 8:
{
MatrixAccessor<double> mat(*xpMat);
}
}
MatrixAccessor<double> mat(*xpMat); // allows you to access matrix elements
NumericVector diag(xpMat->nrow()); // Assume matrix is square
for (int i = 0; i < xpMat->nrow(); i++) {
diag[i] = mat[i][i];
}
return diag;
}
然而,這會導致編譯器錯誤,因爲我重新定義mat
已經在第一個case
中聲明之後。
我可以看到要做到這一點的唯一方法是編寫三種不同的diag
函數,每種類型一個,其代碼與mat
的初始化例外相同。有沒有更好的辦法?
感謝您的支持,並將其作爲[bigmemory文章](http://gallery.rcpp.org/articles/using-bigmemory-with-rcpp/)的修訂版移至Rcpp Gallery。 –