feldtruby 0.3.8 → 0.3.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/README.md +9 -11
- data/Rakefile +21 -4
- data/lib/feldtruby/array.rb +5 -0
- data/lib/feldtruby/minitest_extensions.rb +10 -0
- data/lib/feldtruby/optimize/objective.rb +168 -125
- data/lib/feldtruby/optimize/search_space.rb +105 -9
- data/lib/feldtruby/optimize/sub_qualities_comparators.rb +73 -0
- data/lib/feldtruby/statistics/array_archive.rb +66 -0
- data/lib/feldtruby/statistics/clustering.rb +31 -0
- data/lib/feldtruby/statistics/distance.rb +35 -0
- data/lib/feldtruby/statistics/euclidean_distance.rb +4 -0
- data/lib/feldtruby/statistics.rb +48 -0
- data/lib/feldtruby/version.rb +1 -1
- data/spikes/zlib_for_short_strings.rb +27 -0
- data/test/skip_test_array_archive.rb +65 -0
- data/test/test_array.rb +6 -0
- data/test/test_clustering.rb +53 -0
- data/test/test_euclidean_distance.rb +28 -0
- data/test/test_optimize_objective.rb +133 -93
- data/test/test_optimize_search_space.rb +54 -0
- data/test/test_sax.rb +14 -1
- data/test/test_sub_qualitites_comparator.rb +109 -0
- metadata +15 -2
@@ -1,28 +1,56 @@
|
|
1
|
+
require 'feldtruby/minitest_extensions'
|
2
|
+
|
1
3
|
require 'feldtruby/optimize/objective'
|
2
4
|
require 'feldtruby/array'
|
3
|
-
|
4
5
|
require 'pp'
|
5
6
|
|
6
7
|
class SingleObjective1 < FeldtRuby::Optimize::Objective
|
7
|
-
# Sum of candidate vector of values should be small
|
8
|
-
def
|
8
|
+
# Sum of candidate vector of values should be as small as possible
|
9
|
+
def objective_min_sum(candidate)
|
9
10
|
candidate.sum
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
describe "a single minimizing objective" do
|
15
|
+
before do
|
15
16
|
@o = SingleObjective1.new
|
16
17
|
end
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
it "has one aspect/sub-objective" do
|
20
|
+
@o.num_aspects.must_equal 1
|
21
|
+
@o.num_sub_objectives.must_equal 1
|
22
|
+
end
|
23
|
+
|
24
|
+
it "correctly calculates the sub-qualitites" do
|
25
|
+
@o.sub_qualities_of([1]).must_equal [1]
|
26
|
+
@o.sub_qualities_of([1, 2]).must_equal [3]
|
27
|
+
@o.sub_qualities_of([1, 2, -45]).must_equal [-42]
|
20
28
|
end
|
21
29
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
30
|
+
it "correctly calculates the quality value / fitness_for" do
|
31
|
+
@o.quality_of([1]).must_equal 1
|
32
|
+
@o.quality_of([1, 2]).must_equal 3
|
33
|
+
@o.quality_of([1, 2, -45]).must_equal -42
|
34
|
+
|
35
|
+
@o.fitness_for([1]).must_equal 1
|
36
|
+
@o.fitness_for([1, 2]).must_equal 3
|
37
|
+
@o.fitness_for([1, 2, -45]).must_equal -42
|
38
|
+
end
|
39
|
+
|
40
|
+
it "can detect valid and invalid aspect/sub_objective names" do
|
41
|
+
@o.is_aspect_method?("objective_min_anything").must_be_truthy
|
42
|
+
@o.is_aspect_method?("objective_max_anything").must_be_truthy
|
43
|
+
@o.is_aspect_method?("objective_min_very_complex_names_are_not_a_problem").must_be_truthy
|
44
|
+
@o.is_aspect_method?("min_anything").must_be_falsey
|
45
|
+
@o.is_aspect_method?("max_anything").must_be_falsey
|
46
|
+
end
|
47
|
+
|
48
|
+
it "can detect valid and invalid minimization aspect/sub_objective names" do
|
49
|
+
@o.is_min_aspect_method?("objective_min_anything").must_be_truthy
|
50
|
+
@o.is_min_aspect_method?("objective_min_very_complex_names_are_not_a_problem").must_be_truthy
|
51
|
+
@o.is_min_aspect_method?("objective_max_anything").must_be_falsey
|
52
|
+
@o.is_min_aspect_method?("min_anything").must_be_falsey
|
53
|
+
@o.is_min_aspect_method?("max_anything").must_be_falsey
|
26
54
|
end
|
27
55
|
end
|
28
56
|
|
@@ -35,97 +63,109 @@ class TwoMinObjectives1 < FeldtRuby::Optimize::Objective
|
|
35
63
|
end
|
36
64
|
end
|
37
65
|
|
38
|
-
|
39
|
-
|
66
|
+
describe "two sub-objectives" do
|
67
|
+
before do
|
40
68
|
@o = TwoMinObjectives1.new
|
41
69
|
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
70
|
+
|
71
|
+
it "has two aspects/sub-objectives" do
|
72
|
+
@o.num_aspects.must_equal 2
|
73
|
+
@o.num_sub_objectives.must_equal 2
|
74
|
+
end
|
75
|
+
|
76
|
+
it "returns the global min value per aspect, which is initially at a max value since we might not now its range" do
|
77
|
+
@o.global_min_values_per_aspect.must_equal [Float::INFINITY, Float::INFINITY]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "returns the global max value per aspect, which is initially at a min value since we might not now its range" do
|
81
|
+
@o.global_max_values_per_aspect.must_equal [-Float::INFINITY, -Float::INFINITY]
|
82
|
+
end
|
83
|
+
|
84
|
+
it "correctly updates the global min and maxs, given a sequence of updates" do
|
85
|
+
@o.update_global_mins_and_maxs([1,2])
|
86
|
+
@o.global_min_values_per_aspect.must_equal [1,2]
|
87
|
+
@o.global_max_values_per_aspect.must_equal [1,2]
|
88
|
+
|
89
|
+
@o.update_global_mins_and_maxs([1,3])
|
90
|
+
@o.global_min_values_per_aspect.must_equal [1,2]
|
91
|
+
@o.global_max_values_per_aspect.must_equal [1,3]
|
92
|
+
|
93
|
+
@o.update_global_mins_and_maxs([0,8])
|
94
|
+
@o.global_min_values_per_aspect.must_equal [0,2]
|
95
|
+
@o.global_max_values_per_aspect.must_equal [1,8]
|
96
|
+
end
|
97
|
+
|
98
|
+
it "can return the vector of sub_objective values for a candidate" do
|
99
|
+
@o.sub_qualities_of([1,2]).must_equal [1,3]
|
100
|
+
@o.sub_qualities_of([1,2,4]).must_equal [3,7]
|
101
|
+
@o.sub_qualities_of([1,2,5]).must_equal [4,8]
|
102
|
+
end
|
103
|
+
|
104
|
+
it "correctly calculates mean-weighted-global-ratios" do
|
105
|
+
# Lets first update so there is a spread between mins and maxs
|
106
|
+
@o.update_global_mins_and_maxs([0, 0])
|
107
|
+
@o.update_global_mins_and_maxs([1, 3])
|
108
|
+
|
109
|
+
# Now check at either extreme of the interval, the quality value is always in [0.0, 1.0]
|
110
|
+
@o.qv_mwgr([1,2]).must_equal 0.0
|
111
|
+
@o.qv_mwgr([0,0]).must_equal 1.0
|
112
|
+
end
|
113
|
+
|
114
|
+
it "always returns a fitness_for of zero for the first call" do
|
115
|
+
@o.fitness_for([1,2,3]).must_equal 0.0
|
116
|
+
end
|
117
|
+
|
118
|
+
it "handles a more complex series of consecutive calls" do
|
119
|
+
# Set first values => fitness_for is always zero
|
120
|
+
@o.fitness_for([1,2,3]).must_equal 0.0
|
121
|
+
|
122
|
+
# Now we come with a worse candidate => still zero
|
123
|
+
@o.fitness_for([1,2,5]).must_equal 0.0
|
124
|
+
|
125
|
+
# But now the previous value is the best candidate we have seen so gets maximum quality value
|
126
|
+
@o.fitness_for([1,2,3]).must_equal 1.0
|
127
|
+
|
128
|
+
# The previous worst is still the worst
|
129
|
+
@o.fitness_for([1,2,5]).must_equal 0.0
|
130
|
+
|
131
|
+
# And now some complex ones that are between the prev best and worst
|
132
|
+
@o.fitness_for([1,2,4]).must_equal (((4.0 - 3.0)/(4-2) + (8.0 - 7)/(8-6))/2)
|
133
|
+
@o.fitness_for([1,2,4.5]).must_equal (((4.0 - 3.5)/(4-2) + (8.0 - 7.5)/(8-6))/2)
|
134
|
+
|
135
|
+
# Now extend the global best with a new best
|
136
|
+
@o.fitness_for([1,2,2]).must_equal 1.0 # new global min = [1, 5] and max the same at [4, 8]
|
137
|
+
|
138
|
+
# And the in between candidates now have new values based on the new mins
|
139
|
+
@o.fitness_for([1,2,4]).must_equal (((4.0 - 3.0)/(4-1) + (8.0 - 7)/(8-5))/2)
|
140
|
+
@o.fitness_for([1,2,4.5]).must_equal (((4.0 - 3.5)/(4-1) + (8.0 - 7.5)/(8-5))/2)
|
141
|
+
end
|
93
142
|
end
|
94
143
|
|
95
|
-
describe "
|
144
|
+
describe "the objective itself and its updates" do
|
96
145
|
before do
|
97
146
|
@o = SingleObjective1.new
|
98
147
|
@o2 = TwoMinObjectives1.new
|
99
148
|
@c = [1,2,3]
|
100
149
|
end
|
101
150
|
|
102
|
-
it "
|
103
|
-
qv = @o.
|
104
|
-
|
105
|
-
@c._objective.must_equal @o
|
151
|
+
it "repeatedly returns the same quality value for an object unless the objective itself has been changed" do
|
152
|
+
qv = @o.quality_of(@c)
|
153
|
+
qv.must_equal @o.quality_of(@c)
|
106
154
|
end
|
107
155
|
|
108
|
-
it "
|
109
|
-
@o.
|
110
|
-
qv2 = @o2.
|
111
|
-
|
112
|
-
@c._objective.must_equal @o2
|
156
|
+
it "returns different quality values for different objectives" do
|
157
|
+
qv = @o.quality_of(@c)
|
158
|
+
qv2 = @o2.quality_of(@c)
|
159
|
+
qv.wont_equal qv2
|
113
160
|
end
|
114
161
|
|
115
162
|
it "is re-evaluated if the objective has changed since original evaluation" do
|
116
|
-
qv = @o2.
|
117
|
-
@o2.
|
118
|
-
qvnew = @c
|
163
|
+
qv = @o2.quality_of(@c)
|
164
|
+
@o2.quality_of([1,2,3,4,5]) # Higher sum so max updated
|
165
|
+
qvnew = @o2.quality_of(@c)
|
119
166
|
qvnew.wont_equal qv
|
120
167
|
end
|
121
168
|
|
122
|
-
describe "objects that have not been evaluated" do
|
123
|
-
it "has not attached quality values" do
|
124
|
-
c = [1,2,3]
|
125
|
-
c._quality_value.must_equal nil
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
169
|
describe "version numbers" do
|
130
170
|
it "has version number 0 when no evaluation has taken place" do
|
131
171
|
@o.current_version.must_equal 0
|
@@ -133,25 +173,25 @@ describe "Objective" do
|
|
133
173
|
end
|
134
174
|
|
135
175
|
it "never changes the version number for a single objective since ratios are not used" do
|
136
|
-
@o.
|
176
|
+
@o.quality_of([1])
|
137
177
|
@o.current_version.must_equal 0
|
138
178
|
end
|
139
179
|
|
140
180
|
it "increases the version number each time a quality aspect of a candidate is more extreme than previously seen (when multi-objective)" do
|
141
|
-
@o2.
|
181
|
+
@o2.quality_of([1])
|
142
182
|
@o2.current_version.must_equal 4 # Both min and max changed for two objectives => 2*2
|
143
|
-
@o2.
|
183
|
+
@o2.quality_of([2])
|
144
184
|
@o2.current_version.must_equal 5 # New max values for sum objective => +1
|
145
|
-
@o2.
|
185
|
+
@o2.quality_of([1,2])
|
146
186
|
@o2.current_version.must_equal 7 # New max values for both objectives => +2
|
147
|
-
@o2.
|
187
|
+
@o2.quality_of([0])
|
148
188
|
@o2.current_version.must_equal 8 # New min value for sum objective => +1
|
149
|
-
@o2.
|
189
|
+
@o2.quality_of([-1])
|
150
190
|
@o2.current_version.must_equal 9 # New min value for sum objective => +1
|
151
|
-
@o2.
|
191
|
+
@o2.quality_of([-2])
|
152
192
|
@o2.current_version.must_equal 10 # New min value for sum objective => +1
|
153
|
-
@o2.
|
193
|
+
@o2.quality_of([1,2,3])
|
154
194
|
@o2.current_version.must_equal 12 # New max for both objectives => +1
|
155
195
|
end
|
156
196
|
end
|
157
|
-
end
|
197
|
+
end
|
@@ -50,6 +50,60 @@ describe "SearchSpace#bound" do
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
describe "LatinHypercubeSampler" do
|
54
|
+
before do
|
55
|
+
@sampler = FeldtRuby::Optimize::SearchSpace::LatinHypercubeSampler.new
|
56
|
+
@sp = FeldtRuby::Optimize::SearchSpace.new([0, 2], [1, 5], @sampler)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "has been linked up to the search space" do
|
60
|
+
@sampler.search_space.must_equal @sp
|
61
|
+
end
|
62
|
+
|
63
|
+
it "can generate a set of two valid candidates from a search space and they are properly spread out" do
|
64
|
+
100.times do
|
65
|
+
set = @sampler.sample_candidates(2)
|
66
|
+
set.must_be_instance_of Array
|
67
|
+
set.length.must_equal 2
|
68
|
+
c1, c2 = set
|
69
|
+
if c1[0] < 0.5
|
70
|
+
c2[0].must_be :>=, 0.5
|
71
|
+
c1[0].must_be :>=, 0.0
|
72
|
+
else
|
73
|
+
c2[0].must_be :<, 0.5
|
74
|
+
c1[0].must_be :<, 1.0
|
75
|
+
end
|
76
|
+
if c1[1] < 3.5
|
77
|
+
c2[1].must_be :>=, 3.5
|
78
|
+
c1[1].must_be :>=, 2.0
|
79
|
+
else
|
80
|
+
c2[1].must_be :<, 3.5
|
81
|
+
c1[1].must_be :<, 5.0
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "can generate a single candidate that are within the search space" do
|
87
|
+
100.times do
|
88
|
+
c = @sampler.sample_candidate
|
89
|
+
c.must_be_instance_of Array
|
90
|
+
c.length.must_equal 2
|
91
|
+
c[0].must_be :>=, 0.0
|
92
|
+
c[0].must_be :<, 1.0
|
93
|
+
c[1].must_be :>=, 2.0
|
94
|
+
c[1].must_be :<, 5.0
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "does not return the same candidate twice even if generating a single candidate" do
|
99
|
+
100.times do
|
100
|
+
c1 = @sampler.sample_candidate
|
101
|
+
c2 = @sampler.sample_candidate
|
102
|
+
c1.wont_equal c2
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
53
107
|
class TestSearchSpace < MiniTest::Unit::TestCase
|
54
108
|
def setup
|
55
109
|
@s1 = FeldtRuby::Optimize::SearchSpace.new([-5], [5])
|
data/test/test_sax.rb
CHANGED
@@ -39,10 +39,23 @@ describe 'Symbolic Adaptive approXimation - SAX' do
|
|
39
39
|
proc {SAX.new(3, 1)}.must_raise ArgumentError
|
40
40
|
end
|
41
41
|
|
42
|
-
it "maps some simple time series to symbols when directly mapping" do
|
42
|
+
it "maps some simple time series to symbols when directly mapping values" do
|
43
43
|
sax = SAX.new(1, 4)
|
44
44
|
sax.process([-1, 0, 1]).must_equal [1,3,4]
|
45
45
|
sax.process([-1, -0.5, 0, 0.5, 1]).must_equal [1,2,3,3,4]
|
46
46
|
sax.process([-1, -0.5, 0, 0.5, 1].reverse).must_equal [1,2,3,3,4].reverse
|
47
47
|
end
|
48
|
+
|
49
|
+
it "maps some simple time series to symbols when window size is 2" do
|
50
|
+
sax = SAX.new(2, 4)
|
51
|
+
sax.process([-1, 0, 0, 1]).must_equal [2,3]
|
52
|
+
sax.process([-1, 0, 0, 1]).must_equal [2,3]
|
53
|
+
sax.process([-1, -1, -1, 0, 0, 1, 1, 1]).must_equal [1,2,3,4]
|
54
|
+
end
|
55
|
+
|
56
|
+
it "maps some simple time series to symbols when window size is 4" do
|
57
|
+
sax = SAX.new(4, 4)
|
58
|
+
sax.process([-1, 0, 0, 1]).must_equal [3]
|
59
|
+
sax.process([-1, -1, -1, 0, 0, 1, 1, 1]).must_equal [1,4]
|
60
|
+
end
|
48
61
|
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'feldtruby/optimize/sub_qualities_comparators'
|
2
|
+
|
3
|
+
describe "EpsilonNonDominance with epsilon=0.0 i.e. normal non-dominance" do
|
4
|
+
before do
|
5
|
+
@c = FeldtRuby::Optimize::EpsilonNonDominance.new(1, 0.0)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "correctly calculates dominance for single-objective examples" do
|
9
|
+
@c.compare_sub_qualitites([1], [1]).must_equal 0
|
10
|
+
|
11
|
+
@c.first_dominates?([1], [1]).must_equal false
|
12
|
+
@c.second_dominates?([1], [1]).must_equal false
|
13
|
+
|
14
|
+
@c.compare_sub_qualitites([1], [2]).must_equal -1
|
15
|
+
@c.compare_sub_qualitites([2], [1]).must_equal 1
|
16
|
+
|
17
|
+
@c.compare_sub_qualitites([-1], [1]).must_equal -1
|
18
|
+
@c.compare_sub_qualitites([1], [-1]).must_equal 1
|
19
|
+
|
20
|
+
@c.compare_sub_qualitites([-10], [0]).must_equal -1
|
21
|
+
@c.compare_sub_qualitites([0], [-10]).must_equal 1
|
22
|
+
end
|
23
|
+
|
24
|
+
it "correctly calculates dominance for two-objective examples" do
|
25
|
+
@c.compare_sub_qualitites([2, 1], [2, 1]).must_equal 0
|
26
|
+
|
27
|
+
@c.compare_sub_qualitites([1, 2], [1, 3]).must_equal -1
|
28
|
+
@c.compare_sub_qualitites([1, 3], [1, 2]).must_equal 1
|
29
|
+
|
30
|
+
@c.compare_sub_qualitites([2, -1], [3, -1]).must_equal -1
|
31
|
+
@c.compare_sub_qualitites([3, -1], [2, -1]).must_equal 1
|
32
|
+
|
33
|
+
@c.compare_sub_qualitites([1, 2], [2, 1]).must_equal 0
|
34
|
+
end
|
35
|
+
|
36
|
+
it "correctly calculates dominance for three-objective examples" do
|
37
|
+
@c.compare_sub_qualitites([1, 2, 4], [1, 2, 4]).must_equal 0
|
38
|
+
|
39
|
+
@c.compare_sub_qualitites([1, 2, 4], [1, 3, 4]).must_equal -1
|
40
|
+
@c.compare_sub_qualitites([1, 3, 4], [1, 2, 4]).must_equal 1
|
41
|
+
|
42
|
+
@c.compare_sub_qualitites([1, 2, 3], [1, 3, 4]).must_equal -1
|
43
|
+
@c.compare_sub_qualitites([1, 3, 4], [1, 2, 3]).must_equal 1
|
44
|
+
end
|
45
|
+
|
46
|
+
it "never shows dominance when comparing the same objects" do
|
47
|
+
100.times do
|
48
|
+
candidate = Array.new(1 + rand(20)).map {rand(1e3)}
|
49
|
+
@c.compare_sub_qualitites(candidate, candidate).must_equal 0
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "always shows dominance when comparing objects where left is better in a single sub-objective" do
|
54
|
+
100.times do
|
55
|
+
candidate1 = Array.new(1 + rand(20)).map {rand(1e3)}
|
56
|
+
candidate2 = candidate1.clone
|
57
|
+
candidate2[rand(candidate2.length)] += 1
|
58
|
+
@c.compare_sub_qualitites(candidate1, candidate2).must_equal -1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "always shows dominance when comparing objects where right is better in a single sub-objective" do
|
63
|
+
100.times do
|
64
|
+
candidate1 = Array.new(1 + rand(20)).map {rand(1e3)}
|
65
|
+
candidate2 = candidate1.clone
|
66
|
+
candidate2[rand(candidate2.length)] -= 1
|
67
|
+
@c.compare_sub_qualitites(candidate1, candidate2).must_equal 1
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "EpsilonNonDominance with epsilon=1.0" do
|
73
|
+
before do
|
74
|
+
@c = FeldtRuby::Optimize::EpsilonNonDominance.new(1, 1.0)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "correctly calculates dominance for single-objective examples" do
|
78
|
+
@c.compare_sub_qualitites([1], [1]).must_equal 0
|
79
|
+
|
80
|
+
@c.compare_sub_qualitites([1], [2]).must_equal 0
|
81
|
+
@c.compare_sub_qualitites([2], [1]).must_equal 0
|
82
|
+
|
83
|
+
@c.compare_sub_qualitites([1], [2.01]).must_equal -1
|
84
|
+
@c.compare_sub_qualitites([2.01], [1]).must_equal 1
|
85
|
+
|
86
|
+
@c.compare_sub_qualitites([-1], [1]).must_equal -1
|
87
|
+
@c.compare_sub_qualitites([1], [-1]).must_equal 1
|
88
|
+
|
89
|
+
@c.compare_sub_qualitites([-10], [0]).must_equal -1
|
90
|
+
@c.compare_sub_qualitites([0], [-10]).must_equal 1
|
91
|
+
end
|
92
|
+
|
93
|
+
it "correctly calculates dominance for two-objective examples" do
|
94
|
+
@c.compare_sub_qualitites([2, 1], [2, 1]).must_equal 0
|
95
|
+
|
96
|
+
@c.compare_sub_qualitites([1, 2], [1, 3]).must_equal 0
|
97
|
+
@c.compare_sub_qualitites([1, 3], [1, 2]).must_equal 0
|
98
|
+
|
99
|
+
@c.compare_sub_qualitites([1, 1.9], [1, 3]).must_equal -1
|
100
|
+
@c.compare_sub_qualitites([1, 3.1], [1, 2]).must_equal 1
|
101
|
+
|
102
|
+
@c.compare_sub_qualitites([2, -1], [4, -1]).must_equal -1
|
103
|
+
@c.compare_sub_qualitites([4, -1], [2, -1]).must_equal 1
|
104
|
+
|
105
|
+
@c.compare_sub_qualitites([1, 2], [2, 1]).must_equal 0
|
106
|
+
|
107
|
+
@c.compare_sub_qualitites([1, 3], [2, 1]).must_equal 1
|
108
|
+
end
|
109
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: feldtruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rinruby
|
@@ -77,7 +77,11 @@ files:
|
|
77
77
|
- lib/feldtruby/optimize/random_search.rb
|
78
78
|
- lib/feldtruby/optimize/search_space.rb
|
79
79
|
- lib/feldtruby/optimize/stdout_logger.rb
|
80
|
+
- lib/feldtruby/optimize/sub_qualities_comparators.rb
|
80
81
|
- lib/feldtruby/statistics.rb
|
82
|
+
- lib/feldtruby/statistics/array_archive.rb
|
83
|
+
- lib/feldtruby/statistics/clustering.rb
|
84
|
+
- lib/feldtruby/statistics/distance.rb
|
81
85
|
- lib/feldtruby/statistics/distance/string_distance.rb
|
82
86
|
- lib/feldtruby/statistics/euclidean_distance.rb
|
83
87
|
- lib/feldtruby/statistics/fastmap.rb
|
@@ -89,10 +93,14 @@ files:
|
|
89
93
|
- lib/feldtruby/version.rb
|
90
94
|
- lib/feldtruby/visualization/circos.rb
|
91
95
|
- lib/feldtruby/word_counter.rb
|
96
|
+
- spikes/zlib_for_short_strings.rb
|
92
97
|
- test/helper.rb
|
98
|
+
- test/skip_test_array_archive.rb
|
93
99
|
- test/test_array.rb
|
94
100
|
- test/test_array_basic_stats.rb
|
95
101
|
- test/test_array_count_by.rb
|
102
|
+
- test/test_clustering.rb
|
103
|
+
- test/test_euclidean_distance.rb
|
96
104
|
- test/test_fastmap.rb
|
97
105
|
- test/test_float.rb
|
98
106
|
- test/test_html_doc_getter.rb
|
@@ -106,6 +114,7 @@ files:
|
|
106
114
|
- test/test_sax.rb
|
107
115
|
- test/test_statistics.rb
|
108
116
|
- test/test_string_distance.rb
|
117
|
+
- test/test_sub_qualitites_comparator.rb
|
109
118
|
- test/test_time.rb
|
110
119
|
- test/test_vector.rb
|
111
120
|
- test/test_word_counter.rb
|
@@ -135,9 +144,12 @@ specification_version: 3
|
|
135
144
|
summary: Robert Feldt's Common Ruby Code lib
|
136
145
|
test_files:
|
137
146
|
- test/helper.rb
|
147
|
+
- test/skip_test_array_archive.rb
|
138
148
|
- test/test_array.rb
|
139
149
|
- test/test_array_basic_stats.rb
|
140
150
|
- test/test_array_count_by.rb
|
151
|
+
- test/test_clustering.rb
|
152
|
+
- test/test_euclidean_distance.rb
|
141
153
|
- test/test_fastmap.rb
|
142
154
|
- test/test_float.rb
|
143
155
|
- test/test_html_doc_getter.rb
|
@@ -151,6 +163,7 @@ test_files:
|
|
151
163
|
- test/test_sax.rb
|
152
164
|
- test/test_statistics.rb
|
153
165
|
- test/test_string_distance.rb
|
166
|
+
- test/test_sub_qualitites_comparator.rb
|
154
167
|
- test/test_time.rb
|
155
168
|
- test/test_vector.rb
|
156
169
|
- test/test_word_counter.rb
|