Class: Triangle
Overview
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.
-
Instance Attribute Summary collapse
-
#max ⇒ Object
readonly
Returns the value of attribute max.
-
#mean ⇒ Object
readonly
Returns the value of attribute mean.
-
#min ⇒ Object
readonly
Returns the value of attribute min.
-
#mode ⇒ Object
readonly
Returns the value of attribute mode.
-
#range ⇒ Object
readonly
Returns the value of attribute range.
Attributes included from RV_Generator
Instance Method Summary collapse
-
#initialize(rng: U_GENERATOR, **args) ⇒ Triangle
constructor
A new instance of Triangle.
Methods included from RV_Generator
Constructor Details
#initialize(rng: U_GENERATOR, **args) ⇒ Triangle
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/random_variates.rb', line 74 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]) } @range = @max - @min raise 'Min must be less than Max.' if @range <= 0 raise 'Mode must be between Min and Max.' unless (@min..@max).include? @mode crossover_p = (@mode - @min).to_f / @range @generator = Enumerator.new do |yielder| loop do u = rng.next yielder << ( u < crossover_p ? @min + Math.sqrt(@range * (@mode - @min) * u) : @max - Math.sqrt(@range * (@max - @mode) * (1.0 - u)) ) end end end |
Instance Attribute Details
#max ⇒ Object (readonly)
Returns the value of attribute max.
72 73 74 |
# File 'lib/random_variates.rb', line 72 def max @max end |
#mean ⇒ Object (readonly)
Returns the value of attribute mean.
72 73 74 |
# File 'lib/random_variates.rb', line 72 def mean @mean end |
#min ⇒ Object (readonly)
Returns the value of attribute min.
72 73 74 |
# File 'lib/random_variates.rb', line 72 def min @min end |
#mode ⇒ Object (readonly)
Returns the value of attribute mode.
72 73 74 |
# File 'lib/random_variates.rb', line 72 def mode @mode end |
#range ⇒ Object (readonly)
Returns the value of attribute range.
72 73 74 |
# File 'lib/random_variates.rb', line 72 def range @range end |