Class: Wallace::Utility::ScaledArray

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

Instance Method Summary collapse

Constructor Details

#initialize(items, probabilities) ⇒ ScaledArray

Returns a new instance of ScaledArray.



3
4
5
6
7
8
9
10
11
12
13
14
# File 'lib/utility/scaled_array.rb', line 3

def initialize(items, probabilities)
  @items = items
  @cprob = []
  
  # Convert the probabilities into cumulative probabilities.
  sum = 0.0
  for p in probabilities
    @cprob << sum
    sum += p
  end
  
end

Instance Method Details

#sampleObject



16
17
18
19
# File 'lib/utility/scaled_array.rb', line 16

def sample
  point = Random.rand
  return self.select(point)
end

#select(point) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/utility/scaled_array.rb', line 21

def select(point)
  
  # Initialise the lower and upper bounds of the binary search
  # at either end of the distribution.
  lb = 0
  ub = @items.length - 1
  
  # Keep searching until the upper and lower bound converge.
  until lb == ub
  
    # Select the point in between the lower and upper bound
    # as the pivot.
    pivot = lb + ((ub - lb) / 2)
    
    # If the point is less than the start of the area for
    # the pivot, move the upper bound back one.
    if point < @cprob[pivot]
      ub = pivot - 1
      
    # Check if the point lies within the bounds of the pivot.
    elsif pivot == ub or point < @cprob[pivot+1]
      lb = ub = pivot
      
    # If it doesn't, then move the lower bound forward.
    else
      lb = pivot + 1
    end
    
  
  end
  
  return @items[lb]
  
end

#select_old(point) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/utility/scaled_array.rb', line 57

def select_old(point)

  # If there is only a single item in the distribution,
  # then return that item.
  return @items[0] if @items.length == 1
  
  # Initialise the lower and upper bounds of the binary search
  # at either end of the distribution.
  lb = 0
  ub = @items.length - 1
  
  # Keep searching until the upper and lower bound converge.
  until lb == ub
  
    # Select the point in between the lower and upper bound
    # as the pivot.
    pivot = lb + ((ub - lb) / 2)
  
    if point <= @cprob[pivot]
      ub = pivot
    else
      lb = pivot + 1
    end
    
  
  end
  
  return @items[pivot]
  
end