more_math 0.3.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +0 -1
- data/{README.rdoc → README.md} +7 -6
- data/Rakefile +5 -2
- data/lib/more_math/continued_fraction.rb +51 -4
- data/lib/more_math/functions.rb +32 -11
- data/lib/more_math/histogram.rb +30 -11
- data/lib/more_math/linear_regression.rb +11 -3
- data/lib/more_math/sequence.rb +7 -1
- data/lib/more_math/version.rb +1 -1
- data/more_math.gemspec +21 -27
- data/tests/histogram_test.rb +23 -6
- data/tests/sequence/refinement_test.rb +13 -0
- data/tests/sequence_test.rb +30 -12
- metadata +28 -18
- data/.codeclimate.yml +0 -16
- data/.gitignore +0 -9
- data/.rubocop.yml +0 -1158
- data/.travis.yml +0 -6
- data/VERSION +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1a9d46106c13337d7b3b949a3984d57de664ba0f8f7931a4ac8aa91139e36a2b
|
4
|
+
data.tar.gz: ce02a111f04c4bc8aab30603d172e47bae8f62bd500484a5ea9b20d2438cb5cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44864c937a9f957f6aaf9a7fad4d5a300c75e4db9e69f882f1fc42ff07c9f811b405c70d7c0a8b312e698053aef63f787d26bb66a7b37f86c58c22e8bfcafdd2
|
7
|
+
data.tar.gz: 9a0dfb7c53d2c1487cb2f8597268b921dfdb0898e3130ca894cb0222dad2a1ee2ee54d466c56ae51ddc17063d35a7b05dde4e3a3c6fa080e720eba0ae9a00d44
|
data/Gemfile
CHANGED
data/{README.rdoc → README.md}
RENAMED
@@ -1,20 +1,21 @@
|
|
1
|
-
|
1
|
+
# MoreMath - More mathematics in Ruby
|
2
2
|
|
3
|
-
|
3
|
+
## Description
|
4
4
|
|
5
5
|
Ruby library that contains various mathematical functions and algorithms.
|
6
6
|
|
7
|
-
|
7
|
+
## Download
|
8
8
|
|
9
9
|
The homepage of this library is located at
|
10
10
|
|
11
|
-
*
|
11
|
+
* http://github.com/flori/more_math
|
12
12
|
|
13
|
-
|
13
|
+
|
14
|
+
## Author
|
14
15
|
|
15
16
|
Florian Frank mailto:flori@ping.de
|
16
17
|
|
17
|
-
|
18
|
+
## License
|
18
19
|
|
19
20
|
This software is licensed under the X11 (or MIT) license:
|
20
21
|
http://www.xfree86.org/3.3.6/COPYRIGHT2.html#3
|
data/Rakefile
CHANGED
@@ -12,8 +12,10 @@ GemHadar do
|
|
12
12
|
test_dir 'tests'
|
13
13
|
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', 'coverage', '.rvmrc',
|
14
14
|
'.AppleDouble', 'tags', '.byebug_history', '.DS_Store'
|
15
|
-
readme 'README.
|
15
|
+
readme 'README.md'
|
16
16
|
title "#{name.camelize} -- More Math in Ruby"
|
17
|
+
package_ignore '.all_images.yml', '.gitignore', 'VERSION',
|
18
|
+
*Dir.glob('.github/**/*', File::FNM_DOTMATCH)
|
17
19
|
|
18
20
|
required_ruby_version '>= 2.0'
|
19
21
|
dependency 'tins', '~>1.0'
|
@@ -21,6 +23,7 @@ GemHadar do
|
|
21
23
|
development_dependency 'rake'
|
22
24
|
development_dependency 'simplecov'
|
23
25
|
development_dependency 'test-unit'
|
24
|
-
development_dependency
|
26
|
+
development_dependency 'debug'
|
27
|
+
development_dependency 'all_images'
|
25
28
|
licenses << 'MIT'
|
26
29
|
end
|
@@ -14,11 +14,13 @@ module MoreMath
|
|
14
14
|
# ...
|
15
15
|
#
|
16
16
|
class ContinuedFraction
|
17
|
+
SIMPLE_B = proc { 1 }
|
18
|
+
|
17
19
|
# Creates a continued fraction instance. With the defaults for_a { 1 } and
|
18
20
|
# for_b { 1 } it approximates the golden ration phi if evaluated.
|
19
21
|
def initialize
|
20
|
-
@a = proc { 1
|
21
|
-
@b =
|
22
|
+
@a = proc { 1 }
|
23
|
+
@b = SIMPLE_B
|
22
24
|
end
|
23
25
|
|
24
26
|
# Creates a ContinuedFraction instances and passes its arguments to a call
|
@@ -35,7 +37,7 @@ module MoreMath
|
|
35
37
|
|
36
38
|
def for_arg(arg = nil, &block)
|
37
39
|
if arg and !block
|
38
|
-
arg
|
40
|
+
arg.freeze
|
39
41
|
elsif block and !arg
|
40
42
|
block
|
41
43
|
else
|
@@ -44,6 +46,17 @@ module MoreMath
|
|
44
46
|
end
|
45
47
|
private :for_arg
|
46
48
|
|
49
|
+
def self.from(number)
|
50
|
+
number = number.to_r
|
51
|
+
n, d = number.numerator, number.denominator
|
52
|
+
as = []
|
53
|
+
while d > 0
|
54
|
+
n, (a, d) = d, n.divmod(d)
|
55
|
+
as << a
|
56
|
+
end
|
57
|
+
for_a(as)
|
58
|
+
end
|
59
|
+
|
47
60
|
# This method either takes a block or an argument +arg+. The argument +arg+
|
48
61
|
# has to respond to an integer index n >= 0 and return the value a_n. The
|
49
62
|
# block has to return the value for a_n when +n+ is passed as the first
|
@@ -64,6 +77,30 @@ module MoreMath
|
|
64
77
|
self
|
65
78
|
end
|
66
79
|
|
80
|
+
def simple?
|
81
|
+
@b == SIMPLE_B
|
82
|
+
end
|
83
|
+
|
84
|
+
def inspect
|
85
|
+
"#<#{self.class} #{to_s}>"
|
86
|
+
end
|
87
|
+
|
88
|
+
include Enumerable
|
89
|
+
def each(&block)
|
90
|
+
if simple?
|
91
|
+
(0..Float::INFINITY).lazy.map { |i| @a[i] }.take_while { |x| x }.each(&block)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_s(length: 10)
|
96
|
+
if simple?
|
97
|
+
convergents = take(length)
|
98
|
+
"[#{convergents[0]}; #{convergents[1..-1] * ', '}#{",…" if convergents.size >= length}]"
|
99
|
+
else
|
100
|
+
"CF(a=#@a, b=#@b)"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
67
104
|
def value(v, n, x = nil)
|
68
105
|
result = if x
|
69
106
|
v[n, x]
|
@@ -86,7 +123,7 @@ module MoreMath
|
|
86
123
|
# Evaluates the continued fraction for the value +x+ (if any) with the
|
87
124
|
# accuracy +epsilon+ and +max_iterations+ as the maximum number of
|
88
125
|
# iterations using the Wallis-method with scaling.
|
89
|
-
def call(x = nil, epsilon
|
126
|
+
def call(x = nil, epsilon: 1E-16, max_iterations: 1 << 31)
|
90
127
|
c_0, c_1 = 1.0, a(0, x)
|
91
128
|
c_1 == nil and return 0 / 0.0
|
92
129
|
d_0, d_1 = 0.0, 1.0
|
@@ -127,8 +164,18 @@ module MoreMath
|
|
127
164
|
result
|
128
165
|
end
|
129
166
|
|
167
|
+
def reciprocal
|
168
|
+
if @a[0] > 0
|
169
|
+
dup.for_a { |i| i == 0 ? 0 : @a[i - 1] }
|
170
|
+
else
|
171
|
+
dup.for_a { |i| @a[i + 1] }
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
130
175
|
alias [] call
|
131
176
|
|
177
|
+
alias to_f call
|
178
|
+
|
132
179
|
# Returns this continued fraction as a Proc object which takes the same
|
133
180
|
# arguments like its call method does.
|
134
181
|
def to_proc
|
data/lib/more_math/functions.rb
CHANGED
@@ -15,6 +15,7 @@ module MoreMath
|
|
15
15
|
end
|
16
16
|
else
|
17
17
|
def log_gamma(x)
|
18
|
+
x = x.to_f
|
18
19
|
if x.nan? || x <= 0
|
19
20
|
0 / 0.0
|
20
21
|
else
|
@@ -33,6 +34,15 @@ module MoreMath
|
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
37
|
+
# Returns the value of the gamma function, extended to a negative domain.
|
38
|
+
def gamma(x)
|
39
|
+
if x < 0.0
|
40
|
+
return PI / (sin(PI * x) * exp(log_gamma(1 - x)))
|
41
|
+
else
|
42
|
+
exp(log_gamma(x))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
36
46
|
# Returns the natural logarithm of the beta function value for +(a, b)+.
|
37
47
|
def log_beta(a, b)
|
38
48
|
log_gamma(a) + log_gamma(b) - log_gamma(a + b)
|
@@ -40,16 +50,25 @@ module MoreMath
|
|
40
50
|
0 / 0.0
|
41
51
|
end
|
42
52
|
|
53
|
+
# Returns the value of the beta function for +(a, b)+, +a > 0, b > 0'.
|
54
|
+
def beta(a, b)
|
55
|
+
if a > 0 && b > 0
|
56
|
+
exp(log_beta(a, b))
|
57
|
+
else
|
58
|
+
0.0 / 0
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
43
62
|
# Return an approximation value of Euler's regularized beta function for
|
44
63
|
# +x+, +a+, and +b+ with an error <= +epsilon+, but only iterate
|
45
64
|
# +max_iterations+-times.
|
46
|
-
def beta_regularized(x, a, b, epsilon
|
65
|
+
def beta_regularized(x, a, b, epsilon: 1E-16, max_iterations: 1 << 16)
|
47
66
|
x, a, b = x.to_f, a.to_f, b.to_f
|
48
67
|
case
|
49
68
|
when a.nan? || b.nan? || x.nan? || a <= 0 || b <= 0 || x < 0 || x > 1
|
50
69
|
0 / 0.0
|
51
70
|
when x > (a + 1) / (a + b + 2)
|
52
|
-
1 - beta_regularized(1 - x, b, a, epsilon, max_iterations)
|
71
|
+
1 - beta_regularized(1 - x, b, a, epsilon: epsilon, max_iterations: max_iterations)
|
53
72
|
else
|
54
73
|
fraction = ContinuedFraction.for_b do |n, y|
|
55
74
|
if n % 2 == 0
|
@@ -61,7 +80,7 @@ module MoreMath
|
|
61
80
|
end
|
62
81
|
end
|
63
82
|
exp(a * log(x) + b * log(1.0 - x) - log(a) - log_beta(a, b)) /
|
64
|
-
fraction[x, epsilon, max_iterations]
|
83
|
+
fraction[x, epsilon: epsilon, max_iterations: max_iterations]
|
65
84
|
end
|
66
85
|
rescue Errno::ERANGE, Errno::EDOM
|
67
86
|
0 / 0.0
|
@@ -70,7 +89,7 @@ module MoreMath
|
|
70
89
|
# Return an approximation of the regularized gammaP function for +x+ and
|
71
90
|
# +a+ with an error of <= +epsilon+, but only iterate
|
72
91
|
# +max_iterations+-times.
|
73
|
-
def gammaP_regularized(x, a, epsilon
|
92
|
+
def gammaP_regularized(x, a, epsilon: 1E-16, max_iterations: 1 << 16)
|
74
93
|
x, a = x.to_f, a.to_f
|
75
94
|
case
|
76
95
|
when a.nan? || x.nan? || a <= 0 || x < 0
|
@@ -78,7 +97,7 @@ module MoreMath
|
|
78
97
|
when x == 0
|
79
98
|
0.0
|
80
99
|
when 1 <= a && a < x
|
81
|
-
1 - gammaQ_regularized(x, a, epsilon, max_iterations)
|
100
|
+
1 - gammaQ_regularized(x, a, epsilon: epsilon, max_iterations: max_iterations)
|
82
101
|
else
|
83
102
|
n = 0
|
84
103
|
an = 1 / a
|
@@ -101,7 +120,7 @@ module MoreMath
|
|
101
120
|
# Return an approximation of the regularized gammaQ function for +x+ and
|
102
121
|
# +a+ with an error of <= +epsilon+, but only iterate
|
103
122
|
# +max_iterations+-times.
|
104
|
-
def gammaQ_regularized(x, a, epsilon
|
123
|
+
def gammaQ_regularized(x, a, epsilon: 1E-16, max_iterations: 1 << 16)
|
105
124
|
x, a = x.to_f, a.to_f
|
106
125
|
case
|
107
126
|
when a.nan? || x.nan? || a <= 0 || x < 0
|
@@ -109,7 +128,7 @@ module MoreMath
|
|
109
128
|
when x == 0
|
110
129
|
1.0
|
111
130
|
when a > x || a < 1
|
112
|
-
1 - gammaP_regularized(x, a, epsilon, max_iterations)
|
131
|
+
1 - gammaP_regularized(x, a, epsilon: epsilon, max_iterations: max_iterations)
|
113
132
|
else
|
114
133
|
fraction = ContinuedFraction.for_a do |n, y|
|
115
134
|
(2 * n + 1) - a + y
|
@@ -117,7 +136,7 @@ module MoreMath
|
|
117
136
|
n * (a - n)
|
118
137
|
end
|
119
138
|
exp(-x + a * log(x) - log_gamma(a)) *
|
120
|
-
fraction[x, epsilon, max_iterations] ** -1
|
139
|
+
fraction[x, epsilon: epsilon, max_iterations: max_iterations] ** -1
|
121
140
|
end
|
122
141
|
rescue Errno::ERANGE, Errno::EDOM
|
123
142
|
0 / 0.0
|
@@ -130,9 +149,11 @@ module MoreMath
|
|
130
149
|
r = sqrt(1 - exp(-x ** 2 * (4 / Math::PI + erf_a * x ** 2) / (1 + erf_a * x ** 2)))
|
131
150
|
x < 0 ? -r : r
|
132
151
|
end
|
133
|
-
|
134
|
-
|
135
|
-
|
152
|
+
end
|
153
|
+
|
154
|
+
unless Math.respond_to?(:erfc)
|
155
|
+
def erfc(x)
|
156
|
+
1.0 - erf(x)
|
136
157
|
end
|
137
158
|
end
|
138
159
|
|
data/lib/more_math/histogram.rb
CHANGED
@@ -4,7 +4,14 @@ module MoreMath
|
|
4
4
|
Bin = Struct.new(:left, :right, :count)
|
5
5
|
|
6
6
|
# Create a Histogram for the elements of +sequence+ with +bins+ bins.
|
7
|
-
def initialize(sequence,
|
7
|
+
def initialize(sequence, arg = 10)
|
8
|
+
@with_counts = false
|
9
|
+
if arg.is_a?(Hash)
|
10
|
+
bins = arg.fetch(:bins, 10)
|
11
|
+
wc = arg[:with_counts] and @with_counts = wc
|
12
|
+
else
|
13
|
+
bins = arg
|
14
|
+
end
|
8
15
|
@sequence = sequence
|
9
16
|
@bins = bins
|
10
17
|
@result = compute
|
@@ -29,9 +36,8 @@ module MoreMath
|
|
29
36
|
# Display this histogram to +output+, +width+ is the parameter for
|
30
37
|
# +prepare_display+
|
31
38
|
def display(output = $stdout, width = 50)
|
32
|
-
|
33
|
-
|
34
|
-
output << "%11.5f -|%s\n" % [ (l + r) / 2.0, "*" * bar ]
|
39
|
+
for r in rows
|
40
|
+
output << output_row(r, width)
|
35
41
|
end
|
36
42
|
output << "max_count=#{max_count}\n"
|
37
43
|
self
|
@@ -43,13 +49,26 @@ module MoreMath
|
|
43
49
|
|
44
50
|
private
|
45
51
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
52
|
+
def output_row(row, width)
|
53
|
+
left, right, count = row
|
54
|
+
if @with_counts
|
55
|
+
left_width = width - (counts.map { |x| x.to_s.size }.max + 1)
|
56
|
+
else
|
57
|
+
left_width = width
|
58
|
+
end
|
59
|
+
factor = left_width.to_f / max_count
|
60
|
+
bar_width = (count * factor).ceil
|
61
|
+
bar = ?* * bar_width
|
62
|
+
if @with_counts
|
63
|
+
bar += count.to_s.rjust(width - bar_width)
|
64
|
+
end
|
65
|
+
"%11.5f -|%s\n" % [ (left + right) / 2.0, bar ]
|
66
|
+
end
|
67
|
+
|
68
|
+
def rows
|
69
|
+
@result.reverse_each.map { |bin|
|
70
|
+
[ bin.left, bin.right, bin.count ]
|
71
|
+
}
|
53
72
|
end
|
54
73
|
|
55
74
|
# Computes the histogram and returns it as an array of tuples (l, c, r).
|
@@ -32,9 +32,9 @@ module MoreMath
|
|
32
32
|
t.abs <= td.inverse_probability(1 - alpha.abs / 2.0).abs
|
33
33
|
end
|
34
34
|
|
35
|
-
# Returns the
|
35
|
+
# Returns the residuals of this linear regression in relation to the given
|
36
36
|
# domain and image.
|
37
|
-
def
|
37
|
+
def residuals
|
38
38
|
result = []
|
39
39
|
@domain.zip(@image) do |x, y|
|
40
40
|
result << y - (@a * x + @b)
|
@@ -42,13 +42,21 @@ module MoreMath
|
|
42
42
|
result
|
43
43
|
end
|
44
44
|
|
45
|
+
def r2
|
46
|
+
image_seq = MoreMath::Sequence.new(@image)
|
47
|
+
sum_res = residuals.inject(0.0) { |s, r| s + r ** 2 }
|
48
|
+
[
|
49
|
+
1.0 - sum_res / image_seq.sum_of_squares,
|
50
|
+
0.0,
|
51
|
+
].max
|
52
|
+
end
|
53
|
+
|
45
54
|
private
|
46
55
|
|
47
56
|
def compute
|
48
57
|
size = @image.size
|
49
58
|
sum_xx = sum_xy = sum_x = sum_y = 0.0
|
50
59
|
@domain.zip(@image) do |x, y|
|
51
|
-
x += 1
|
52
60
|
sum_xx += x ** 2
|
53
61
|
sum_xy += x * y
|
54
62
|
sum_x += x
|
data/lib/more_math/sequence.rb
CHANGED
@@ -74,6 +74,12 @@ module MoreMath
|
|
74
74
|
Math.sqrt(variance)
|
75
75
|
end
|
76
76
|
|
77
|
+
# Returns the Z-score sequence derived from the current sequence.
|
78
|
+
memoize method:
|
79
|
+
def z_score
|
80
|
+
self.class.new(elements.map { |t| t.to_f - mean / standard_deviation })
|
81
|
+
end
|
82
|
+
|
77
83
|
# Returns the standard deviation of the elements in percentage of the
|
78
84
|
# arithmetic mean.
|
79
85
|
memoize method:
|
@@ -289,7 +295,7 @@ module MoreMath
|
|
289
295
|
# Returns the d-value for the Durbin-Watson statistic. The value is d << 2
|
290
296
|
# for positive, d >> 2 for negative and d around 2 for no autocorrelation.
|
291
297
|
def durbin_watson_statistic
|
292
|
-
e = linear_regression.
|
298
|
+
e = linear_regression.residuals
|
293
299
|
e.size <= 1 and return 2.0
|
294
300
|
(1...e.size).inject(0.0) { |s, i| s + (e[i] - e[i - 1]) ** 2 } /
|
295
301
|
e.inject(0.0) { |s, x| s + x ** 2 }
|
data/lib/more_math/version.rb
CHANGED
data/more_math.gemspec
CHANGED
@@ -1,52 +1,46 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: more_math 0.
|
2
|
+
# stub: more_math 1.0.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "more_math".freeze
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "1.0.0"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
10
10
|
s.authors = ["Florian Frank".freeze]
|
11
|
-
s.date = "
|
11
|
+
s.date = "2023-05-26"
|
12
12
|
s.description = "Library that provides more mathematical functions/algorithms than standard Ruby.".freeze
|
13
13
|
s.email = "flori@ping.de".freeze
|
14
|
-
s.extra_rdoc_files = ["README.
|
15
|
-
s.files = ["
|
14
|
+
s.extra_rdoc_files = ["README.md".freeze, "lib/more_math.rb".freeze, "lib/more_math/cantor_pairing_function.rb".freeze, "lib/more_math/constants/functions_constants.rb".freeze, "lib/more_math/continued_fraction.rb".freeze, "lib/more_math/distributions.rb".freeze, "lib/more_math/entropy.rb".freeze, "lib/more_math/exceptions.rb".freeze, "lib/more_math/functions.rb".freeze, "lib/more_math/histogram.rb".freeze, "lib/more_math/linear_regression.rb".freeze, "lib/more_math/newton_bisection.rb".freeze, "lib/more_math/numberify_string_function.rb".freeze, "lib/more_math/permutation.rb".freeze, "lib/more_math/ranking_common.rb".freeze, "lib/more_math/sequence.rb".freeze, "lib/more_math/sequence/moving_average.rb".freeze, "lib/more_math/sequence/refinement.rb".freeze, "lib/more_math/string_numeral.rb".freeze, "lib/more_math/subset.rb".freeze, "lib/more_math/version.rb".freeze]
|
15
|
+
s.files = ["CHANGES".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "lib/more_math.rb".freeze, "lib/more_math/cantor_pairing_function.rb".freeze, "lib/more_math/constants/functions_constants.rb".freeze, "lib/more_math/continued_fraction.rb".freeze, "lib/more_math/distributions.rb".freeze, "lib/more_math/entropy.rb".freeze, "lib/more_math/exceptions.rb".freeze, "lib/more_math/functions.rb".freeze, "lib/more_math/histogram.rb".freeze, "lib/more_math/linear_regression.rb".freeze, "lib/more_math/newton_bisection.rb".freeze, "lib/more_math/numberify_string_function.rb".freeze, "lib/more_math/permutation.rb".freeze, "lib/more_math/ranking_common.rb".freeze, "lib/more_math/sequence.rb".freeze, "lib/more_math/sequence/moving_average.rb".freeze, "lib/more_math/sequence/refinement.rb".freeze, "lib/more_math/string_numeral.rb".freeze, "lib/more_math/subset.rb".freeze, "lib/more_math/version.rb".freeze, "more_math.gemspec".freeze, "tests/cantor_pairing_function_test.rb".freeze, "tests/continued_fraction_test.rb".freeze, "tests/distribution_test.rb".freeze, "tests/entropy_test.rb".freeze, "tests/functions_test.rb".freeze, "tests/histogram_test.rb".freeze, "tests/newton_bisection_test.rb".freeze, "tests/numberify_string_function_test.rb".freeze, "tests/permutation_test.rb".freeze, "tests/sequence/refinement_test.rb".freeze, "tests/sequence_moving_average_test.rb".freeze, "tests/sequence_test.rb".freeze, "tests/string_numeral_test.rb".freeze, "tests/subset_test.rb".freeze, "tests/test_helper.rb".freeze]
|
16
16
|
s.homepage = "http://flori.github.com/more_math".freeze
|
17
17
|
s.licenses = ["MIT".freeze]
|
18
|
-
s.rdoc_options = ["--title".freeze, "MoreMath -- More Math in Ruby".freeze, "--main".freeze, "README.
|
18
|
+
s.rdoc_options = ["--title".freeze, "MoreMath -- More Math in Ruby".freeze, "--main".freeze, "README.md".freeze]
|
19
19
|
s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
|
20
|
-
s.rubygems_version = "
|
20
|
+
s.rubygems_version = "3.3.26".freeze
|
21
21
|
s.summary = "Library that provides more mathematics.".freeze
|
22
|
-
s.test_files = ["tests/cantor_pairing_function_test.rb".freeze, "tests/continued_fraction_test.rb".freeze, "tests/distribution_test.rb".freeze, "tests/entropy_test.rb".freeze, "tests/functions_test.rb".freeze, "tests/histogram_test.rb".freeze, "tests/newton_bisection_test.rb".freeze, "tests/numberify_string_function_test.rb".freeze, "tests/permutation_test.rb".freeze, "tests/sequence_moving_average_test.rb".freeze, "tests/sequence_test.rb".freeze, "tests/string_numeral_test.rb".freeze, "tests/subset_test.rb".freeze, "tests/test_helper.rb".freeze]
|
22
|
+
s.test_files = ["tests/cantor_pairing_function_test.rb".freeze, "tests/continued_fraction_test.rb".freeze, "tests/distribution_test.rb".freeze, "tests/entropy_test.rb".freeze, "tests/functions_test.rb".freeze, "tests/histogram_test.rb".freeze, "tests/newton_bisection_test.rb".freeze, "tests/numberify_string_function_test.rb".freeze, "tests/permutation_test.rb".freeze, "tests/sequence/refinement_test.rb".freeze, "tests/sequence_moving_average_test.rb".freeze, "tests/sequence_test.rb".freeze, "tests/string_numeral_test.rb".freeze, "tests/subset_test.rb".freeze, "tests/test_helper.rb".freeze]
|
23
23
|
|
24
24
|
if s.respond_to? :specification_version then
|
25
25
|
s.specification_version = 4
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.9.1"])
|
37
|
-
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
38
|
-
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
39
|
-
s.add_dependency(%q<test-unit>.freeze, [">= 0"])
|
40
|
-
s.add_dependency(%q<codeclimate-test-reporter>.freeze, [">= 0"])
|
41
|
-
s.add_dependency(%q<tins>.freeze, ["~> 1.0"])
|
42
|
-
s.add_dependency(%q<mize>.freeze, [">= 0"])
|
43
|
-
end
|
28
|
+
if s.respond_to? :add_runtime_dependency then
|
29
|
+
s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.12.0"])
|
30
|
+
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
|
31
|
+
s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
|
32
|
+
s.add_development_dependency(%q<test-unit>.freeze, [">= 0"])
|
33
|
+
s.add_development_dependency(%q<debug>.freeze, [">= 0"])
|
34
|
+
s.add_development_dependency(%q<all_images>.freeze, [">= 0"])
|
35
|
+
s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.0"])
|
36
|
+
s.add_runtime_dependency(%q<mize>.freeze, [">= 0"])
|
44
37
|
else
|
45
|
-
s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.
|
38
|
+
s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.12.0"])
|
46
39
|
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
47
40
|
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
48
41
|
s.add_dependency(%q<test-unit>.freeze, [">= 0"])
|
49
|
-
s.add_dependency(%q<
|
42
|
+
s.add_dependency(%q<debug>.freeze, [">= 0"])
|
43
|
+
s.add_dependency(%q<all_images>.freeze, [">= 0"])
|
50
44
|
s.add_dependency(%q<tins>.freeze, ["~> 1.0"])
|
51
45
|
s.add_dependency(%q<mize>.freeze, [">= 0"])
|
52
46
|
end
|
data/tests/histogram_test.rb
CHANGED
@@ -17,13 +17,30 @@ class HistogramTest < Test::Unit::TestCase
|
|
17
17
|
def test_histogram_display
|
18
18
|
sequence = Sequence.new [ 1, 2, 3, 0, 2 ]
|
19
19
|
histogram = Histogram.new sequence, 3
|
20
|
-
assert_equal [[2.0,
|
21
|
-
histogram.instance_eval {
|
20
|
+
assert_equal [[2.0, 3.0, 1], [1.0, 2.0, 2], [0.0, 1.0, 2]],
|
21
|
+
histogram.instance_eval { rows }
|
22
22
|
output = StringIO.new
|
23
23
|
histogram.display output
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
assert_equal <<~end, output.string
|
25
|
+
2.50000 -|*************************
|
26
|
+
1.50000 -|**************************************************
|
27
|
+
0.50000 -|**************************************************
|
28
|
+
max_count=2
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_histogram_display_with_counts
|
33
|
+
sequence = Sequence.new [ 1, 2, 3, 0, 2 ]
|
34
|
+
histogram = Histogram.new sequence, with_counts: true, bins: 3
|
35
|
+
assert_equal [[2.0, 3.0, 1], [1.0, 2.0, 2], [0.0, 1.0, 2]],
|
36
|
+
histogram.instance_eval { rows }
|
37
|
+
output = StringIO.new
|
38
|
+
histogram.display output
|
39
|
+
assert_equal <<~end, output.string
|
40
|
+
2.50000 -|************************ 1
|
41
|
+
1.50000 -|************************************************ 2
|
42
|
+
0.50000 -|************************************************ 2
|
43
|
+
max_count=2
|
44
|
+
end
|
28
45
|
end
|
29
46
|
end
|
data/tests/sequence_test.rb
CHANGED
@@ -126,8 +126,8 @@ class SequenceTest < Test::Unit::TestCase
|
|
126
126
|
3, 94, 5, 79, 11, 16, 0, 90, 81, 42, 64, 76, 92, 25,
|
127
127
|
3, 90, 51, 15, 0, 74, 98, 93, 90, 14, 81, 85, 28, 30,
|
128
128
|
73, 32, 88])
|
129
|
-
@rand_up = Sequence.new(Array.new(rand.size) { |i| rand[i]
|
130
|
-
@rand_down = Sequence.new(Array.new(rand.size) { |i| rand[i]
|
129
|
+
@rand_up = Sequence.new(Array.new(rand.size) { |i| rand[i] + 10 * i })
|
130
|
+
@rand_down = Sequence.new(Array.new(rand.size) { |i| rand[i] - 10 * i })
|
131
131
|
@rasi = Sequence.new(
|
132
132
|
[ 0.0, 11.7813239550446, 23.8742291678261, 0.368124552684678,
|
133
133
|
20.233654312272, 7.64120827980215, 61.609239533582, 69.346191849821,
|
@@ -186,7 +186,8 @@ class SequenceTest < Test::Unit::TestCase
|
|
186
186
|
assert_in_delta 0.3, @flat.median, 1E-8
|
187
187
|
assert_in_delta 0.3, @flat.percentile(75), 1E-8
|
188
188
|
assert_equal 100, @flat.histogram(10).each_bin.first.count
|
189
|
-
assert @flat.linear_regression.
|
189
|
+
assert @flat.linear_regression.residuals.all? { |r| r.abs <= 1E-6 }
|
190
|
+
assert_in_delta 0.0, @flat.linear_regression.r2, 1E-8
|
190
191
|
end
|
191
192
|
|
192
193
|
def test_half
|
@@ -207,7 +208,8 @@ class SequenceTest < Test::Unit::TestCase
|
|
207
208
|
assert_in_delta 37.375, @half.percentile(75), 1E-8
|
208
209
|
assert_equal [10] * 10, counts = @half.histogram(10).counts
|
209
210
|
assert_equal 100, counts.inject { |s, x| s + x }
|
210
|
-
assert @half.linear_regression.
|
211
|
+
assert @half.linear_regression.residuals.all? { |r| r.abs <= 0.5 }
|
212
|
+
assert_in_delta 1.0, @half.linear_regression.r2, 1E-8
|
211
213
|
end
|
212
214
|
|
213
215
|
def test_rand
|
@@ -227,13 +229,15 @@ class SequenceTest < Test::Unit::TestCase
|
|
227
229
|
assert_in_delta 50.0, @rand.median, 1E-8
|
228
230
|
assert_in_delta 81, @rand.percentile(75), 1E-8
|
229
231
|
assert_in_delta 0.05660, @rand.linear_regression.a, 1E-4
|
230
|
-
assert_in_delta
|
232
|
+
assert_in_delta 48.0378, @rand.linear_regression.b, 1E-4
|
231
233
|
assert @rand.linear_regression.slope_zero?
|
232
|
-
assert_in_delta(-
|
233
|
-
assert_in_delta
|
234
|
+
assert_in_delta(-9.9433, @rand_down.linear_regression.a, 1E-4)
|
235
|
+
assert_in_delta 48.0378, @rand_down.linear_regression.b, 1E-4
|
236
|
+
assert_in_delta 0.9883, @rand_down.linear_regression.r2, 1E-4
|
234
237
|
assert !@rand_down.linear_regression.slope_zero?
|
235
|
-
assert_in_delta
|
236
|
-
assert_in_delta
|
238
|
+
assert_in_delta 10.0566, @rand_up.linear_regression.a, 1E-4
|
239
|
+
assert_in_delta 48.0378, @rand_up.linear_regression.b, 1E-4
|
240
|
+
assert_in_delta 0.98857, @rand_up.linear_regression.r2, 1E-4
|
237
241
|
assert !@rand_up.linear_regression.slope_zero?
|
238
242
|
assert_nil @rand.detect_outliers
|
239
243
|
assert !@rand.detect_autocorrelation[:detected]
|
@@ -258,7 +262,8 @@ class SequenceTest < Test::Unit::TestCase
|
|
258
262
|
assert_in_delta 0.0, @rasi.median, 1E-2
|
259
263
|
assert_in_delta 30.58, @rasi.percentile(75), 1E-2
|
260
264
|
assert_in_delta(-0.41, @rasi.linear_regression.a, 1E-2)
|
261
|
-
assert_in_delta(
|
265
|
+
assert_in_delta(23.94, @rasi.linear_regression.b, 1E-2)
|
266
|
+
assert_in_delta 0.0887, @rasi.linear_regression.r2, 1E-4
|
262
267
|
assert !@rasi.linear_regression.slope_zero?
|
263
268
|
assert_equal 13, @rasi.detect_outliers[:high]
|
264
269
|
assert @rasi.detect_autocorrelation[:detected]
|
@@ -284,8 +289,9 @@ class SequenceTest < Test::Unit::TestCase
|
|
284
289
|
assert_in_delta 51.5, @book.median, 1E-2
|
285
290
|
assert_in_delta 58.25, @book.percentile(75), 1E-2
|
286
291
|
assert_in_delta(-0.0952, @book.linear_regression.a, 1E-4)
|
287
|
-
assert_in_delta(54.
|
292
|
+
assert_in_delta(54.5420, @book.linear_regression.b, 1E-4)
|
288
293
|
assert @book.linear_regression.slope_zero?
|
294
|
+
assert_in_delta 0.0249, @book.linear_regression.r2, 1E-4
|
289
295
|
assert_equal 7, @book.detect_outliers[:high]
|
290
296
|
ought = [1.0, -0.39, 0.3, -0.17, 0.07, -0.10, 0.05, 0.04, -0.04, -0.01,
|
291
297
|
0.01, 0.11, -0.07, 0.15, 0.04, -0.01
|
@@ -297,7 +303,7 @@ class SequenceTest < Test::Unit::TestCase
|
|
297
303
|
assert_equal [3, 4, 9, 12, 18, 14, 4, 5, 0, 1],
|
298
304
|
counts = @book.histogram(10).counts
|
299
305
|
assert_equal 70, counts.inject { |s, x| s + x }
|
300
|
-
assert @flat.linear_regression.
|
306
|
+
assert @flat.linear_regression.residuals.all? { |r| r.abs <= 1E-6 }
|
301
307
|
end
|
302
308
|
|
303
309
|
def test_cover
|
@@ -338,4 +344,16 @@ class SequenceTest < Test::Unit::TestCase
|
|
338
344
|
assert_not_same seq2, seq
|
339
345
|
assert_equal [ 1, 2, 3 ], seq2.elements
|
340
346
|
end
|
347
|
+
|
348
|
+
def test_z_score
|
349
|
+
s = MoreMath::Sequence.new(
|
350
|
+
[
|
351
|
+
697.195, 913.583, 793.187, 363.926, 111.559, 296.687, 500.225,
|
352
|
+
303.019, 4.702, 378.132,
|
353
|
+
]
|
354
|
+
)
|
355
|
+
assert_equal s.size, s.z_score.size
|
356
|
+
assert_in_delta 276.57, s.z_score.standard_deviation, 1E-2
|
357
|
+
assert_in_delta 434.64, s.z_score.mean, 1E-2
|
358
|
+
end
|
341
359
|
end
|