Trying the Rmath library
This documents a first attempt in learning to use R's standalone math
library written in C called libRmath
.
I'm using Lubuntu and searched via this:
apt search r-mathlib # based on trial and error
Sorting... Full Text Search... r-mathlib/jammy,now 4.1.2-1ubuntu2 amd64 [installed] GNU R standalone mathematics library
That was what I wanted so I installed it very easily.
sudo apt install r-mathlib Reading package lists... Done Building dependency tree... Done Reading state information... Done The following NEW packages will be installed: r-mathlib 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 2,188 kB of archives. After this operation, 2,950 kB of additional disk space will be used. Get:1 http://archive.ubuntu.com/ubuntu jammy/universe amd64 r-mathlib amd64 4.1.2-1ubuntu2 [2,188 kB] Fetched 2,188 kB in 2s (1,383 kB/s) Selecting previously unselected package r-mathlib. (Reading database ... 305885 files and directories currently installed.) Preparing to unpack .../r-mathlib_4.1.2-1ubuntu2_amd64.deb ... Unpacking r-mathlib (4.1.2-1ubuntu2) ... Setting up r-mathlib (4.1.2-1ubuntu2) ... Processing triggers for libc-bin (2.35-0ubuntu3.1) ...
Simple example using dnorm
Next, a search gave me this Stack Overflow question on how to write an example and comple it. So here is the poster's example.
#define MATHLIB_STANDALONE #include <R.h> #include <Rmath.h> int main() { /* Inputs */ double V1 = 1; double V2 = 2; /* Normal Distribution */ double result = dnorm(V1, V2, M_PI, 1); printf("%lf\n",result); return 0; }
Compiling
From the Stack Overflow post I got this:
gcc -Wall -o answer answer.c -lRmath -I /usr/share/R/include ./answer
My system does not need me to specifically link to the math library
(i.e., I don't need -lm
).
>This is amazingly easy.
Documentation on the functions
What are the arguments to dnorm
? An article called Using the R
Standalone Math Library pointed out I can look at the R interpreter's
version of dnorm
:
print(dnorm)
function (x, mean = 0, sd = 1, log = FALSE) .Call(C_dnorm, x, mean, sd, log) <bytecode: 0x55ddefe93c40> <environment: namespace:stats>
So the four arguments are x
, mean
, sd
, and log
(an integer).
The function above uses the constant M_PI
and to find out
what that is, I grepped:
grep 'M_PI' /usr/share/R/include/*.h
/usr/share/R/include/Rmath.h:#ifndef M_PI /usr/share/R/include/Rmath.h:#define M_PI 3.141592653589793238462643383280 /* pi */ /usr/share/R/include/Rmath.h:#ifndef M_PI_2 /usr/share/R/include/Rmath.h:#define M_PI_2 1.570796326794896619231321691640 /* pi/2 */ /usr/share/R/include/Rmath.h:#ifndef M_PI_4 /usr/share/R/include/Rmath.h:#define M_PI_4 0.785398163397448309615660845820 /* pi/4 */
With this information, I can replicate my C program in R.
dnorm(1, 2, pi, log = TRUE)
[1] -2.114329
Generating random numbers
This next example shows how to generate random numbers. (I'm borrowing from the article linked to above.)
#define MATHLIB_STANDALONE #include <R.h> #include <Rmath.h> int main(void) { set_seed(1, 1); double variate; variate = rnorm(0, 1); printf("The random N(0, 1) variate is %f\n", variate); return 0; }
Now to compile it:
gcc -Wall -o myrandom myrandom.c -lRmath -I /usr/share/R/include ./myrandom
Again, this is very easy which is so nice.
The section in the R extensions manual titled Using these functions in your own C code says:
A little care is needed to use the random-number routines. You will need to supply the uniform random number generator
double unif_rand(void)or use the one supplied (and with a dynamic library or DLL you will have to use the one supplied, which is the Marsaglia-multicarry with an entry points
set_seed(unsigned int, unsigned int)to set its seeds and
get_seed(unsigned int *, unsigned int *)to read the seeds).
I don't know what this means exactly. (In particular I don't know what
the two arguments to set_seed
do.)