6

This question is motivated by usage of a PRNG in Scala, but the answer can very well be language agnostic.

Problem

I want to have a functional interface to my PRNG. Currently the PRNG implementations I know (Java stdlib, Scala stdlib, commons math) are OO, in the sense that the PRNG is an object with mutable state. But I prefer a purely functional PRNG, which mainly has the following method:

def nextInt(state: S): (Int,S)

Here, S is the internal state of the PRNG (call it seed or whatever) and the method returns the desired random value plus the modified state.

What I need

Best would be an implementation. But I can do this easily by myself. A very simple implementation using Java's built-in PRNG would be:

def nextInt(state: Int): (Int,Int) = {
  val rng = new Random(state)
  (rng.nextInt(),rng.next())
}

or a bit more dangerous and less wasting

def nextInt(state: Random): (Int, Random) = {
  val newRng = state.clone
  (newRng.nextInt(),newRng)
}

What I truly need is a PRNG algorithm with good quality, small state and quick calculation. Mersenne Twister has a state of 600+ bytes. Note, that the state has to be copied in every step. So, is there something smaller?

Is there some kind of comparison of PRNG algorithms?

ziggystar
  • 28,410
  • 9
  • 72
  • 124
  • 3
    This isn't an answer to your question, but I asked a related question on Twitter a couple of weeks ago and was pointed to [this library](https://github.com/NICTA/rng), which provides a purely functional PRNG interface for Scala and a kind of wrapper for `java.util.Random`. – Travis Brown Nov 24 '13 at 12:11

2 Answers2

1

You don't need a functional implementation to get a functional interface.

You could represent your function PRNG as just a Stream of numbers generated by the Java PRNG---or any other stateful PRNG. As you explore the stream, it automatically calls the Java PRNG and remembers the result.

Ryan Culpepper
  • 10,495
  • 4
  • 31
  • 30
-1

Very good review and implementations for PRNG published in Knuth, TAOCP, Vol. 2, C.3.

Nikolay
  • 1,949
  • 18
  • 26