drp 0.0.6

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.
@@ -0,0 +1,98 @@
1
+
2
+ =begin
3
+
4
+ DRP, Genetic Programming + Grammatical Evolution = Directed Ruby Programming
5
+ Copyright (C) 2006, Christophe McKeon
6
+
7
+ This program is free software; you can redistribute it and/or
8
+ modify it under the terms of the GNU General Public License
9
+ as published by the Free Software Foundation; either version 2
10
+ of the License, or (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program; if not, write to the Free Softwar Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
+
20
+ =end
21
+
22
+ class TestMaxDepthsHelper
23
+
24
+ extend DRP::RuleEngine
25
+
26
+ attr_reader :test_simple_depth_attained
27
+
28
+ def initialize single_codon = nil
29
+ @test_simple_depth_attained = 0
30
+ @single_codon = single_codon
31
+ # init_drp
32
+ end
33
+
34
+ # note max_depths call next_meta_codon
35
+ # but their is a default next_meta_codon which
36
+ # just calls next_codon
37
+ def next_codon
38
+ @single_codon || rand
39
+ end
40
+
41
+ begin_rules
42
+
43
+ # note, some of these tests depend on the return
44
+ # value of default_rule_method below
45
+
46
+ max_depth 4
47
+ def test_simple
48
+ test_simple + 1
49
+ end
50
+
51
+ max_depth 3..9
52
+ def test_map_range
53
+ test_map_range + 1
54
+ end
55
+
56
+ max_depth { |x,y| x + y }
57
+ def test_proc
58
+ test_proc + 1
59
+ end
60
+
61
+ end_rules
62
+
63
+ def default_rule_method
64
+ 0
65
+ end
66
+
67
+ end
68
+
69
+ class TestMaxDepths < Test::Unit::TestCase
70
+
71
+ def test_exceptions
72
+ # TODO
73
+ end
74
+
75
+ def test_simple
76
+ @drp_obj = TestMaxDepthsHelper.new
77
+ assert_equal 4, @drp_obj.test_simple
78
+ end
79
+
80
+ def test_map_range
81
+ 7.times do |i|
82
+ codon = i/7.0
83
+ @drp_obj = TestMaxDepthsHelper.new codon
84
+ #puts "i: #{i}, cod: #{codon}, map: #{@drp_obj.test_map_range}"
85
+ assert_equal i + 3, @drp_obj.test_map_range
86
+ end
87
+ @drp_obj = TestMaxDepthsHelper.new 0.99999999999
88
+ assert_equal 9, @drp_obj.test_map_range
89
+ end
90
+
91
+ def test_proc
92
+ @drp_obj = TestMaxDepthsHelper.new 3
93
+ assert_equal 6, @drp_obj.test_proc
94
+ end
95
+
96
+ end
97
+
98
+
@@ -0,0 +1,60 @@
1
+
2
+ =begin
3
+
4
+ DRP, Genetic Programming + Grammatical Evolution = Directed Ruby Programming
5
+ Copyright (C) 2006, Christophe McKeon
6
+
7
+ This program is free software; you can redistribute it and/or
8
+ modify it under the terms of the GNU General Public License
9
+ as published by the Free Software Foundation; either version 2
10
+ of the License, or (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program; if not, write to the Free Softwar Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
+
20
+ =end
21
+
22
+ # TODO test if the range is of the form n..n where n is the same number
23
+
24
+ class TestUtils < Test::Unit::TestCase
25
+
26
+ def test_i_linear_map
27
+
28
+ r = 0..4
29
+
30
+ assert_equal 0, DRP::Utils::map(r, 0, :i_linear)
31
+ assert_equal 0, DRP::Utils::map(r, 0.19999, :i_linear)
32
+ assert_equal 1, DRP::Utils::map(r, 0.2, :i_linear)
33
+ assert_equal 1, DRP::Utils::map(r, 0.39999, :i_linear)
34
+ assert_equal 2, DRP::Utils::map(r, 0.4, :i_linear)
35
+ assert_equal 2, DRP::Utils::map(r, 0.59999, :i_linear)
36
+ assert_equal 3, DRP::Utils::map(r, 0.6, :i_linear)
37
+ assert_equal 3, DRP::Utils::map(r, 0.79999, :i_linear)
38
+ assert_equal 4, DRP::Utils::map(r, 0.8, :i_linear)
39
+ assert_equal 4, DRP::Utils::map(r, 0.99999, :i_linear)
40
+ # this is 5 but codons need to be 0 <= c < 1 so it should never happen
41
+ # assert_equal 5, DRP::Utils::map(r, 1, :i_linear)
42
+
43
+ r = 4..0
44
+
45
+ assert_equal 4, DRP::Utils::map(r, 0, :i_linear)
46
+ assert_equal 4, DRP::Utils::map(r, 0.19999, :i_linear)
47
+ assert_equal 3, DRP::Utils::map(r, 0.2, :i_linear)
48
+ assert_equal 3, DRP::Utils::map(r, 0.39999, :i_linear)
49
+ assert_equal 2, DRP::Utils::map(r, 0.4, :i_linear)
50
+ assert_equal 2, DRP::Utils::map(r, 0.59999, :i_linear)
51
+ assert_equal 1, DRP::Utils::map(r, 0.6, :i_linear)
52
+ assert_equal 1, DRP::Utils::map(r, 0.79999, :i_linear)
53
+ assert_equal 0, DRP::Utils::map(r, 0.8, :i_linear)
54
+ assert_equal 0, DRP::Utils::map(r, 0.99999, :i_linear)
55
+
56
+ end
57
+ end
58
+
59
+
60
+
@@ -0,0 +1,372 @@
1
+
2
+ =begin
3
+
4
+ DRP, Genetic Programming + Grammatical Evolution = Directed Ruby Programming
5
+ Copyright (C) 2006, Christophe McKeon
6
+
7
+ This program is free software; you can redistribute it and/or
8
+ modify it under the terms of the GNU General Public License
9
+ as published by the Free Software Foundation; either version 2
10
+ of the License, or (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program; if not, write to the Free Softwar Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
+
20
+ =end
21
+
22
+ ############### STATIC WEIGHTS ###############
23
+
24
+ =begin
25
+ weight 10.0 static weight
26
+ weight 0..1 static mapped
27
+ weight 0..1, :function static mapped w/ function
28
+ weight {} static proc gets codons
29
+ =end
30
+
31
+ class TestStaticWeightsHelper
32
+
33
+ extend DRP::RuleEngine
34
+
35
+ attr_writer :codon
36
+ attr_reader :_1, :_0, :_33, :_67, :_m1, :_m01_02, :_p30, :_p70
37
+
38
+ def initialize codon = nil
39
+ @codon = codon
40
+ @_1 = @_0 = @_33 = @_67 = @_m1 = @_m01_02 = @_p30 = @_p70 = 0
41
+ end
42
+
43
+ def next_codon
44
+ @codon || rand
45
+ end
46
+
47
+ begin_rules
48
+
49
+ # test constant
50
+
51
+ weight 1
52
+ def _1_0
53
+ @_1 += 1
54
+ end
55
+
56
+ weight 0
57
+ def _1_0
58
+ @_0 += 1
59
+ end
60
+
61
+ weight 33
62
+ def _33_67
63
+ @_33 += 1
64
+ end
65
+
66
+ weight 67
67
+ def _33_67
68
+ @_67 += 1
69
+ end
70
+
71
+ # test mapped
72
+
73
+ weight 0.1..0.2
74
+ def mapped
75
+ @_m01_02 += 1
76
+ end
77
+
78
+ weight 1
79
+ def mapped
80
+ @_m1 += 1
81
+ end
82
+
83
+ # test proc
84
+
85
+ weight { |x,y,z| ((x + y + z) * 100).to_i }
86
+ def proc
87
+ @_p30 += 1
88
+ end
89
+
90
+ weight 70
91
+ def proc
92
+ @_p70 += 1
93
+ end
94
+
95
+ end_rules
96
+
97
+ end
98
+
99
+ class TestStaticWeights < Test::Unit::TestCase
100
+
101
+ def test_constant
102
+ ts = TestStaticWeightsHelper.new
103
+ 100.times do |i|
104
+ ts.codon = i.to_f/100
105
+ ts._1_0
106
+ ts._33_67
107
+ end
108
+ assert_equal 100, ts._1
109
+ assert_equal 0, ts._0
110
+ assert_equal 33, ts._33
111
+ assert_equal 67, ts._67
112
+ end
113
+
114
+ def test_mapped
115
+ ts = TestStaticWeightsHelper.new
116
+ 100.times do |i|
117
+ ts.codon = i.to_f/100
118
+ ts.mapped
119
+ end
120
+ m = ts._m01_02
121
+ m1 = ts._m1
122
+ # puts ">>>>>", m, m1, "<<<<<"
123
+ # these figures take normalization into account
124
+ assert m >= 9 && m <= 17
125
+ assert m1 >= 83
126
+ end
127
+
128
+ def test_mapped_w_function
129
+ # TODO no functions yet
130
+ assert true
131
+ end
132
+
133
+ def test_proc
134
+ ts = TestStaticWeightsHelper.new(0.1)
135
+ # since the codon is set here
136
+ # to 0.1 then (x + y + z) * 100 in proc equal 30
137
+ 100.times do |i|
138
+ ts.codon = i.to_f/100
139
+ ts.proc
140
+ end
141
+ assert_equal 30, ts._p30
142
+ assert_equal 70, ts._p70
143
+ end
144
+
145
+ end
146
+
147
+ ############### FROM CURRENT DEPTH WEIGHTS ##################
148
+
149
+
150
+ =begin
151
+ weight_fcd 0..1 dynamic from current depth (uses max_depth)
152
+ weight_fcd 0..1, :function dynamic fcd w/ function
153
+ weight_fcd 0..1, 0..1 dynamic like previous but start
154
+ and end of range mapped from codons
155
+ weight_fcd 0..1, 0..1, :function like previous with function
156
+ the function applies to the dynamic mapping
157
+ of the current depth, and not the static
158
+ mapping via codons of start and end
159
+ which is always just linear
160
+ weight_fcd { |max_depth| dynamic, expects a block which takes the
161
+ ... max_depth and returns a proc which
162
+ proc {|depth| ... } which takes the current depth
163
+ }
164
+ =end
165
+
166
+ class TestFCDWeightsHelper
167
+
168
+ extend DRP::RuleEngine
169
+
170
+ attr_reader :str
171
+
172
+ def initialize
173
+ reset
174
+ end
175
+ def reset
176
+ @str = ''
177
+ end
178
+
179
+ begin_rules
180
+
181
+ max_depth 3
182
+
183
+ weight_fcd 1.0..0.0
184
+ def simple
185
+ @str << 'a'
186
+ # print @str, '>>', depth, "\n"
187
+ simple
188
+ end
189
+
190
+ weight_fcd 0.0..1.0
191
+ def simple
192
+ @str << 'b'
193
+ # print @str, '>>', depth, "\n"
194
+ simple
195
+ end
196
+
197
+ end_rules
198
+
199
+ end
200
+
201
+ class TestFCDWeights < Test::Unit::TestCase
202
+
203
+ def test_simple
204
+ td = TestFCDWeightsHelper.new
205
+ 100.times do
206
+ td.simple
207
+ # on first pick 'a' must be chosen w/ 1.0 vs 0.0 weight
208
+ # on second pick 'a' must be chosen with 0.5 vs 0 weight
209
+ # on third pick 'a' and 'b' both have weight 0 so
210
+ # either can be chosen
211
+ # if 'a' was chosen on third then
212
+ # all the rest will be 'b' because 'a' has exceeded max depth 3
213
+ # else
214
+ # on fourth pick 'b' must be chosen because it now has weight
215
+ # 0.5 vs 'a' which still has weight 0.0
216
+ # on fifth pick 'b' must be chosen because it now has weight 1.0
217
+ # on sixth pick 'a' is the only active rule method because 'b' has
218
+ # gone past it's max_depth, so 'a' must be picked
219
+ assert ('aaabbb' == td.str) || ('aabbba' == td.str)
220
+ td.reset
221
+ end
222
+ end
223
+
224
+ end
225
+
226
+ ##############################################################
227
+
228
+
229
+
230
+
231
+
232
+
233
+
234
+
235
+ ############### DYNAMIC WEIGHTS ##############
236
+
237
+ =begin
238
+ weight_dyn 0..1 codon maps to range for every rule method choice
239
+ weight_dyn 0..1, :function same but using function
240
+ weight_dyn 0..1, 0..1 initial min and max determined by metacodons
241
+ and further runtime mapping also
242
+ weight_dyn 0..1, 0..1, :function same but function used for runtime mapping
243
+ weight_dyn { |codon| } same but using user block, gets meta_codons
244
+ =end
245
+
246
+ =begin NOT SURE HOW USEFUL 'DYNAMIC' WEIGHTS ARE
247
+
248
+ class TestDynamicWeightsHelper
249
+
250
+ extend DRP::RuleEngine
251
+
252
+ attr_reader :test_simple_count, :num_meta_codon_requests, :num_codon_requests
253
+
254
+ def initialize codon = nil
255
+ @codon = codon
256
+ reset
257
+ end
258
+
259
+ def next_codon
260
+ @num_codon_requests += 1
261
+ @codon || rand
262
+ end
263
+
264
+ def next_meta_codon
265
+ @num_meta_codon_requests += 1
266
+ rand
267
+ end
268
+
269
+ def reset
270
+ @num_codon_requests = 0
271
+ @num_meta_codon_requests = 0
272
+ end
273
+
274
+ begin_rules
275
+
276
+ weight_dyn 0..1
277
+ def test_simple
278
+ end
279
+ def test_simple
280
+ end
281
+
282
+ weight_dyn 0..1, 0..1
283
+ def test_init_range
284
+ end
285
+ def test_init_range
286
+ end
287
+
288
+ end_rules
289
+
290
+ end
291
+
292
+ class TestDynamicWeights < Test::Unit::TestCase
293
+
294
+ # this is a very indirect test
295
+ def test_simple
296
+ td = TestDynamicWeightsHelper.new
297
+ # 4 meta_codons are used to initialize test_init_range weights
298
+ # so need to reset
299
+ td.reset
300
+ n = 10
301
+ n.times do
302
+ td.test_simple
303
+ end
304
+ # both test_simple rule methods get weights
305
+ # allocated via meta_codons for each and every choice
306
+ assert_equal n * 2, td.num_meta_codon_requests
307
+ # once the weights are set a rule must be
308
+ # picked which uses a regular codon
309
+ assert_equal n, td.num_codon_requests
310
+ end
311
+
312
+ def test_init_range
313
+ td = TestDynamicWeightsHelper.new
314
+ # 4 meta_codons are used to initialize test_init_range weights
315
+ assert_equal 4, td.num_meta_codon_requests
316
+ n = 10
317
+ n.times do
318
+ td.test_init_range
319
+ end
320
+ # both test_init_range rule methods get
321
+ # their initial weight range set at initialization time
322
+ # which requires 2 metacodons each.
323
+ assert_equal (n * 2) + 4, td.num_meta_codon_requests
324
+ # once the weights are set a rule must be
325
+ # picked which uses a regular codon
326
+ assert_equal n, td.num_codon_requests
327
+ end
328
+
329
+ end
330
+
331
+ =end
332
+
333
+
334
+ =begin
335
+
336
+ ITER_TEST_DEFAULT_NUM_ITER = 1000
337
+ ITER_TEST_MAX_NUM_ITER = 100000
338
+
339
+ def iter_test(
340
+ test_helper, selector, expected = true,
341
+ num_iter = ITER_TEST_DEFAULT_NUM_ITER,
342
+ max_num_iter = ITER_TEST_MAX_NUM_ITER
343
+ )
344
+
345
+ if num_iter > max_num_iter
346
+ return false
347
+ end
348
+
349
+ test = true
350
+ num_iter.times do
351
+ test &&= test_helper.send(selector)
352
+ end
353
+
354
+ if test == expected
355
+ return true
356
+ else
357
+ return iter_test(test_helper, selector, expected, num_iter * 2, max_num_iter)
358
+ end
359
+
360
+ end
361
+
362
+ # non deterministic assert
363
+ def nd_assert test_helper, selector, expected = true
364
+ val = iter_test(test_helper, selector, expected)
365
+ msg = "nondeterministic test failure: '#{selector}', " +
366
+ # TODO these instructions should be in the docs
367
+ "run 'rake test' a few more times to double check"
368
+ assert val, msg
369
+ end
370
+
371
+ =end
372
+