PCG submodule

To solve the rendering equation we need a random number generator that can be used to make the Monte Carlo estimates necessary for image reconstruction. In PhotoNim we use O’Neill algorithm in order to generate random number: it requires to do calculations with bit masks. We implemented a PCG type such as following:

type PCG* = object 
    state*, incr*: uint64

As you can see PCG stores its actual state and increment: if two random generator variables will be initialized exactly with the same numbers, they will produce the same sequence of pseudo-casual numbers. The actual O’Neill algorithm is:

proc random*(gen: var PCG): uint32 =
    var 
        oldstate = gen.state
        xorshift = uint32(((oldstate shr 18) xor oldstate) shr 27)
        rot = int32(oldstate shr 59)

    gen.state = oldstate * uint64(6364136223846793005) + gen.incr
    result = ((xorshift shr rot) or (xorshift shl ((-rot) and 31)))

You can initialize a new variable via newPCG procedure:

proc newPCG*(inState: uint64 = 42, inSeq: uint64 = 54): PCG = result = PCG(state: 0, incr: (inSeq shl 1) or 1) discard result.random result.state += inState discard result.random

You could get float random number by means of rand procedure: you can also specify the limiting values of the interval from which you want to extract random number.

Example

var randgen = newPCG()          # Using default values

echo "Randgen state: ", randgen.state              # You should get 1753877967969059832
echo "Randgen inc: ", randgen.inc                  # You should get 109


echo "Random number: ", randgen.random()                # You ehould get 2707161783
echo "Random number in (0, 1): ", randgen.rand()        # You should get a number in (0, 1)
echo "Random number in (4, 8): ", randgen.rand(4, 8)    # You should get a number in (4, 8)