This is a toy example:

# ----------------------- Creating the pointers to C++ functions --------
        
 otherCode <- ' // -------------------------- function definitions ---
                double f0(double x) {
                  return( tanh(x) );
                }

                double f1(double x) {
                  return( 1-tanh(x)*tanh(x) );
                }
                        '

        testCode <- '  // --------------- return a couple of Xptr to f0 and f1
               typedef double (*funcPtr)(double);
               return List::create( _["f0"]=XPtr<funcPtr>(new
funcPtr(&f0)),
                                    _["f1"]=XPtr<funcPtr>(new
funcPtr(&f1)) ) ;
                        '

        
        testCodefun <- cxxfunction(sig = character(), body = testCode, includes 
=
otherCode, plugin="Rcpp")

        functionPointers <- testCodefun()
        functionPointers
        # $f0
        # <pointer: 0x10043eca0>
        # 
        # $f1
        # <pointer: 0x10043f420>
        

# ----------------------- Using the pointers to C++ functions --------

        testCode <- '
              typedef double (*funcPtr)(double);
              List functionPointers(listOfFunctionPointers);
              double xx=as<double>(x);
              XPtr<funcPtr> f0XPtr = functionPointers["f0"];
              XPtr<funcPtr> f1XPtr = functionPointers["f1"];
              return NumericVector::create( _["f0(x)"]=(*f0XPtr)(xx) ,
                                            _["f1(x)"]=(*f1XPtr)(xx) ) ;
                        '
        testCodefun <- cxxfunction(sig =
signature(listOfFunctionPointers="externalpointer", x="numeric"), body =
testCode, includes = otherCode, plugin="Rcpp")

result <-testCodefun(listOfFunctionPointers=functionPointers, x=0.1)


result
# f0(x)      f1(x)
# 0.09966799 0.99006629










El 04/08/11 00:18, "Dirk Eddelbuettel" <e...@debian.org> escribió:

>
>On 3 August 2011 at 14:48, Christian Gunning wrote:
>| On Wed, Aug 3, 2011 at 10:22 AM,
>| <rcpp-devel-requ...@r-forge.wu-wien.ac.at> wrote:
>| > Simple examples are in a demo file in the
>| > package, see demo(CompiledBenchmark) -- or more importantly, see its
>source
>| > and the RcppDE source.
>| 
>| I'm now cobbling together a small XPtr section in Rcpp-quickref based
>| on these 2 related threads, which have been enormously helpful to me.
>
>You are the man! Much appreciated. But we should really make sure we
>settle
>on something simple yet complete.  Maybe feeding R's optim or something
>simpler.
>
>| Thanks, I think I finally get it.
>| 
>| In the meantime, for the inveterately lazy and/or confused, here's the
>| horse's mouth, with some key lines therein to trace up from:
>| 
>| 
>https://r-forge.r-project.org/scm/viewvc.php/pkg/RcppDE/demo/CompiledBench
>mark.R?view=markup&root=rcpp
>| 
>|         create_xptr <- cxxfunction(signature(funname="character"),
>| body=src.xptr, inc=inc, plugin="Rcpp")
>|         ## ...
>|         cppDE <- function(n, maxIt, fun) RcppDE::DEoptim(fn=fun,
>| lower=rep(-25, n),
>|                upper=rep(25, n), control=list(NP=10*n, itermax=maxIt,
>| trace=FALSE))#, bs=TRUE))
>|         ## ...
>|         xptr <- create_xptr(funname)
>|         ct <- system.time(invisible(cppDE(n, maxIt, xptr)))[3]
>
>What I didn't show was the receiving end.  In the C++ function doing the
>optimisation setip, we switch based on what the user gives us (R
>function, or
>inline-created XPtr SEXP with a C function):
>
>    Rcpp::DE::EvalBase *ev = NULL;             // pointer to abstract base 
> class
>    if (TYPEOF(fcall) == EXTPTRSXP) {          // non-standard mode: we are
>being passed an external pointer
>       ev = new Rcpp::DE::EvalCompiled(fcall); // so assign a pointer using
>external pointer in fcall SEXP
>    } else {                                   // standard mode: env_ is an 
> env, fcall_ is a function
>       ev = new Rcpp::DE::EvalStandard(fcall, rho);    // so assign R function 
> and
>environment
>    }
>
>and this 'ev' object is then evaluated with the parameters:
>
>    double t_tmpC = ev->eval(par);                             // Evaluate 
> mutant in t_tmpP
>
>It is implemented as some quick classes wrapped in a header file
>evaluate.h:
>
>
>       class EvalBase {
>       public:
>           EvalBase() : neval(0) {};
>           virtual double eval(SEXP par) = 0;
>           unsigned long getNbEvals() { return neval; }
>        protected:
>            unsigned long int neval;
>       };
>
>       class EvalStandard : public EvalBase {
>       public:
>           EvalStandard(SEXP fcall_, SEXP env_) : fcall(fcall_), env(env_) {}
>           double eval(SEXP par) {
>               neval++;
>               return defaultfun(par);
>           }
>       private:
>           SEXP fcall, env;
>           double defaultfun(SEXP par) {                       // essentialy 
> same as the old
>evaluate
>               SEXP fn = ::Rf_lang3(fcall, par, R_DotsSymbol); // this could 
> be done
>with Rcpp
>               SEXP sexp_fvec = ::Rf_eval(fn, env);            // but is still 
> a lot slower
>right now
>               double f_result = REAL(sexp_fvec)[0];
>               if (ISNAN(f_result))
>                   ::Rf_error("NaN value of objective function! \nPerhaps 
> adjust the
>bounds.");
>               return(f_result);
>           }
>       };
>
>       typedef double (*funcPtr)(SEXP);
>       class EvalCompiled : public EvalBase {
>       public:
>           EvalCompiled( Rcpp::XPtr<funcPtr> xptr ) {
>               funptr = *(xptr);
>           };
>           EvalCompiled( SEXP xps ) {
>               Rcpp::XPtr<funcPtr> xptr(xps);
>               funptr = *(xptr);
>           };
>           double eval(SEXP par) {
>               neval++;
>               return funptr(par);
>           }
>       private:
>           funcPtr funptr;
>       };
>
>EvalBase is the abstract base class, EvalStandard uses standard R and
>EvalCompiled uses the compiled function.
>
>It all looks mighty complicated but once you squint at it for a few
>minutes
>it starts to make sense.  And I share Manuel's excitement for doing
>something
>like this for Amore -- it make sense.
>
>But we need to clean it up into a simpler selfcontained example.
>Volunteers?
>
>Dirk
>
>-- 
>Gauss once played himself in a zero-sum game and won $50.
>                      -- #11 at http://www.gaussfacts.com


_______________________________________________
Rcpp-devel mailing list
Rcpp-devel@lists.r-forge.r-project.org
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to