Skip to content

[Rcpp-devel] Pointer troubles

3 messages · Christian Gunning, Dirk Eddelbuettel

#
Q: In latex code after quote, I've highlighted the new/free/finalizer
issue (adapted from Romain).  Alternately, this code (again, Romain's)
highlights passing an SEXP to XPtr<...>.  It seems that one or the
other should be primary.

SEXP doubleIntPointer(SEXP test){
    XPtr<int> test2(test) ;
    return wrap( *test2 * 2 ) ;
}

Comment: A concise example that uses an XPtr in a C++ function is
still lacking.  I'll look at this now+20hrs-ish.

It's been a hectic summer, sorry to reappear on list out of nowhere...
-xian
\paragraph{External Pointers}~
  \newline
<<lang=cpp>>=
// The Rcpp::XPtr template class is parameterized by the class of the
pointer.  XPtr objects are smart pointers and can be passed to C++
functions that require pointers.  XPtr objects can also be wrap()ed
and passed back to R as external pointers.

// XPtr includes a default finalizer.  Thus in this example test need
not be freed.
SEXP getIntPointer(){
    int *test = new int;
    *test = 6;
    XPtr<int> retVal(test);
    return retVal ;
}

// Define a simple function
double sumFun(SEXP xs) {
    Rcpp::NumericVector x(xs);
    double sum = std::accumulate(x.begin(), x.end(), 0.0);
    return(sum);
}

// Define a pointer to the above function
typedef double (*funcPtr)(SEXP);
ret = XPtr<funcPtr>(new funcPtr(&sumFun));
return ret;
@
14 days later
#
Sorry I missed Manuel's example when I last posted.  I guess I was
thinking something like below, which is a direct analog of apply. This
concisely mirrors the semantics in RcppDE (interchangable work
function for a well-defined task).  Here, the user needs only change
inc.  Only thing is, this example seems annoyingly long for inclusion
in the quickref.  Also, I'm not sure whether using inline here is more
or less confusing to the overall idea...

Any thoughts on documentation priorities?
-xian

require(inline); require(Rcpp)

inc <- '
// Define a simple function
double myFun(SEXP xs) { // sum
    Rcpp::NumericVector x(xs);
    double sum = std::accumulate(x.begin(), x.end(), 0.0);
    return(sum);
}
'

src <- '
// Define a pointer to the above function
typedef double (*funcPtr)(SEXP);
return(XPtr<funcPtr>(new funcPtr(&myFun)));
'

src1 <- '
// Define a pointer to the above function
typedef double (*funcPtr)(SEXP);
XPtr<funcPtr> myptr(infun);
// apply myptr to rows/columns of x
NumericMatrix xx(x);
int margin = as<int>(margin_);
int nr = xx.nrow();
int nc = xx.ncol();
if ( margin == 1 ) {
    NumericVector ret(nr);
    for( int i = 0; i<nr; i++) {
        ret[i] = (*myptr)( wrap(xx(i,_)) );
    };
    return(ret);
};
if ( margin == 2 ) {
    NumericVector ret(nc);
    for( int i = 0; i<nc; i++) {
        ret[i] = (*myptr)( wrap(xx(_,i)) );
    };
    return(ret);
};
'

mksum <- cxxfunction(signature(), body = src, includes = inc, plugin="Rcpp")
myapply <- cxxfunction(signature(x='numeric', margin_='integer', infun='XPtr'),
                    body = src1, includes = inc, plugin="Rcpp")

aa = matrix(1:100, nrow=5)
res1 = myapply(aa, 1, mksum() )
res1R = apply(aa, 1, sum)
res2 = myapply(aa, 2, mksum() )
res2R = apply(aa, 2, sum)
#
On 18 August 2011 at 19:27, Christian Gunning wrote:
| > Comment: A concise example that uses an XPtr in a C++ function is
| > still lacking.
| 
| Sorry I missed Manuel's example when I last posted.  I guess I was
| thinking something like below, which is a direct analog of apply. This
| concisely mirrors the semantics in RcppDE (interchangable work
| function for a well-defined task).  Here, the user needs only change
| inc.  Only thing is, this example seems annoyingly long for inclusion
| in the quickref. 

Well do not have a publisher-mandated page limit, so I'd say the more the
merrier!

| Also, I'm not sure whether using inline here is more
| or less confusing to the overall idea...

I like it. Maybe add a comment or two more, but the basic idea comes across
nicely.

Dirk
 
| Any thoughts on documentation priorities?
| -xian
| 
| require(inline); require(Rcpp)
| 
| inc <- '
| // Define a simple function
| double myFun(SEXP xs) { // sum
|     Rcpp::NumericVector x(xs);
|     double sum = std::accumulate(x.begin(), x.end(), 0.0);
|     return(sum);
| }
| '
| 
| src <- '
| // Define a pointer to the above function
| typedef double (*funcPtr)(SEXP);
| return(XPtr<funcPtr>(new funcPtr(&myFun)));
| '
| 
| src1 <- '
| // Define a pointer to the above function
| typedef double (*funcPtr)(SEXP);
| XPtr<funcPtr> myptr(infun);
| // apply myptr to rows/columns of x
| NumericMatrix xx(x);
| int margin = as<int>(margin_);
| int nr = xx.nrow();
| int nc = xx.ncol();
| if ( margin == 1 ) {
|     NumericVector ret(nr);
|     for( int i = 0; i<nr; i++) {
|         ret[i] = (*myptr)( wrap(xx(i,_)) );
|     };
|     return(ret);
| };
| if ( margin == 2 ) {
|     NumericVector ret(nc);
|     for( int i = 0; i<nc; i++) {
|         ret[i] = (*myptr)( wrap(xx(_,i)) );
|     };
|     return(ret);
| };
| '
| 
| mksum <- cxxfunction(signature(), body = src, includes = inc, plugin="Rcpp")
| myapply <- cxxfunction(signature(x='numeric', margin_='integer', infun='XPtr'),
|                     body = src1, includes = inc, plugin="Rcpp")
| 
| aa = matrix(1:100, nrow=5)
| res1 = myapply(aa, 1, mksum() )
| res1R = apply(aa, 1, sum)
| res2 = myapply(aa, 2, mksum() )
| res2R = apply(aa, 2, sum)
| 
| -- 
| A man, a plan, a cat, a ham, a yak, a yam, a hat, a canal ? Panama!