class ABSplit::Functions::HeavisideWeightedSplit
Weighted split based on a modified Heaviside function. In case a numeric value is passed, it uses a sigmoid function applying a modified Heaviside to choose the experiment. In case a none numeric value is passed it uses SHA2 algorithm to get a value from the object, and after decide based on weights.
Persistent - Supports 256 bits as input
No collisions are possible
Constants
- MAX_HASH_VALUE
Protected Class Methods
select_experiment_for(value, experiments)
click to toggle source
# File lib/a_b_split/functions/heaviside_weighted_split.rb, line 22 def select_experiment_for(value, experiments) x = value.is_a?(Numeric) ? value : hash(value) heaviside(x, experiments) end
Private Class Methods
hash(value)
click to toggle source
# File lib/a_b_split/functions/heaviside_weighted_split.rb, line 30 def hash(value) (sha256(value) - (MAX_HASH_VALUE / 2)).to_f / (MAX_HASH_VALUE / 2) end
heaviside(value, experiments)
click to toggle source
# File lib/a_b_split/functions/heaviside_weighted_split.rb, line 38 def heaviside(value, experiments) x = sigmoid(value) accumulated_percentages = 0 experiments.each do |experiment| accumulated_percentages += percentage(experiment) return experiment['name'] if x <= accumulated_percentages end end
percentage(experiment)
click to toggle source
# File lib/a_b_split/functions/heaviside_weighted_split.rb, line 49 def percentage(experiment) experiment['weight'].to_f / 100 end
sha256(value)
click to toggle source
# File lib/a_b_split/functions/heaviside_weighted_split.rb, line 34 def sha256(value) Digest::SHA256.hexdigest(value.to_s).to_i(16) end
sigmoid(value)
click to toggle source
# File lib/a_b_split/functions/heaviside_weighted_split.rb, line 53 def sigmoid(value) BigDecimal((1.0 / (1 + Math.exp(-2 * value))).to_s) end