[Rcpp-devel] Calling an internal do_* C level function

Romain Francois romain at r-enthusiasts.com
Tue Oct 15 11:03:02 CEST 2013


Le 15/10/13 10:46, Martyn Plummer a écrit :
> On Mon, 2013-10-14 at 22:24 +0200, Romain Francois wrote:
>> Le 14/10/13 21:47, Mark Fredrickson a écrit :
>>> Thank you to Romain and Dirk. I've seen some C++ rank implementations,
>>> and I'll probably copy one of those.
>>>
>>>      Lastly, not a milligram of Rcpp in this question. Plain R programming
>>>      questions should go to r-devel, not rcpp-devel.
>>>
>>>
>>> Noted. My apologies. I was hoping there was some magic/sugar for this
>>> particular problem that I had missed in the docs. Perhaps something that
>>> negotiated the look up table that R uses for these functions.
>>>
>>> -M
>>
>> Here comes the magic.
>>
>> The internal function table (R_FunTab) is not hidden. With a bit of
>> copying from R's unexported Defn.h, you can get the function pointer for
>> the internal rank. see this gist:
>> https://gist.github.com/romainfrancois/6981372
>>
>> However, if you do this in a package, there is a good chance R CMD check
>> will moan about it because you use R_FunTab.
>>
>> Romain
>
> Calling non-API functions and subverting the mechanism for hiding them
> is a good way to make yourself unpopular.

I agree that one should not do that. It was just a fun challenge. I 
usually don't like "can't do that". Note that the example did not 
completely subvert it, there would have been a message complaining about 
the use of the R_FunTab symbol.

But I agree with you that in this example, and in many other examples, 
the STL provides the right tool.

Romainx

> Anyway, Mark wants to use the rank() function from R. So here is some
> code that I used to emulate it JAGS using the STL stable_sort algorithm.
>
> //Create a vector of pointers to the elements of args and sort it
> vector<double const*> argptrs(N);
> for (int i = 0; i < N; ++i) {
>     argptrs[i] = args + i;
> }
> stable_sort(argptrs.begin(), argptrs.end(), lt_doubleptr);
>
> //Ranks can be inferred from the sorted vector of pointers
> for (int i = 0; i < N; ++i) {
>     value[argptrs[i] - args] = i + 1;
> }
>
> Here "args" is an array of doubles containing the input vector, "value"
> is an array to hold the output vector, both of length "N", and
> "lt_doubleptr" is a comparison function that works on the vector of
> pointers:
>
> static bool lt_doubleptr (double const *arg1, double const *arg2) {
>    return *arg1 < *arg2;
> }
>
> Martyn


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30



More information about the Rcpp-devel mailing list