The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

03 - Converting between R and Armadillo types

Adapted from the official Armadillo documentation.

armadillo4r provides a set of conversion functions, declared across armadillo4r/wrappers/matrices.hpp, armadillo4r/wrappers/vectors.hpp, armadillo4r/wrappers/cubes.hpp, and armadillo4r/wrappers/fields.hpp, and all automatically available after including <armadillo4r.hpp>. This vignette documents every function and shows a minimal C++ example for each group.

1 R to Armadillo

1.1 Matrices

R matrices are represented in cpp4r as doubles_matrix<> (numeric) or integers_matrix<> (integer). The following functions convert them to Armadillo dense matrices:

cpp4r input Function Armadillo output Notes
doubles_matrix<> as_Mat(x) / as_mat(x) Mat<double> as_mat() is a lowercase alias
integers_matrix<> as_Mat(x) / as_mat(x) Mat<int> same alias applies
integers_matrix<> as_imat(x) imat (Mat<sword>) signed integer matrix
integers_matrix<> as_umat(x) umat (Mat<uword>) unsigned integer matrix; copies element-by-element
doubles_matrix<> as_fmat(x) fmat (Mat<float>) narrows double to float
#include <cpp4r.hpp>
#include <armadillo4r.hpp>

using namespace arma;
using namespace cpp4r;

[[cpp4r::register]]
doubles_matrix<> mat_demo_(const doubles_matrix<>& x,
                           const integers_matrix<>& xi) {
  mat    A  = as_Mat(x);    // double matrix
  imat   Ai = as_imat(xi);  // signed int matrix
  umat   Au = as_umat(xi);  // unsigned int matrix
  fmat   Af = as_fmat(x);   // float matrix

  // use A, Ai, Au, Af ...
  return as_doubles_matrix(A * A.t());
}
x <- matrix(c(1.5, 2.5, 3.5, 4.5), nrow = 2)
xi <- matrix(1:4, nrow = 2)
mat_demo_(x, xi)

1.2 Vectors

R vectors (doubles / integers) map to Armadillo column vectors:

cpp4r input Function Armadillo output Notes
doubles as_Col(x) / as_col(x) Col<double> (vec) as_col() is a lowercase alias
integers as_Col(x) / as_col(x) Col<int> same alias applies
integers as_uvec(x) uvec (Col<uword>) copies element-by-element (no reinterpret)
[[cpp4r::register]]
doubles vec_demo_(const doubles& y, const integers& yi) {
  vec  v  = as_Col(y);    // double column vector
  uvec vu = as_uvec(yi);  // unsigned int column vector

  // use v, vu ...
  return as_doubles(v % v);   // element-wise square
}
vec_demo_(c(1.0, 2.0, 3.0), 1:3)

1.3 Cubes

R has no native quasi third-order tensors (“3D matrices”) that maps directly onto Armadillo’s memory layout. armadillo4r therefore represents a cube on the R side as a list of matrices, where every element is a matrix of the same dimensions. Slice s of the Armadillo cube corresponds to element s + 1 of the R list (R is 1-indexed).

The most commonly used cube typedefs are:

Typedef Equivalent Element type
cube / dcube Cube<double> double
fcube Cube<float> float
icube Cube<sword> long long (signed, platform-dependent)
ucube Cube<uword> unsigned int
cx_cube / cx_dcube Cube<cx_double> std::complex<double>
cpp4r input Function Armadillo output Notes
list of doubles_matrix<> as_Cube(x) / as_cube(x) Cube<double> (cube) as_cube() is a lowercase alias
list of integers_matrix<> as_icube(x) Cube<int> note: assigns to Cube<int>, not icube (Cube<sword>)

Both functions throw std::runtime_error if the list is empty or any matrix has dimensions different from the first.

[[cpp4r::register]]
doubles_matrix<> cube_col_means_(const list& slices) {
  cube C = as_Cube(slices);   // list of doubles_matrix<> -> cube

  mat result(C.n_slices, C.n_cols);
  for (uword s = 0; s < C.n_slices; ++s) {
    result.row(s) = mean(C.slice(s), 0);  // column means of each slice
  }

  return as_doubles_matrix(result);
}
slices <- list(
  matrix(1:6, nrow = 2), # slice 1
  matrix(7:12, nrow = 2), # slice 2
  matrix(13:18, nrow = 2) # slice 3
)
cube_col_means_(slices)

1.4 Fields

An Armadillo field<object_type> stores arbitrary objects (matrices, vectors, strings, …) in a matrix-like or cube-like layout. Unlike Cube, the elements of a field do not need to have the same size — each element is an independent object.

Tip: when all matrices share the same dimensions, prefer Cube over field<mat> because Cube is more memory-efficient and faster.

On the R side a field is always represented as a plain list (or strings for field<std::string>). Element i of the Armadillo field (0-indexed) corresponds to element i + 1 of the R list (1-indexed).

cpp4r input Function Armadillo output Notes
list of doubles_matrix<> as_field_mat(x) field<mat> matrices may differ in size
list of integers_matrix<> as_field_imat(x) field<imat> matrices may differ in size
list of doubles as_field_vec(x) field<vec> vectors may differ in length
strings as_field_str(x) field<std::string>

All four functions throw std::runtime_error if the input list is empty.

[[cpp4r::register]]
list field_mat_demo_(const list& mats) {
  // Ragged list of matrices -> field<mat>
  field<mat> F = as_field_mat(mats);

  // Normalise each matrix independently
  for (uword i = 0; i < F.n_elem; ++i) {
    F(i) = normalise(F(i));  // L2-normalise columns
  }

  // field<mat> -> list of doubles_matrix<>
  return as_doubles_matrix_field(F);
}
mats <- list(
  matrix(1:6, nrow = 2), # 2x3 matrix
  matrix(1:12, nrow = 4) # 4x3 matrix  (different nrow!)
)
field_mat_demo_(mats)

2 Armadillo to R

2.1 Matrices

Armadillo input Function cpp4r output
Mat<double> / mat / fmat as_doubles_matrix(A) doubles_matrix<>
Mat<int> / imat / umat as_integers_matrix(A) integers_matrix<>
Mat<cx_double> / cx_mat as_complexes_matrix(A) complexes_matrix<>
[[cpp4r::register]]
doubles_matrix<> mat_out_demo_(const doubles_matrix<>& x) {
  mat A = as_Mat(x);
  return as_doubles_matrix(A.t() * A);  // mat -> doubles_matrix<>
}
x <- matrix(1:9, nrow = 3) * 1.0
mat_out_demo_(x)

2.2 Vectors

Armadillo input Function cpp4r output
Col<double> / vec as_doubles(v) doubles
Col<int> / ivec as_integers(v) integers
uvec as_integers(v) integers
[[cpp4r::register]]
doubles vec_out_demo_(const doubles& y) {
  return as_doubles(normalise(as_Col(y)));  // vec -> doubles
}
vec_out_demo_(c(3.0, 4.0)) # should give c(0.6, 0.8)

2.3 Cubes

Armadillo input Function cpp4r output
Cube<double> / cube as_doubles_matrix_list(C) list of doubles_matrix<>
Cube<int> / icube as_integers_matrix_list(C) list of integers_matrix<>
ucube as_integers_matrix_list(C) list of integers_matrix<>

Slice s of the cube becomes element s + 1 of the returned R list.

[[cpp4r::register]]
list random_cube_(const int n_rows, const int n_cols, const int n_slices) {
  cube C(n_rows, n_cols, n_slices, fill::randn);
  return as_doubles_matrix_list(C);  // cube -> list of doubles_matrix<>
}
set.seed(42)
result <- random_cube_(3L, 4L, 2L)

length(result) # 2  (one element per slice)
dim(result[[1]]) # 3 4

2.4 Fields

Armadillo input Function cpp4r output
field<mat> as_doubles_matrix_field(F) list of doubles_matrix<>
field<imat> as_integers_matrix_field(F) list of integers_matrix<>
field<vec> as_doubles_field(F) list of doubles
field<std::string> as_strings_field(F) strings

Element i of the field (0-indexed) becomes element i + 1 of the returned R list (1-indexed). Because field elements may differ in size, the returned list is potentially ragged.

[[cpp4r::register]]
list build_field_(const integers& sizes) {
  // Build a field<vec> where each vector has a different length
  field<vec> F(sizes.size());

  for (uword i = 0; i < F.n_elem; ++i) {
    F(i) = randn<vec>(sizes[static_cast<int>(i)]);  // random vector of length sizes[i]
  }

  return as_doubles_field(F);  // field<vec> -> list of doubles
}
build_field_(c(3L, 5L, 2L)) # list of three vectors of lengths 3, 5, 2

2.5 Generic conversion with cpp4r::as_sexp()

For cases where the return type is determined at compile time, cpp4r::as_sexp() provides a single generic entry point that dispatches to the appropriate conversion based on the Armadillo type:

Armadillo input as_sexp() output
vec / fvec doubles
ivec / uvec integers
mat / fmat doubles_matrix<>
imat / umat integers_matrix<>
rowvec / frowvec doubles_matrix<> (1-row matrix)
irowvec / urowvec integers_matrix<> (1-row matrix)
[[cpp4r::register]]
SEXP as_sexp_demo_(const doubles& y) {
  return cpp4r::as_sexp(arma::sort(as_Col(y)));  // vec -> doubles (dispatched automatically)
}
as_sexp_demo_(c(3.0, 1.0, 2.0)) # returns c(1, 2, 3)

3 References

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.