weighted_sampler 1.0.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/weighted_sampler.rb +21 -16
- data/lib/weighted_sampler/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 418175c950561e4d8afe70b6d19be4c9957107d79416f6b5600dc83bb51f57f2
|
4
|
+
data.tar.gz: 1d1f5bac8a18c12fa86027ca024a3705fe39a1f65c0e39b69401854e34ea9626
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0182411300d8c5e8355d376658b0d6cc58ac8ca973c9b06962ff45280c45b70ce4d32754f3d0afab212349e1dee0f05596805d462eecb302ddb7b66ee9426ab4'
|
7
|
+
data.tar.gz: 3df0c7ebecc6b17f2f12f58a059772889d93f852cee6ba302cd03969124be5ca3b2c5c694796077b0d705f38bae8060eec9a83ea5d8f9603767024c471e60e16
|
data/lib/weighted_sampler.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'weighted_sampler/version'
|
4
|
+
# require 'pry'
|
5
|
+
|
4
6
|
module WeightedSampler
|
5
7
|
|
6
8
|
# sum of floats are never stable enough to guarantee exact equality to 1
|
@@ -12,33 +14,34 @@ module WeightedSampler
|
|
12
14
|
@random = Random.new(seed) unless seed.nil?
|
13
15
|
|
14
16
|
if enum.is_a?(Hash)
|
15
|
-
@
|
17
|
+
@p_margins = normalized_margins(enum.values, skip_normalization)
|
16
18
|
@keys = enum.keys
|
17
19
|
elsif enum.is_a?(Array)
|
18
|
-
@
|
20
|
+
@p_margins = normalized_margins(enum, skip_normalization)
|
19
21
|
@keys = [*0...enum.size]
|
20
22
|
end
|
21
23
|
|
22
|
-
return unless @
|
24
|
+
return unless @p_margins.nil? || @keys.nil? || @keys.empty?
|
25
|
+
|
23
26
|
raise ArgumentError, 'input structure must be a non-empty Hash or Array'
|
24
27
|
end
|
25
28
|
|
26
29
|
def sample
|
27
30
|
pick = @random ? @random.rand : rand
|
28
31
|
|
29
|
-
idx = @
|
30
|
-
|
32
|
+
idx = @p_margins.find_index { |margin| pick < margin }
|
33
|
+
idx ||= @p_margins.count - 1 # safe assignment if last margin was not good enough
|
34
|
+
|
35
|
+
@keys[idx]
|
31
36
|
end
|
32
37
|
|
33
38
|
private
|
34
39
|
|
35
|
-
def
|
40
|
+
def normalized_margins(array, skip_normalization)
|
36
41
|
raise ArgumentError, 'weights can be only positive' if array.any?(&:negative?)
|
37
42
|
|
38
|
-
probabilities = array
|
39
|
-
|
40
|
-
|
41
|
-
array_to_ranges probabilities
|
43
|
+
probabilities = skip_normalization ? array : normalize_probabilities(array)
|
44
|
+
incremental_margins probabilities
|
42
45
|
end
|
43
46
|
|
44
47
|
def normalize_probabilities(array)
|
@@ -47,18 +50,20 @@ module WeightedSampler
|
|
47
50
|
array.map { |el| el / sum }
|
48
51
|
end
|
49
52
|
|
50
|
-
|
53
|
+
# convert probs like [0.1, 0.2, 0.3, 0.4]
|
54
|
+
# to incremental margins [0.1, 0.3, 0.6, 1.0]
|
55
|
+
def incremental_margins(array)
|
51
56
|
start = 0.0
|
52
|
-
|
53
|
-
|
54
|
-
start
|
57
|
+
margins = array.map do |v|
|
58
|
+
res = v + start
|
59
|
+
start = res
|
55
60
|
|
56
|
-
|
61
|
+
res
|
57
62
|
end
|
58
63
|
|
59
64
|
raise 'normalized probabilities total is not 1' if (start - 1.0).abs > ERROR_ALLOWANCE
|
60
65
|
|
61
|
-
|
66
|
+
margins
|
62
67
|
end
|
63
68
|
|
64
69
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: weighted_sampler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oleksiy Babich
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -85,8 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '0'
|
87
87
|
requirements: []
|
88
|
-
|
89
|
-
rubygems_version: 2.7.6
|
88
|
+
rubygems_version: 3.0.1
|
90
89
|
signing_key:
|
91
90
|
specification_version: 4
|
92
91
|
summary: Weighted Sampler helps you to pick a random samples from a collection with
|