pest 0.0.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.
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ class TestClass
4
+ include Pest::DataSet
5
+ end
6
+
7
+ describe Pest::DataSet do
8
+ before(:each) { @instance = TestClass.new }
9
+
10
+ describe Pest::DataSet::ClassMethods do
11
+ before(:each) { @class = TestClass }
12
+
13
+ describe "::from" do
14
+ before(:each) do
15
+ @class.stub(:translators).and_return(Hash => :from_hash)
16
+ @class.stub(:from_hash).and_return(Hash.new)
17
+ @class.stub(:send).with(:from_hash, kind_of(Hash)).and_return(true)
18
+
19
+ @hash_source = {:foo => :bar}
20
+ @unknown_source = double("Unknown Instance")
21
+ @unknown_source.stub(:to_hash).and_return(@hash_source)
22
+ end
23
+
24
+ it "checks for translator with passed class" do
25
+ @class.translators.should_receive(:[]).with(Hash).and_return(:from_hash)
26
+ @class.from({:foo => :bar})
27
+ end
28
+
29
+ it "passes to translator if found" do
30
+ @class.should_receive(:send).with(:from_hash, @hash_source)
31
+ @class.from(@hash_source)
32
+ end
33
+
34
+ it "calls to_hash if unrecognized class" do
35
+ @unknown_source.should_receive(:to_hash)
36
+ @class.from(@unknown_source)
37
+ end
38
+
39
+ it "passes to translator after converting to hash" do
40
+ @class.should_receive(:send).with(:from_hash, @hash_source)
41
+ @class.from(@unknown_source)
42
+ end
43
+ end
44
+
45
+ describe "::translators" do
46
+ # Required
47
+ it "raises an error if called from module" do
48
+ lambda { @class.translators }.should raise_error(NotImplementedError)
49
+ end
50
+ end
51
+
52
+ describe "::from_file" do
53
+ # Required
54
+ it "raises an error if called from module" do
55
+ lambda { @class.from_file }.should raise_error(NotImplementedError)
56
+ end
57
+ end
58
+
59
+ describe "::from_hash" do
60
+ # Required
61
+ it "raises an error if called from module" do
62
+ lambda { @class.from_hash }.should raise_error(NotImplementedError)
63
+ end
64
+ end
65
+ end
66
+
67
+ describe "#variables" do
68
+ it "defaults to an empty list" do
69
+ @instance.variables.should == {}
70
+ end
71
+ end
72
+
73
+ describe "#to_hash" do
74
+ # Required
75
+ it "raises an error if called from module" do
76
+ lambda { @instance.to_hash }.should raise_error(NotImplementedError)
77
+ end
78
+ end
79
+
80
+ describe "#save" do
81
+ # Required
82
+ it "raises an error if called from module" do
83
+ lambda { @instance.save }.should raise_error(NotImplementedError)
84
+ end
85
+ end
86
+
87
+ describe "#length" do
88
+ # Required
89
+ it "raises an error if called from module" do
90
+ lambda { @instance.length }.should raise_error(NotImplementedError)
91
+ end
92
+ end
93
+
94
+ # Enumerable interface?
95
+ end
@@ -0,0 +1,21 @@
1
+ # require 'spec_helper'
2
+ #
3
+ # describe Pest::Estimator::Bernoulli do
4
+ # it "inherits from set"
5
+ #
6
+ # describe "estimate_class" do
7
+ # before(:each) { @instance = Pest::Estimator::Bernoulli.new }
8
+ #
9
+ # it "returns class" do
10
+ # @instance.estimate_class.should == Pest::Estimate::Bernoulli
11
+ # end
12
+ # end
13
+ #
14
+ # describe Distribution do
15
+ # describe "cache" do
16
+ # end
17
+ #
18
+ # describe "evaluate" do
19
+ # end
20
+ # end
21
+ # end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pest::Estimator::Frequency do
4
+ before(:each) do
5
+ @class = Pest::Estimator::Frequency
6
+ @v1 = Pest::Variable.new(:name => :foo)
7
+ @v2 = Pest::Variable.new(:name => :bar)
8
+ @data = Pest::DataSet::NArray.from_hash @v1 => [1,1,2,3], @v2 => [1,1,1,1]
9
+ @test = Pest::DataSet::NArray.from_hash @v1 => [1,2,4], @v2 => [1,1,1]
10
+ @instance = @class.new(@data)
11
+ end
12
+
13
+ it "inherits from set" do
14
+ @instance.should be_a(Pest::Estimator)
15
+ end
16
+
17
+ it "generates marginal probabilities" do
18
+ @instance.p(@v2).in(@test).should === NArray[[1.0, 1.0, 1.0]]
19
+ end
20
+
21
+ it "generates joint probability" do
22
+ @instance.p(@v1, @v2).in(@test).should == NArray[[0.5, 0.25, 0]]
23
+ end
24
+
25
+ it "generates conditional probability" do
26
+ @instance.p(@v1).given(@v2).in(@test).should == NArray[[0.5, 0.25, 0]]
27
+ end
28
+
29
+ describe Pest::Estimator::Frequency::Distribution do
30
+ before(:each) do
31
+ @dist = @instance.distributions[@data.variables.values.to_set]
32
+ end
33
+
34
+ describe "#cache_model" do
35
+ context "with unrecognized checksum" do
36
+ it "determines vector frequency" do
37
+ @dist.cache_model
38
+ @dist.frequencies[[1,1]].should == 2
39
+ end
40
+
41
+ it "defaults to 0" do
42
+ @dist.cache_model
43
+ @dist.frequencies[[4,1]].should == 0
44
+ end
45
+ end
46
+
47
+ context "with recognized checksum but no file" do
48
+ it "determines vector frequency" do
49
+ @data.should_receive(:data_vectors).and_return @data
50
+ @dist.cache_model
51
+ end
52
+ end
53
+
54
+ context "with recognized checksum and cache file" do
55
+ before(:each) do
56
+ @file = @dist.cache_model
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "#probability" do
62
+ it "returns an NArray" do
63
+ @dist.probability(@test).should be_a(NArray)
64
+ end
65
+
66
+ it "calculates vector frequency / dataset length" do
67
+ @dist.probability(@test).should == NArray[[0.5,0.25,0]]
68
+ end
69
+ end
70
+
71
+ describe "#entropy" do
72
+ it "returns a Float" do
73
+ @dist.entropy.should be_a(Float)
74
+ end
75
+
76
+ it "calculates -sum(PlogP)" do
77
+ # Outcomes = ([1,1]: 2, [2,1]: 1, [3,1]: 1)
78
+ # P = (0.5, 0.25, 0.25)
79
+ # logP = (-1, -2, -2) (log base 2 for bits)
80
+ # -sum(PlogP) = (0.5, 0.5, 0.5).sum
81
+ @dist.entropy.should == 1.5
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,21 @@
1
+ # require 'spec_helper'
2
+ #
3
+ # describe Pest::Estimator::Gaussian do
4
+ # it "inherits from discrete"
5
+ #
6
+ # describe "estimate_class" do
7
+ # before(:each) { @instance = Pest::Extimator::Gaussian.new }
8
+ #
9
+ # it "returns class" do
10
+ # @instance.estimate_class.should == Pest::Estimate::Gaussian
11
+ # end
12
+ # end
13
+ #
14
+ # describe Distribution do
15
+ # describe "cache" do
16
+ # end
17
+ #
18
+ # describe "evaluate" do
19
+ # end
20
+ # end
21
+ # end
@@ -0,0 +1,21 @@
1
+ # require 'spec_helper'
2
+ #
3
+ # describe Pest::Estimator::Multinomial do
4
+ # it "inherits from set"
5
+ #
6
+ # describe "estimate_class" do
7
+ # before(:each) { @instance = Pest::Estimator::Multinomial.new }
8
+ #
9
+ # it "returns class" do
10
+ # @instance.estimate_class.should == Pest::Estimate::Multinomial
11
+ # end
12
+ # end
13
+ #
14
+ # describe Distribution do
15
+ # describe "cache" do
16
+ # end
17
+ #
18
+ # describe "evaluate" do
19
+ # end
20
+ # end
21
+ # end
@@ -0,0 +1,21 @@
1
+ # require 'spec_helper'
2
+ #
3
+ # describe Pest::Estimator::Parzen do
4
+ # it "inherits from continuous"
5
+ #
6
+ # describe "estimate_class" do
7
+ # before(:each) { @instance = Pest::Estimator::Parzen.new }
8
+ #
9
+ # it "returns class" do
10
+ # @instance.estimate_class.should == Pest::Estimate::Parzen
11
+ # end
12
+ # end
13
+ #
14
+ # describe Distribution do
15
+ # describe "cache" do
16
+ # end
17
+ #
18
+ # describe "evaluate" do
19
+ # end
20
+ # end
21
+ # end
@@ -0,0 +1,21 @@
1
+ # require 'spec_helper'
2
+ #
3
+ # describe Pest::Estimator::SVD do
4
+ # it "inherits from continuous"
5
+ #
6
+ # describe "estimate_class" do
7
+ # before(:each) { @instance = Pest::Estimator::SVD.new }
8
+ #
9
+ # it "returns class" do
10
+ # @instance.estimate_class.should == Pest::Estimate::SVD
11
+ # end
12
+ # end
13
+ #
14
+ # describe Distribution do
15
+ # describe "cache" do
16
+ # end
17
+ #
18
+ # describe "evaluate" do
19
+ # end
20
+ # end
21
+ # end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ class TestClass
4
+ include Pest::Estimator
5
+ def distribution_class; Distribution end
6
+ class Distribution
7
+ include Pest::Estimator::Distribution
8
+ end
9
+ end
10
+
11
+ describe Pest::Estimator do
12
+ before(:each) do
13
+ @data = Pest::DataSet::NArray.from_hash :foo => [1,1,2,3], :bar => [1,1,1,1]
14
+ @class = TestClass
15
+ end
16
+
17
+ describe "::new" do
18
+ it "accepts a dataset" do
19
+ @class.new(@data).data.should == @data
20
+ end
21
+ end
22
+
23
+ describe "#variables" do
24
+ it "proxies data set" do
25
+ @class.new(@data).variables.should == @data.variables
26
+ end
27
+ end
28
+
29
+ describe "#estimates" do
30
+ before(:each) do
31
+ @v1 = Pest::Variable.new(:name => :foo)
32
+ @v2 = Pest::Variable.new(:name => :bar)
33
+ @v3 = Pest::Variable.new(:name => :baz)
34
+
35
+ @instance = TestClass.new
36
+ @instance.stub(:variables).and_return({:foo => @v1, :bar => @v2})
37
+ end
38
+
39
+ it "accepts a set of variables" do
40
+ @instance.distributions[@v1, @v2].should be_a(Pest::Estimator::Distribution)
41
+ end
42
+
43
+ it "returns an estimator for the passed variables" do
44
+ @instance.distributions[@v1, @v2].variables.should == [@v1, @v2].to_set
45
+ end
46
+
47
+ it "returns an estimator for the passed strings" do
48
+ @instance.distributions[:foo, :bar].variables.should == [@v1, @v2].to_set
49
+ end
50
+
51
+ it "is variable order agnostic" do
52
+ @instance.distributions[@v1, @v2].should == @instance.distributions[@v2, @v1]
53
+ end
54
+
55
+ it "fails if a set variable isn't defined" do
56
+ lambda { @instance.distributions[@v1, @v3] }.should raise_error(ArgumentError)
57
+ end
58
+ end
59
+
60
+ describe Pest::Estimator::Distribution do
61
+ before(:each) do
62
+ @class = TestClass::Distribution
63
+ @estimator = TestClass.new
64
+ @estimator.stub(:variables).and_return({:foo => @v1, :bar => @v2})
65
+ @instance = @class.new(@estimator, @estimator.variables)
66
+ end
67
+
68
+ describe "#probability" do
69
+ it "raises no implemented" do
70
+ expect { @instance.probability }.to raise_error(NotImplementedError)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ class EntropyTestClass
4
+ include Pest::Estimator
5
+ include Pest::Function::Entropy
6
+ end
7
+
8
+ describe Pest::Function::Entropy do
9
+ before(:each) do
10
+ @v1 = Pest::Variable.new(:name => :foo)
11
+ @v2 = Pest::Variable.new(:name => :bar)
12
+ @v3 = Pest::Variable.new(:name => :baz)
13
+ @instance = EntropyTestClass.new
14
+ @instance.stub(:variables).and_return({:foo => @v1, :bar => @v2})
15
+ end
16
+
17
+ describe "#entropy" do
18
+ it "returns a Builder" do
19
+ @instance.entropy.should be_a(Pest::Function::Entropy::Builder)
20
+ end
21
+
22
+ it "is aliased as h" do
23
+ @instance.h.should be_a(Pest::Function::Entropy::Builder)
24
+ end
25
+ end
26
+
27
+ describe Pest::Function::Entropy::Builder do
28
+ describe "::new" do
29
+ before(:each) { @builder = EntropyTestClass::Builder.new(@instance, [@v1, :bar]) }
30
+
31
+ it "sets estimator" do
32
+ @builder.estimator.should == @instance
33
+ end
34
+
35
+ it "sets event" do
36
+ @builder.event.should == [@v1, @v2].to_set
37
+ end
38
+
39
+ it "fails if variable undefined for estimator" do
40
+ lambda { EntropyTestClass::Builder.new(@instance, [@v1, @v3]) }.should raise_error(ArgumentError)
41
+ end
42
+
43
+ it "constructs dataset if passed hash"
44
+ end
45
+
46
+ describe "#given" do
47
+ before(:each) { @builder = EntropyTestClass::Builder.new(@instance, [:foo]) }
48
+
49
+ it "sets givens" do
50
+ @builder.given(:bar)
51
+ @builder.givens.should include(@v2)
52
+ end
53
+
54
+ it "returns self" do
55
+ @builder.given(:bar).should be_a(EntropyTestClass::Builder)
56
+ end
57
+
58
+ it "fails if variables aren't variables on the estimator" do
59
+ lambda { @builder.given(:baz) }.should raise_error(ArgumentError)
60
+ end
61
+
62
+ it "adds to dataset if passed hash"
63
+
64
+ it "raises error if passed hash with existing (non hash) dataset"
65
+ end
66
+
67
+ describe "#evaluate" do
68
+ it "generates dataset if not specified"
69
+
70
+ it "gets entropy of event" do
71
+ event = double('EntropyEventDist')
72
+ @instance.distributions.stub(:[]).with([@v1].to_set).and_return(event)
73
+ event.should_receive(:entropy).and_return 0.5
74
+
75
+ EntropyTestClass::Builder.new(@instance,[:foo]).evaluate
76
+ end
77
+
78
+ it "gets entropy of givens" do
79
+ event = double("EntropyEventDist", :entropy => 0.5)
80
+ given = double("EntropyGivenDist", :entropy => 0.25)
81
+ @instance.distributions.stub(:[]).with([@v1].to_set).and_return(event)
82
+ @instance.distributions.stub(:[]).with([@v2].to_set).and_return(given)
83
+ given.should_receive(:entropy).and_return 0.25
84
+
85
+ EntropyTestClass::Builder.new(@instance,[:foo]).given(:bar).evaluate
86
+ end
87
+
88
+ it "returns H event - givens (if givens)" do
89
+ event = double("EntropyEventDist", :entropy => 0.5)
90
+ given = double("EntropyGivenDist", :entropy => 0.1)
91
+ @instance.distributions.stub(:[]).with([@v1].to_set).and_return(event)
92
+ @instance.distributions.stub(:[]).with([@v2].to_set).and_return(given)
93
+
94
+ EntropyTestClass::Builder.new(@instance,[:foo]).given(:bar).evaluate.should == 0.4
95
+ end
96
+
97
+ it "returns H event (if no givens)" do
98
+ event = double("EntropyEventDist", :entropy => 0.5)
99
+ @instance.distributions.stub(:[]).with([@v1].to_set).and_return(event)
100
+
101
+ EntropyTestClass::Builder.new(@instance,[:foo]).evaluate.should == 0.5
102
+ end
103
+ end
104
+ end
105
+ end