class TingYun::Support::QuantileP2

Attributes

count[RW]
markers_x[RW]
markers_y[RW]
p2_n[RW]
quartileList[RW]

Public Class Methods

new(quartileList) click to toggle source
# File lib/ting_yun/support/quantile_p2.rb, line 19
def initialize(quartileList)
  @quartileList = quartileList.sort!
  @markers_y = Array.new(@quartileList.length * 2 + 3){0.0}
  @count = 0
  initMarkers
end
support?() click to toggle source
# File lib/ting_yun/support/quantile_p2.rb, line 8
def self.support?
  return false if !TingYun::Agent.config[:'nbs.quantile']
  quantile = TingYun::Agent.config[:'nbs.quantile']
  quantile = JSON.parse(quantile) rescue false unless quantile.is_a?(Array)
  return false if !quantile || quantile.empty? || (quantile.size > quantile.uniq.size) || quantile.any? { |i| i.to_i == 0 || !i.is_a?(Fixnum)}
  return true
end

Public Instance Methods

add(v) click to toggle source
# File lib/ting_yun/support/quantile_p2.rb, line 115
def add(v)

  return unless v.is_a?(Numeric)
  obsIdx = count
  @count += 1

  if (obsIdx < markers_y.length)
    markers_y[obsIdx] = v
    if (obsIdx == markers_y.length - 1)
      markers_y.sort!
    end
  else


    # k = markers_y.find_index {|i| i==v or i>v}
    #
    # if k ##in
    #   if v==markers_y[k] ##exist
    #     if k == 0##first
    #       markers_y[0] = v
    #       k = 1
    #     elsif k == markers_y.length-1 ##last
    #       k = markers_y.length - 1;
    #       markers_y[k] = v
    #     end
    #   end
    # else
    #   k = markers_y.length -1
    # end
    k = binarySearch markers_y, v

    if k< 0
      k = -(k + 1)
    end
    if k==0
      markers_y[0] = v
      k = 1
    elsif k == markers_y.length
      k = markers_y.length - 1
      markers_y[k] = v
    end

    (k..p2_n.length-1).each do |i|
      p2_n[i] += 1
    end

    (1..markers_y.length - 2).each do |i|

      n_ = markers_x[i] * obsIdx
      di = n_ - p2_n[i]
      if ((di-1.0 >=0.000001  && p2_n[i + 1] - p2_n[i] > 1) || ((di+1.0 <=0.000001  && p2_n[i - 1] - p2_n[i] < -1)))
        d = di < 0 ? -1 : 1
        qi_ = quadPred(d, i)
        if (qi_ < markers_y[i - 1] || qi_ > markers_y[i + 1])

          qi_ = linPred(d, i)
        end

        markers_y[i] = qi_

        p2_n[i] += d
      end
    end
  end
end
binarySearch(arr, key) click to toggle source
# File lib/ting_yun/support/quantile_p2.rb, line 66
def binarySearch(arr, key)
  low = 0
  high = arr.length-1

  while(low <=high) do
    mid = (low + high) >> 1
    midVal = arr[mid]
    if (midVal < key)
      low = mid + 1
    elsif(midVal > key)
      high = mid - 1
    else
      midBits = midVal.round 16
      keyBits = key.round 16
      if (midBits == keyBits)
        return mid
      elsif(midBits < keyBits)
        low = mid + 1
      else
        high = mid - 1
      end
    end
  end
  return -(low + 1)
end
initMarkers() click to toggle source
# File lib/ting_yun/support/quantile_p2.rb, line 26
def initMarkers
  quartile_count = quartileList.length
  marker_count = quartile_count * 2 + 3
  @markers_x = Array.new(marker_count){0.0}
  @markers_x[0] = 0.0
  @p2_n = Array.new(markers_y.length){0}
  (0..quartile_count-1).each do |i|
    marker = quartileList[i]
    markers_x[i * 2 + 1] = (marker + markers_x[i * 2]) / 2
    markers_x[i * 2 + 2] = marker
  end
  markers_x[marker_count - 2] = (1 + quartileList[quartile_count - 1]) / 2
  markers_x[marker_count - 1] = 1.0
  (0..marker_count-1).each do |i|
    p2_n[i] = i
  end
end
linPred(d, i) click to toggle source
# File lib/ting_yun/support/quantile_p2.rb, line 106
def linPred(d, i)
  qi = markers_y[i]
  qipd = markers_y[i + d]
  ni = p2_n[i]
  nipd = p2_n[i + d]

  return qi + d * (qipd - qi) / (nipd - ni)
end
markers() click to toggle source
# File lib/ting_yun/support/quantile_p2.rb, line 44
def markers

  if (count < markers_y.length)
    result = Array.new(count){0.0}
    markers = Array.new(markers_y.length){0.0}
    pw_q_copy = markers_y.clone()
    pw_q_copy.sort!
    j = 0
    (pw_q_copy.length - count .. pw_q_copy.length - 1).each do |i|
      result[j] = pw_q_copy[i]
      j+=1
    end

    (0..pw_q_copy.length-1).each do |i|
      markers[i] = result[((count - 1) * i * 1.0 / (pw_q_copy.length - 1)).round]
    end
    return markers;
  end

  return markers_y;
end
quadPred(d, i) click to toggle source
# File lib/ting_yun/support/quantile_p2.rb, line 92
def quadPred(d, i)
  qi = markers_y[i]
  qip1 = markers_y[i + 1]
  qim1 = markers_y[i - 1]
  ni = p2_n[i]
  nip1 = p2_n[i + 1]
  nim1 = p2_n[i - 1]

  a = (ni - nim1 + d) * (qip1 - qi) / (nip1 - ni)
  b = (nip1 - ni - d) * (qi - qim1) / (ni - nim1)
  return qi + (d * (a + b)) / (nip1 - nim1)
end