Class: Random::MT19937

### Home Classes Methods

### In Files

- lib/backports/extra/random/MT19937.rb
- lib/backports/extra/random/bits_and_bytes.rb

### Parent

Object

### Methods

- ::[]
- ::convert_seed
- ::new
- #left
- #marshal_dump
- #marshal_load
- #next_state
- #random_32_bits
- #random_bytes
- #random_float
- #random_integer
- #seed=
- #state_as_bignum

### Class/Module Index

Quicksearch

- Prime
- Prime::EratosthenesGenerator
- Prime::EratosthenesSieve
- Prime::Generator23
- Prime::OldCompatibility
- Prime::PseudoPrimeGenerator
- Prime::TrialDivision
- Prime::TrialDivisionGenerator
- Backports
- Backports::MOST_EXTREME_OBJECT_EVER
- Backports::StdLib
- Backports::StdLib::LoadedFeatures
- Enumerator
- Enumerator::GeneratorBP
- Enumerator::Lazy
- Enumerator::Yielder
- Matrix
- Matrix::EigenvalueDecomposition
- Matrix::LUPDecomposition
- Random
- Random::Implementation
- Random::MT19937
- Enumerable
- Enumerable::Enumerator
- File
- File::Constants
- ARGF
- Array
- BasicObject
- Binding
- Complex
- Dir
- ENV
- Fixnum
- Float
- GC
- Hash
- IO
- Integer
- Kernel
- Math
- Method
- Module
- NilClass
- Numeric
- Object
- ObjectSpace
- OpenStruct
- Proc
- Process
- Range
- Regexp
- Set
- StopIteration
- String
- Struct
- Symbol
- UnboundMethod

No matching classes.

# Random::MT19937

An implementation of Mersenne Twister MT19937 in Ruby

Supplement the MT19937 class with methods to do conversions the same way as MRI. No argument checking is done here either.

### Constants

FLOAT_FACTOR
LAST_31_BITS
LAST_STATE
MASK_BY
OFFSET
PAD_32_BITS
STATE_SIZE

### Public Class Methods

[](seed) click to toggle source

    # File lib/backports/extra/random/bits_and_bytes.rb, line 78
    def self.[](seed)
      new(convert_seed(seed))
    end

convert_seed(seed) click to toggle source

Convert an Integer seed of arbitrary size to either a single 32 bit integer, or an Array of 32 bit integers

    # File lib/backports/extra/random/bits_and_bytes.rb, line 65
    def self.convert_seed(seed)
      seed = seed.abs
      long_values = []
      begin
        long_values << (seed & PAD_32_BITS)
        seed >>= 32
      end until seed == 0

      long_values.pop if long_values[-1] == 1 && long_values.size > 1 # Done to allow any kind of sequence of integers

      long_values.size > 1 ? long_values : long_values.first
    end

new(seed) click to toggle source

See seed=

    # File lib/backports/extra/random/MT19937.rb, line 9
    def initialize(seed)
      self.seed = seed
    end

### Public Instance Methods

left() click to toggle source

    # File lib/backports/extra/random/bits_and_bytes.rb, line 46
    def left # It's actually the number of words left + 1, as per MRI...
      MT19937::STATE_SIZE - @last_read
    end

marshal_dump() click to toggle source

    # File lib/backports/extra/random/bits_and_bytes.rb, line 50
    def marshal_dump
      [state_as_bignum, left]
    end

marshal_load(ary) click to toggle source

    # File lib/backports/extra/random/bits_and_bytes.rb, line 54
    def marshal_load(ary)
      b, left = ary
      @last_read = MT19937::STATE_SIZE - left
      @state = Array.new(STATE_SIZE)
      STATE_SIZE.times do |i|
        @state[i] = b & PAD_32_BITS
        b >>= 32
      end
    end

next_state() click to toggle source

Generates a completely new state out of the previous one.

    # File lib/backports/extra/random/MT19937.rb, line 17
    def next_state
      STATE_SIZE.times do |i|
        mix = @state[i] & 0x80000000 | @state[i+1 - STATE_SIZE] & 0x7fffffff
        @state[i] = @state[i+OFFSET - STATE_SIZE] ^ (mix >> 1)
        @state[i] ^= 0x9908b0df if mix.odd?
      end
      @last_read = -1
    end

random_32_bits() click to toggle source

Returns a random Integer from the range 0 ... (1 << 32)

    # File lib/backports/extra/random/MT19937.rb, line 65
    def random_32_bits
      next_state if @last_read >= LAST_STATE
      @last_read += 1
      y = @state[@last_read]
      # Tempering
      y ^= (y >> 11)
      y ^= (y << 7) & 0x9d2c5680
      y ^= (y << 15) & 0xefc60000
      y ^= (y >> 18)
    end

random_bytes(nb) click to toggle source

    # File lib/backports/extra/random/bits_and_bytes.rb, line 32
    def random_bytes(nb)
      nb_32_bits = (nb + 3) / 4
      random = nb_32_bits.times.map { random_32_bits }
      random.pack("L" * nb_32_bits)[0, nb]
    end

random_float() click to toggle source

generates a random number on [0,1) with 53-bit resolution

    # File lib/backports/extra/random/bits_and_bytes.rb, line 9
    def random_float
      ((random_32_bits >> 5) * 67108864.0 + (random_32_bits >> 6)) * FLOAT_FACTOR;
    end

random_integer(upto) click to toggle source

Returns an integer within 0...upto

    # File lib/backports/extra/random/bits_and_bytes.rb, line 14
    def random_integer(upto)
      n = upto - 1
      nb_full_32 = 0
      while n > PAD_32_BITS
        n >>= 32
        nb_full_32 += 1
      end
      mask = mask_32_bits(n)
      begin
        rand = random_32_bits & mask
        nb_full_32.times do
          rand <<= 32
          rand |= random_32_bits
        end
      end until rand < upto
      rand
    end

seed=(seed) click to toggle source

Seed must be either an Integer (only the first 32 bits will be used) or an Array of Integers (of which only the first 32 bits will be used)

No conversion or type checking is done at this level

    # File lib/backports/extra/random/MT19937.rb, line 30
    def seed=(seed)
      case seed
      when Integer
        @state = Array.new(STATE_SIZE)
        @state[0] = seed & PAD_32_BITS
        (1..LAST_STATE).each do |i|
          @state[i] = (1812433253 * (@state[i-1]  ^ @state[i-1]>>30) + i)& PAD_32_BITS
        end
        @last_read = LAST_STATE
      when Array
        self.seed = 19650218
        i=1
        j=0
        [STATE_SIZE, seed.size].max.times do
          @state[i] = (@state[i] ^ (@state[i-1] ^ @state[i-1]>>30) * 1664525) + j + seed[j] & PAD_32_BITS
          if (i+=1) >= STATE_SIZE
            @state[0] = @state[-1]
            i = 1
          end
          j = 0 if (j+=1) >= seed.size
        end
        (STATE_SIZE-1).times do
          @state[i] = (@state[i] ^ (@state[i-1] ^ @state[i-1]>>30) * 1566083941) - i & PAD_32_BITS
          if (i+=1) >= STATE_SIZE
            @state[0] = @state[-1]
            i = 1
          end
        end
        @state[0] = 0x80000000
      else
        raise ArgumentError, "Seed must be an Integer or an Array"
      end
    end

state_as_bignum() click to toggle source

    # File lib/backports/extra/random/bits_and_bytes.rb, line 38
    def state_as_bignum
      b = 0
      @state.each_with_index do |val, i|
        b |= val << (32 * i)
      end
      b
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.