Class: RV::Triangle

Inherits:
Object
  • Object
show all
Includes:
RV_Generator
Defined in:
lib/random_variates.rb

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 (minmodemax).

  • mean -> the expected value of the distribution.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from RV_Generator

#each

Constructor Details

#initialize(rng: U_GENERATOR, **args) ⇒ Triangle

Returns a new instance of Triangle.



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
# File 'lib/random_variates.rb', line 77

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

Instance Attribute Details

#maxObject (readonly)

Returns the value of attribute max.



75
76
77
# File 'lib/random_variates.rb', line 75

def max
  @max
end

#meanObject (readonly)

Returns the value of attribute mean.



75
76
77
# File 'lib/random_variates.rb', line 75

def mean
  @mean
end

#minObject (readonly)

Returns the value of attribute min.



75
76
77
# File 'lib/random_variates.rb', line 75

def min
  @min
end

#modeObject (readonly)

Returns the value of attribute mode.



75
76
77
# File 'lib/random_variates.rb', line 75

def mode
  @mode
end

#rangeObject (readonly)

Returns the value of attribute range.



75
76
77
# File 'lib/random_variates.rb', line 75

def range
  @range
end

Instance Method Details

#nextObject



117
118
119
120
121
122
# File 'lib/random_variates.rb', line 117

def next
  u = @rng.rand
  u < @crossover_p ?
    @min + Math.sqrt(@range * (@mode - @min) * u) :
    @max - Math.sqrt(@range * (@max - @mode) * (1.0 - u))
end