Class: RationalChoice::ManyDimensions

Inherits:
Object
  • Object
show all
Defined in:
lib/rational_choice.rb

Overview

Performs an evaluation based on multiple dimensions. The dimensions will be first coerced into one (number of truthy evaluations vs. number of falsey evaluations) and then a true/false value will be deduced from that.

Instance Method Summary collapse

Constructor Details

#initialize(*dimensions, random: Random.new) ⇒ ManyDimensions

Initializes a new Dimension to evaluate values

Parameters:

  • dimensions (Array<Dimension>)

    the dimensions to make a choice over

  • random (Random) (defaults to: Random.new)

    the RNG, defaults to a new Random

Raises:



86
87
88
89
90
# File 'lib/rational_choice.rb', line 86

def initialize(*dimensions, random: Random.new)
  @dimensions = dimensions
  @random = random
  raise CardinalityError, '%s has no dimensions to evaluate' % inspect if @dimensions.empty?
end

Instance Method Details

#choose(*values) ⇒ Boolean

Performs a weighted choice, by first collecting choice results from all the dimensions, and then by interpolating those results by the ratio of truthy values vs falsey values.

x = Dimension.new(0,1)
y = Dimension.new(0,1)
z = Dimension.new(0,1)

within_positive_3d_space = ManyDimensions.new(x, y, z)
within_positive_3d_space.choose(-1, -1, -0.5) #=> false
within_positive_3d_space.choose(1.1, 123, 1) #=> true
within_positive_3d_space.choose(1, 0.5, 0.7) #=> true or false depending on 3 probabilities

Parameters:

  • values (Array<Comparable,#to_f>)

    an array of values of the same size as the ‘dimensions` given to `initialize`

Returns:

  • (Boolean)

    true or false



106
107
108
109
110
111
112
113
114
115
# File 'lib/rational_choice.rb', line 106

def choose(*values)
  if @dimensions.length != values.length
    raise CardinalityError, '%s has %d dimensions but %d values were given' % [inspect, @dimensions.length, values.length]
  end

  evaluations = values.zip(@dimensions).map { |(v, d)| d.choose(v) }
  num_truthy_choices = evaluations.select { |e| e }.length

  Dimension.new(false_at_or_below: 0, true_at_or_above: evaluations.length, random: @random).choose(num_truthy_choices)
end