fathom 0.3.7 → 0.5.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.
- data/.autotest +7 -5
- data/.document +2 -2
- data/Gemfile +9 -10
- data/{LICENSE → LICENSE.txt} +1 -1
- data/README.md +29 -90
- data/Rakefile +34 -32
- data/VERSION +1 -1
- data/fathom.gemspec +105 -0
- data/features/fathom.feature +26 -0
- data/features/step_definitions/fathom_steps.rb +23 -0
- data/features/support/env.rb +13 -0
- data/lib/ext/array.rb +6 -2
- data/lib/ext/string.rb +86 -7
- data/lib/fathom.rb +51 -88
- data/lib/fathom/behaviors/attribute_system.rb +91 -0
- data/lib/fathom/behaviors/context_behavior.rb +28 -0
- data/lib/fathom/behaviors/plugins.rb +16 -0
- data/lib/fathom/contexts/network_population.rb +47 -0
- data/lib/fathom/contexts/network_traversal.rb +4 -0
- data/lib/fathom/data/adjacency_matrix.rb +27 -0
- data/lib/fathom/data/definition.rb +22 -0
- data/lib/fathom/data/edge.rb +58 -0
- data/lib/fathom/data/network.rb +35 -0
- data/lib/fathom/data/outcome.rb +30 -0
- data/lib/fathom/data/property.rb +31 -0
- data/lib/fathom/data/variable.rb +59 -0
- data/lib/fathom/roles/general_graph_tools.rb +87 -0
- data/lib/fathom/roles/network_builder.rb +61 -0
- data/spec/fathom/behaviors/attribute_system_spec.rb +141 -0
- data/spec/fathom/behaviors/context_behavior_spec.rb +15 -0
- data/spec/fathom/behaviors/plugins_spec.rb +80 -0
- data/spec/fathom/contexts/network_population_spec.rb +55 -0
- data/spec/fathom/contexts/network_traversal_spec.rb +11 -0
- data/spec/fathom/data/adjacency_matrix_spec.rb +42 -0
- data/spec/fathom/data/definition_spec.rb +19 -0
- data/spec/fathom/data/edge_spec.rb +77 -0
- data/spec/fathom/data/network_spec.rb +72 -0
- data/spec/fathom/data/outcome_spec.rb +17 -0
- data/spec/fathom/data/property_spec.rb +17 -0
- data/spec/fathom/data/variable_spec.rb +101 -0
- data/spec/fathom/ext/array_spec.rb +17 -0
- data/spec/fathom/ext/string_spec.rb +90 -0
- data/spec/fathom/roles/general_graph_tools_spec.rb +95 -0
- data/spec/fathom/roles/network_builder_spec.rb +90 -0
- data/spec/fathom_spec.rb +28 -49
- data/spec/spec_helper.rb +7 -11
- data/spec/support/context_behavior.rb +14 -0
- data/spec/support/custom_matchers.rb +12 -0
- data/spec/support/files.rb +8 -0
- data/spec/support/network.yml +42 -0
- metadata +133 -174
- data/.bundle/config +0 -2
- data/.gitignore +0 -6
- data/Gemfile.lock +0 -42
- data/TODO.md +0 -127
- data/autotest/discover.rb +0 -1
- data/lib/ext/faster_csv.rb +0 -1
- data/lib/ext/open_struct.rb +0 -17
- data/lib/fathom/agent.rb +0 -48
- data/lib/fathom/agent/agent_cluster.rb +0 -23
- data/lib/fathom/agent/properties.rb +0 -48
- data/lib/fathom/archive/causal_graph.rb +0 -12
- data/lib/fathom/archive/concept.rb +0 -83
- data/lib/fathom/archive/conditional_probability_matrix.rb +0 -119
- data/lib/fathom/archive/inverter.rb +0 -20
- data/lib/fathom/archive/n2.rb +0 -198
- data/lib/fathom/archive/n3.rb +0 -119
- data/lib/fathom/archive/node.rb +0 -97
- data/lib/fathom/archive/noodle.rb +0 -136
- data/lib/fathom/archive/scratch.rb +0 -45
- data/lib/fathom/distributions.rb +0 -8
- data/lib/fathom/distributions/discrete_gaussian.rb +0 -44
- data/lib/fathom/distributions/discrete_uniform.rb +0 -25
- data/lib/fathom/distributions/gaussian.rb +0 -46
- data/lib/fathom/distributions/uniform.rb +0 -35
- data/lib/fathom/import.rb +0 -85
- data/lib/fathom/import/csv_import.rb +0 -59
- data/lib/fathom/import/import_node.rb +0 -17
- data/lib/fathom/import/yaml_import.rb +0 -74
- data/lib/fathom/knowledge_base.rb +0 -46
- data/lib/fathom/knowledge_base/search.rb +0 -19
- data/lib/fathom/monte_carlo_set.rb +0 -152
- data/lib/fathom/node.rb +0 -139
- data/lib/fathom/node/belief_node.rb +0 -121
- data/lib/fathom/node/cpm_node.rb +0 -100
- data/lib/fathom/node/data_collection.rb +0 -97
- data/lib/fathom/node/data_node.rb +0 -22
- data/lib/fathom/node/decision.rb +0 -11
- data/lib/fathom/node/discrete_node.rb +0 -41
- data/lib/fathom/node/fact.rb +0 -24
- data/lib/fathom/node/mc_node.rb +0 -70
- data/lib/fathom/node/node_extensions/enforced_name.rb +0 -12
- data/lib/fathom/node/node_extensions/numeric_methods.rb +0 -68
- data/lib/fathom/node/plausible_range.rb +0 -98
- data/lib/fathom/simulation.rb +0 -59
- data/lib/fathom/simulation/tick_methods.rb +0 -25
- data/lib/fathom/simulation/tick_simulation.rb +0 -12
- data/lib/fathom/value_description.rb +0 -79
- data/lib/options_hash.rb +0 -186
- data/spec/ext/array_spec.rb +0 -10
- data/spec/ext/faster_csv_spec.rb +0 -10
- data/spec/ext/open_struct_spec.rb +0 -20
- data/spec/ext/string_spec.rb +0 -7
- data/spec/fathom/agent/agent_cluster_spec.rb +0 -17
- data/spec/fathom/agent_spec.rb +0 -51
- data/spec/fathom/distributions/discrete_gaussian_spec.rb +0 -64
- data/spec/fathom/distributions/discrete_uniform_spec.rb +0 -0
- data/spec/fathom/distributions/gaussian_spec.rb +0 -64
- data/spec/fathom/distributions/uniform_spec.rb +0 -0
- data/spec/fathom/import/csv_import_spec.rb +0 -52
- data/spec/fathom/import/import_node_spec.rb +0 -10
- data/spec/fathom/import/yaml_import_spec.rb +0 -73
- data/spec/fathom/import_spec.rb +0 -36
- data/spec/fathom/knowledge_base_spec.rb +0 -20
- data/spec/fathom/monte_carlo_set_spec.rb +0 -149
- data/spec/fathom/node/belief_node_spec.rb +0 -180
- data/spec/fathom/node/cpm_node_spec.rb +0 -144
- data/spec/fathom/node/data_collection_spec.rb +0 -26
- data/spec/fathom/node/data_node_spec.rb +0 -102
- data/spec/fathom/node/decision_spec.rb +0 -15
- data/spec/fathom/node/discrete_node_spec.rb +0 -56
- data/spec/fathom/node/fact_spec.rb +0 -33
- data/spec/fathom/node/mc_node_spec.rb +0 -66
- data/spec/fathom/node/node_extensions/enforced_name_spec.rb +0 -15
- data/spec/fathom/node/node_extensions/numeric_methods_spec.rb +0 -124
- data/spec/fathom/node/plausible_range_spec.rb +0 -151
- data/spec/fathom/node_spec.rb +0 -172
- data/spec/fathom/simulation/tick_simulation_spec.rb +0 -32
- data/spec/fathom/simulation_spec.rb +0 -24
- data/spec/fathom/value_description_spec.rb +0 -70
- data/spec/support/demo.yml +0 -17
- data/spec/support/demo_agent.rb +0 -8
- data/spec/support/dummy_numeric_node.rb +0 -8
- data/spec/support/fact.yml +0 -11
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'fathom'))
|
|
2
|
-
|
|
3
|
-
=begin
|
|
4
|
-
A DataNode is a node generated from data itself. It stores the data and reveals some statistical
|
|
5
|
-
measurements for the data. It expects an array or vector of values and generates a vector on demans.
|
|
6
|
-
=end
|
|
7
|
-
class Fathom::DataNode < Fathom::Node
|
|
8
|
-
|
|
9
|
-
include Fathom::NumericMethods
|
|
10
|
-
|
|
11
|
-
def initialize(opts={})
|
|
12
|
-
super(opts)
|
|
13
|
-
raise ArgumentError, "Must provided values: DataNode.new(:values => [...])" unless self.values
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
if __FILE__ == $0
|
|
19
|
-
include Fathom
|
|
20
|
-
# TODO: Is there anything you want to do to run this file on its own?
|
|
21
|
-
# DataNode.new
|
|
22
|
-
end
|
data/lib/fathom/node/decision.rb
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'fathom'))
|
|
2
|
-
class Fathom::Decision < Fathom::Node
|
|
3
|
-
undef_method :values
|
|
4
|
-
undef_method :distribution
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
if __FILE__ == $0
|
|
8
|
-
include Fathom
|
|
9
|
-
# TODO: Is there anything you want to do to run this file on its own?
|
|
10
|
-
# Decision.new
|
|
11
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'fathom'))
|
|
2
|
-
class Fathom::DiscreteNode < Fathom::Node
|
|
3
|
-
attr_reader :labels
|
|
4
|
-
|
|
5
|
-
def initialize(opts={})
|
|
6
|
-
opts[:distribution] ||= :discrete_uniform
|
|
7
|
-
super(opts)
|
|
8
|
-
assert_labels(opts)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def size
|
|
12
|
-
@size ||= self.labels.length
|
|
13
|
-
end
|
|
14
|
-
alias :length :size
|
|
15
|
-
|
|
16
|
-
def rand
|
|
17
|
-
self.labels[self.distribution.rand(self.size)]
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# This makes it easier to interface to a belief node
|
|
21
|
-
def likelihood(ignored_value)
|
|
22
|
-
GSL::Vector.ary_to_gv(Array.new(self.size, 1))
|
|
23
|
-
end
|
|
24
|
-
alias :l :likelihood
|
|
25
|
-
|
|
26
|
-
protected
|
|
27
|
-
def assert_labels(opts)
|
|
28
|
-
@labels = opts[:labels]
|
|
29
|
-
@labels ||= self.values
|
|
30
|
-
@labels ||= [:true, :false]
|
|
31
|
-
@labels = Array[@labels] unless @labels.is_a?(Array)
|
|
32
|
-
@labels.uniq!
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
if __FILE__ == $0
|
|
38
|
-
include Fathom
|
|
39
|
-
# TODO: Is there anything you want to do to run this file on its own?
|
|
40
|
-
# DiscreteNode.new
|
|
41
|
-
end
|
data/lib/fathom/node/fact.rb
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'fathom'))
|
|
2
|
-
class Fathom::Fact < Fathom::Node
|
|
3
|
-
|
|
4
|
-
attr_reader :value
|
|
5
|
-
|
|
6
|
-
def initialize(opts={})
|
|
7
|
-
symbolize_keys!(opts)
|
|
8
|
-
@value = opts[:value]
|
|
9
|
-
@value ||= opts[:values]
|
|
10
|
-
super(opts)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
alias :rand :value
|
|
14
|
-
|
|
15
|
-
undef_method :values
|
|
16
|
-
undef_method :distribution
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
if __FILE__ == $0
|
|
21
|
-
include Fathom
|
|
22
|
-
# TODO: Is there anything you want to do to run this file on its own?
|
|
23
|
-
# Fact.new
|
|
24
|
-
end
|
data/lib/fathom/node/mc_node.rb
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'fathom'))
|
|
2
|
-
class Fathom::MCNode < Fathom::Node
|
|
3
|
-
|
|
4
|
-
attr_reader :samples_taken
|
|
5
|
-
attr_accessor :value_description
|
|
6
|
-
|
|
7
|
-
def initialize(opts={}, &block)
|
|
8
|
-
super(opts)
|
|
9
|
-
@value_description = opts[:value_description]
|
|
10
|
-
@value_description ||= block if block_given?
|
|
11
|
-
raise ArgumentError, "Must provide a value_description from either a parameter or by passing in a block" unless
|
|
12
|
-
@value_description
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def process(n=10_000)
|
|
16
|
-
@samples_taken, @samples = n, {}
|
|
17
|
-
@samples_taken.times do
|
|
18
|
-
result = value_description.call(self)
|
|
19
|
-
store(result)
|
|
20
|
-
end
|
|
21
|
-
assert_nodes
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def reset!
|
|
25
|
-
@samples_taken, @samples = nil, {}
|
|
26
|
-
@samples_asserted = false
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def fields
|
|
30
|
-
self.children.map {|c| c.name_sym}.compact
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
protected
|
|
34
|
-
|
|
35
|
-
def store(result)
|
|
36
|
-
result = assert_result_hash(result)
|
|
37
|
-
assert_samples(result)
|
|
38
|
-
result.each do |key, value|
|
|
39
|
-
@samples[key.to_sym] << value
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def assert_samples(result)
|
|
44
|
-
return true if @samples_asserted
|
|
45
|
-
result.each do |k, v|
|
|
46
|
-
@samples[k.to_sym] ||= []
|
|
47
|
-
end
|
|
48
|
-
@samples_asserted = true
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def assert_result_hash(result)
|
|
52
|
-
result.is_a?(Hash) ? result : {:result => result}
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# Assumes the same value description for all samples taken
|
|
56
|
-
def assert_nodes
|
|
57
|
-
@samples.each do |key, values|
|
|
58
|
-
node = Fathom::DataNode.new(:name => key, :values => values)
|
|
59
|
-
add_child(node)
|
|
60
|
-
# self.class.define_summary_method(key)
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
if __FILE__ == $0
|
|
67
|
-
include Fathom
|
|
68
|
-
# TODO: Is there anything you want to do to run this file on its own?
|
|
69
|
-
# MCNode.new
|
|
70
|
-
end
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'fathom'))
|
|
2
|
-
module Fathom
|
|
3
|
-
module NumericMethods
|
|
4
|
-
def initialize(opts={})
|
|
5
|
-
super(opts)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def rand
|
|
9
|
-
return nil unless vector
|
|
10
|
-
distribution.rand(sd) + mean
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def vector
|
|
14
|
-
return @vector if @vector
|
|
15
|
-
return nil unless values
|
|
16
|
-
case values
|
|
17
|
-
when Array
|
|
18
|
-
@vector = GSL::Vector.ary_to_gv(values)
|
|
19
|
-
when GSL::Vector
|
|
20
|
-
@vector = values
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def standard_deviation
|
|
25
|
-
return nil unless vector
|
|
26
|
-
vector.sd
|
|
27
|
-
end
|
|
28
|
-
alias :std :standard_deviation
|
|
29
|
-
alias :sd :standard_deviation
|
|
30
|
-
|
|
31
|
-
def mean
|
|
32
|
-
return nil unless vector
|
|
33
|
-
vector.mean
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def inverse_cdf(opts={})
|
|
37
|
-
distribution.inverse_cdf(opts.merge(:mean => mean, :sd => sd))
|
|
38
|
-
end
|
|
39
|
-
alias :lower_bound :inverse_cdf
|
|
40
|
-
|
|
41
|
-
def upper_bound(opts={})
|
|
42
|
-
distribution.upper_bound(opts.merge(:mean => mean, :sd => sd))
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def interval_values(opts={})
|
|
46
|
-
distribution.interval_values(opts.merge(:mean => mean, :sd => sd))
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def coefficient_of_variation
|
|
50
|
-
return nil unless vector
|
|
51
|
-
vector.sd / vector.mean
|
|
52
|
-
end
|
|
53
|
-
alias :cov :coefficient_of_variation
|
|
54
|
-
|
|
55
|
-
def summary
|
|
56
|
-
{
|
|
57
|
-
:mean => mean,
|
|
58
|
-
:standard_deviation => standard_deviation,
|
|
59
|
-
:min => vector ? vector.min : nil,
|
|
60
|
-
:max => vector ? vector.max : nil,
|
|
61
|
-
:lower_bound => lower_bound,
|
|
62
|
-
:upper_bound => upper_bound,
|
|
63
|
-
:coefficient_of_variation => coefficient_of_variation
|
|
64
|
-
}
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
end
|
|
68
|
-
end
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'fathom'))
|
|
2
|
-
module Fathom
|
|
3
|
-
class PlausibleRange < Fathom::Node
|
|
4
|
-
|
|
5
|
-
include NumericMethods
|
|
6
|
-
|
|
7
|
-
attr_reader :upper_bound, :lower_bound, :confidence_interval, :hard_lower_bound, :hard_upper_bound
|
|
8
|
-
|
|
9
|
-
def initialize(opts={})
|
|
10
|
-
super(opts)
|
|
11
|
-
|
|
12
|
-
opts = OptionsHash.new(opts)
|
|
13
|
-
|
|
14
|
-
@hard_upper_bound = opts[:hard_upper_bound]
|
|
15
|
-
@upper_bound = opts[:upper_bound]
|
|
16
|
-
@upper_bound ||= opts[:max]
|
|
17
|
-
@upper_bound ||= @hard_upper_bound
|
|
18
|
-
@upper_bound = @hard_upper_bound if @upper_bound and @hard_upper_bound and @hard_upper_bound < @upper_bound
|
|
19
|
-
raise ArgumentError, "Must provide an upper bound." unless @upper_bound
|
|
20
|
-
|
|
21
|
-
@hard_lower_bound = opts[:hard_lower_bound]
|
|
22
|
-
@lower_bound = opts[:lower_bound]
|
|
23
|
-
@lower_bound ||= opts[:min]
|
|
24
|
-
@lower_bound ||= @hard_lower_bound
|
|
25
|
-
@lower_bound = @hard_lower_bound if @lower_bound and @hard_lower_bound and @hard_lower_bound > @lower_bound
|
|
26
|
-
raise ArgumentError, "Must provide a lower bound." unless @lower_bound
|
|
27
|
-
|
|
28
|
-
@confidence_interval = opts[:confidence_interval]
|
|
29
|
-
@confidence_interval ||= opts[:ci]
|
|
30
|
-
@confidence_interval ||= 0.9
|
|
31
|
-
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
alias :min :lower_bound
|
|
35
|
-
alias :max :upper_bound
|
|
36
|
-
alias :ci :confidence_interval
|
|
37
|
-
|
|
38
|
-
def midpoint
|
|
39
|
-
@midpoint ||= lower_bound + (range / 2.0)
|
|
40
|
-
end
|
|
41
|
-
alias :mean :midpoint
|
|
42
|
-
|
|
43
|
-
def range
|
|
44
|
-
@range ||= upper_bound - lower_bound
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def standard_deviation
|
|
48
|
-
@standard_deviation ||= range / distribution.standard_deviations_under(confidence_interval)
|
|
49
|
-
end
|
|
50
|
-
alias :std :standard_deviation
|
|
51
|
-
alias :sd :standard_deviation
|
|
52
|
-
|
|
53
|
-
def rand
|
|
54
|
-
value = get_rand
|
|
55
|
-
until is_bounded?(value) do
|
|
56
|
-
value = get_rand
|
|
57
|
-
end
|
|
58
|
-
value
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def array_of_random_values(n=10)
|
|
62
|
-
n.times.map {self.rand}
|
|
63
|
-
end
|
|
64
|
-
alias :to_a :array_of_random_values
|
|
65
|
-
|
|
66
|
-
def vector_of_random_values(n=10)
|
|
67
|
-
GSL::Vector.alloc(array_of_random_values(n))
|
|
68
|
-
end
|
|
69
|
-
alias :to_v :vector_of_random_values
|
|
70
|
-
|
|
71
|
-
protected
|
|
72
|
-
|
|
73
|
-
def is_bounded?(value)
|
|
74
|
-
return true unless hard_lower_bound or hard_upper_bound
|
|
75
|
-
if hard_lower_bound and hard_upper_bound
|
|
76
|
-
value >= hard_lower_bound and value <= hard_upper_bound
|
|
77
|
-
elsif hard_lower_bound
|
|
78
|
-
value >= hard_lower_bound
|
|
79
|
-
elsif hard_upper_bound
|
|
80
|
-
value <= hard_upper_bound
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Uses the distribution system, but doesn't use a vector to determine the sd, mean, etc.
|
|
85
|
-
# So keeping this part in-house.
|
|
86
|
-
def get_rand
|
|
87
|
-
distribution.rand(sd) + mean
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
if __FILE__ == $0
|
|
95
|
-
include Fathom
|
|
96
|
-
# TODO: Is there anything you want to do to run this file on its own?
|
|
97
|
-
# PlausibleRange.new
|
|
98
|
-
end
|
data/lib/fathom/simulation.rb
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'fathom'))
|
|
2
|
-
class Fathom::Simulation
|
|
3
|
-
|
|
4
|
-
class << self
|
|
5
|
-
|
|
6
|
-
# Expects a symbol for the callback to define on the simulation.
|
|
7
|
-
def define_callback_accessor(callback, obj)
|
|
8
|
-
call_method = callback.to_s.scan(/^on_(\w+)/).flatten.compact.first
|
|
9
|
-
raise ArgumentError, "Callback doesn't appear to be a callback: #{callback}" unless call_method
|
|
10
|
-
return true if self.respond_to?(call_method)
|
|
11
|
-
define_method(call_method) do
|
|
12
|
-
callbacks[callback].each do |agent|
|
|
13
|
-
agent.send(callback, obj)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
agent_lookup_method = "agents_using_#{call_method}".to_sym
|
|
18
|
-
return true if self.respond_to?(agent_lookup_method)
|
|
19
|
-
define_method(agent_lookup_method) do
|
|
20
|
-
callbacks[callback]
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
attr_reader :agents
|
|
27
|
-
|
|
28
|
-
def initialize(*agents)
|
|
29
|
-
@agents = agents
|
|
30
|
-
assert_callbacks
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def callbacks
|
|
34
|
-
@callbacks ||= {}
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
protected
|
|
38
|
-
def assert_callbacks
|
|
39
|
-
self.agents.each do |agent|
|
|
40
|
-
assert_agent(agent)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def assert_agent(agent)
|
|
45
|
-
return false unless agent.respond_to?(:callbacks)
|
|
46
|
-
agent.callbacks.each do |callback|
|
|
47
|
-
callback_sym = callback.to_sym
|
|
48
|
-
self.callbacks[callback_sym] ||= []
|
|
49
|
-
self.callbacks[callback_sym] << agent
|
|
50
|
-
self.class.define_callback_accessor(callback_sym, self)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
if __FILE__ == $0
|
|
56
|
-
include Fathom
|
|
57
|
-
# TODO: Is there anything you want to do to run this file on its own?
|
|
58
|
-
# Simulation.new
|
|
59
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'fathom'))
|
|
2
|
-
module Fathom
|
|
3
|
-
module TickMethods
|
|
4
|
-
def initialize(*agents)
|
|
5
|
-
super(*agents)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
attr_reader :ticks_designed, :ticks_executed
|
|
9
|
-
|
|
10
|
-
def process(n)
|
|
11
|
-
@ticks_designed = n
|
|
12
|
-
@ticks_executed = 0
|
|
13
|
-
n.times do
|
|
14
|
-
self.tick(self)
|
|
15
|
-
@ticks_executed += 1
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
if __FILE__ == $0
|
|
22
|
-
include Fathom
|
|
23
|
-
# TODO: Is there anything you want to do to run this file on its own?
|
|
24
|
-
# TicksSimulation.new
|
|
25
|
-
end
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'fathom'))
|
|
2
|
-
module Fathom
|
|
3
|
-
class TickSimulation < Simulation
|
|
4
|
-
include TickMethods
|
|
5
|
-
end
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
if __FILE__ == $0
|
|
9
|
-
include Fathom
|
|
10
|
-
# TODO: Is there anything you want to do to run this file on its own?
|
|
11
|
-
# TickSimulator.new
|
|
12
|
-
end
|