drp 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+