0

I am using RcppGSL to make a wrapper package around a C library. I encounter an error when I am trying to return the result which comes from a gsl_matrix *

cannot convert const RcppGSL::matrix<double> to "SEXP" in initialization

Here is the code that creates the problem

try {
   exp.run_experiment(graphm_obj_A, graphm_obj_B);
        gsl_matrix *tmp =  exp.get_P_result(0) ;
    RcppGSL::Matrix P(tmp); // ((gsl_matrix *) exp.get_P_result(0) )    ;
 //const RcppGSL::matrix<double> P (gsl_matrix_

        Rcpp::List  res = Rcpp::List::create(
    Rcpp::Named("debugprint_file") = algorithm_params["debugprint_file"],
        //);
            //
    Rcpp::Named("Pmat") = P );
  P.free();
     return res;
    } catch( std::exception &ex) {
        Rf_error(ex.what());
    } catch (...) {
   return Rcpp::List();
    }

If I don't try to return P , the package is built without errors. So the relevant lines in wrap.h (added below) show this is due to not being implicitly convertible to SEXP. But my understanding was that the RcppGSL::Matrix objects were implicitly converted to SEXP objects. What am I missing

/**
 * This is the worst case :
 * - not a primitive
 * - not implicitely convertible tp SEXP
 * - not iterable
 *
 * so we just give up and attempt to use static_assert to generate
 * a compile time message if it is available, otherwise we use
 * implicit conversion to SEXP to bomb the compiler, which will give
 * quite a cryptic message
 */
template <typename T>
inline SEXP wrap_dispatch_unknown_iterable(const T& object, ::Rcpp::traits::false_type){
RCPP_DEBUG_1( "wrap_dispatch_unknown_iterable<%s>(., false  )", DEMANGLE(T) )
        // here we know that T is not convertible to SEXP
#ifdef HAS_STATIC_ASSERT
    static_assert( !sizeof(T), "cannot convert type to SEXP" ) ;
#else
    // leave the cryptic message
    SEXP x = object ;
  • 2
    Please study the _working_ examples in the RcppGSL carefully and see how they deal with GSL types. Also learn to use Rcpp Attributes; you have way too much boilerplate code above which is generated for us and generally hidden, letting us focus on what matters. – Dirk Eddelbuettel Nov 17 '16 at 02:37

1 Answers1

1

Here is a very minimal example of getting a matrix to GSL, having it transformed by adding it to itself, and returning it.

It is all contained in this one file:

#include <RcppGSL.h>

// [[Rcpp::depends(RcppGSL)]]

// [[Rcpp::export]]
RcppGSL::Matrix doubleMe(RcppGSL::Matrix X) {
  RcppGSL::Matrix res = X;
  gsl_matrix_add(res, X);    // adds X to res

  return res;
}

/*** R
M <- matrix(1:9, 3, 3)
doubleMe(M)
*/

which, when sourced, not only is compiled, linked and loaded but also executes the "unit test" in the marked R comment at the bottom:

R> sourceCpp("/tmp/GSLmatrixEx.cpp")

R> M <- matrix(1:9, 3, 3)

R> doubleMe(M)
     [,1] [,2] [,3]
[1,]    2    8   14
[2,]    4   10   16
[3,]    6   12   18
R> 

There really is no complication in getting a matrix to and from GSL. As RcppGSL::Matrix is a just a typedef for the more explict RcppGSL::matrix<double> you had; they are of course interchangeable.

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725