gene 0.0.1 → 0.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.
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