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
|