Hi all,

It turns out that both Aleksi and I have developed Ruby extensions for
random number generators. They are needed since the rng's in the OS:es are
typically not very good (ie. random) or fast and you want to be able to
create stream of rn's that are not affected by calls from other threads /
programs.

We will merge our efforts and intend to submit a working copy to RAA in a
couple of days. Below you'll find a proposed structure for the extension.
If you have any comments, additions, code or ideas that relate to this 
effort then please mail them to us as quickly as possible (and we'll try
to include them...).

We especially request comments on the naming of classes and methods. We
want them to adhere to the "principle-of-least-surprise" for as many of
you as possible!

Thanks in advance,

Robert

Ps. Initial testing show that the implementation of the MersenneTwister
RNG is actually 80% faster than using rand()! And this for a very good RNG
(with a period of 2**19937-1!).




Design of Ruby Random extension
-------------------------------

module Math::Random

class RandomNumberGenerator
  include Marshal

  initialize(seed = nil)
    if seed == nil then use Time.now.usec

  rand(n)
    call rand_float if n = 0, call rand_integer otherwise

  rand_integer(n)
    returns Fixnum or Bignum (Bignum if n is Bignum)
  rand_fixnum(n)
  rand_bignum(n)
  rand_float
    returns Float in [0.0, 1.0) (ie. including 0.0 but NOT 1.0)

  alias_mehod :randint, :rand_integer
  alias_mehod :randfloat, :rand_float

  rand_interval(min, max)
    return a Fixnum in the interval [min, max] (inclusive)

  seed=(newSeed)
    set new (fixnum) seed
  seed
    returns the current seed

  stream_position
    returns the current position in the RNG stream ie. the number of rn's
    taken from the stream since the last seeding

  inspect
    Prints name of RNG algorithm, seed and position.
  to_s
    calls inspect

  _dump(aDepth)
    dump internal state to string

  RandomNumberGenerator._load(aString)
    create object with state from string
end

class MersenneTwister19937 < RandomNumberGenerator
  # Fast implementation of the Mersenne Twister RNG algorithm
end

class RubyRng < RandomNumberGenerator
  # Wrapper for Ruby rand() and srand() for testing purposes.
  # WARNING! Will not give a unique stream since external rand/srand calls 
  # will alter the nums from the stream.
end

class RngTester
  initialize(aRng)

  average_float(iterations)

  performance(iterations)
end

class RandomGauss
  initialize(aRng = nil, mean = 0.0, stdDev = 1.0)

  attr_accessor :mean, :std_deviation

  sample(mean = 0.0, stdDev = 1.0)
    Get a random number sampled from a Gaussian(mean, stdDev) distribution
end

end

Todo
----

* Add more RNG's: R250 (faster than MT but shorter period), taus...
* Basic testing in RubyUnit/Rubicon
* Random strings? RandomString.sample("CCcc!nc") could give "RShi$5w"...
* Add more non-uniform distributions: binomial, cauchy, ...
* Wrap the built-ins?! Global singleton object that rand/srand delegates
to?
* Cryptographic RNG's: ISAAC and/or Yarrow
* RngTester
    chi2_uniformity
    kolomogorov_smirnov_uniformity