class RV::Triangle
Triangular random variate generator with specified min
, mode
, and max
.
- Arguments
-
rng
-> the (Enumerable
) source of U(0, 1)'s (default: U_GENERATOR) -
min
-> the lower bound for the range. -
max
-> the upper bound for the range. -
mode
-> the highest likelihood value (min
≤mode
≤max
). -
mean
-> the expected value of the distribution.
-
Attributes
max[R]
mean[R]
min[R]
mode[R]
range[R]
Public Class Methods
new(rng: U_GENERATOR, **args)
click to toggle source
# File lib/random_variates.rb, line 72 def initialize(rng: U_GENERATOR, **args) param_names = %i[mean min max mode] unless args.size > 2 && args.keys.all? { |k| param_names.include? k } raise "invalid args - can only be #{param_names.join ', '}, or rng." end param_names.each { |k| args[k] ||= nil } if args.size < param_names.size nil_args = args.select { |_, v| v.nil? }.keys nil_args_count = nil_args.count raise 'too many nil args' if nil_args_count > 1 args.transform_values! &:to_f if nil_args_count == 0 if args[:mean] != (args[:min] + args[:max] + args[:mode]) / 3.0 raise 'inconsistent args' end else key = nil_args.shift case key when :mean args[key] = (args[:min] + args[:max] + args[:mode]) / 3.0 else others = param_names - [key, :mean] args[key] = 3 * args[:mean] - args.values_at(*others).sum end end param_names.each { |parm| instance_variable_set("@#{parm}", args[parm]) } @rng = rng @range = @max - @min raise 'Min must be less than Max.' if @range <= 0 unless (@min..@max).include? @mode raise 'Mode must be between Min and Max.' end @crossover_p = (@mode - @min).to_f / @range end
Public Instance Methods
next()
click to toggle source
# File lib/random_variates.rb, line 112 def next u = @rng.next u < @crossover_p ? @min + Math.sqrt(@range * (@mode - @min) * u) : @max - Math.sqrt(@range * (@max - @mode) * (1.0 - u)) end