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.
Files changed (134) hide show
  1. data/.autotest +7 -5
  2. data/.document +2 -2
  3. data/Gemfile +9 -10
  4. data/{LICENSE → LICENSE.txt} +1 -1
  5. data/README.md +29 -90
  6. data/Rakefile +34 -32
  7. data/VERSION +1 -1
  8. data/fathom.gemspec +105 -0
  9. data/features/fathom.feature +26 -0
  10. data/features/step_definitions/fathom_steps.rb +23 -0
  11. data/features/support/env.rb +13 -0
  12. data/lib/ext/array.rb +6 -2
  13. data/lib/ext/string.rb +86 -7
  14. data/lib/fathom.rb +51 -88
  15. data/lib/fathom/behaviors/attribute_system.rb +91 -0
  16. data/lib/fathom/behaviors/context_behavior.rb +28 -0
  17. data/lib/fathom/behaviors/plugins.rb +16 -0
  18. data/lib/fathom/contexts/network_population.rb +47 -0
  19. data/lib/fathom/contexts/network_traversal.rb +4 -0
  20. data/lib/fathom/data/adjacency_matrix.rb +27 -0
  21. data/lib/fathom/data/definition.rb +22 -0
  22. data/lib/fathom/data/edge.rb +58 -0
  23. data/lib/fathom/data/network.rb +35 -0
  24. data/lib/fathom/data/outcome.rb +30 -0
  25. data/lib/fathom/data/property.rb +31 -0
  26. data/lib/fathom/data/variable.rb +59 -0
  27. data/lib/fathom/roles/general_graph_tools.rb +87 -0
  28. data/lib/fathom/roles/network_builder.rb +61 -0
  29. data/spec/fathom/behaviors/attribute_system_spec.rb +141 -0
  30. data/spec/fathom/behaviors/context_behavior_spec.rb +15 -0
  31. data/spec/fathom/behaviors/plugins_spec.rb +80 -0
  32. data/spec/fathom/contexts/network_population_spec.rb +55 -0
  33. data/spec/fathom/contexts/network_traversal_spec.rb +11 -0
  34. data/spec/fathom/data/adjacency_matrix_spec.rb +42 -0
  35. data/spec/fathom/data/definition_spec.rb +19 -0
  36. data/spec/fathom/data/edge_spec.rb +77 -0
  37. data/spec/fathom/data/network_spec.rb +72 -0
  38. data/spec/fathom/data/outcome_spec.rb +17 -0
  39. data/spec/fathom/data/property_spec.rb +17 -0
  40. data/spec/fathom/data/variable_spec.rb +101 -0
  41. data/spec/fathom/ext/array_spec.rb +17 -0
  42. data/spec/fathom/ext/string_spec.rb +90 -0
  43. data/spec/fathom/roles/general_graph_tools_spec.rb +95 -0
  44. data/spec/fathom/roles/network_builder_spec.rb +90 -0
  45. data/spec/fathom_spec.rb +28 -49
  46. data/spec/spec_helper.rb +7 -11
  47. data/spec/support/context_behavior.rb +14 -0
  48. data/spec/support/custom_matchers.rb +12 -0
  49. data/spec/support/files.rb +8 -0
  50. data/spec/support/network.yml +42 -0
  51. metadata +133 -174
  52. data/.bundle/config +0 -2
  53. data/.gitignore +0 -6
  54. data/Gemfile.lock +0 -42
  55. data/TODO.md +0 -127
  56. data/autotest/discover.rb +0 -1
  57. data/lib/ext/faster_csv.rb +0 -1
  58. data/lib/ext/open_struct.rb +0 -17
  59. data/lib/fathom/agent.rb +0 -48
  60. data/lib/fathom/agent/agent_cluster.rb +0 -23
  61. data/lib/fathom/agent/properties.rb +0 -48
  62. data/lib/fathom/archive/causal_graph.rb +0 -12
  63. data/lib/fathom/archive/concept.rb +0 -83
  64. data/lib/fathom/archive/conditional_probability_matrix.rb +0 -119
  65. data/lib/fathom/archive/inverter.rb +0 -20
  66. data/lib/fathom/archive/n2.rb +0 -198
  67. data/lib/fathom/archive/n3.rb +0 -119
  68. data/lib/fathom/archive/node.rb +0 -97
  69. data/lib/fathom/archive/noodle.rb +0 -136
  70. data/lib/fathom/archive/scratch.rb +0 -45
  71. data/lib/fathom/distributions.rb +0 -8
  72. data/lib/fathom/distributions/discrete_gaussian.rb +0 -44
  73. data/lib/fathom/distributions/discrete_uniform.rb +0 -25
  74. data/lib/fathom/distributions/gaussian.rb +0 -46
  75. data/lib/fathom/distributions/uniform.rb +0 -35
  76. data/lib/fathom/import.rb +0 -85
  77. data/lib/fathom/import/csv_import.rb +0 -59
  78. data/lib/fathom/import/import_node.rb +0 -17
  79. data/lib/fathom/import/yaml_import.rb +0 -74
  80. data/lib/fathom/knowledge_base.rb +0 -46
  81. data/lib/fathom/knowledge_base/search.rb +0 -19
  82. data/lib/fathom/monte_carlo_set.rb +0 -152
  83. data/lib/fathom/node.rb +0 -139
  84. data/lib/fathom/node/belief_node.rb +0 -121
  85. data/lib/fathom/node/cpm_node.rb +0 -100
  86. data/lib/fathom/node/data_collection.rb +0 -97
  87. data/lib/fathom/node/data_node.rb +0 -22
  88. data/lib/fathom/node/decision.rb +0 -11
  89. data/lib/fathom/node/discrete_node.rb +0 -41
  90. data/lib/fathom/node/fact.rb +0 -24
  91. data/lib/fathom/node/mc_node.rb +0 -70
  92. data/lib/fathom/node/node_extensions/enforced_name.rb +0 -12
  93. data/lib/fathom/node/node_extensions/numeric_methods.rb +0 -68
  94. data/lib/fathom/node/plausible_range.rb +0 -98
  95. data/lib/fathom/simulation.rb +0 -59
  96. data/lib/fathom/simulation/tick_methods.rb +0 -25
  97. data/lib/fathom/simulation/tick_simulation.rb +0 -12
  98. data/lib/fathom/value_description.rb +0 -79
  99. data/lib/options_hash.rb +0 -186
  100. data/spec/ext/array_spec.rb +0 -10
  101. data/spec/ext/faster_csv_spec.rb +0 -10
  102. data/spec/ext/open_struct_spec.rb +0 -20
  103. data/spec/ext/string_spec.rb +0 -7
  104. data/spec/fathom/agent/agent_cluster_spec.rb +0 -17
  105. data/spec/fathom/agent_spec.rb +0 -51
  106. data/spec/fathom/distributions/discrete_gaussian_spec.rb +0 -64
  107. data/spec/fathom/distributions/discrete_uniform_spec.rb +0 -0
  108. data/spec/fathom/distributions/gaussian_spec.rb +0 -64
  109. data/spec/fathom/distributions/uniform_spec.rb +0 -0
  110. data/spec/fathom/import/csv_import_spec.rb +0 -52
  111. data/spec/fathom/import/import_node_spec.rb +0 -10
  112. data/spec/fathom/import/yaml_import_spec.rb +0 -73
  113. data/spec/fathom/import_spec.rb +0 -36
  114. data/spec/fathom/knowledge_base_spec.rb +0 -20
  115. data/spec/fathom/monte_carlo_set_spec.rb +0 -149
  116. data/spec/fathom/node/belief_node_spec.rb +0 -180
  117. data/spec/fathom/node/cpm_node_spec.rb +0 -144
  118. data/spec/fathom/node/data_collection_spec.rb +0 -26
  119. data/spec/fathom/node/data_node_spec.rb +0 -102
  120. data/spec/fathom/node/decision_spec.rb +0 -15
  121. data/spec/fathom/node/discrete_node_spec.rb +0 -56
  122. data/spec/fathom/node/fact_spec.rb +0 -33
  123. data/spec/fathom/node/mc_node_spec.rb +0 -66
  124. data/spec/fathom/node/node_extensions/enforced_name_spec.rb +0 -15
  125. data/spec/fathom/node/node_extensions/numeric_methods_spec.rb +0 -124
  126. data/spec/fathom/node/plausible_range_spec.rb +0 -151
  127. data/spec/fathom/node_spec.rb +0 -172
  128. data/spec/fathom/simulation/tick_simulation_spec.rb +0 -32
  129. data/spec/fathom/simulation_spec.rb +0 -24
  130. data/spec/fathom/value_description_spec.rb +0 -70
  131. data/spec/support/demo.yml +0 -17
  132. data/spec/support/demo_agent.rb +0 -8
  133. data/spec/support/dummy_numeric_node.rb +0 -8
  134. data/spec/support/fact.yml +0 -11
@@ -1,144 +0,0 @@
1
- require File.expand_path('../../../spec_helper', __FILE__)
2
-
3
- describe CPMNode do
4
-
5
- before do
6
- @child = BeliefNode.new(:name => :color, :values => {:red => 0.4, :green => 0.6})
7
- @parent = BeliefNode.new(:name => :child, :values => {:asher => 0.2, :stella => 0.8})
8
- @cpm = CPMNode.new(:child => @child, :parent => @parent)
9
- end
10
-
11
- it "should subclass Node" do
12
- CPMNode.ancestors[1].should eql(Node)
13
- end
14
-
15
- it "should allow a BeliefNode child and parent" do
16
- @cpm.parent.should eql(@parent)
17
- @cpm.child.should eql(@child)
18
- end
19
-
20
- it "should generate a conditional probability matrix from the parent and child" do
21
- parent_values = @cpm.parent.probabilities.col
22
- child_values = @cpm.child.probabilities
23
- matrix = parent_values * child_values
24
- @cpm.values.to_a.should eql(matrix.to_a)
25
- end
26
-
27
- it "should alias the values with matrix" do
28
- @cpm.values.should eql(@cpm.matrix)
29
- end
30
-
31
- it "should raise an error when trying to load non-BeliefNode parent or child" do
32
- lambda{CPMNode.new(:child => :not_a_belief_node, :parent => @parent)}.should raise_error(/must be a BeliefNode/)
33
- lambda{CPMNode.new(:child => @child, :parent => :not_a_belief_node)}.should raise_error(/must be a BeliefNode/)
34
- end
35
-
36
- it "should have a probability lookup" do
37
- @cpm.should be_respond_to(:probability)
38
- end
39
-
40
- it "should only allow options for the parent and child names" do
41
- lambda{@cpm.probability :not_a_link => true}.should raise_error(/unknown/i)
42
- end
43
-
44
- it "should be able to lookup the values we're looking for" do
45
- # The Matrix looks like this:
46
- # GSL::Matrix
47
- # [ 8.000e-02 1.200e-01
48
- # 3.200e-01 4.800e-01 ]
49
- @cpm.probability(:color => :red, :child => :asher).should be_within(1e-10).of(0.08)
50
- @cpm.probability(:color => :red, :child => :stella).should be_within(1e-10).of(0.32)
51
- @cpm.probability(:color => :green, :child => :asher).should be_within(1e-10).of(0.12)
52
- @cpm.probability(:color => :green, :child => :stella).should be_within(1e-10).of(0.48)
53
- end
54
-
55
- it "should look for all children values, if no child is provided" do
56
- @cpm.probability(:child => :asher).should be_within(1e-10).of(0.2)
57
- @cpm.probability(:child => :stella).should be_within(1e-10).of(0.8)
58
- end
59
-
60
- it "should look for all parent values, if no parent is provided" do
61
- @cpm.probability(:color => :red).should be_within(1e-10).of(0.4)
62
- @cpm.probability(:color => :green).should be_within(1e-10).of(0.6)
63
- end
64
-
65
- it "should provide a probability of 1 if no filter is set" do
66
- @cpm.probability.should be_within(1e-10).of(1.0)
67
- end
68
-
69
- it "should give a description in a hash, if description is turned on" do
70
- @cpm.probability(:color => :red, :child => :asher, :describe => true).keys.first.should eql('P(red | asher)')
71
- @cpm.probability(:color => :red, :child => :stella, :describe => true).keys.first.should eql('P(red | stella)')
72
- @cpm.probability(:color => :green, :child => :asher, :describe => true).keys.first.should eql('P(green | asher)')
73
- @cpm.probability(:color => :green, :child => :stella, :describe => true).keys.first.should eql('P(green | stella)')
74
- @cpm.probability(:child => :asher, :describe => true).keys.first.should eql('P(red or green | asher)')
75
- @cpm.probability(:child => :stella, :describe => true).keys.first.should eql('P(red or green | stella)')
76
- @cpm.probability(:color => :red, :describe => true).keys.first.should eql('P(red | asher or stella)')
77
- @cpm.probability(:color => :green, :describe => true).keys.first.should eql('P(green | asher or stella)')
78
- @cpm.probability(:describe => true).keys.first.should eql('P(red or green | asher or stella)')
79
- end
80
-
81
- it "should alias p for probability" do
82
- @cpm.p(:color => :red, :child => :asher).should be_within(1e-10).of(0.08)
83
- @cpm.p(:color => :red, :child => :stella).should be_within(1e-10).of(0.32)
84
- @cpm.p(:color => :green, :child => :asher).should be_within(1e-10).of(0.12)
85
- @cpm.p(:color => :green, :child => :stella).should be_within(1e-10).of(0.48)
86
- @cpm.p(:child => :asher).should be_within(1e-10).of(0.2)
87
- @cpm.p(:child => :stella).should be_within(1e-10).of(0.8)
88
- @cpm.p(:color => :red).should be_within(1e-10).of(0.4)
89
- @cpm.p(:color => :green).should be_within(1e-10).of(0.6)
90
- @cpm.p.should be_within(1e-10).of(1.0)
91
- end
92
-
93
- it "should have odds for any query" do
94
- @cpm.odds(:color => :red, :child => :asher).should be_within(1e-3).of(0.087)
95
- @cpm.odds(:color => :red, :child => :stella).should be_within(1e-3).of(0.471)
96
- @cpm.odds(:color => :green, :child => :asher).should be_within(1e-3).of(0.136)
97
- @cpm.odds(:color => :green, :child => :stella).should be_within(1e-3).of(0.923)
98
- @cpm.odds(:child => :asher).should be_within(1e-3).of(0.25)
99
- @cpm.odds(:child => :stella).should be_within(1e-3).of(4.0)
100
- @cpm.odds(:color => :red).should be_within(1e-3).of(0.666)
101
- @cpm.odds(:color => :green).should be_within(1e-3).of(1.5)
102
- @cpm.odds.should eql(1 / 0.0)
103
- end
104
-
105
- it "should alias o for odds" do
106
- @cpm.o(:color => :red, :child => :asher).should be_within(1e-3).of(0.087)
107
- @cpm.o(:color => :red, :child => :stella).should be_within(1e-3).of(0.471)
108
- @cpm.o(:color => :green, :child => :asher).should be_within(1e-3).of(0.136)
109
- @cpm.o(:color => :green, :child => :stella).should be_within(1e-3).of(0.923)
110
- @cpm.o(:child => :asher).should be_within(1e-3).of(0.25)
111
- @cpm.o(:child => :stella).should be_within(1e-3).of(4.0)
112
- @cpm.o(:color => :red).should be_within(1e-3).of(0.666)
113
- @cpm.o(:color => :green).should be_within(1e-3).of(1.5)
114
- @cpm.o.should eql(1 / 0.0)
115
- end
116
-
117
- it "should default the name to :cpm" do
118
- @cpm.name.should eql(:cpm)
119
- end
120
-
121
- it "should default the description" do
122
- @cpm.description.should eql("Conditional Probability Matrix from child to color.")
123
- end
124
-
125
- it "should return a vector for likelihood" do
126
- @cpm.likelihood(:red).should be_a(GSL::Vector)
127
- end
128
-
129
- it "should offer the likelihood of each parent value, given a child value" do
130
- values = @cpm.likelihood(:red).to_a
131
- values.sort.map {|e| (e * 100).to_i}.should eql([8, 32])
132
-
133
- values = @cpm.likelihood(:green).to_a
134
- values.sort.map {|e| (e * 100).to_i}.should eql([12, 48])
135
- end
136
-
137
- it "should offer l as an alias for likelihood" do
138
- values = @cpm.l(:red).to_a
139
- values.sort.map {|e| (e * 100).to_i}.should eql([8, 32])
140
-
141
- values = @cpm.l(:green).to_a
142
- values.sort.map {|e| (e * 100).to_i}.should eql([12, 48])
143
- end
144
- end
@@ -1,26 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- include Fathom
4
-
5
- describe DataCollection do
6
- it "should be a node" do
7
- DataCollection.ancestors.should be_include(Node)
8
- end
9
-
10
- it "should be a DiscreteNode as well" do
11
- DataCollection.ancestors.should be_include(DiscreteNode)
12
- end
13
-
14
- it "should be able to extract the discrete labels from the first discrete parent node added to it" do
15
- pr = PlausibleRange.new(:min => 0, :max => 1)
16
- dn = DiscreteNode.new(:labels => [1,2,3])
17
- dc = DataCollection.new(:parents => [pr, dn])
18
- dc.labels.should eql([1,2,3])
19
- end
20
-
21
- it "should enforce a name" do
22
- dc = DataCollection.new(:labels => [1,2,3])
23
- dc.name.should_not be_nil
24
- end
25
-
26
- end
@@ -1,102 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- include Fathom
4
-
5
- describe DataNode do
6
-
7
- before do
8
- @values = [1,2,3,4,5]
9
- @opts = {:values => @values}
10
- @dn = DataNode.new(@opts)
11
- @vector = GSL::Vector.ary_to_gv(@values)
12
- end
13
-
14
- it "should initialize requiring values in the options" do
15
- lambda{DataNode.new}.should raise_error(/values/)
16
- lambda{DataNode.new(:values => @values)}.should_not raise_error
17
- end
18
-
19
- it "should make the values readable" do
20
- @dn.values.should eql(@values)
21
- end
22
-
23
- it "should allow an optional name for the node" do
24
- @dn = DataNode.new(:values => @values, :name => "Demo Name")
25
- @dn.name.should eql("Demo Name")
26
- end
27
-
28
- it "should take an optional distribiution" do
29
- @dn = DataNode.new(@opts.merge(:distribution => :gaussian))
30
- @dn.distribution.should eql(Fathom::Distributions::Gaussian)
31
- end
32
-
33
- it "should create a vector from the values" do
34
- @dn.vector.should ==(@vector)
35
- end
36
-
37
- it "should provide the standard deviation" do
38
- @dn.standard_deviation.should ==(@vector.sd)
39
- end
40
-
41
- it "should alias sd and std for standard_deviation" do
42
- @dn.sd.should eql(@dn.standard_deviation)
43
- @dn.std.should eql(@dn.standard_deviation)
44
- end
45
-
46
- it "should be able to produce the mean" do
47
- @dn.mean.should eql(@vector.mean)
48
- end
49
-
50
- it "should generate a random variable that fits the data's distribution" do
51
- @dn.rand.should be_a(Float)
52
- end
53
-
54
- it "should have a name_sym method" do
55
- dn = DataNode.new(:name => "Demo Node", :values => [1,2,3])
56
- dn.name_sym.should eql(:demo_node)
57
- end
58
-
59
- it "should offer the lower bounds at a default confidence level of 0.05" do
60
- GSL::Cdf.should_receive(:gaussian_Pinv).with(0.05, @dn.vector.sd).and_return(0.0)
61
- @dn.inverse_cdf
62
- end
63
-
64
- it "should offer the lower bounds at an arbitrary confidence level" do
65
- GSL::Cdf.should_receive(:gaussian_Pinv).with(0.95, @dn.vector.sd).and_return(0.0)
66
- @dn.inverse_cdf(:confidence_interval => 0.95)
67
- end
68
-
69
- it "should be able to calculate the upper bound by passing upper as a parameter" do
70
- GSL::Cdf.should_receive(:gaussian_Qinv).with(0.05, @dn.vector.sd).and_return(0.0)
71
- @dn.inverse_cdf(:confidence_interval => 0.05, :upper => true)
72
- end
73
-
74
- it "should be able to calculate a lower_bound, an alias for inverse_cdf" do
75
- GSL::Cdf.should_receive(:gaussian_Pinv).with(0.05, @dn.vector.sd).and_return(0.0)
76
- @dn.lower_bound
77
- end
78
-
79
- it "should be able to pass arguments to lower_bound" do
80
- GSL::Cdf.should_receive(:gaussian_Pinv).with(0.1, @dn.vector.sd).and_return(0.0)
81
- @dn.lower_bound(:confidence_interval => 0.1)
82
- end
83
-
84
- it "should be able to calculate an upper_bound, a shortcut for inverse_cdf(confidence_interval, false)" do
85
- GSL::Cdf.should_receive(:gaussian_Qinv).with(0.05, @dn.vector.sd).and_return(0.0)
86
- @dn.upper_bound
87
- end
88
-
89
- it "should be able to pass arguments to upper_bound" do
90
- GSL::Cdf.should_receive(:gaussian_Qinv).with(0.1, @dn.vector.sd).and_return(0.0)
91
- @dn.upper_bound(:confidence_interval => 0.1)
92
- end
93
-
94
- it "should offset the cdf results by the mean" do
95
- @dn.lower_bound.should eql(GSL::Cdf.gaussian_Pinv(0.05, @dn.vector.sd) + @dn.vector.mean)
96
- end
97
-
98
- it "should return the lower and upper bounds of a confidence interval" do
99
- @dn.interval_values.should eql([@dn.lower_bound, @dn.upper_bound])
100
- end
101
-
102
- end
@@ -1,15 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- include Fathom
4
-
5
- describe Decision do
6
- it "should be a type of node" do
7
- Decision.ancestors.should be_include(Node)
8
- end
9
-
10
- it "should not have a distribution or values" do
11
- @d = Decision.new
12
- @d.should_not be_respond_to(:distribution)
13
- @d.should_not be_respond_to(:values)
14
- end
15
- end
@@ -1,56 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- include Fathom
4
-
5
- describe DiscreteNode do
6
-
7
- before do
8
- @dn = DiscreteNode.new(:labels => [1,2,3])
9
- end
10
-
11
- it "should assign :true and :false for labels, if none are provided" do
12
- lambda{@dn = DiscreteNode.new}.should_not raise_error
13
- @dn.labels.should eql([:true, :false])
14
- end
15
-
16
- it "should create an array from a single value for its labels" do
17
- dn = DiscreteNode.new(:labels => 1)
18
- dn.labels.should eql([1])
19
- end
20
-
21
- it "should take the values and convert them to labels, if there are no labels provided" do
22
- dn = DiscreteNode.new(:values => [1,2,3])
23
- dn.labels.should eql([1,2,3])
24
- end
25
-
26
- it "should create a unique list of labels" do
27
- dn = DiscreteNode.new(:labels => [1,1,2,3,1])
28
- dn.labels.should eql([1,2,3])
29
- end
30
-
31
- it "should expose the size of the labels" do
32
- @dn.size.should eql(3)
33
- end
34
-
35
- it "should alias length for size" do
36
- @dn.length.should eql(3)
37
- end
38
-
39
- it "should have a default distribution of DiscreteUniform" do
40
- @dn.distribution.should eql(Fathom::Distributions::DiscreteUniform)
41
- end
42
-
43
- it "should be able to produce a random variable from the discrete distribution" do
44
- @dn = DiscreteNode.new(:labels => [1,2])
45
- # 9.31322574615479e-10 chance of failing
46
- 30.times.map {@dn.rand}.uniq.sort.should eql([1,2])
47
- end
48
-
49
- it "should offer a uniform likelihood" do
50
- @dn.likelihood(:anything).to_a.should eql([1.0, 1.0, 1.0])
51
- end
52
-
53
- it "should offer an alias of l for likelihood" do
54
- @dn.l(:anything).to_a.should eql([1.0, 1.0, 1.0])
55
- end
56
- end
@@ -1,33 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- include Fathom
4
-
5
- describe Fact do
6
- before do
7
- @f = Fact.new(
8
- :value => 2,
9
- :name => "Some Fact",
10
- :description => "Just a demonstration of what a good fact may look like. Facts are really about things that are certain--there are 7 days in a week, that sort of thing. Too often I was creating a PlausibleRange with the min and max to the same value."
11
- )
12
- end
13
-
14
- it "should be a Node" do
15
- Fact.ancestors.should be_include(Fathom::Node)
16
- end
17
-
18
- it "should take a value (rather than values)" do
19
- @f.value.should eql(2)
20
- end
21
-
22
- it "should return the value for rand" do
23
- @f.rand.should eql(2)
24
- end
25
-
26
- it "should have removed the distribution and values methods" do
27
- @f.should_not be_respond_to(:values)
28
- @f.should_not be_respond_to(:distribution)
29
- @n = Node.new(:distribution => :standard, :values => [1,2,3])
30
- @n.values.should eql([1,2,3])
31
- @n.distribution.should eql(Fathom::Distributions::Gaussian)
32
- end
33
- end
@@ -1,66 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- include Fathom
4
-
5
- describe MCNode do
6
-
7
- before(:all) do
8
- @fields = [:value_result]
9
- end
10
-
11
- before do
12
- @vd = lambda{|n| {:value_result => 1}}
13
- @mcn = MCNode.new(:value_description => @vd)
14
- end
15
-
16
- it "should be a type of Node" do
17
- MCNode.ancestors.should be_include(Fathom::Node)
18
- end
19
-
20
- it "should use a value_description from the command-line arguments" do
21
- mcn = MCNode.new(:value_description => @vd)
22
- mcn.value_description.should eql(@vd)
23
- end
24
-
25
- it "should be able to take a block instead of a named lambda for the value description" do
26
- mcn = MCNode.new {|n| {:value_result => 1}}
27
- mcn.value_description.should be_a(Proc)
28
- end
29
-
30
- it "should require a value_description from either a parameter or a block passed in" do
31
- lambda{MCNode.new}.should raise_error(/value_description/)
32
- end
33
-
34
- it "should process with the default number of runs at 10,000", :slow => true do
35
- lambda{@mcn.process}.should_not raise_error
36
- @mcn.samples_taken.should eql(10_000)
37
- end
38
-
39
- it "should call the value_description block each time it is processed" do
40
- @vd.should_receive(:call).exactly(3).times.with(@mcn).and_return({:value_result => 1})
41
- @mcn.process(3)
42
- end
43
-
44
- it "should define children nodes for all keys in the result set" do
45
- @mcn.process(1)
46
- @mcn.value_result.should be_a(Node)
47
- @mcn.value_result.values.should eql([1])
48
- @mcn.value_result.vector.should be_a(GSL::Vector)
49
- end
50
-
51
- it "should be resetable" do
52
- @mcn.process(1)
53
- @mcn.reset!
54
- lambda{@mcn.process(1)}.should_not raise_error
55
- end
56
-
57
- it "should expose the fields from the samples" do
58
- @mcn.process(1)
59
- sort_array_of_symbols(@mcn.fields).should eql(@fields)
60
- end
61
-
62
-
63
- end
64
- def sort_array_of_symbols(array)
65
- array.map {|e| e.to_s}.sort.map {|e| e.to_sym}
66
- end