ruby_native_statistics 0.8.2 → 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
2
  SHA256:
3
- metadata.gz: 58cae049ef922fead26f20dff3714c2f9c1bcccd95fe38228add9d7f6d57e787
4
- data.tar.gz: 3529205f8a822cc3c418d54d36d4651708384cc885f990517e03fc0f1c8edb15
3
+ metadata.gz: 73a2fd8450ce06d2b1d1292bfb91e41e6d764651b850895a9b85fd1d9c2a9596
4
+ data.tar.gz: 0ca7e20b6b91e1eacef10a844a07819fb5562fdc7e44c0ecbf268ff5134b69b5
5
5
  SHA512:
6
- metadata.gz: fe760b4680dbf1d11685404718589c7d24c659d086c422977ee3e8c1223073331dfb125c83275a9254ce7fa161b33b388cd66008f6de429417c0ba92acedad87
7
- data.tar.gz: 768f2745a827ffa45fe34a89ff7eb4cc1f4d444bfa6c99f2c4bcd75058131b25cfc17f93ee58599511f8e6a265335af7480dc7890988c8e10e5aa318f4d4514c
6
+ metadata.gz: a04f40565730406b34a3591d734e9d33286d41abc19ff49736d715f91b916995e9cdc9b1d6014c8b7745fe44aad1701bdd5dba49aee0e0ab3f39f6fab85a430b
7
+ data.tar.gz: b0cc9f0fff6e26fbbfab5b27d69cfe7b7c19465944a1e0be14455380a312d536ff388246fe1766734bd1b210420acc04f58a71e07448275c6cbf5f19a1e9c969
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior:
15
+ 1. Go to '...'
16
+ 2. Click on '....'
17
+ 3. Scroll down to '....'
18
+ 4. See error
19
+
20
+ **Expected behavior**
21
+ A clear and concise description of what you expected to happen.
22
+
23
+ **Screenshots**
24
+ If applicable, add screenshots to help explain your problem.
25
+
26
+ **Desktop (please complete the following information):**
27
+ - OS: [e.g. iOS]
28
+ - Version [e.g. 22]
29
+
30
+ **Additional context**
31
+ Add any other context about the problem here.
@@ -13,29 +13,17 @@ jobs:
13
13
  strategy:
14
14
  matrix:
15
15
  ruby:
16
- - 2.4.9
17
- - 2.5.7
18
- - 2.6.5
19
- - 2.7.0
16
+ - 2.6.9
17
+ - 2.7.5
18
+ - 3.0.3
19
+ - 3.1.0
20
20
  steps:
21
- - name: Setup Ruby
22
- uses: eregon/use-ruby-action@master
21
+ - uses: actions/checkout@v2
22
+
23
+ - uses: ruby/setup-ruby@v1
23
24
  with:
24
25
  ruby-version: ${{ matrix.ruby }}
25
26
 
26
- - name: Checkout
27
- uses: actions/checkout@master
28
-
29
- - name: Install Bundler
30
- run: gem install bundler -v 2.1.2
31
-
32
- - name: Install gems
33
- run: bundle
34
-
35
- - name: Run tests
36
- run: rake
37
-
38
- - name: Coveralls
39
- uses: coverallsapp/github-action@master
40
- with:
41
- github-token: ${{ secrets.GITHUB_TOKEN }}
27
+ - run: gem install bundler --version 2.3.4 --no-document
28
+ - run: bundle
29
+ - run: rake
@@ -0,0 +1,21 @@
1
+ {
2
+ "configurations": [
3
+ {
4
+ "name": "Mac",
5
+ "includePath": [
6
+ "${workspaceFolder}/**",
7
+ "/Users/corybuecker/.asdf/installs/ruby/2.7.0/include/ruby-2.7.0",
8
+ "/Users/corybuecker/.asdf/installs/ruby/2.7.0/include/ruby-2.7.0/x86_64-darwin19"
9
+ ],
10
+ "defines": [],
11
+ "macFrameworkPath": [
12
+ "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"
13
+ ],
14
+ "compilerPath": "/usr/bin/clang",
15
+ "cStandard": "c11",
16
+ "cppStandard": "c++17",
17
+ "intelliSenseMode": "clang-x64"
18
+ }
19
+ ],
20
+ "version": 4
21
+ }
@@ -3,5 +3,9 @@
3
3
  "editor.tabSize": 2,
4
4
  "search.useGlobalIgnoreFiles": true,
5
5
  "editor.wordWrap": "on",
6
- "editor.renderWhitespace": "all"
6
+ "editor.renderWhitespace": "all",
7
+ "files.associations": {
8
+ "conversions.h": "c",
9
+ "algorithm": "c"
10
+ }
7
11
  }
data/Gemfile CHANGED
@@ -2,8 +2,9 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem "rake", "~> 12.0"
6
- gem "minitest", "~> 5.0"
5
+ gem "rake", "~> 13.0"
6
+ gem "minitest", "~> 5.15"
7
+ gem "minitest-reporters", "~> 1.4"
7
8
  gem "rake-compiler", "~> 1.1"
8
- gem "simplecov", "~> 0.17", require: false
9
- gem "simplecov-lcov", "~> 0.7", require: false
9
+ gem "simplecov", "~> 0.21", require: false
10
+ gem "simplecov-lcov", "~> 0.8", require: false
data/Gemfile.lock CHANGED
@@ -1,34 +1,43 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby_native_statistics (0.8)
4
+ ruby_native_statistics (1.0.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- docile (1.3.2)
10
- json (2.3.0)
11
- minitest (5.13.0)
12
- rake (12.3.3)
13
- rake-compiler (1.1.0)
9
+ ansi (1.5.0)
10
+ builder (3.2.4)
11
+ docile (1.4.0)
12
+ minitest (5.15.0)
13
+ minitest-reporters (1.4.3)
14
+ ansi
15
+ builder
16
+ minitest (>= 5.0)
17
+ ruby-progressbar
18
+ rake (13.0.6)
19
+ rake-compiler (1.1.7)
14
20
  rake
15
- simplecov (0.17.1)
21
+ ruby-progressbar (1.11.0)
22
+ simplecov (0.21.2)
16
23
  docile (~> 1.1)
17
- json (>= 1.8, < 3)
18
- simplecov-html (~> 0.10.0)
19
- simplecov-html (0.10.2)
20
- simplecov-lcov (0.7.0)
24
+ simplecov-html (~> 0.11)
25
+ simplecov_json_formatter (~> 0.1)
26
+ simplecov-html (0.12.3)
27
+ simplecov-lcov (0.8.0)
28
+ simplecov_json_formatter (0.1.3)
21
29
 
22
30
  PLATFORMS
23
31
  ruby
24
32
 
25
33
  DEPENDENCIES
26
- minitest (~> 5.0)
27
- rake (~> 12.0)
34
+ minitest (~> 5.15)
35
+ minitest-reporters (~> 1.4)
36
+ rake (~> 13.0)
28
37
  rake-compiler (~> 1.1)
29
38
  ruby_native_statistics!
30
- simplecov (~> 0.17)
31
- simplecov-lcov (~> 0.7)
39
+ simplecov (~> 0.21)
40
+ simplecov-lcov (~> 0.8)
32
41
 
33
42
  BUNDLED WITH
34
- 2.1.2
43
+ 2.3.3
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # Ruby Native Statistics ![](https://github.com/corybuecker/ruby-native-statistics/workflows/Test%20suite/badge.svg) [![Coverage Status](https://coveralls.io/repos/github/corybuecker/ruby-native-statistics/badge.svg?branch=master)](https://coveralls.io/github/corybuecker/ruby-native-statistics?branch=master)
1
+ # Ruby Native Statistics
2
+
3
+ [![Test status](https://github.com/corybuecker/ruby-native-statistics/workflows/Test%20suite/badge.svg)](https://github.com/corybuecker/ruby-native-statistics/actions)
2
4
 
3
5
  This is a native extension to Ruby that adds native (C) statistical functions to the Array class. At present the following functions are provided:
4
6
 
@@ -6,14 +8,32 @@ This is a native extension to Ruby that adds native (C) statistical functions to
6
8
  - [Population Standard Deviation](https://en.wikipedia.org/wiki/Standard_deviation#Uncorrected_sample_standard_deviation) (stdevp)
7
9
  - [Sample Variance](https://en.wikipedia.org/wiki/Variance#Population_variance_and_sample_variance) (var)
8
10
  - [Population Variance](https://en.wikipedia.org/wiki/Variance#Population_variance_and_sample_variance) (varp)
11
+ - [Median](https://en.wikipedia.org/wiki/Median) (median)
9
12
  - [Mean](https://en.wikipedia.org/wiki/Arithmetic_mean) (mean)
13
+ - [Percentile](https://en.wikipedia.org/wiki/Quantile) (percentile)
14
+
15
+ Check the Github Actions build to see the currently supported versions of Ruby. This list will match whatever stable versions are specified at https://www.ruby-lang.org/en/downloads/.
16
+
17
+ It is generally more performant than calculating these values with pure Ruby. For a comparison, run the benchmarks with `rake benchmark`.
18
+
19
+ | Test (Ruby 3.1.0) | Run 1 | Run 2 | Run 3 | Run 4 | Run 5 |
20
+ | ------------------ | -------- | -------- | -------- | -------- | -------- |
21
+ | bench_native_stdev | 0.000074 | 0.000070 | 0.000071 | 0.000070 | 0.000068 |
22
+ | bench_ruby_stdev | 0.000945 | 0.000942 | 0.000944 | 0.000941 | 0.000969 |
23
+
24
+ | Test (Ruby 3.1.0) | Run 1 | Run 2 | Run 3 | Run 4 | Run 5 |
25
+ | ------------------- | -------- | -------- | -------- | -------- | -------- |
26
+ | bench_native_median | 0.000813 | 0.000773 | 0.000774 | 0.000776 | 0.000773 |
27
+ | bench_ruby_median | 0.000816 | 0.000797 | 0.000832 | 0.000797 | 0.000799 |
10
28
 
11
- Check the CircleCI build to see the currently supported versions of Ruby. This list will match whatever stable versions are specified at https://www.ruby-lang.org/en/downloads/.
29
+ | Test (Ruby 3.1.0) | Run 1 | Run 2 | Run 3 | Run 4 | Run 5 |
30
+ | ----------------- | -------- | -------- | -------- | -------- | -------- |
31
+ | bench_native_mean | 0.000040 | 0.000038 | 0.000038 | 0.000037 | 0.000037 |
32
+ | bench_ruby_mean | 0.000347 | 0.000350 | 0.000358 | 0.000349 | 0.000347 |
12
33
 
13
- It is much more performant than calculating the standard deviation with pure Ruby. For a comparison, run the benchmarks with rake.
34
+ ## Found a bug? Need a function?
14
35
 
15
- bench_native_dispersion 0.000425 0.000341 0.000420 0.000324 0.000319
16
- bench_ruby_dispersion 0.002168 0.002156 0.002148 0.002149 0.002151
36
+ If you found a bug or need a particular function, please let me know! I work on this gem in my spare time, mainly for learning purposes. Feel free to open a PR or a Github issue and I'll take a look as soon as possible.
17
37
 
18
38
  ## Usage
19
39
 
@@ -29,6 +49,18 @@ It is much more performant than calculating the standard deviation with pure Rub
29
49
  # calculate mean
30
50
  p r.mean
31
51
 
52
+ # calculate median
53
+ p r.median
54
+
55
+ # calculate percentile
56
+ p r.percentile(0.3333)
57
+
58
+ ## Implementation notes
59
+
60
+ ### Percentile
61
+
62
+ Percentile uses the same rounding method as Excel, sometimes called R7.
63
+
32
64
  ## Links
33
65
 
34
66
  This is the third version of this gem, and it is a total rewrite of a SWIG-based design. Lots of thanks to the following resources:
data/Rakefile CHANGED
@@ -1,12 +1,8 @@
1
1
  require "rake/extensiontask"
2
2
  require "rake/testtask"
3
3
 
4
- Rake::ExtensionTask.new "dispersion" do |ext|
5
- ext.lib_dir = "lib"
6
- end
7
-
8
- Rake::ExtensionTask.new "mathematics" do |ext|
9
- ext.lib_dir = "lib"
4
+ Rake::ExtensionTask.new "ruby_native_statistics" do |ext|
5
+ ext.lib_dir = "lib/ruby_native_statistics"
10
6
  end
11
7
 
12
8
  Rake::TestTask.new(:test) do |t|
@@ -15,10 +11,10 @@ Rake::TestTask.new(:test) do |t|
15
11
  t.test_files = FileList["test/**/*_test.rb"]
16
12
  end
17
13
 
18
- Rake::TestTask.new(:benchmark) do |t|
14
+ Rake::TestTask.new(benchmark: [:clean, :compile]) do |t|
19
15
  t.libs << "test"
20
16
  t.libs << "lib"
21
17
  t.test_files = FileList["test/**/*_benchmark.rb"]
22
18
  end
23
19
 
24
- task :default => [:compile, :test]
20
+ task :default => [:clean, :compile, :test]
File without changes
data/changelog.md CHANGED
@@ -1,3 +1,12 @@
1
+ # Version 1.0.0
2
+
3
+ - Update all supported Ruby versions
4
+ - Update all dependencies
5
+
6
+ # Version 0.9.0
7
+
8
+ - Add median function
9
+
1
10
  # Version 0.8.2
2
11
 
3
12
  - Bug fix for build process
@@ -0,0 +1,45 @@
1
+ #include "conversions.h"
2
+
3
+ int compare_doubles(const void *a, const void *b)
4
+ {
5
+ double *dbl_a = (double *)a;
6
+ double *dbl_b = (double *)b;
7
+
8
+ double cmp_a = *dbl_a;
9
+ double cmp_b = *dbl_b;
10
+
11
+ return (cmp_a - cmp_b);
12
+ }
13
+
14
+ double *sorted_ruby_array(VALUE array, long array_length)
15
+ {
16
+ long i;
17
+ double *working_array;
18
+
19
+ working_array = malloc(array_length * sizeof(double));
20
+
21
+ if (working_array == NULL)
22
+ {
23
+ rb_raise(rb_eStandardError, "unknown problem calculating median (possibly array is too large)");
24
+ }
25
+
26
+ for (i = 0; i < array_length; i++)
27
+ {
28
+ VALUE item = rb_ary_entry(array, i);
29
+
30
+ if (!RB_INTEGER_TYPE_P(item) && !RB_FLOAT_TYPE_P(item))
31
+ {
32
+ free(working_array);
33
+ rb_raise(rb_eTypeError, "element is not a number");
34
+ }
35
+
36
+ working_array[i] = NUM2DBL(item);
37
+ }
38
+
39
+ // Reminder to myself as I'm learning C. Using an array as a function parameter decays that reference
40
+ // to a pointer to the first element in the array.
41
+ // https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Function-Parameters
42
+ qsort(working_array, array_length, sizeof(double), compare_doubles);
43
+
44
+ return working_array;
45
+ }
@@ -0,0 +1,5 @@
1
+ #include <stdbool.h>
2
+ #include <ruby.h>
3
+
4
+ int compare_doubles(const void *a, const void *b);
5
+ double *sorted_ruby_array(VALUE array, long array_length);
@@ -0,0 +1,102 @@
1
+ #include "dispersion.h"
2
+
3
+ VALUE rb_sample_standard_deviation(VALUE self)
4
+ {
5
+ unsigned int array_length;
6
+
7
+ Check_Type(self, T_ARRAY);
8
+
9
+ array_length = rb_long2int(RARRAY_LEN(self));
10
+
11
+ if (array_length <= 1)
12
+ {
13
+ rb_raise(rb_eRangeError, "array must have more than one element");
14
+ }
15
+
16
+ return DBL2NUM(sqrt((calculate_total_distance_from_mean(self, array_length) / (array_length - 1))));
17
+ }
18
+
19
+ VALUE rb_sample_variance(VALUE self)
20
+ {
21
+ unsigned int array_length;
22
+
23
+ Check_Type(self, T_ARRAY);
24
+
25
+ array_length = rb_long2int(RARRAY_LEN(self));
26
+
27
+ if (array_length <= 1)
28
+ {
29
+ rb_raise(rb_eRangeError, "array must have more than one element");
30
+ }
31
+
32
+ return DBL2NUM((calculate_total_distance_from_mean(self, array_length) / (array_length - 1)));
33
+ }
34
+
35
+ VALUE rb_population_standard_deviation(VALUE self)
36
+ {
37
+ unsigned int array_length;
38
+
39
+ Check_Type(self, T_ARRAY);
40
+
41
+ array_length = rb_long2int(RARRAY_LEN(self));
42
+
43
+ if (array_length <= 1)
44
+ {
45
+ rb_raise(rb_eRangeError, "array must have more than one element");
46
+ }
47
+
48
+ return DBL2NUM(sqrt(calculate_total_distance_from_mean(self, array_length) / array_length));
49
+ }
50
+
51
+ VALUE rb_population_variance(VALUE self)
52
+ {
53
+ unsigned int array_length;
54
+
55
+ Check_Type(self, T_ARRAY);
56
+
57
+ array_length = rb_long2int(RARRAY_LEN(self));
58
+
59
+ if (array_length <= 1)
60
+ {
61
+ rb_raise(rb_eRangeError, "array must have more than one element");
62
+ }
63
+
64
+ return DBL2NUM(calculate_total_distance_from_mean(self, array_length) / array_length);
65
+ }
66
+
67
+ VALUE rb_percentile(VALUE self, VALUE r_percentile)
68
+ {
69
+ double result;
70
+ Check_Type(self, T_ARRAY);
71
+
72
+ long array_length = rb_array_len(self);
73
+ double percentile = NUM2DBL(r_percentile);
74
+
75
+ if (array_length == 0)
76
+ {
77
+ rb_raise(rb_eRangeError, "array must have at least one element");
78
+ }
79
+
80
+ if (percentile < 0 || percentile > 1)
81
+ {
82
+ rb_raise(rb_eRangeError, "percentile must be between 0 and 1 inclusive");
83
+ }
84
+
85
+ double *sorted_array = sorted_ruby_array(self, array_length);
86
+
87
+ double h = (array_length - 1) * percentile + 1;
88
+
89
+ if (trunc(h) == h)
90
+ {
91
+ result = sorted_array[(long)h - 1];
92
+ }
93
+ else
94
+ {
95
+ long h_floor = (long)trunc(h);
96
+ result = (h - h_floor) * (sorted_array[h_floor] - sorted_array[h_floor - 1]) + sorted_array[h_floor - 1];
97
+ }
98
+
99
+ free(sorted_array);
100
+
101
+ return DBL2NUM(result);
102
+ }
@@ -1,5 +1,10 @@
1
- VALUE DispersionModule = Qnil;
1
+ #include <ruby.h>
2
+ #include <math.h>
3
+ #include "conversions.h"
4
+ #include "mathematics.h"
5
+
2
6
  VALUE rb_sample_standard_deviation(VALUE self);
3
7
  VALUE rb_population_standard_deviation(VALUE self);
4
8
  VALUE rb_sample_variance(VALUE self);
5
9
  VALUE rb_population_variance(VALUE self);
10
+ VALUE rb_percentile(VALUE self, VALUE percentile);
@@ -0,0 +1,9 @@
1
+ require "mkmf"
2
+
3
+ abort "missing pow()" unless have_func "pow"
4
+ abort "missing sqrt()" unless have_func "sqrt"
5
+ abort "missing malloc()" unless have_func "malloc"
6
+ abort "missing free()" unless have_func "free"
7
+ abort "missing trunc()" unless have_func "trunc"
8
+
9
+ create_makefile "ruby_native_statistics/ruby_native_statistics"
@@ -0,0 +1,84 @@
1
+
2
+ #include "mathematics.h"
3
+
4
+ double calculate_mean(VALUE array, unsigned long array_length)
5
+ {
6
+ unsigned long i;
7
+ double total = 0;
8
+ double mean = 0;
9
+
10
+ for (i = 0; i < array_length; i++)
11
+ {
12
+ total += rb_num2dbl(rb_ary_entry(array, i));
13
+ }
14
+
15
+ mean = total / array_length;
16
+
17
+ return mean;
18
+ }
19
+
20
+ double calculate_total_distance_from_mean(VALUE array, unsigned long array_length)
21
+ {
22
+ unsigned long i;
23
+ double mean = 0;
24
+ double total_distance_from_mean = 0;
25
+
26
+ mean = calculate_mean(array, array_length);
27
+
28
+ for (i = 0; i < array_length; i++)
29
+ {
30
+ total_distance_from_mean += pow((rb_num2dbl(rb_ary_entry(array, i)) - mean), 2);
31
+ }
32
+
33
+ return total_distance_from_mean;
34
+ }
35
+
36
+ VALUE rb_mean(VALUE self)
37
+ {
38
+ unsigned int array_length;
39
+
40
+ Check_Type(self, T_ARRAY);
41
+
42
+ array_length = rb_long2int(RARRAY_LEN(self));
43
+
44
+ if (array_length <= 0)
45
+ {
46
+ rb_raise(rb_eRangeError, "array must have at least one element");
47
+ }
48
+
49
+ return DBL2NUM(calculate_mean(self, array_length));
50
+ }
51
+
52
+ VALUE rb_median(VALUE self)
53
+ {
54
+ unsigned long array_length;
55
+
56
+ VALUE result;
57
+
58
+ Check_Type(self, T_ARRAY);
59
+
60
+ array_length = RARRAY_LEN(self);
61
+
62
+ if (array_length <= 0)
63
+ {
64
+ rb_raise(rb_eRangeError, "array must have at least one element");
65
+ }
66
+
67
+ bool array_even_size = (array_length % 2) == 0;
68
+ unsigned long middle = (long)floor(array_length / 2.0);
69
+
70
+ double *working_array = sorted_ruby_array(self, array_length);
71
+
72
+ if (!array_even_size)
73
+ {
74
+ result = DBL2NUM(working_array[middle]);
75
+ }
76
+ else
77
+ {
78
+ result = DBL2NUM((working_array[middle - 1] + working_array[middle]) / 2);
79
+ }
80
+
81
+ free(working_array);
82
+
83
+ return result;
84
+ }
@@ -1,4 +1,9 @@
1
- VALUE MathematicsModule = Qnil;
1
+ #include <stdbool.h>
2
+ #include <ruby.h>
3
+ #include "conversions.h"
4
+
2
5
  VALUE rb_mean(VALUE self);
6
+ VALUE rb_median(VALUE self);
7
+
3
8
  double calculate_mean(VALUE array, unsigned long array_length);
4
- double calculate_total_distance_from_mean(VALUE array, unsigned long array_length);
9
+ double calculate_total_distance_from_mean(VALUE array, unsigned long array_length);
@@ -0,0 +1,16 @@
1
+ #include "ruby_native_statistics.h"
2
+
3
+ void Init_ruby_native_statistics()
4
+ {
5
+ DispersionModule = rb_define_module("Dispersion");
6
+ rb_define_method(DispersionModule, "stdev", rb_sample_standard_deviation, 0);
7
+ rb_define_method(DispersionModule, "stdevs", rb_sample_standard_deviation, 0);
8
+ rb_define_method(DispersionModule, "stdevp", rb_population_standard_deviation, 0);
9
+ rb_define_method(DispersionModule, "var", rb_sample_variance, 0);
10
+ rb_define_method(DispersionModule, "varp", rb_population_variance, 0);
11
+ rb_define_method(DispersionModule, "percentile", rb_percentile, 1);
12
+
13
+ MathematicsModule = rb_define_module("Mathematics");
14
+ rb_define_method(MathematicsModule, "mean", rb_mean, 0);
15
+ rb_define_method(MathematicsModule, "median", rb_median, 0);
16
+ }
@@ -0,0 +1,5 @@
1
+ #include "dispersion.h"
2
+ #include "mathematics.h"
3
+
4
+ VALUE MathematicsModule = Qnil;
5
+ VALUE DispersionModule = Qnil;
@@ -1,3 +1,3 @@
1
1
  module RubyNativeStatistics
2
- VERSION = "0.8.2"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,6 +1,5 @@
1
1
  require "ruby_native_statistics/version"
2
- require "mathematics"
3
- require "dispersion"
2
+ require "ruby_native_statistics/ruby_native_statistics"
4
3
 
5
4
  class Array
6
5
  include Mathematics
@@ -7,10 +7,10 @@ Gem::Specification.new do |spec|
7
7
  spec.email = ["cory.buecker@gmail.com"]
8
8
 
9
9
  spec.license = "Unlicense"
10
- spec.summary = "This is a native extension to Ruby that adds various statistical functions to the Array class."
10
+ spec.summary = "High performance, native (C) implementations of various statistical functions."
11
11
  spec.homepage = "https://github.com/corybuecker/ruby-native-statistics"
12
12
 
13
- spec.required_ruby_version = Gem::Requirement.new(">= 2.4.9")
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.6")
14
14
 
15
15
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
16
16
 
@@ -21,5 +21,5 @@ Gem::Specification.new do |spec|
21
21
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
22
  spec.require_paths = ["lib"]
23
23
 
24
- spec.extensions = %w[ext/mathematics/extconf.rb ext/dispersion/extconf.rb]
24
+ spec.extensions = %w[ext/ruby_native_statistics/extconf.rb]
25
25
  end
metadata CHANGED
@@ -1,39 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_native_statistics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cory Buecker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-11 00:00:00.000000000 Z
11
+ date: 2022-01-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
15
15
  - cory.buecker@gmail.com
16
16
  executables: []
17
17
  extensions:
18
- - ext/mathematics/extconf.rb
19
- - ext/dispersion/extconf.rb
18
+ - ext/ruby_native_statistics/extconf.rb
20
19
  extra_rdoc_files: []
21
20
  files:
21
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
22
22
  - ".github/workflows/main.yml"
23
23
  - ".gitignore"
24
+ - ".vscode/c_cpp_properties.json"
24
25
  - ".vscode/settings.json"
25
26
  - Gemfile
26
27
  - Gemfile.lock
27
- - LICENSE
28
28
  - README.md
29
29
  - Rakefile
30
+ - UNLICENSE
30
31
  - changelog.md
31
- - ext/dispersion/dispersion.c
32
- - ext/dispersion/dispersion.h
33
- - ext/dispersion/extconf.rb
34
- - ext/mathematics/extconf.rb
35
- - ext/mathematics/mathematics.c
36
- - ext/mathematics/mathematics.h
32
+ - ext/ruby_native_statistics/conversions.c
33
+ - ext/ruby_native_statistics/conversions.h
34
+ - ext/ruby_native_statistics/dispersion.c
35
+ - ext/ruby_native_statistics/dispersion.h
36
+ - ext/ruby_native_statistics/extconf.rb
37
+ - ext/ruby_native_statistics/mathematics.c
38
+ - ext/ruby_native_statistics/mathematics.h
39
+ - ext/ruby_native_statistics/ruby_native_statistics.c
40
+ - ext/ruby_native_statistics/ruby_native_statistics.h
37
41
  - lib/ruby_native_statistics.rb
38
42
  - lib/ruby_native_statistics/version.rb
39
43
  - ruby_native_statistics.gemspec
@@ -53,16 +57,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
53
57
  requirements:
54
58
  - - ">="
55
59
  - !ruby/object:Gem::Version
56
- version: 2.4.9
60
+ version: '2.6'
57
61
  required_rubygems_version: !ruby/object:Gem::Requirement
58
62
  requirements:
59
63
  - - ">="
60
64
  - !ruby/object:Gem::Version
61
65
  version: '0'
62
66
  requirements: []
63
- rubygems_version: 3.1.2
67
+ rubygems_version: 3.0.3.1
64
68
  signing_key:
65
69
  specification_version: 4
66
- summary: This is a native extension to Ruby that adds various statistical functions
67
- to the Array class.
70
+ summary: High performance, native (C) implementations of various statistical functions.
68
71
  test_files: []
@@ -1,68 +0,0 @@
1
- #include "ruby.h"
2
- #include "dispersion.h"
3
- #include "../mathematics/mathematics.h"
4
-
5
- void Init_dispersion() {
6
- DispersionModule = rb_define_module("Dispersion");
7
- rb_define_method(DispersionModule, "stdev", rb_sample_standard_deviation, 0);
8
- rb_define_method(DispersionModule, "stdevs", rb_sample_standard_deviation, 0);
9
- rb_define_method(DispersionModule, "stdevp", rb_population_standard_deviation, 0);
10
- rb_define_method(DispersionModule, "var", rb_sample_variance, 0);
11
- rb_define_method(DispersionModule, "varp", rb_population_variance, 0);
12
- }
13
-
14
- VALUE rb_sample_standard_deviation(VALUE self) {
15
- unsigned int array_length;
16
-
17
- Check_Type(self, T_ARRAY);
18
-
19
- array_length = rb_long2int(RARRAY_LEN(self));
20
-
21
- if (array_length <= 1) {
22
- rb_raise(rb_eRangeError, "array must have more than one element");
23
- }
24
-
25
- return DBL2NUM(sqrt((calculate_total_distance_from_mean(self, array_length)/(array_length - 1))));
26
- }
27
-
28
- VALUE rb_sample_variance(VALUE self) {
29
- unsigned int array_length;
30
-
31
- Check_Type(self, T_ARRAY);
32
-
33
- array_length = rb_long2int(RARRAY_LEN(self));
34
-
35
- if (array_length <= 1) {
36
- rb_raise(rb_eRangeError, "array must have more than one element");
37
- }
38
-
39
- return DBL2NUM((calculate_total_distance_from_mean(self, array_length)/(array_length - 1)));
40
- }
41
-
42
- VALUE rb_population_standard_deviation(VALUE self) {
43
- unsigned int array_length;
44
-
45
- Check_Type(self, T_ARRAY);
46
-
47
- array_length = rb_long2int(RARRAY_LEN(self));
48
-
49
- if (array_length <= 1) {
50
- rb_raise(rb_eRangeError, "array must have more than one element");
51
- }
52
-
53
- return DBL2NUM(sqrt(calculate_total_distance_from_mean(self, array_length) / array_length));
54
- }
55
-
56
- VALUE rb_population_variance(VALUE self) {
57
- unsigned int array_length;
58
-
59
- Check_Type(self, T_ARRAY);
60
-
61
- array_length = rb_long2int(RARRAY_LEN(self));
62
-
63
- if (array_length <= 1) {
64
- rb_raise(rb_eRangeError, "array must have more than one element");
65
- }
66
-
67
- return DBL2NUM(calculate_total_distance_from_mean(self, array_length) / array_length);
68
- }
@@ -1,3 +0,0 @@
1
- require "mkmf"
2
-
3
- create_makefile "dispersion"
@@ -1,5 +0,0 @@
1
- require "mkmf"
2
-
3
- abort "missing pow()" unless have_func "pow"
4
-
5
- create_makefile "mathematics"
@@ -1,50 +0,0 @@
1
- #include "ruby.h"
2
- #include "mathematics.h"
3
-
4
- void Init_mathematics() {
5
- MathematicsModule = rb_define_module("Mathematics");
6
- rb_define_method(MathematicsModule, "mean", rb_mean, 0);
7
- }
8
-
9
- double calculate_mean(VALUE array, unsigned long array_length){
10
- unsigned long i;
11
- double total = 0;
12
- double mean = 0;
13
-
14
- for(i = 0; i < array_length; i++){
15
- total += rb_num2dbl(rb_ary_entry(array, i));
16
- }
17
-
18
- mean = total / array_length;
19
-
20
- return mean;
21
- }
22
-
23
- double calculate_total_distance_from_mean(VALUE array, unsigned long array_length){
24
- unsigned long i;
25
- double mean = 0;
26
- double total_distance_from_mean = 0;
27
-
28
- mean = calculate_mean(array, array_length);
29
-
30
- for(i = 0; i < array_length; i++){
31
- total_distance_from_mean += pow((rb_num2dbl(rb_ary_entry(array, i)) - mean), 2);
32
- }
33
-
34
- return total_distance_from_mean;
35
- }
36
-
37
- VALUE rb_mean(VALUE self) {
38
- unsigned int array_length;
39
-
40
- Check_Type(self, T_ARRAY);
41
-
42
- array_length = rb_long2int(RARRAY_LEN(self));
43
-
44
- if (array_length <= 0) {
45
- rb_raise(rb_eRangeError, "array must have at least one element");
46
- }
47
-
48
- return DBL2NUM(calculate_mean(self, array_length));
49
- }
50
-