File: uniform_spec.rb

package info (click to toggle)
ruby-distribution 0.8.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 624 kB
  • sloc: ruby: 4,535; makefile: 10
file content (154 lines) | stat: -rw-r--r-- 4,323 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
require File.expand_path(File.dirname(__FILE__) + "/spec_helper.rb")
require 'distribution/uniform'

describe Distribution::Uniform do

  shared_examples_for "uniform engine" do

    it ".rng should generate sequences with the right mean & variance" do
      skip("This method is very innacurrate due to the low convergence rate")
      # samples = 100_000
      # sum = 0
      # ss = 0
      # lower = 0
      # upper = 20

      # # Expectations
      # exp_mean = (upper + lower) / 2
      # exp_variance = ((upper - lower) ** 2) / 12
      # rng = @engine.rng(lower, upper)

      # samples.times do
      #   v = rng.call
      #   sum += v
      #   ss += (v - exp_mean) ** 2
      # end

      # mean = sum.to_f / samples
      # variance = ss.to_f / samples
      # mean.should be_within(1e-5).of(exp_mean)
      # variance.should be_within(1e-5).of(exp_variance)
    end

    it ".rng with a specified seed should be reproducible" do
      seed = Random.new_seed.modulo 100000007
      gen_a = @engine.rng(0, 1, seed)
      gen_b = @engine.rng(0, 1, seed)

      expect((gen_a.call)).to eq(gen_b.call)
    end

    it ".pdf should return correct pdf for values within the defined range" do
      if @engine.respond_to? :pdf
        10.times do
          low, width = rand, rand
          x = low + rand * width
          epdf = 1.0 / width
          expect(@engine.pdf(x, low, low + width)).to be_within(1e-10).of(epdf)
        end

      else
        pending("No #{@engine}.pdf")
      end
    end

    it ".pdf should return 0 for values outside the defined range" do
      if @engine.respond_to? :pdf
        10.times do
          low, width = rand, rand
          # x lies just outside of  where the pdf exists as a non-zero value
          # A small amount (1e-10) is removed from bad_x to ensure no overlap
          x = low - (1 + rand) * width - 1e-10
          expect(@engine.pdf(x, low, low + width)).to be_within(1e-10).of(0.0)
        end

      else
        pending("No #{@engine}.pdf")
      end
    end


    it ".cdf should return 0 for values smaller than the lower bound" do
      if @engine.respond_to? :cdf
        low, width = rand, rand
        x = low - rand * width
        expect(@engine.cdf(x, low, low + width)).to be_within(1e-10).of(0.0)
      else
        pending("No #{@engine}.cdf")
      end
    end

    it ".cdf should return correct cdf for x within defined range" do
      if @engine.respond_to? :cdf
        low, width = rand, rand
        x = low + rand * width
        ecdf = (x - low) / width
        expect(@engine.cdf(x, low, low + width)).to be_within(1e-10).of(ecdf)
      else
        pending("No #{@engine}.cdf")
      end
    end

    it ".cdf should return 1 for values greater than the upper bound" do
      if @engine.respond_to? :cdf
        low, width = rand, rand
        x = low + (1 + rand) * (width)
        expect(@engine.cdf(x, low, low + width)).to be_within(1e-10).of(1.0)
      else
        pending("No #{@engine}.cdf")
      end
    end
    
    it ".quantile should return correct inverse cdf" do
      if @engine.respond_to? :quantile
        low, width = rand, rand
        scale = rand
        x = low + scale * width
        qn = (x - low) / width
        expect(@engine.quantile(qn, low, low + width)).to be_within(1e-10).of(x)
      else
        pending("No #{@engine}.quantile")
      end
    end
    
    it ".p_value should return same result as .quantile" do
      if @engine.respond_to? :p_value and @engine.respond_to? :quantile
        low, width = rand, rand
        scale = rand
        x = low + scale * width
        qn = (x - low) / width
        
        expect(@engine.quantile(qn, low, low + width)).to eq(@engine.p_value(qn, low, low + width))
      else
        pending("No #{@engine}.p_value")
      end
    end
  end


  describe "singleton" do
    before do
      @engine = Distribution::Uniform
    end
    it_should_behave_like "uniform engine"
  end

  describe Distribution::Uniform::Ruby_ do
    before do
      @engine = Distribution::Uniform::Ruby_
    end
    it_should_behave_like "uniform engine"

  end

  if Distribution.has_gsl?
    describe Distribution::Uniform::GSL_ do
      before do
        @engine = Distribution::Uniform::GSL_
      end
      it_should_behave_like "uniform engine"
    end
  end


end