3

I have a c++ class svol_leverage that inherits from an abstract base class BasePF (actually that's a type alias for something messy coming from a specialized class template).

Using the Rcpp modules vignette and this answer, I was able to use .factory to call methods of the base class in R:

install.packages("~/pfr_1.0.tar.gz", repos = NULL, type="source")
library(pfr)
mod <- new(BasePF, phi=.5, mu=.5, sigma=.5, rho=.5)
mod$getLogCondLike() 

However, I need to expose more methods, and I've started having difficulty. Some base class methods don't have great signatures--their types aren't easily wrapped to R types.

For example, in BasePF there's a filter() method I need to call that accepts, among other things, std::vector<>s of std::function<>s, of ... I decide to write wrappers in the derived class: svol_leverage::update. This returns void and takes two doubles. Simple.

*How would I update the RCPP_MODULE macro to expose this derived clas method, though? This isn't cutting it:

#include "svol_leverage.h" 



BasePF *newSvolLeverage(FLOATTYPE phi, FLOATTYPE mu, FLOATTYPE sigma, FLOATTYPE rho) {
  return new svol_leverage(phi, mu, sigma, rho);
}


// Expose the svol leverage model class
// Recall FLOATTYPE is defined in the header we're including above
RCPP_MODULE(svol_leverage_module){
  
  Rcpp::class_< BasePF >("BasePF")
  .factory<FLOATTYPE,FLOATTYPE,FLOATTYPE,FLOATTYPE>(newSvolLeverage)
  .method("getLogCondLike", &BasePF::getLogCondLike);
  
  Rcpp::class_<svol_leverage>("svol_leverage")
  .derives<BasePF>("BasePF")
  .method("update", &svol_leverage::update);
}

It R CMD builds fine, but when I go to call the update() method on my R object, I get this:

mod$update(.1, .1)
Error in envRefInferField(x, what, getClass(class(x)), selfEnv) : 
  ‘update’ is not a valid field or method name for reference class “Rcpp_BasePF”

I can get it available when I add .constructor to the Derived class, and then set up variables using the regular constructor (i.e. mod <- new(svol_leverage, phi=.5, mu=.5, sigma=.5, rho=.5). But these variables won't have access to the other method mod$lastLogCondLike(). So it's one or the other at the moment. How can I avoid this slicing behavior?

Taylor
  • 1,797
  • 4
  • 26
  • 51
  • R only offers us a C language interface and hence simpler signatures, so there are limits to what can be done with code generation. Rcpp Methods never had inheritance, I thinkl. I use it in RcppCNPy just fine with _templated versions of one core function_ varying different metrics. You may be able to work something out if you only expose the derived class to C. – Dirk Eddelbuettel Feb 27 '23 at 11:45
  • What I have done in the past is to stick with a clean C++ side of things, and then add glue methods to instantiate (and tear down) as well as basic interfaces to the key functions. – Dirk Eddelbuettel Feb 27 '23 at 20:24
  • Thanks @DirkEddelbuettel yeah I'll move in that direction – Taylor Feb 27 '23 at 23:39

0 Answers0