0
votes

I am trying to write a R package that is a wrapper for a C++ library that uses RcppGSL. I have successfully installed gsl and the package check stops at the Rcpp function compilation:

#include <Rcpp.h>
#include <RcppGSL.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <stdlib.h>
#include "graphm-0.52/graph.h"

#include <cstdlib>
#include <iostream>
#include <stdlib.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_permutation.h>


using namespace std;
using namespace Rcpp;

// declare a dependency on the RcppGSL package; also activates plugin
// (but not needed when ’LinkingTo: RcppGSL’ is used with a package)
//
// [[Rcpp::depends(RcppGSL)]]

//
//
// [[Rcpp::export]]
Rcpp::List run_graph_match(const RcppGSL::Matrix & A, const RcppGSL::Matrix & B, const Rcpp::List &algorithm_params ){
  graph graphm_obj_A;
  graphm_obj_A.set_adjmatrix (((*A)));
  graph graphm_obj_B;
  graphm_obj_B.set_adjmatrix (((*B)));


}

The function graph::set_adjmatrix (const gsl_matrix* A) takes in a const gsl_matrix pointer. My question is what would be the right level of referencing I need from going from const RcppGSL::Matrix reference to const gsl_matrix pointer. I would think just one, but I get the following error

graphmatch_rcpp.cpp:31:34: error: no matching function for call to 'graph::set_adjmatrix(RcppGSL::matrix<double>::gsltype&)'
   graphm_obj_A.set_adjmatrix((*A)));
                                  ^
graphmatch_rcpp.cpp:31:34: note: candidate is:
In file included from graphmatch_rcpp.cpp:9:0:
graphm-0.52/graph.h:52:9: note: int graph::set_adjmatrix(const gsl_matrix*)
     int set_adjmatrix(const gsl_matrix* _gm_A);
         ^
graphm-0.52/graph.h:52:9: note:   no known conversion for argument 1 from 'RcppGSL::matrix<double>::gsltype {aka gsl_matrix}' to 'const gsl_matrix*'
graphmatch_rcpp.cpp:33:34: error: no matching function for call to 'graph::set_adjmatrix(RcppGSL::matrix<double>::gsltype&)'
   graphm_obj_B.set_adjmatrix((*B)));

which suggests I should reference it once more and cast to const pointer. There is some implicit conversion from RcppGSL::matrix to gsl_matrix, so I am not sure I understand the details. Can anyone more familiar with RcppGSL, Rcpp give an answer as to how I could pass RcppGSL::matrix & to 'const gsl_matrix*' ?

1

1 Answers

0
votes

RcppGSL::Matrix is a proxy for a GSL Matrix; it is not the same as a GSL Matrix. If the "graphm" you are using expects one I would instantiate one first.

In fastLm.cpp we do this, and it passes a RcppGSL::Matrix on 'down' to the GSL:

// [[Rcpp::export]]
Rcpp::List fastLm(const RcppGSL::Matrix &X, const RcppGSL::Vector &y) {

    int n = X.nrow(), k = X.ncol();
    double chisq;

    RcppGSL::Vector coef(k);                // to hold the coefficient vector 
    RcppGSL::Matrix cov(k,k);               // and the covariance matrix

    // the actual fit requires working memory we allocate and free
    gsl_multifit_linear_workspace *work = gsl_multifit_linear_alloc (n, k);
    gsl_multifit_linear (X, y, coef, cov, &chisq, work);
    gsl_multifit_linear_free (work);

    // assign diagonal to a vector, then take square roots to get std.error
    Rcpp::NumericVector std_err;
    std_err = gsl_matrix_diagonal(cov);     // need two step decl. and assignment
    std_err = Rcpp::sqrt(std_err);          // sqrt() is an Rcpp sugar function

    return Rcpp::List::create(Rcpp::Named("coefficients") = coef, 
                              Rcpp::Named("stderr")       = std_err,
                              Rcpp::Named("df.residual")  = n - k);

}