ruby_native_statistics 0.8.2 → 1.0.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.
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
-