Class: SISFC::LatencyManager

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

Instance Method Summary collapse

Constructor Details

#initialize(latency_models) ⇒ LatencyManager

Returns a new instance of LatencyManager.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/sisfc/latency_manager.rb', line 7

def initialize(latency_models)
  # here we build a (strictly upper triangular) matrix of random variables
  # that represent the communication latency models between the different
  # locations
  @latency_models_matrix = latency_models.map do |lms_conf|
    lms_conf.map do |rv_conf| 
      rv_conf
      ERV::RandomVariable.new(rv_conf) 
    end
  end

  # should we turn @latency_models_matrix from a (strictly upper)
  # triangular to a full matrix, for convenience? probably not. it would
  # require more memory and: 1) ruby is ***very*** memory hungry already,
  # 2) ruby's performance is very sensitive to memory usage.

  # precalculate average latencies
  @average_latency_matrix = @latency_models_matrix.map do |lms|
    lms.map{|x| x.mean }
  end

  # latency in the same location is implemented as a truncated gaussian
  # with mean = 20ms, sd = 5ms, and a = 2ms
  @same_location_latency = ERV::RandomVariable.new(distribution: :gaussian, args: { mean: 20E-3, sd: 5E-3 })
end

Instance Method Details

#average_latency_between(loc1, loc2) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/sisfc/latency_manager.rb', line 49

def average_latency_between(loc1, loc2)
  # the results returned by this method are not entirely accurate, because
  # rejection sampling changes the shape of the PDF. see, e.g.,
  # https://stackoverflow.com/questions/47933019/how-to-properly-sample-truncated-distributions
  # still, it is an acceptable approximation
  if loc1 == loc2
    @same_location_latency.mean
  else
    l1, l2 = loc1 < loc2 ? [ loc1, loc2 ] : [ loc2, loc1 ]

    # since we use a compact representation for @average_latency_between, the
    # indexes become l1 and (l2-l1-1)
    @average_latency_between[l1][l2-l1-1]
  end
end

#sample_latency_between(loc1, loc2) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/sisfc/latency_manager.rb', line 33

def sample_latency_between(loc1, loc2)
  if loc1 == loc2
    # rejection sampling to implement (crudely) PDF truncation
    while (lat = @same_location_latency.next) < 2E-3; end
    lat
  else
    l1, l2 = loc1 < loc2 ? [ loc1, loc2 ] : [ loc2, loc1 ]

    # since we use a compact representation for @latency_models_matrix, the
    # indexes become l1 and (l2-l1-1)
    # rejection sampling to implement (crudely) PDF truncation to positive numbers
    while (lat = @latency_models_matrix[l1][l2-l1-1].next) <= 0.0; end
    lat
  end
end