Module: NEAT::DSL

Includes:
Math, NEAT, BasicNeuronTypes
Defined in:
lib/rubyneat/dsl.rb

Constant Summary

Constant Summary

Constants included from NEAT

STIMULUS

Instance Method Summary (collapse)

Methods included from NEAT

controller, controller=, create_controller, dpp, gaussian, new_innovation, random_name_generator

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(m, *args, &block)

This is used to handle the details of our DSL.



114
115
116
117
118
119
120
121
122
123
124
# File 'lib/rubyneat/dsl.rb', line 114

def method_missing(m, *args, &block)
  # we want to catch parameters settings here.
  if NEAT::controller.parms.respond_to? (assignment = (m.to_s + '=').to_sym)
    raise NeatException.new("Missing value(s) to %s" % m) if args.empty?
    val = (args.size == 1) ? args[0] : args
    $log.debug { "Caught method %s with parameter of %s" % [assignment, val] }
    NEAT::controller.parms.send(assignment, val)
  else
    super
  end
end

Instance Method Details

- (Object) compare(&block)

Fitness ordering – given 2 fitness numbers, use the <=> to compare them (or the equivalent, following the +1, 0, -1 that is in the sense of <=>)



63
64
65
# File 'lib/rubyneat/dsl.rb', line 63

def compare(&block)
  NEAT::controller.compare_func = block
end

- (Object) condition_boolean_vector(vec, sig = :tanh)

Helper function to Condition boolean vectors to be +1 if true, -1 if false (0 if sigmoid)



81
82
83
# File 'lib/rubyneat/dsl.rb', line 81

def condition_boolean_vector(vec, sig = :tanh)
  vec.map{|b| b ? 1 : ((sig == :sigmoid) ? 0 : -1)}
end

- (Object) cost(&block)

Calculation to add the cost to the fitness, resulting in a fitness that incorporates the cost for sorting purposes.



69
70
71
# File 'lib/rubyneat/dsl.rb', line 69

def cost(&block)
  NEAT::controller.cost_func = block
end

- (Object) define(name = NEAT.random_name_generator, &block)

DSL – Define defines the parameters to the controller.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/rubyneat/dsl.rb', line 15

def define(name = NEAT.random_name_generator, &block)
  [
   :inputs,
   :outputs,
   :hidden  # we really don't care about mapping hidden neurons, but we'll ignore them later.
  ].each do |iometh|
    instance_eval %Q[
   def #{iometh}(nodes = nil, &block)
 neui = unless nodes.nil?
          nodes
        else
          block.()
        end
 NEAT::controller.neural_#{iometh} = if neui.kind_of? Hash
                                       neui
                                     else
                                       Hash[neui.map{|n| [NEAT::random_name_generator, n]}]
                                     end
   end]
  end
  block.(NEAT::controller)
end

- (Object) evolve(&block)

DSL – Run evolution



39
40
41
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
93
94
95
96
97
98
99
100
# File 'lib/rubyneat/dsl.rb', line 39

def evolve(&block)
  # Query function is called with the sequence (time evolution) number,
  # and returns an array or hash of parameters that will be given
  # to the input nodes. In the case of hash, the keys in the hash
  # shall correspond to the names given to the input neurons.
  def query(&block)
    NEAT::controller.query_func = block
  end

  def recurrence(&block)
    NEAT::controller.recurrence_func = block
  end

  # fitness function calls the block with 2 vectors or two hashes, input and output
  # vectors of the critter being evaluated for fitness, as well as a sequence
  # number that can be used to index what the actual output should be.
  # |vin, vout, seq|
  def fitness(&block)
    NEAT::controller.fitness_func = block
  end

  # Fitness ordering -- given 2 fitness numbers,
  # use the <=> to compare them (or the equivalent, following
  # the +1, 0, -1 that is in the sense of <=>)
  def compare(&block)
    NEAT::controller.compare_func = block
  end

  # Calculation to add the cost to the fitness, resulting in a fitness
  # that incorporates the cost for sorting purposes.
  def cost(&block)
    NEAT::controller.cost_func = block
  end

  # Stop the progression once the fitness criteria is reached
  # for the most fit critter
  def stop_on_fitness(&block)
    NEAT::controller.stop_on_fit_func = block
  end

  # Helper function to
  # Condition boolean vectors to be +1 if true, -1 if false (0 if sigmoid)
  def condition_boolean_vector(vec, sig = :tanh)
    vec.map{|b| b ? 1 : ((sig == :sigmoid) ? 0 : -1)}
  end

  # Helper function to
  # Uncondition boolean vectors to be +1 if true, -1 if false
  # FIXME we need a better discrimination function
  def uncondition_boolean_vector(vec, sig = :tanh)
    vec.map{|o| o > ((sig == :sigmoid) ? 0.5 : 0) ? true : false}
  end

  # Helper function to do a simple fitness calculation
  # on the basis of the sum of the square of the diffences
  # of the element in the two vectors.
  def simple_fitness_error(v1, v2)
    sqrt v1.zip(v2).map{|a, b| (a - b) ** 2.0}.reduce{|m, c| m + c}
  end

  block.(NEAT::controller)
end

- (Object) fitness(&block)

fitness function calls the block with 2 vectors or two hashes, input and output vectors of the critter being evaluated for fitness, as well as a sequence number that can be used to index what the actual output should be. |vin, vout, seq|



56
57
58
# File 'lib/rubyneat/dsl.rb', line 56

def fitness(&block)
  NEAT::controller.fitness_func = block
end

- (Object) query(&block)

Query function is called with the sequence (time evolution) number, and returns an array or hash of parameters that will be given to the input nodes. In the case of hash, the keys in the hash shall correspond to the names given to the input neurons.



44
45
46
# File 'lib/rubyneat/dsl.rb', line 44

def query(&block)
  NEAT::controller.query_func = block
end

- (Object) recurrence(&block)



48
49
50
# File 'lib/rubyneat/dsl.rb', line 48

def recurrence(&block)
  NEAT::controller.recurrence_func = block
end

- (Object) report(&block)

Report on evaluations



103
104
105
# File 'lib/rubyneat/dsl.rb', line 103

def report(&block)
  NEAT::controller.report_hook = block
end

- (Object) run_engine(&block)

Run the engine. The block is called on each generation.



108
109
110
111
# File 'lib/rubyneat/dsl.rb', line 108

def run_engine(&block)
  NEAT::controller.end_run_func = block
  NEAT::controller.run
end

- (Object) simple_fitness_error(v1, v2)

Helper function to do a simple fitness calculation on the basis of the sum of the square of the diffences of the element in the two vectors.



95
96
97
# File 'lib/rubyneat/dsl.rb', line 95

def simple_fitness_error(v1, v2)
  sqrt v1.zip(v2).map{|a, b| (a - b) ** 2.0}.reduce{|m, c| m + c}
end

- (Object) stop_on_fitness(&block)

Stop the progression once the fitness criteria is reached for the most fit critter



75
76
77
# File 'lib/rubyneat/dsl.rb', line 75

def stop_on_fitness(&block)
  NEAT::controller.stop_on_fit_func = block
end

- (Object) uncondition_boolean_vector(vec, sig = :tanh)

Helper function to Uncondition boolean vectors to be +1 if true, -1 if false FIXME we need a better discrimination function



88
89
90
# File 'lib/rubyneat/dsl.rb', line 88

def uncondition_boolean_vector(vec, sig = :tanh)
  vec.map{|o| o > ((sig == :sigmoid) ? 0.5 : 0) ? true : false}
end