class Statistical::Distribution::UniformDiscrete

This class abstracts the discrete uniform distribution over a given set

of elements

@author Vaibhav Yenamandra @attr_reader [Array, Numeric] support The support set of valid values a random variate from the distribution can take. Must have at least 1 value

Attributes

count[R]
lower[R]
support[R]
upper[R]

Public Class Methods

new(elems) click to toggle source

Returns a model for the discrete uniform distribution on all elements present in the given set of elemets `elems`

@note The constructor sorts the array of elements given to it, as this

is a key assumption of the discrete uniform distribution. This set
must also be homogenous

@param [Array] elems The elements over which the distribution exists

in [lower, upper]

@raise [RangeError] if elems isn't one of Array, Range, Fixnum or

Bignum
# File lib/statistical/distribution/uniform_discrete.rb, line 27
def initialize(elems)
  case elems
  when Fixnum, Bignum
    @support = [elems]
  when Array
    @support = elems.sort
  when Range
    @support = elems.to_a
  else
    raise ArgumentError,
          "Expected Fixnum, Bignum, Array or Range, found #{elems.class}"
  end
  @count = @support.length
  @lower = @support[0]
  @upper = @support[-1]
  self
end

Public Instance Methods

==(other)
Alias for: eql?
cdf(k) click to toggle source

Returns value of cumulative density function at a point on the real line Uses a binary search on the support array internally.

@note This suffers from some floating point comparison issues. Errors

start appearing when dealing with precision > 1E-18

@param [Fixnum, Bignum] k Point at which cdf value is desired @return [Float] 0 if k is on the left of the support,

1 if k on the right support and the
evaluates CDF for any other legal value
# File lib/statistical/distribution/uniform_discrete.rb, line 67
def cdf(k)
  return 0.0 if k < @lower
  return 1.0 if k >= @upper

  # Ruby has a Array#bsearch_index already but it supports find-min mode
  # What we need is a find-max mode. This can be achieved by reversing
  # and then searching, but reverse is O(N) so it defeats the purpose
  low = 0
  high = @count - 1
  while low < high
    mid = (low + high) / 2
    if @support[mid] <= k
      low = mid + 1
    else
      high = mid
    end
  end
  # This should be true for all i > low
  return low.fdiv(@count)
end
mean() click to toggle source

Returns the mean value for the calling instance. Calculated mean, and

not inferred from simulations

@return [Float] Mean of the distribution

# File lib/statistical/distribution/uniform_discrete.rb, line 106
def mean
  return @support.mean
end
p_value(p)
Alias for: quantile
pdf(k) click to toggle source

Returns value of probability density function at a point on the real

line

@param [Fixnum, Bignum] k Point at which pdf is desired @return [Float] 0 if k doesn't belong to the elements over which the

current instance is distributed. 1/n otherwise where n is number
of elements
# File lib/statistical/distribution/uniform_discrete.rb, line 52
def pdf(k)
  return 1.0 / @count if @support.include?(k)
  return 0.0
end
quantile(p) click to toggle source

Returns value of inverse CDF for a given probability.

@see p_value

@param [Numeric] p a value within [0, 1] @return [Numeric] Returns inverse CDF for valid p @raise [RangeError] if p > 1 or p < 0

# File lib/statistical/distribution/uniform_discrete.rb, line 95
def quantile(p)
  raise RangeError, "`p` must be in [0, 1], found: #{p}" if p < 0 || p > 1
  return @lower if p.zero?
  return @upper if (p - 1).zero?
  return @support[(p * count).ceil - 1]
end
Also aliased as: p_value
variance() click to toggle source

Returns the expected value of population variance for the calling

instance.

@return [Float] Variance of the distribution

# File lib/statistical/distribution/uniform_discrete.rb, line 114
def variance
  return @support.pvariance
end

Private Instance Methods

eql?(other) click to toggle source

Compares two distribution instances and returns a boolean

Available publicly as #==

@private

@param other A distribution object (preferred) @return [Boolean] true if-and-only-if two instances are of the same

class and have the same parameters.
# File lib/statistical/distribution/uniform_discrete.rb, line 126
def eql?(other)
  return other.is_a?(self.class) &&
         @support == other.support
end
Also aliased as: ==