[Rd] Calling C implementations of rnorm and friends

Luis Usier luis.henrique.usier at gmail.com
Thu Jun 30 22:51:58 CEST 2016


Hi all,

Looking at the body for the function rnorm, I see that the body of the
function is:

    .Call(C_rnorm, n, mean, sd)

I want to implement functions that generate normal (and other) random
variables. Now, I understand that I can perfectly well just call the R
wrapper for these functions and that will be almost indistinguishable for
most purposes, but for whatever reason I wanted to try and call the C
function directly. My first instinct was to call them as:

    .Call(C_rnorm, 1, 1, 1)

This doesn't work because R assumes C_rnorm is an object. Looking at the
documentation for .Call, I try passing it in as a string:

    .Call("C_rnorm", 1, 1, 1, PACKAGE = "stats")

This doesn't work either. The help page links to getNativeSymbolInfo(),
which I can't make work either. It also refers me to the dyn.load()
function and the "Writing R  Extensions" manual.

After reading and trying to digest those, I try

    getDLLRegisteredRoutines("stats")

which shows me all the C and Fortran functions as registered routines,
along with their number of parameters. I retrieve rnorm from the list and
pass it on to .Call, which then works fine.

However, is there an easier way to do this? Specifically, I would like to
call the DLL registered routines from within functions in a package I am
writing. The manual tells me I should use useDynLib(). So if I added
useDynLib("stats") to my namespace, would that work? Could I then have a
function such as:

    function(x, y, z) .Call(C_rnorm, x, y, z)

in my package? If not, what is the proper way of calling these functions
from other packages? Should I use "C_rnorm" or "norm"?

Also, I was looking for the C source code of rnorm, because I wanted to
understand how the function works. Looking at Winston Chang's github R
mirror, I found rnorm in the random.c file in the stats package. However,
the code I find for it:



#define DEFRAND2_REAL(name) \
SEXP do_##name(SEXP sn, SEXP sa, SEXP sb) { \
    return random2(sn, sa, sb, name, REALSXP); \
}
DEFRAND2_REAL(rnorm)


Doesn't help me at all in understanding how it works. It should create a
function random2(sn, sa, sb, norm, REALSXP); I understand that is a version
of the random2 function that returns a real S expression taking sn, sa and
sb as parameters. But how does find the actual functional form for the
normal distribution?

I am asking because I would like to rewrite some of the other functions,
such as parameterizing rbeta by the mean and sample size rather than by the
number of successes and failures and rgamma by the mean and total time
elapsed instead of the number of events. Once I understand how the C source
code works, it would be hopefully not very difficult to reparameterize them.

Thanks,

Luis Usier

	[[alternative HTML version deleted]]



More information about the R-devel mailing list