0

I was prepossessing data in C++ using the Armadillo library. The program end product is a ucube, which is a cube filled with unsigned integers. After its run, I want to load the ucube to R to perform some final statistical tests. To do so, I made a C++ function that load the ucube returning an array.

But it does not work!
I got the following warning: "warning: Cube::load(): incorrect header in B.bin" and the program returns a 0x0x0 array.

Trying to find why, I made a toy C++ program, which works fine. It is able to load the cubes without any problem.

#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]);

}

But I do not know why, doing the same steps in R does not work. To illustrate, please run the toy program as ./a.out A.bin B.bin. It will yield the Cube<double> A.bin and the Cube<uword> B.bin, which I will mention later.

The problem
If I source the following C++ code with Rcpp::sourceCpp and I try to read the Cube<double> A.bin with read_cube("A.bin") it works, but if I do the same for the Cube<uword> B.bin with read_ucube("B.bin") it does not (I get the warning).

#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;
}

Of course I could cast the Cube<uword> to a Cube<double> before ending the C++ program, but I would like to know why this happen and if it is possible to load a Cube<uword> in RcppArmadillo. Because it should be possible, right?

1 Answers1

2

Unfortunately R still only supports 32 bit integers, so RcppArmadillo forces Armadillo to use 32 bit integers. This is done by defining ARMA_32BIT_WORD before including the armadillo header. See RcppArmadillo's configuration here.

You can apply the same "trick" with your Armadillo programs like so:

#define ARMA_32BIT_WORD
#include <armadillo>

One of the effects is that ucube (Cube<uword>) will use 32 bit unsigned integers.

After doing the above trick, recompile your Armadillo programs and save the ucubes again. They can then be loaded in RcppArmadillo.

mtall
  • 3,574
  • 15
  • 23