rubystats 0.1.2 → 0.2.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.
@@ -1,114 +0,0 @@
1
- require 'probability_distribution'
2
- require 'modules/special_math'
3
- # This class provides an object for encapsulating normal distributions
4
- # Ported to Ruby from PHPMath class by Bryan Donovan
5
- # Author:: Jaco van Kooten
6
- # Author:: Paul Meagher
7
- # Author:: Bryan Donovan (mailto:bryandonovan@myrealbox.com)
8
-
9
- class NormalDistribution < ProbabilityDistribution
10
- include SpecialMath
11
-
12
- # Constructs a normal distribution (defaults to zero mean and
13
- # unity variance).
14
- def initialize(mu=0.0, sigma=1.0)
15
- @mean = mu
16
- if sigma <= 0.0
17
- return "error"
18
- end
19
- @stdev = sigma
20
- @variance = sigma**2
21
- @pdf_denominator = Sqrt2pi * Math.sqrt(@variance)
22
- @cdf_denominator = Sqrt2 * Math.sqrt(@variance)
23
- end
24
-
25
- # Returns the mean of the distribution
26
- def get_mean
27
- return @mean
28
- end
29
-
30
- # Returns the standard deviation of the distribution
31
- def get_standard_deviation
32
- return @stdev
33
- end
34
-
35
- # Returns the variance of the distribution
36
- def get_variance
37
- return @variance
38
- end
39
-
40
- private
41
-
42
- # Obtain single PDF value
43
- # Returns the probability that a stochastic variable x has the value X,
44
- # i.e. P(x=X)
45
- def get_pdf(x)
46
- Math.exp( -((x-@mean)**2) / (2 * @variance)) / @pdf_denominator
47
- end
48
-
49
- # Obtain single CDF value
50
- # Returns the probability that a stochastic variable x is less than X,
51
- # i.e. P(x<X)
52
- def get_cdf(x)
53
- complementary_error( -(x - @mean) / @cdf_denominator) / 2
54
- end
55
-
56
- # Obtain single inverse CDF value.
57
- # returns the value X for which P(x&lt;X).
58
- def get_icdf(p)
59
- check_range(p)
60
- if p == 0.0
61
- return -Max_value
62
- end
63
- if p == 1.0
64
- return Max_value
65
- end
66
- if p == 0.5
67
- return @mean
68
- end
69
-
70
- mean_save = @mean
71
- var_save = @variance
72
- pdf_D_save = @pdf_denominator
73
- cdf_D_save = @cdf_denominator
74
- @mean = 0.0
75
- @variance = 1.0
76
- @pdf_denominator = Math.sqrt(Two_pi)
77
- @cdf_denominator = Sqrt2
78
- x = find_root(p, 0.0, -100.0, 100.0)
79
- #scale back
80
- @mean = mean_save
81
- @variance = var_save
82
- @pdf_denominator = pdf_D_save
83
- @cdf_denominator = cdf_D_save
84
- return x * Math.sqrt(@variance) + @mean
85
- end
86
-
87
- # Uses the polar form of the Box-Muller transformation which
88
- # is both faster and more robust numerically than basic Box-Muller
89
- # transform. To speed up repeated RNG computations, two random values
90
- # are computed after the while loop and the second one is saved and
91
- # directly used if the method is called again.
92
- # see http://www.taygeta.com/random/gaussian.html
93
- # returns single normal deviate
94
- def get_rng
95
- if @use_last
96
- y1 = @last
97
- @use_last = false
98
- else
99
- until w < 1.0 do
100
- r1 = Kernel.rand
101
- r2 = Kernel.rand
102
- x1 = 2.0 * r1 - 1.0
103
- x2 = 2.0 * r2 - 1.0
104
- w = x1 * x1 * x2 * x2
105
- end
106
- w = Math.sqrt((-2.0 * Math.log(w)) / w)
107
- y1 = x1 * w
108
- @last = x2 * w
109
- @use_last = true
110
- end
111
- return @mean + y1 * Math.sqrt(@variance)
112
- end
113
- end
114
-
@@ -1,132 +0,0 @@
1
- require 'modules/numerical_constants'
2
- require 'modules/extra_math'
3
- require 'modules/special_math'
4
-
5
- class ProbabilityDistribution
6
- include NumericalConstants
7
- include SpecialMath
8
- include ExtraMath
9
-
10
- def initialize
11
- end
12
-
13
- def mean
14
- get_mean
15
- end
16
-
17
- def get_mean
18
- end
19
-
20
-
21
- def pdf(x)
22
- if x.class == Array
23
- pdf_vals = []
24
- for i in (0..x.length)
25
- pdf_vals[i] = get_pdf(x[i])
26
- end
27
- return pdf_vals
28
- else
29
- return get_pdf(x)
30
- end
31
- end
32
-
33
- def get_pdf(x)
34
- end
35
-
36
- def cdf(x)
37
- if x.class == Array
38
- cdf_vals = []
39
- for i in (0...x.size)
40
- cdf_vals[i] = get_cdf(x[i])
41
- end
42
- return cdf_vals
43
- else
44
- return get_cdf(x)
45
- end
46
- end
47
-
48
- def get_cdf(x)
49
- end
50
-
51
- def icdf(p)
52
- if p.class == Array
53
- inv_vals = []
54
- for i in (0..p.length)
55
- inv_vals[i] = get_icdf(p[i])
56
- end
57
- return inv_vals
58
- else
59
- return get_icdf(p)
60
- end
61
- end
62
-
63
- def get_icdf(p)
64
- end
65
-
66
- def rng(n=1)
67
- if n < 1
68
- return "Number of random numbers to return must be 1 or greater"
69
- end
70
- if (n > 1)
71
- rnd_vals = []
72
- for i in (0..n)
73
- rnd_vals[i] = get_rng()
74
- end
75
- return rnd_vals
76
- else
77
- return get_rng()
78
- end
79
- end
80
-
81
- def get_rng()
82
- end
83
-
84
- def check_range(x, lo=0.0, hi=1.0)
85
- if (x < lo) || (x > hi)
86
- return "error"
87
- end
88
- end
89
-
90
- def get_factorial(n)
91
- if n <= 1
92
- return 1
93
- else
94
- return n * get_factorial(n-1)
95
- end
96
- end
97
-
98
- def find_root (prob, guess, x_lo, x_hi)
99
- accuracy = 1.0e-10
100
- max_iteration = 150
101
- x = guess
102
- x_new = guess
103
- error = 0.0
104
- pdf = 0.0
105
- dx = 1000.0
106
- i = 0
107
- while ( dx.abs > accuracy && (i += 1) < max_iteration )
108
- #Apply Newton-Raphson step
109
- error = cdf(x) - prob
110
- if error < 0.0
111
- x_lo = x
112
- else
113
- x_hi = x
114
- end
115
- pdf = pdf(x)
116
- if pdf != 0.0
117
- dx = error / pdf
118
- x_new = x -dx
119
- end
120
- # If the NR fails to converge (which for example may be the
121
- # case if the initial guess is to rough) we apply a bisection
122
- # step to determine a more narrow interval around the root.
123
- if x_new < x_lo || x_new > x_hi || pdf == 0.0
124
- x_new = (x_lo + x_hi) / 2.0
125
- dx = x_new - x
126
- end
127
- x = x_new
128
- end
129
- return x
130
- end
131
- end
132
-
@@ -1,13 +0,0 @@
1
- $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
- require 'test/unit'
3
- require 'normal_distribution'
4
-
5
- class TestNormal < Test::Unit::TestCase
6
- def test_simple
7
-
8
- norm = NormalDistribution.new(10,2)
9
- cdf = norm.cdf(11)
10
-
11
- assert_equal("0.691462461274013",cdf.to_s)
12
- end
13
- end