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
data/lib/fathom/archive/n3.rb
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
class Array
|
|
2
|
-
def expand(array)
|
|
3
|
-
return array.map{|e| [e]} if self.empty?
|
|
4
|
-
array.inject([]) do |list, other_e|
|
|
5
|
-
self.each do |e|
|
|
6
|
-
list << [e,other_e].flatten
|
|
7
|
-
end
|
|
8
|
-
list
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
class Variable
|
|
14
|
-
|
|
15
|
-
attr_reader :values, :name, :observations, :total
|
|
16
|
-
|
|
17
|
-
def initialize(name, *values)
|
|
18
|
-
values = [true, false] if values.empty?
|
|
19
|
-
@name = name
|
|
20
|
-
@values = values
|
|
21
|
-
@observations = Array.new(@values.size, 0)
|
|
22
|
-
@total = 0
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# You can observe anything but nothing: we record any observation but nil.
|
|
26
|
-
# If nil is set, we use the first value as the default.
|
|
27
|
-
def observe(value=nil)
|
|
28
|
-
value = self.values.first if value.nil?
|
|
29
|
-
unless self.values.include?(value)
|
|
30
|
-
self.values << value
|
|
31
|
-
self.observations << 0
|
|
32
|
-
end
|
|
33
|
-
index = self.values.index(value)
|
|
34
|
-
self.observations[index] += 1
|
|
35
|
-
@total += 1
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Lookup observations
|
|
39
|
-
def observed(value)
|
|
40
|
-
index = self.values.index(value)
|
|
41
|
-
return 0 unless index
|
|
42
|
-
self.observations[index]
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def inspect
|
|
46
|
-
"Variable: #{self.name} #{self.values.inspect}"
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
class << self
|
|
50
|
-
def infer(obj, *values)
|
|
51
|
-
return obj if obj.is_a?(Variable)
|
|
52
|
-
case obj
|
|
53
|
-
when Symbol
|
|
54
|
-
Variable.new(obj, *values)
|
|
55
|
-
when String
|
|
56
|
-
Variable.new(obj.to_sym, *values)
|
|
57
|
-
else
|
|
58
|
-
nil
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
class Table
|
|
66
|
-
|
|
67
|
-
attr_reader :columns, :variables, :legend
|
|
68
|
-
def initialize(*variables)
|
|
69
|
-
@columns = variables.map {|v| v.name}
|
|
70
|
-
@variables = variables
|
|
71
|
-
@legend = @variables.inject([]) do |list, e|
|
|
72
|
-
list = list.expand(e)
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
protected
|
|
77
|
-
def lookup()
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
class Node
|
|
82
|
-
def initialize(name, *parents)
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# Take an array, array of arrays, dictionary, hash, or OpenStruct.
|
|
86
|
-
# Anything but an array can add a new parent to observe.
|
|
87
|
-
def observe(values)
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
require 'rubygems'
|
|
92
|
-
require 'spec'
|
|
93
|
-
|
|
94
|
-
=begin
|
|
95
|
-
variables = [[:spring, :summer, :fall, :winter], [:true, :false], [:true, :false], [:true, :false]]
|
|
96
|
-
|
|
97
|
-
@all = []
|
|
98
|
-
(0...variables.size).each do |i|
|
|
99
|
-
@all << variables.inject([]) do |list, v|
|
|
100
|
-
list << (0...v.size).map do |j|
|
|
101
|
-
variables[i][j]
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
@all
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
v1 = [:spring, :summer, :fall, :winter]
|
|
110
|
-
v2 = [:true, :false]
|
|
111
|
-
a = [v1, v2]
|
|
112
|
-
b = []
|
|
113
|
-
a.each do |e|
|
|
114
|
-
b << e
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
=end
|
data/lib/fathom/archive/node.rb
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
|
-
require 'gsl'
|
|
3
|
-
|
|
4
|
-
include GSL
|
|
5
|
-
|
|
6
|
-
class Node
|
|
7
|
-
|
|
8
|
-
attr_reader :name, :labels, :probabilities, :likelihood
|
|
9
|
-
|
|
10
|
-
def initialize(*args)
|
|
11
|
-
@name = args.shift
|
|
12
|
-
raise ArgumentError, "Must provide a node name" unless self.name
|
|
13
|
-
if args.empty?
|
|
14
|
-
extract_from_array([:true, :false])
|
|
15
|
-
elsif args.length == 1 and args.first.is_a?(Hash)
|
|
16
|
-
extract_from_hash(args.first)
|
|
17
|
-
elsif args.length == 1 and args.first.is_a?(Array)
|
|
18
|
-
extract_from_array(args.first)
|
|
19
|
-
else
|
|
20
|
-
extract_from_array(args)
|
|
21
|
-
end
|
|
22
|
-
assert_likelihood
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def inspect
|
|
26
|
-
matched_array = []
|
|
27
|
-
self.labels.each_with_index {|e, i| matched_array << e; matched_array << self.probabilities[i]}
|
|
28
|
-
"Node: #{self.name.to_s} #{self.labels.inspect} #{self.probabilities.to_a.inspect}"
|
|
29
|
-
"Node: #{self.name.to_s} #{matched_array.inspect}"
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def belief
|
|
33
|
-
probabilities * likelihood
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
alias :b :belief
|
|
37
|
-
alias :l :likelihood
|
|
38
|
-
alias :p :probabilities
|
|
39
|
-
|
|
40
|
-
def probability(label)
|
|
41
|
-
probabilities[index_for(label)]
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def inverse_probability(label)
|
|
45
|
-
1 - probability(label)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def odds(label)
|
|
49
|
-
probability(label) / inverse_probability(label)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def to_a
|
|
53
|
-
self.probabilities.to_a
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
protected
|
|
57
|
-
|
|
58
|
-
def index_for(label)
|
|
59
|
-
labels.index(label)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def assert_likelihood
|
|
63
|
-
@likelihood = Vector.ary_to_gv(Array.new(@probabilities.size, 1))
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def extract_from_array(array)
|
|
67
|
-
@labels = array
|
|
68
|
-
@probabilities = Vector.ary_to_gv(uniform_distribution(array.size))
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def uniform_distribution(n)
|
|
72
|
-
Array.new(n, 1/n.to_f)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def extract_from_hash(hash)
|
|
76
|
-
@labels, probabilities = [], []
|
|
77
|
-
hash.each do |k, v|
|
|
78
|
-
@labels << k
|
|
79
|
-
probabilities << v
|
|
80
|
-
end
|
|
81
|
-
@probabilities = Vector.ary_to_gv(probabilities)
|
|
82
|
-
normalize_probabilities!
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# I don't like GSL::Vector#normalize!, it's not accurate, or has a different
|
|
86
|
-
# idea of what a normalized vector looks like.
|
|
87
|
-
def normalize_probabilities!
|
|
88
|
-
sum = 0.0
|
|
89
|
-
@probabilities.each do |value|
|
|
90
|
-
sum += value
|
|
91
|
-
end
|
|
92
|
-
@probabilities.map! do |value|
|
|
93
|
-
value.to_f / sum
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
end
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
=begin
|
|
2
|
-
I want to noodle around a bit with basic probabilities, odds, that sort of thing. Here's the example:
|
|
3
|
-
|
|
4
|
-
Upon being awakened by the sound of a burglar alary, what is your degree of belief that a burglary attempt took place?
|
|
5
|
-
|
|
6
|
-
Supporting information:
|
|
7
|
-
|
|
8
|
-
* There is a 95% chance that an attempted burglary will trigger the alarm system, P(alarm|burglary) = 95%
|
|
9
|
-
* There is a 1% chance that the alarms will be triggered by non-burglary attempts, p(alarm|no burglary) = 1%
|
|
10
|
-
* There is a 1/10_000 chance of a particular home being burglarized, generally, P(burglary) = 10^-4
|
|
11
|
-
|
|
12
|
-
O(burglary|alarm) = L(alarm|burglary)O(burglary)
|
|
13
|
-
|
|
14
|
-
P(burglary|alarm) = O(burglary|alarm) / 1 + O(burglary|alarm)
|
|
15
|
-
|
|
16
|
-
=end
|
|
17
|
-
|
|
18
|
-
require 'mathn'
|
|
19
|
-
|
|
20
|
-
def likelihood(effect, cause)
|
|
21
|
-
effect / cause
|
|
22
|
-
end
|
|
23
|
-
alias :l :likelihood
|
|
24
|
-
|
|
25
|
-
def odds(effect, cause=nil)
|
|
26
|
-
cause ? ( likelihood(cause, effect) * odds(effect) ) : (effect / (1 - effect))
|
|
27
|
-
end
|
|
28
|
-
alias :o :odds
|
|
29
|
-
|
|
30
|
-
# The same as the odds above, but only in the case of a single hypothesis
|
|
31
|
-
def prior_odds(e)
|
|
32
|
-
e / ( 1 - e )
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def likelihood_ratio(e, h)
|
|
36
|
-
p(e,h) / p(e, 1 - h)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def probability(e, h)
|
|
40
|
-
(e * h) / h
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def product_rule(*e)
|
|
44
|
-
end
|
|
45
|
-
alias :p :probability
|
|
46
|
-
|
|
47
|
-
class Array
|
|
48
|
-
|
|
49
|
-
def givens
|
|
50
|
-
@givens ||= {}
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def give(sym, array=Array.new(self.size, 1/self.size))
|
|
54
|
-
self.givens[sym] = array
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def given(sym, index)
|
|
58
|
-
self.givens[sym][index]
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
=begin
|
|
63
|
-
Since Rational is the automatic choice for probabilistic data,
|
|
64
|
-
and since I don't want to override how mathn infers numbers,
|
|
65
|
-
I am adding some baggage to Rational:
|
|
66
|
-
|
|
67
|
-
* It still reduces to the LCD
|
|
68
|
-
* It keeps track of all events,
|
|
69
|
-
so that I can keep a new event proportional to old ones
|
|
70
|
-
* It has an add_event (add) which takes a true or false value
|
|
71
|
-
true values, records that a condition was found
|
|
72
|
-
|
|
73
|
-
This really only works for binary data, but this is a noodle file.
|
|
74
|
-
|
|
75
|
-
=end
|
|
76
|
-
class Rational < Numeric
|
|
77
|
-
class << self
|
|
78
|
-
alias :orig_reduce :reduce
|
|
79
|
-
def reduce(num, den=1)
|
|
80
|
-
val = orig_reduce(num, den)
|
|
81
|
-
val.total_events = den
|
|
82
|
-
val.positive_events = num
|
|
83
|
-
val
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def total_events(val=nil)
|
|
88
|
-
@total_events ||= 0
|
|
89
|
-
@total_events = val if val
|
|
90
|
-
@total_events
|
|
91
|
-
end
|
|
92
|
-
alias :events :total_events
|
|
93
|
-
alias :total :total_events
|
|
94
|
-
|
|
95
|
-
def total_events=(val)
|
|
96
|
-
total_events(val)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def positive_events(val=nil)
|
|
100
|
-
@positive_events ||= 0
|
|
101
|
-
@positive_events = val if val
|
|
102
|
-
@positive_events
|
|
103
|
-
end
|
|
104
|
-
alias :positive :positive_events
|
|
105
|
-
|
|
106
|
-
def positive_events=(val)
|
|
107
|
-
positive_events(val)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# Uses the Rational constructor to calculate the lowest common denominator
|
|
111
|
-
def add_event(positive=true)
|
|
112
|
-
num = positive ? self.positive_events + 1 : self.positive_events
|
|
113
|
-
den = self.total_events + 1
|
|
114
|
-
other = Rational(num, den)
|
|
115
|
-
@numerator, @denominator, @positive_events, @total_events = other.numerator, other.denominator, num, den
|
|
116
|
-
self
|
|
117
|
-
end
|
|
118
|
-
alias :add :add_event
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
class A
|
|
123
|
-
class << self
|
|
124
|
-
include GSL
|
|
125
|
-
|
|
126
|
-
def r
|
|
127
|
-
@r ||= Rng.alloc
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def pdf
|
|
131
|
-
r = self.r.gaussian
|
|
132
|
-
pdf = Ran.gaussian_pdf(r)
|
|
133
|
-
puts r, pdf
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
require 'node'
|
|
2
|
-
require 'conditional_probability_matrix'
|
|
3
|
-
|
|
4
|
-
class A
|
|
5
|
-
class << self
|
|
6
|
-
# def will_pay
|
|
7
|
-
# @will_pay ||= Node.new :true, :false
|
|
8
|
-
# end
|
|
9
|
-
#
|
|
10
|
-
# def has_money
|
|
11
|
-
# @has_money ||= Node.new :plenty => 0.1, :some => 0.8, :little => 0.1
|
|
12
|
-
# end
|
|
13
|
-
#
|
|
14
|
-
# def ones
|
|
15
|
-
# Matrix.ones(will_pay.values.length, has_money.values.length)
|
|
16
|
-
# end
|
|
17
|
-
#
|
|
18
|
-
# def parents
|
|
19
|
-
# will_pay.values.col * has_money.values
|
|
20
|
-
# # will_pay.each do |value|
|
|
21
|
-
# #
|
|
22
|
-
# # end
|
|
23
|
-
# end
|
|
24
|
-
#
|
|
25
|
-
# def cpm
|
|
26
|
-
# ConditionalProbabilityMatrix.new(will_pay, has_money)
|
|
27
|
-
# end
|
|
28
|
-
|
|
29
|
-
def killer_identity
|
|
30
|
-
@killer_identity ||= Node.new(:killer_identity, :jack => 0.8, :joe => 0.1, :jeff => 0.1)
|
|
31
|
-
end
|
|
32
|
-
alias :k :killer_identity
|
|
33
|
-
alias :x :killer_identity
|
|
34
|
-
|
|
35
|
-
def fingerprint_information
|
|
36
|
-
@fingerprint_information ||= Node.new(:fingerprint_information, :jack => 2/3.0, :joe => 1/6.0, :jeff => 1/6.0)
|
|
37
|
-
end
|
|
38
|
-
alias :f :fingerprint_information
|
|
39
|
-
alias :y :fingerprint_information
|
|
40
|
-
|
|
41
|
-
def cpm
|
|
42
|
-
@cpm ||= ConditionalProbabilityMatrix.new(x, y)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
data/lib/fathom/distributions.rb
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'fathom'))
|
|
2
|
-
class Fathom::Distributions::DiscreteGaussian
|
|
3
|
-
extend Fathom::Distributions::SharedMethods
|
|
4
|
-
class << self
|
|
5
|
-
def rng
|
|
6
|
-
@rng ||= GSL::Rng.alloc(GSL::Rng::MT19937_1999, Kernel.rand(100_000))
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def rand(sd)
|
|
10
|
-
(rng.gaussian(sd) / size).floor + 1
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def inverse_cdf(opts={})
|
|
14
|
-
mean = opts[:mean]
|
|
15
|
-
sd = opts[:sd]
|
|
16
|
-
sd ||= opts[:std]
|
|
17
|
-
sd ||= opts[:standard_deviation]
|
|
18
|
-
lower = opts.fetch(:lower, true)
|
|
19
|
-
lower = false if opts[:upper]
|
|
20
|
-
confidence_interval = opts.fetch(:confidence_interval, 0.05)
|
|
21
|
-
value = lower ? GSL::Cdf.gaussian_Pinv(confidence_interval, sd) : GSL::Cdf.gaussian_Qinv(confidence_interval, sd)
|
|
22
|
-
value + mean
|
|
23
|
-
end
|
|
24
|
-
alias :lower_bound :inverse_cdf
|
|
25
|
-
|
|
26
|
-
def upper_bound(opts={})
|
|
27
|
-
inverse_cdf(opts.merge(:lower => false))
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def interval_values(opts={})
|
|
31
|
-
confidence_interval = opts.fetch(:confidence_interval, 0.9)
|
|
32
|
-
bound = (1 - confidence_interval) / 2.0
|
|
33
|
-
[lower_bound(opts.merge(:confidence_interval => bound)), upper_bound(opts.merge(:confidence_interval => bound))]
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# If only I had the background to explain what this is....
|
|
37
|
-
# I want to know how many standard deviations are expressed by the confidence interval
|
|
38
|
-
# I can then divide the range by this number to get the standard deviation
|
|
39
|
-
def standard_deviations_under(confidence_interval)
|
|
40
|
-
GSL::Cdf.gaussian_Qinv((1 - confidence_interval) / 2) * 2
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|