Search code examples
rcpprcpparmadillo

Invoke the element in `Rcpp::List` for futher use directly


In an application, I use List to contain some variables (double, arma::mat and other types), and then take the arma::mat component in this list for futher use directly, such as matrix addition. However, some error is thrown.

Below is a toy example to throw the same error as I met:

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

arma::mat f(){
    arma::mat x = arma::randn(3, 4) ;
    List y = List::create( ::Named("a") = arma::randn(3, 4) ) ;
    
    return x - y["a"] ;
}

The error information is

ambiguous overload for 'operator-' (operand types are 'arma::mat' 
{aka 'arma::Mat<double>'} and 'Rcpp::Vector<19>::NameProxy' {aka
 'Rcpp::internal::generic_name_proxy<19, Rcpp::PreserveStorage>'})

Is there any way to use the y["a"] directly in numerical computation?


Solution

  • You need cast back from the SEXP type you create when adding to an (R or Rcpp, it's the same) List. Correcting that and adding a missing exports tag gives us what is below where I also added the sample invocation (another nice feature).

    Code

    // [[Rcpp::depends(RcppArmadillo)]]
    #include <RcppArmadillo.h>
    using namespace Rcpp;
    
    // [[Rcpp::export]]
    arma::mat f(){
        arma::mat x = arma::randn(3, 4) ;
        List y = List::create( ::Named("a") = arma::randn(3, 4) ) ;
    
        return x - Rcpp::as<arma::mat>(y["a"]);
    }
    
    /*** R
    set.seed(42) # reproducible RNG draws
    f()
    */
    

    Output

    > Rcpp::sourceCpp("~/git/stackoverflow/71612260/answer.cpp")
    
    > 
    set.seed(42) # reproducible RNG draws
    
    > 
    f()
              [,1]      [,2]      [,3]      [,4]
    [1,] -0.471335 -2.337283  1.205825  0.537811
    [2,]  0.119150  1.251941  0.486474 -0.513627
    [3,]  3.309860 -0.654003 -0.146678 -0.835439
    >