使用 RcppArmadillo 时无法加载犰狳 Cube<uword>

Unable to load armadillo Cube<uword> when using RcppArmadillo

我使用 Armadillo 库在 C++ 中预先处理数据。程序最终产品是一个 ucube,它是一个用无符号整数填充的立方体。在 运行 之后,我想将 ucube 加载到 R 以执行一些最终的统计测试。为此,我创建了一个 C++ 函数来加载返回数组的 ucube。

但是不行!
我收到以下警告:"warning: Cube::load(): incorrect header in B.bin" 程序 returns 一个 0x0x0 数组。

为了找出原因,我制作了一个玩具 C++ 程序,运行良好。它能够毫无问题地加载多维数据集。

#include <iostream>
#include <armadillo>
using namespace arma;

void read_cubes(char const* A, char const* B){

    cube C;
    ucube D;

    C.load(A, arma_binary);
    D.load(B, arma_binary);

}   

int main(int argc, char** argv){

    cube A = randu<cube>(5,5,5);
    ucube B = randi<ucube>(5,5,5, distr_param(1, 10));

    A.save(argv[1], arma_binary);
    B.save(argv[2], arma_binary);

    read_cubes(argv[1], argv[2]);

}

但不知为何,在R中做同样的步骤,却行不通。为了说明,请运行玩具程序为./a.outA.binB.bin。它将产生 Cube<double> A.bin 和 Cube<uword> B.bin,我稍后会提到。

问题
如果我使用 Rcpp::sourceCpp 获取以下 C++ 代码并尝试使用 read_cube("A.bin") 读取 Cube<double> A.bin 它有效,但如果我对 Cube<uword> B.bin 与 read_ucube("B.bin") 它没有(我收到警告)。

#include <RcppArmadillo.h>
#include <iostream>
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
arma::cube read_cube(char const* x){
    arma::cube A;
    A.load(x, arma::arma_binary);
    return A;
}

// [[Rcpp::export]]
arma::ucube read_ucube(char const* x){
    arma::ucube B;
    B.load(x, arma::arma_binary);
    return B;
}

当然我可以在结束 C++ 程序之前将 Cube<uword> 转换为 Cube<double>,但我想知道为什么会发生这种情况以及是否可以加载 Cube<uword> ] 在 RcppArmadillo 中。因为它应该是可能的,对吧?

不幸的是,R 仍然只支持 32 位整数,所以 RcppArmadillo 强制 Armadillo 使用 32 位整数。这是通过在包含犰狳 header 之前定义 ARMA_32BIT_WORD 来完成的。查看 RcppArmadillo 的配置 here

您可以像这样在 Armadillo 程序中应用相同的 "trick":

#define ARMA_32BIT_WORD
#include <armadillo>

其中一个影响是 ucube (Cube<uword>) 将使用 32 位无符号整数。

完成上述技巧后,重新编译你的 Armadillo 程序并再次保存 ucubes。然后可以将它们加载到 RcppArmadillo 中。