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.)

Author: Stephen Weigand

Created: 2023-08-28 Mon 08:59

Validate