gene 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/Manifest +46 -0
  2. data/Rakefile +12 -9
  3. data/TODO +7 -0
  4. data/gene.gemspec +34 -0
  5. data/initializers/functional_extensions.rb +44 -0
  6. data/initializers/module_extensions.rb +14 -0
  7. data/initializers/object_extensions.rb +25 -0
  8. data/initializers/range_extensions.rb +9 -0
  9. data/initializers/runner.rb +15 -0
  10. data/initializers/symbol_extensions.rb +11 -0
  11. data/initializers/unbound_method_extensions.rb +3 -0
  12. data/lib/aligner.rb +34 -0
  13. data/lib/calculator.rb +42 -0
  14. data/lib/cell.rb +41 -0
  15. data/lib/color.rb +9 -0
  16. data/lib/dsl.rb +16 -0
  17. data/lib/gene.rb +67 -3
  18. data/lib/generator.rb +83 -0
  19. data/lib/geometry.rb +64 -0
  20. data/lib/hungarian.rb +205 -0
  21. data/lib/imagine.rb +22 -0
  22. data/lib/petri.rb +85 -0
  23. data/lib/point.rb +1 -0
  24. data/lib/trait.rb +60 -0
  25. data/tasks/test.rake +23 -0
  26. data/test/assets/Nova.jpg +0 -0
  27. data/test/assets/Rex.jpg +0 -0
  28. data/test/assets/Squares.jpg +0 -0
  29. data/test/test_helper.rb +6 -0
  30. data/test/unit/aligner_test.rb +91 -0
  31. data/test/unit/calculator_test.rb +100 -0
  32. data/test/unit/cell_test.rb +64 -0
  33. data/test/unit/color_test.rb +23 -0
  34. data/test/unit/dsl_test.rb +45 -0
  35. data/test/unit/functionals_extensions_test.rb +51 -0
  36. data/test/unit/gene_test.rb +76 -0
  37. data/test/unit/generator_test.rb +76 -0
  38. data/test/unit/geometry_test.rb +57 -0
  39. data/test/unit/hungarian_test.rb +196 -0
  40. data/test/unit/imagine_test.rb +54 -0
  41. data/test/unit/module_extensions_test.rb +40 -0
  42. data/test/unit/object_extensions_test.rb +34 -0
  43. data/test/unit/petri_test.rb +87 -0
  44. data/test/unit/range_extensions_test.rb +29 -0
  45. data/test/unit/symbol_extensions_test.rb +18 -0
  46. data/test/unit/trait_test.rb +97 -0
  47. data/test/unit/unbound_method_extensions_test.rb +11 -0
  48. metadata +118 -30
  49. data/History.txt +0 -6
  50. data/Manifest.txt +0 -7
  51. data/README.txt +0 -48
  52. data/bin/gene +0 -3
  53. data/test/test_gene.rb +0 -8
@@ -0,0 +1 @@
1
+ Point = Struct.new(:x, :y)
@@ -0,0 +1,60 @@
1
+ class Trait < Dsl
2
+ include Calculator
3
+
4
+ STANDARD_DEVIATION = {
5
+ :default => 0.1,
6
+ :range => 0.01..0.25
7
+ }
8
+
9
+ attr_reader :value, :range, :standard_deviation
10
+
11
+ def initialize(range)
12
+ @range = range
13
+ super
14
+ end
15
+
16
+ def mutated_value
17
+ new_value = value + standard_deviation * Trait.get_normal_random_variable
18
+ new_value = new_value.round if value.is_a?(Fixnum)
19
+
20
+ if new_value > range.max
21
+ range.max
22
+ elsif new_value < range.min
23
+ range.min
24
+ else
25
+ new_value
26
+ end
27
+ end
28
+
29
+ def percentify
30
+ "#{value / range.max.to_f * 100}%"
31
+ end
32
+
33
+ private
34
+
35
+ def finish_init
36
+ fill_out_value
37
+ fill_out_deviation
38
+ end
39
+
40
+ def fill_out_value
41
+ @value ||= Trait.generate_value(range.max)
42
+ end
43
+
44
+ def fill_out_deviation
45
+ @standard_deviation ||= STANDARD_DEVIATION[:default] * range.max
46
+ end
47
+
48
+ def new_standard_deviation_from(fitness)
49
+ deviation_range = STANDARD_DEVIATION[:range].max - STANDARD_DEVIATION[:range].min
50
+ STANDARD_DEVIATION[:range].max - deviation_range * fitness
51
+ end
52
+
53
+ def method_missing(name, *args, &block)
54
+ case name.to_s
55
+ when /^set_value$/: @value = args.first
56
+ when /^deviation$/: @standard_deviation = args.first * range.max
57
+ when /^deviate_from$/: @standard_deviation = new_standard_deviation_from(args.first)
58
+ else super end
59
+ end
60
+ end
@@ -0,0 +1,23 @@
1
+ desc "Runs the test suite"
2
+ task :test do
3
+ require "benchmark"
4
+
5
+ totals = { :tests => 0, :assertions => 0, :failures => 0, :errors => 0 }
6
+ Benchmark.measure do
7
+
8
+ FileList["./test/**/*_test.rb"].map { |path| path.gsub("test/", "") }.each do |test|
9
+ results = `ruby -C test/ #{test}`
10
+ results =~ /(\d+) tests, (\d+) assertions, (\d+) failures, (\d+) errors/
11
+
12
+ totals[:tests] += $1.to_i
13
+ totals[:assertions] += $2.to_i
14
+ totals[:failures] += $3.to_i
15
+ totals[:errors] += $4.to_i
16
+
17
+ print "#{results}\n"
18
+ end
19
+ end.real.to_s.match(/(\d+\.\d{2})/)
20
+
21
+ print "Total results: #{totals[:tests]} tests run in #{$1} seconds: #{totals[:assertions]} assertions, #{totals[:failures]} failures, #{totals[:errors]} errors\n\n"
22
+ print "Your tests are #{totals[:failures].zero? && totals[:errors].zero? ? 'PASSING' : 'FAILING'}.\n"
23
+ end
Binary file
Binary file
Binary file
@@ -0,0 +1,6 @@
1
+ require "rubygems"
2
+ require "mocha"
3
+ require "test/unit"
4
+
5
+ # Pulls in the runner.rb file to autoload dependencies.
6
+ require File.join(File.dirname(__FILE__), "..", "initializers", "runner.rb")
@@ -0,0 +1,91 @@
1
+ require File.join(File.dirname(__FILE__), "..", "test_helper.rb")
2
+
3
+ class AlignerTest < Test::Unit::TestCase
4
+ class TestClass
5
+ attr_accessor :cells
6
+
7
+ include Aligner
8
+ end
9
+
10
+ def setup
11
+ Petri.stubs(:image_dimensions).returns(Point.new(640, 480))
12
+ Petri.stubs(:num_genes).returns(3)
13
+ Petri.stubs(:num_points).returns(3)
14
+
15
+ @test_class = TestClass.new
16
+ end
17
+
18
+ def test_true
19
+ assert true
20
+ end
21
+
22
+ def test_align_crossover_for
23
+ @test_class.cells = [
24
+ Cell.new do
25
+ gene_0 &three_points_at(0, 0)
26
+ gene_1 &three_points_at(10, 0)
27
+ gene_2 &three_points_at(20, 0)
28
+ end,
29
+ Cell.new do
30
+ gene_0 &three_points_at(10, 0)
31
+ gene_1 &three_points_at(20, 0)
32
+ gene_2 &three_points_at(30, 0)
33
+ end
34
+ ]
35
+
36
+ optimal_alignment = @test_class.align_crossover
37
+
38
+ assert_equal [0, 1, 2], optimal_alignment[:cell_1]
39
+ assert_equal [1, 0, 2], optimal_alignment[:cell_2]
40
+ end
41
+
42
+ def test_crossover_map
43
+ Petri.stubs(:num_genes).returns(2)
44
+
45
+ @test_class.cells = [
46
+ Cell.new do
47
+ gene_0 &three_points_at(0, 0)
48
+ gene_1 &three_points_at(15, 0)
49
+ end,
50
+ Cell.new do
51
+ gene_0 &three_points_at(10, 0)
52
+ gene_1 &three_points_at(22.5, 0)
53
+ end
54
+ ]
55
+
56
+ assert_equal [[10, 22.5], [5, 7.5]], @test_class.send(:crossover_map)
57
+ end
58
+
59
+ def test_middle_point_of
60
+ Petri.stubs(:num_points).returns(4)
61
+
62
+ gene = Gene.new do
63
+ point_0 0, 0
64
+ point_1 30, 0
65
+ point_2 0, 15
66
+ point_3 30, 15
67
+ end
68
+
69
+ middle_point = @test_class.send(:middle_point_of, gene)
70
+
71
+ assert_equal 15, middle_point.x
72
+ assert_equal 7.5, middle_point.y
73
+ end
74
+
75
+ def test_distance_between
76
+ point_1 = Point.new(0, 0)
77
+ point_2 = Point.new(3, 4)
78
+
79
+ assert_equal 5, @test_class.send(:distance_between, point_1, point_2)
80
+ end
81
+
82
+ protected
83
+
84
+ def three_points_at(x, y)
85
+ lambda do
86
+ point_0 x, y
87
+ point_1 x, y
88
+ point_2 x, y
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,100 @@
1
+ require File.join(File.dirname(__FILE__), "..", "test_helper.rb")
2
+
3
+ class CalculatorTest < Test::Unit::TestCase
4
+ class TestClass
5
+ include Calculator
6
+ end
7
+
8
+ def test_true
9
+ assert true
10
+ end
11
+
12
+ def test_generate_value__raises_error_when_max_is_nil_or_zero
13
+ assert_raise ArgumentError do
14
+ TestClass.generate_value(nil)
15
+ end
16
+
17
+ assert_raise ArgumentError do
18
+ TestClass.generate_value(0)
19
+ end
20
+ end
21
+
22
+ def test_generate_value__returns_same_type_as_max
23
+ assert TestClass.generate_value(1.0).is_a?(Float)
24
+ assert TestClass.generate_value(100).is_a?(Fixnum)
25
+ end
26
+
27
+ def test_get_normal_random_variable__x
28
+ sum = mock
29
+ sum.expects(:+).with(:y).returns(sum)
30
+ sum.expects(:<).with(1).returns(true)
31
+
32
+ x = mock
33
+ x.expects(:**).with(2).returns(sum)
34
+ y = mock
35
+ y.expects(:**).with(2).returns(:y)
36
+
37
+ TestClass.expects(:get_uniform_random_variable).twice.returns(x, y)
38
+ TestClass.expects(:rand).with(2).returns(0)
39
+ TestClass.expects(:convert).with(x, sum)
40
+
41
+ TestClass.get_normal_random_variable
42
+ end
43
+
44
+ def test_get_normal_random_variable__y
45
+ sum = mock
46
+ sum.expects(:+).with(:y).returns(sum)
47
+ sum.expects(:<).with(1).returns(true)
48
+
49
+ x = mock
50
+ x.expects(:**).with(2).returns(sum)
51
+ y = mock
52
+ y.expects(:**).with(2).returns(:y)
53
+
54
+ TestClass.expects(:get_uniform_random_variable).twice.returns(x, y)
55
+ TestClass.expects(:rand).with(2).returns(1)
56
+ TestClass.expects(:convert).with(y, sum)
57
+
58
+ TestClass.get_normal_random_variable
59
+ end
60
+
61
+ def test_get_normal_random_variable__loops_until_sum_is_less_than_one
62
+ sum = mock
63
+ sum.expects(:+).with(:y).returns(sum)
64
+ sum.expects(:<).with(1).returns(true)
65
+
66
+ x = mock
67
+ x.expects(:**).with(2).returns(sum)
68
+ y = mock
69
+ y.expects(:**).with(2).returns(:y)
70
+
71
+ TestClass.expects(:get_uniform_random_variable).times(4).returns(1, 1, x, y)
72
+ TestClass.expects(:rand).with(2).returns(0)
73
+ TestClass.expects(:convert).with(x, sum)
74
+
75
+ TestClass.get_normal_random_variable
76
+ end
77
+
78
+ def test_get_uniform_random_variable
79
+ random_value = mock
80
+ random_value.expects(:*).with(:sign)
81
+ TestClass.expects(:rand).with(0).returns(random_value)
82
+ TestClass.expects(:random_sign_change).returns(:sign)
83
+
84
+ TestClass.get_uniform_random_variable
85
+ end
86
+
87
+ def test_random_sign_change
88
+ TestClass.expects(:rand).with(2).returns(0)
89
+ assert_equal 1, TestClass.send(:random_sign_change)
90
+
91
+ TestClass.expects(:rand).with(2).returns(1)
92
+ assert_equal -1, TestClass.send(:random_sign_change)
93
+ end
94
+
95
+ def test_convert
96
+ assert_equal 0, TestClass.send(:convert, 1, 0)
97
+ assert_equal 0, TestClass.send(:convert, 0, 0)
98
+ assert_equal 0, TestClass.send(:convert, 0, 1)
99
+ end
100
+ end
@@ -0,0 +1,64 @@
1
+ require File.join(File.dirname(__FILE__), "..", "test_helper.rb")
2
+
3
+ class CellTest < Test::Unit::TestCase
4
+ def setup
5
+ Petri.stubs(:image_dimensions).returns(Point.new(640, 480))
6
+ Petri.stubs(:num_genes).returns(3)
7
+ Petri.stubs(:num_points).returns(3)
8
+
9
+ @cell = Cell.new
10
+ end
11
+
12
+ def test_true
13
+ assert true
14
+ end
15
+
16
+ def test_initialize
17
+ image_range_x = 0...Petri.image_dimensions.x
18
+ image_range_y = 0...Petri.image_dimensions.y
19
+ channel_range = 0.0..1.0
20
+
21
+ @cell.genes.each do |gene|
22
+ assert_equal Petri.num_points, gene.polygon.num_points
23
+
24
+ assert gene.polygon.points.all? { |point| image_range_x.include?(point.x.value) && image_range_y.include?(point.y.value) }
25
+ assert gene.color.each_pair { |channel, trait| channel_range.include?(trait.value) }
26
+ end
27
+ end
28
+
29
+ def test_initialize__with_block
30
+ lambda { |index| assert Cell.new.genes[index].is_a?(Gene) } | Petri.num_genes.times
31
+
32
+ assert_raise NoMethodError do
33
+ Cell.new { rawr! }
34
+ end
35
+ end
36
+
37
+ def test_genes_by_alpha
38
+ cell = Cell.new do
39
+ gene_0 do
40
+ trait_a do
41
+ set_value 0.5
42
+ end
43
+ end
44
+ gene_1 do
45
+ trait_a do
46
+ set_value 0.0
47
+ end
48
+ end
49
+ gene_2 do
50
+ trait_a do
51
+ set_value 1.0
52
+ end
53
+ end
54
+ end
55
+
56
+ assert_equal [0.5, 0.0, 1.0], cell.genes.map(&:color).map(&:a).map(&:value)
57
+ assert_equal [1.0, 0.5, 0.0], cell.genes_by_alpha.map(&:color).map(&:a).map(&:value)
58
+ end
59
+
60
+ def test_genes_from_alignment_map
61
+ cell = Cell.new
62
+ assert_equal [cell.genes[2], cell.genes[0], cell.genes[1]], cell.genes_from_alignment_map([2, 0, 1])
63
+ end
64
+ end
@@ -0,0 +1,23 @@
1
+ require File.join(File.dirname(__FILE__), "..", "test_helper.rb")
2
+
3
+ class ColorTest < Test::Unit::TestCase
4
+ def test_true
5
+ assert true
6
+ end
7
+
8
+ def test_rgb
9
+ color = Color.new(:r, :g, :b, :a)
10
+ assert_equal [:r, :g, :b], color.rgb
11
+ end
12
+
13
+ def test_rgba_format
14
+ color = Color.new(
15
+ Trait.new(0.0..1.0) { set_value 0 },
16
+ Trait.new(0.0..1.0) { set_value 0.25 },
17
+ Trait.new(0.0..1.0) { set_value 0.5 },
18
+ Trait.new(0.0..1.0) { set_value 0.75 }
19
+ )
20
+
21
+ assert_equal "rgba(0.0%, 25.0%, 50.0%, 0.75)", color.rgba_format
22
+ end
23
+ end
@@ -0,0 +1,45 @@
1
+ require File.join(File.dirname(__FILE__), "..", "test_helper.rb")
2
+
3
+ class DslTest < Test::Unit::TestCase
4
+ class TestClass < Dsl
5
+ def initialize
6
+ @set_in_init = true
7
+ super
8
+ end
9
+
10
+ def finish_init
11
+ @set_in_finish_init = true
12
+ end
13
+ end
14
+
15
+ def setup
16
+ @test_class = TestClass.new do
17
+ @set_in_block = true
18
+ method_in_binding_scope
19
+ end
20
+ end
21
+
22
+ def test_true
23
+ assert true
24
+ end
25
+
26
+ def test_dsl__self_changed_in_block
27
+ %w[init finish_init block].each do |suffix|
28
+ assert @test_class.instance_variable_get(:"@set_in_#{suffix}")
29
+ end
30
+
31
+ assert_raise NoMethodError do
32
+ TestClass.new { rawr! }
33
+ end
34
+ end
35
+
36
+ def test_dsl__method_resolution_in_binding_scope
37
+ assert @set_in_binding_scope
38
+ end
39
+
40
+ private
41
+
42
+ def method_in_binding_scope
43
+ @set_in_binding_scope = true
44
+ end
45
+ end
@@ -0,0 +1,51 @@
1
+ require File.join(File.dirname(__FILE__), "..", "test_helper.rb")
2
+
3
+ class FunctionalExtensionsTest < Test::Unit::TestCase
4
+ def test_true
5
+ assert true
6
+ end
7
+
8
+ def test_apply
9
+ sum = lambda { |x, y| x + y }
10
+
11
+ assert_equal [3, 7], sum | [[1, 2], [3, 4]]
12
+ assert_equal [3, 7], sum.apply([[1, 2], [3, 4]])
13
+ end
14
+
15
+ def test_reduce
16
+ sum = lambda { |x, y| x + y }
17
+
18
+ assert_equal 10, sum <= [1, 2, 3, 4]
19
+ assert_equal 10, sum.reduce([1, 2, 3, 4])
20
+ end
21
+
22
+ def test_compose
23
+ add_1 = lambda { |x| x + 1 }
24
+ double = lambda { |x| x * 2 }
25
+
26
+ assert_equal 5, (add_1 * double)[2]
27
+ assert_equal 5, (add_1.compose(double))[2]
28
+
29
+ assert_equal 6, (double * add_1)[2]
30
+ assert_equal 6, (double.compose(add_1))[2]
31
+ end
32
+
33
+
34
+ def test_apply_head
35
+ function = lambda { |x, y, z| x * y + z }
36
+ assert_equal 24, (function >> 5)[4, 4]
37
+ end
38
+
39
+ def test_apply_tail
40
+ function = lambda { |x, y, z| x * y + z }
41
+ assert_equal 21, (function << 5)[4, 4]
42
+ end
43
+
44
+ def test_memoize
45
+ factorial = +lambda { |x| x == 1 ? 1 : x * factorial[x - 1] }
46
+ assert_equal 120, factorial[5]
47
+
48
+ factorial = lambda { |x| x == 1 ? 1 : x * factorial[x - 1] }.memoize
49
+ assert_equal 120, factorial[5]
50
+ end
51
+ end