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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8592c5f27e6c601ae312bf1870259967e7763b28
4
- data.tar.gz: b1e23ffdfc15ee89ff25f8cf7d0a3f9ca8f27aa5
2
+ SHA256:
3
+ metadata.gz: 1a9d46106c13337d7b3b949a3984d57de664ba0f8f7931a4ac8aa91139e36a2b
4
+ data.tar.gz: ce02a111f04c4bc8aab30603d172e47bae8f62bd500484a5ea9b20d2438cb5cd
5
5
  SHA512:
6
- metadata.gz: 0a0bf6510034861d95b94abbe7bc6d13d38fa5c5db9d5eb62dec371b8b6a846a76e15de6fd0a1a8151d6459cdb0819fe85ea5503025c4cf49e331a39f7dcd8a8
7
- data.tar.gz: f841cbc883d82f78a834044e84857bc25d212c54da766085e5ea7fe0f7dcebf44044896a5009565a09e6d6183ad6fc991fab166a688f6ec2db57daf1ee9a48c2
6
+ metadata.gz: 44864c937a9f957f6aaf9a7fad4d5a300c75e4db9e69f882f1fc42ff07c9f811b405c70d7c0a8b312e698053aef63f787d26bb66a7b37f86c58c22e8bfcafdd2
7
+ data.tar.gz: 9a0dfb7c53d2c1487cb2f8597268b921dfdb0898e3130ca894cb0222dad2a1ee2ee54d466c56ae51ddc17063d35a7b05dde4e3a3c6fa080e720eba0ae9a00d44
data/Gemfile CHANGED
@@ -3,4 +3,3 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
- gem 'byebug', platform: :mri
@@ -1,20 +1,21 @@
1
- = MoreMath - More mathematics in Ruby
1
+ # MoreMath - More mathematics in Ruby
2
2
 
3
- == Description
3
+ ## Description
4
4
 
5
5
  Ruby library that contains various mathematical functions and algorithms.
6
6
 
7
- == Download
7
+ ## Download
8
8
 
9
9
  The homepage of this library is located at
10
10
 
11
- * http://github.com/flori/more_math
11
+ * http://github.com/flori/more_math
12
12
 
13
- == Author
13
+
14
+ ## Author
14
15
 
15
16
  Florian Frank mailto:flori@ping.de
16
17
 
17
- == License
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.rdoc'
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 "codeclimate-test-reporter"
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.0 }
21
- @b = proc { 1.0 }
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 = 1E-16, max_iterations = 1 << 31)
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
@@ -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 = 1E-16, max_iterations = 1 << 16)
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 = 1E-16, max_iterations = 1 << 16)
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 = 1E-16, max_iterations = 1 << 16)
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
- else
134
- def erf(x)
135
- Math.erf(x)
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
 
@@ -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, bins = 10)
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
- d = prepare_display(width)
33
- for l, bar, r in d
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
- # Returns an array of tuples (l, c, r) where +l+ is the left bin edge, +c+
47
- # the +width+-normalized frequence count value, and +r+ the right bin
48
- # edge. +width+ is usually an integer number representing the width of a
49
- # histogram bar.
50
- def prepare_display(width)
51
- factor = width.to_f / max_count
52
- @result.reverse_each.map { |bin| [ bin.left, (bin.count * factor).round, bin.right ] }
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 residues of this linear regression in relation to the given
35
+ # Returns the residuals of this linear regression in relation to the given
36
36
  # domain and image.
37
- def residues
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
@@ -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.residues
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 }
@@ -1,6 +1,6 @@
1
1
  module MoreMath
2
2
  # MoreMath version
3
- VERSION = '0.3.3'
3
+ VERSION = '1.0.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
data/more_math.gemspec CHANGED
@@ -1,52 +1,46 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: more_math 0.3.3 ruby lib
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.3.3"
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 = "2017-07-04"
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.rdoc".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 = [".codeclimate.yml".freeze, ".gitignore".freeze, ".rubocop.yml".freeze, ".travis.yml".freeze, "CHANGES".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.rdoc".freeze, "Rakefile".freeze, "VERSION".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_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]
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.rdoc".freeze]
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 = "2.6.11".freeze
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
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
28
- s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.9.1"])
29
- s.add_development_dependency(%q<rake>.freeze, [">= 0"])
30
- s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
31
- s.add_development_dependency(%q<test-unit>.freeze, [">= 0"])
32
- s.add_development_dependency(%q<codeclimate-test-reporter>.freeze, [">= 0"])
33
- s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.0"])
34
- s.add_runtime_dependency(%q<mize>.freeze, [">= 0"])
35
- else
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.9.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<codeclimate-test-reporter>.freeze, [">= 0"])
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
@@ -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, 25, 3.0], [1.0, 50, 2.0], [0.0, 50, 1.0]],
21
- histogram.instance_eval { prepare_display(50) }
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
- output_expected =
25
- " 2.50000 -|*************************\n 1.50000 -|*******************************"\
26
- "*******************\n 0.50000 -|**************************************************\nmax_count=2\n"
27
- assert_equal output_expected, output.string
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
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test_helper'
4
+ require 'more_math'
5
+
6
+ using MoreMath::Sequence::Refinement
7
+
8
+ class SequenceTest < Test::Unit::TestCase
9
+ def test_refinement
10
+ assert_kind_of MoreMath::Sequence, [1,2,3].to_seq
11
+ end
12
+ end
13
+
@@ -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] * (1 - 4.0 / (i + 1)) })
130
- @rand_down = Sequence.new(Array.new(rand.size) { |i| rand[i] * (1 + 4.0 / (i + 1)) })
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.residues.all? { |r| r.abs <= 1E-6 }
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.residues.all? { |r| r.abs <= 0.5 }
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 47.9812, @rand.linear_regression.b, 1E-4
232
+ assert_in_delta 48.0378, @rand.linear_regression.b, 1E-4
231
233
  assert @rand.linear_regression.slope_zero?
232
- assert_in_delta(-0.4019, @rand_down.linear_regression.a, 1E-4)
233
- assert_in_delta 82.7303, @rand_down.linear_regression.b, 1E-4
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 0.5151, @rand_up.linear_regression.a, 1E-4
236
- assert_in_delta(13.2320, @rand_up.linear_regression.b, 1E-4)
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(24.35, @rasi.linear_regression.b, 1E-2)
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.6372, @book.linear_regression.b, 1E-4)
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.residues.all? { |r| r.abs <= 1E-6 }
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