Skip to content

mclements/mercury-mt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mercury-mt: Mercury library for the Mersenne Twister random number generator

Introduction

Mercury-only library for the Mersenne Twister random number generator. This uses a unique random number random.urandom type class and a shared random type random.random type class. For each approach, seed(uint32) function is provided that returns a generator that is seeded as per R’s set.seed() function.

32-bit versus 64-bit random numbers

Many of the random number generators in programming languages are based on a 32-bit Mersenne Twister generator. However, Mercury’s random type classes default to using a 64-bit random number generators. We have provided a runif(float::out, mt::in, mt::out) predicate that generates uniform random numbers between 0 and 1 using a 32-bit random number generator to provide the same random numbers as per R’s runif() function.

Question for Mercury users: is it better to do this as a ground generator or as a unique generator?

Examples

:- module test_mt.

:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.

:- implementation.

:- import_module mt, float, list, int, uint32, string, random.

:- pred runif(int::in, list(float)::out, random::in, random::out).
runif(N, List, !Rng) :- 
    map_foldl((pred(_I::in,U::out,R0::in,R::out) is det :- runif(U, R0, R)),
	      1..N, List, !Rng).

main(!IO) :-
    print_line("Expected: {0.72090390, 0.07196114}", !IO),
    seed(12345u32, S0),
    test(S0, S1, !IO),
    test(S1, _, !IO),
    test(S0, _, !IO).

:- pred test(random::in, random::out, io::di, io::uo) is det.

test(R0, R, !IO) :-
    N = 624,
    runif(2*N,Us,R0,R),
    list.det_index1(Us,1,U1),
    list.det_index1(Us,2*N,U2),
    format("Observed: {%10.8f, %10.8f}\n", [f(U1), f(U2)], !IO).

mmc --make test_mt && ./test_mt
Expected: {0.72090390, 0.07196114}
Observed: {0.72090390, 0.07196114}
Observed: {0.76355383, 0.70150276}
Observed: {0.72090390, 0.07196114}
set.seed(12345)
runif(624*2)[c(1,624*2)]
runif(624*2)[c(1,624*2)]
set.seed(12345)
runif(624*2)[c(1,624*2)]
[1] 0.72090390 0.07196114
[1] 0.7635538 0.7015028
[1] 0.72090390 0.07196114

Documentation

mt

:- module mt.

:- interface.
:- import_module random, uint8, uint16, uint32, uint64.

%% Types
:- type params.
:- type ustate.
:- type random == shared_random(params, ustate).

:- instance urandom(params, ustate).
:- instance urandom_dup(ustate).

%% Constructs an instance based on R's set.seed algorithm
:- pred seed(uint32::in, params::out, ustate::uo) is det.
:- pred seed(uint32::in, random::out) is det.

    % Generate a uniformly distributed pseudo-random unsigned integer
    % of 8, 16, 32 or 64 bits, respectively.
    %
:- pred generate_uint8(params::in, uint8::out,
    ustate::di, ustate::uo) is det.
:- pred generate_uint16(params::in, uint16::out,
    ustate::di, ustate::uo) is det.
:- pred generate_uint32(params::in, uint32::out,
    ustate::di, ustate::uo) is det.
:- pred generate_uint64(params::in, uint64::out,
    ustate::di, ustate::uo) is det.

    % Duplicate a 32-bit SFC state.
    %
:- pred urandom_dup(ustate::di, ustate::uo, ustate::uo) is det.

    % Generate a uniformly distributed pseudo-random unsigned integer
    % of 8, 16, 32 or 64 bits, respectively.
    %
    % As above, but does not require the params argument (which is a dummy
    % type only needed to satisfy the typeclass interface).
    %
:- pred generate_uint8(uint8::out, ustate::di, ustate::uo) is det.
:- pred generate_uint16(uint16::out, ustate::di, ustate::uo) is det.
:- pred generate_uint32(uint32::out, ustate::di, ustate::uo) is det.
:- pred generate_uint64(uint64::out, ustate::di, ustate::uo) is det.

:- pred runif(params::in, float::out, ustate::di, ustate::uo) is det.
:- pred runif(float::out, random::in, random::out) is det.

About

Mercury only library for Mersenne Twister random number generator

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published