Skip to content

Field of matrices being returned with class matrix instead of list #263

Description

@coatless

Stumbled across an interesting hiccup in the exporter for arma::field<T> (the generic vector). In particular, the attributes associated with an arma::field<arma::mat> shows as matrix under a class(x) call instead of list. The only way to obtain the list type is to use a typeof() call.

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

// [[Rcpp::export]]
Rcpp::List test_case() {
  
  // Random dimensions
  int N = 5,
      P = 8,
      J = 10,
      K = 3,
      S = 2;

  // Create a 2d matrix
  arma::mat standard_2d_matrix(P, N);

  // Create a 3rd array
  arma::cube standard_3d_array(J, S, N);
  
  // Create a 4D Array
  arma::field<arma::cube> nonstandard_4d_array(N);
  
  // Fill it with cubes
  nonstandard_4d_array.fill(arma::ones<arma::cube>(J, K, S));
  
  return Rcpp::List::create(
    Rcpp::Named("d2", standard_2d_matrix),
    Rcpp::Named("d3", standard_3d_array),
    Rcpp::Named("d4", nonstandard_4d_array)
  );

}

The class issue is shown under d4 being matrix instead of list.

exporter_check = test_case() 

sapply(exporter_check, FUN = class)
#       d2       d3       d4 
# "matrix"  "array" "matrix" 
sapply(exporter_check, FUN = typeof)
#      d2       d3       d4 
# "double" "double"   "list" 

Moreover, the list is registering as a matrix with dim(x) of N x 1 instead of a list without dimensions.

sapply(exporter_check, FUN = dim)
# $d2
# [1] 8 5
# $d3
# [1] 10  2  5
# $d4
# [1] 5 1

And the object structure:

str(exporter_check)
# List of 3
# $ d2: num [1:8, 1:5] 1.49e-154 1.49e-154 2.57e-322 6.95e-310 6.95e-310 ...
# $ d3: num [1:10, 1:2, 1:5] 1.49e-154 1.49e-154 9.96e-320 1.63e-322 1.43e-322 ...
# $ d4:List of 5
#  ..$ : num [1:10, 1:3, 1:2] 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ : num [1:10, 1:3, 1:2] 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ : num [1:10, 1:3, 1:2] 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ : num [1:10, 1:3, 1:2] 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ : num [1:10, 1:3, 1:2] 1 1 1 1 1 1 1 1 1 1 ...
#  ..- attr(*, "dim")= int [1:2] 5 1

Activity

  1. changed the title [-]Field of matrices being returned with class matrix[/-] [+]Field of matrices being returned with class `matrix` instead of `list`[/+] on Jul 30, 2019
  2. coatless commented on Jul 31, 2019

    @coatless
    ContributorAuthor

    Yeah, so the offending piece of code is setting two dimensions and enforcing a matrix object return instead of a list.

    template <typename T>
    SEXP wrap( const arma::field<T>& data){
    RObject x = wrap( RcppArmadillo::FieldImporter<T>( data ) ) ;
    x.attr("dim" ) = Dimension( data.n_rows, data.n_cols ) ;
    return x ;
    }

  3. mlampros commented on Apr 11, 2020

    @mlampros

    For anyone else who might stumble upon this issue - as I did - the following worked for me:

    // [[Rcpp::export]]
    Rcpp::List conv_arma_field_to_rcpp_list(int init_arma_mat = 5,
                                            int dimensions = 6) {
    
      arma::field<arma::Mat<double> > Field_obj(init_arma_mat);
    
      for (unsigned int s = 0; s < init_arma_mat; s++) {
    
        int rows_cols = arma::randi<int>(arma::distr_param(dimensions, dimensions));
        Field_obj(s).zeros(rows_cols, rows_cols);
      }
    
      Rcpp::List list_obj = Rcpp::wrap( Rcpp::RcppArmadillo::FieldImporter< arma::Mat<double> >( Field_obj ) );
      return list_obj;
    }
    
    # res = conv_arma_field_to_rcpp_list()
    
  4. eddelbuettel commented on Nov 26, 2021

    @eddelbuettel
    Member

    This should now be fixed, albeit behind a #define that has to be turned on. See the new unit tests in tests_fields_new.R and the underlying C++ code (with the #define) in fields_new.cpp.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions