I was looking to call a C function https://github.com/wch/r-source/blob/trunk/src/nmath/rmultinom.c#L47 from Raku. For this I have defined Raku function as
use NativeCall;
constant RMATH = "./Rmath.dll";
multi set_seed(uint32, uint32)
is native( RMATH ) { * };
multi set_seed(UInt() $a, UInt() $b) is export {
set_seed(my uint32 $ = $a, my uint32 $ = $b)
}
sub rmultinom(int32, CArray[num64], int32, CArray[int32])
is native( RMATH ) { * };
sub raku_rmultinom($n , $size, @prob is copy) is export {
@prob = @prob.map: {$_.Num};
my $prob = CArray[num64].new(@prob);
my $ints = CArray[int32].allocate($size);
rmultinom($n, $prob, $size, $ints);
return $ints.list
}
A call
my @prob = [0.1, 0.3, 0.5, 0.1];
set_seed(123,456);
say raku_rmultinom(100, 5, @prob);
gives
(9 29 49 13 0)
conformant with C code:
#define MATHLIB_STANDALONE 1
#include "Rmath.h"
#include <stdio.h>
int main(int argc, char** argv) {
int draws = 100;
int classes = 5;
int vals[classes];
double probs[4] = {0.1, 0.3, 0.5, 0.1};
set_seed(123, 456);
rmultinom(draws, probs, classes, vals);
for(int j=0; j < classes; j++) {
printf("Count of class %i drawn: %i\n", j, vals[j]);
}
return 0;
}
Count of class 0 drawn: 9
Count of class 1 drawn: 29
Count of class 2 drawn: 49
Count of class 3 drawn: 13
Count of class 4 drawn: 0
But when I increase size to 10, see example below, the output seems weird:
my @prob = [0.1, 0.3, 0.5, 0.1];
set_seed(123,456);
say raku_rmultinom(100, 10, @prob);
(0 0 0 0 0 -1 0 0 0 0) # expectation was (9 29 49 13 0 0 0 0 0 0)
while in C:
int main(int argc, char** argv) {
int draws = 100;
int classes = 10;
int vals[classes];
double probs[4] = {0.1, 0.3, 0.5, 0.1};
set_seed(123, 456);
rmultinom(draws, probs, classes, vals);
for(int j=0; j < classes; j++) {
printf("Count of class %i drawn: %i\n", j, vals[j]);
}
return 0;
}
Count of class 0 drawn: 9
Count of class 1 drawn: 29
Count of class 2 drawn: 49
Count of class 3 drawn: 13
Count of class 4 drawn: 0
Count of class 5 drawn: 0
Count of class 6 drawn: 0
Count of class 7 drawn: 0
Count of class 8 drawn: 0
Count of class 9 drawn: 0
Is there any issue with implementation of raku_rmultinom in my Raku code?
System info: This is done in Windows 10 64-bit. For reproducibility, I have provided the header and dynamic library here: https://replit.com/@sumankhanal/rakunativecall.
To test C file with the Rmath.h header and library in the same folder, move to that directory and run from cmd line:
gcc -I. -L. <cfile> -lRmath
.\a.exe
Or else, I am the author of this package https://github.com/sumanstats/Statistics which has raku_rmultinom available globally, anyone can install and test the output and its behavior.
The version of Raku used is as downloaded from https://rakudo.org/dl/rakudo/rakudo-moar-2023.09-01-win-x86_64-msvc.zip; raku -v gives:
Welcome to Rakudo™ v2023.09.
Implementing the Raku® Programming Language v6.d.
Built on MoarVM version 2023.09.
I think it's worth summing up what happened in this SO.
First, what @Suman (the asker) concluded (in the comments below their question) was what "looks like" the answer:
This reflects the fact that for this Q, as is sometimes the case when bridging the gap between C and Raku, the problem is mismatches between Raku norms (which generally make sense when coding in Raku) and C norms (which generally make sense when coding in C) rather than problems with the technology on either side. Some excerpts from the comment exchange are illustrative of the process of getting to the bottom of such a mismatch: