enumerable-statistics 2.0.1 → 2.0.8

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: e593e551f4f9b857a009db71093abab619e96680c4d15fc0eaa3a96c6e622bd4
4
- data.tar.gz: eb449c789843e7e3e2c435890b8a9281d49cb6cdaad4ebbfc979b959413f617f
3
+ metadata.gz: 815b5f1b539e61935a709b7f859aeae73dd379959d8aa5e56551b650d20c7abc
4
+ data.tar.gz: be09795e4203a023e23a20b99c2bdd051ace5292ea7c67d6000cda0c3ed7c822
5
5
  SHA512:
6
- metadata.gz: 8866ba9d47c0715b82ffe7370b1fe8f683e1c1a17fd2dfee50db06c536cfa25b469bbf94a0f23c24ce2179c9d81203b761f8d17beadf113752b4f89490a48a2f
7
- data.tar.gz: 942e4dacc202cef906e631c38d9450045f9712ffed811b35f7f28fafeecc0e92f70196b0d8d8053423266d60210a1f556ed600d4c2c2b0ee5320aa97830cab47
6
+ metadata.gz: 3b2af05ed047b86529af90b7c18091d04055b1ded985614a6e4c7422706bd1453bb993a3b84e4b2821c8ff725efc62edb09505e1f3e59865faa71921296cd45d
7
+ data.tar.gz: 97d2f6044a4ebb1a1ca4d068f999192c3255bf8213262c6d038007404be79ca36cc6eaeefab0830e0aa45a658d4e083024ad3a116040ee75e9acbda31984b69a
@@ -0,0 +1,64 @@
1
+ name: CI
2
+
3
+ on:
4
+ - push
5
+
6
+ jobs:
7
+ cruby:
8
+ name: Test
9
+ runs-on: ${{ matrix.os }}
10
+
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ os:
15
+ - ubuntu-latest
16
+ - macos-latest
17
+ - windows-latest
18
+ ruby:
19
+ - 3.3
20
+ - 3.2
21
+ - 3.1
22
+ - 3.0
23
+ - 2.7
24
+ - 2.6
25
+ - 2.5
26
+ - 2.4
27
+ - debug
28
+ exclude:
29
+ - os: macos-latest
30
+ ruby: 2.5
31
+ - os: macos-latest
32
+ ruby: 2.4
33
+ - os: windows-latest
34
+ ruby: debug
35
+
36
+ steps:
37
+ - uses: actions/checkout@v2
38
+
39
+ - name: Setup Ruby
40
+ uses: ruby/setup-ruby@v1
41
+ with:
42
+ ruby-version: ${{ matrix.ruby }}
43
+
44
+ - name: Detect installable bundler version
45
+ run: |
46
+ case "${{ matrix.ruby }}" in
47
+ 2.7|2.6) bundler_version="2.4.22" ;;
48
+ 2.5|2.4) bundler_version="2.3.27" ;;
49
+ *) bundler_version="" ;;
50
+ esac
51
+ echo "bundler_version=$bundler_version" >> $GITHUB_ENV
52
+ shell: bash
53
+
54
+ - run: gem install bundler${bundler_version:+ -v $bundler_version}
55
+ shell: bash
56
+
57
+ - run: bundle install
58
+
59
+ - run: rake --trace compile
60
+
61
+ - run: rake build
62
+ - run: gem install pkg/*gem
63
+
64
+ - run: rake
data/CHANGELOG.md CHANGED
@@ -1,3 +1,35 @@
1
+ # 2.0.8
2
+
3
+ - Prohibit the use of both `nbins` and `edges` kwargs simultaneously in the `histogram` method.
4
+ - Support `skip_na` kwarg in `sum` and related methods.
5
+ - Support Ruby 3.4+.
6
+
7
+ # 2.0.7
8
+
9
+ - Fix the bug of histogram with bin range that is smaller than value range
10
+
11
+ # 2.0.6
12
+
13
+ - Add edges parameter in histogram
14
+ - Rename parameter in histogram to fix typo: `weight` to `weights`
15
+
16
+ # 2.0.5
17
+
18
+ - Add weighted histogram support
19
+
20
+ # 2.0.4
21
+
22
+ - Add `find_min`, `find_max`, `argmin`, `argmax` methods
23
+ - Fix `nbin=:auto` case in `histogram` method
24
+
25
+ # 2.0.3
26
+
27
+ - Ractor-safe version
28
+
29
+ # 2.0.2
30
+
31
+ - Support Ruby 3.0
32
+
1
33
  # 2.0.1
2
34
 
3
35
  - Fix a bug of `histogram` (#9)
data/Rakefile CHANGED
@@ -8,7 +8,14 @@ Rake::ExtensionTask.new('enumerable/statistics/extension')
8
8
 
9
9
  directory 'lib/enumerable/statistics'
10
10
 
11
+ desc "Run test"
12
+ task :test do
13
+ ruby("test/run-test.rb")
14
+ end
15
+ task :test => :compile
16
+
11
17
  RSpec::Core::RakeTask.new(:spec)
18
+ task :spec => :compile
12
19
 
13
20
  task :bench do
14
21
  puts "# sum\n"
@@ -20,3 +27,5 @@ task :bench do
20
27
  puts "# variance\n"
21
28
  system('benchmark-driver bench/variance.yml')
22
29
  end
30
+
31
+ task default: [:test, :spec]
@@ -27,10 +27,11 @@ Gem::Specification.new do |spec|
27
27
 
28
28
  spec.required_ruby_version = '>= 2.4'
29
29
 
30
- spec.add_development_dependency "bundler", ">= 1.17.2"
30
+ spec.add_development_dependency "bundler"
31
31
  spec.add_development_dependency "rake"
32
32
  spec.add_development_dependency "rake-compiler", ">= 0.9.8"
33
33
  spec.add_development_dependency "rspec", ">= 3.4"
34
+ spec.add_development_dependency "test-unit"
34
35
  spec.add_development_dependency "fuubar"
35
36
  spec.add_development_dependency "yard"
36
37
  spec.add_development_dependency "benchmark-driver"
@@ -0,0 +1,60 @@
1
+ #include <ruby/ruby.h>
2
+
3
+ static VALUE
4
+ ary_find_max(VALUE ary)
5
+ {
6
+ const long n = RARRAY_LEN(ary);
7
+ if (n == 0) {
8
+ return Qnil;
9
+ }
10
+
11
+ long imax = 0;
12
+ VALUE max = RARRAY_AREF(ary, imax);
13
+
14
+ long i;
15
+ for (i = 1; i < n; ++i) {
16
+ VALUE v = RARRAY_AREF(ary, i);
17
+ if (RTEST(rb_funcall(v, '>', 1, max))) {
18
+ imax = i;
19
+ max = v;
20
+ }
21
+ }
22
+
23
+ return rb_assoc_new(max, LONG2NUM(imax));
24
+ }
25
+
26
+ static VALUE
27
+ ary_find_min(VALUE ary)
28
+ {
29
+ const long n = RARRAY_LEN(ary);
30
+ if (n == 0) {
31
+ return Qnil;
32
+ }
33
+
34
+ long imin = 0;
35
+ VALUE min = RARRAY_AREF(ary, imin);
36
+
37
+ long i;
38
+ for (i = 1; i < n; ++i) {
39
+ VALUE v = RARRAY_AREF(ary, i);
40
+ if (RTEST(rb_funcall(v, '<', 1, min))) {
41
+ imin = i;
42
+ min = v;
43
+ }
44
+ }
45
+
46
+ return rb_assoc_new(min, LONG2NUM(imin));
47
+ }
48
+
49
+ void
50
+ Init_array_extension(void)
51
+ {
52
+ VALUE mEnumerableStatistics = rb_const_get_at(rb_cObject, rb_intern("EnumerableStatistics"));
53
+ VALUE mArrayExtension = rb_const_get_at(mEnumerableStatistics, rb_intern("ArrayExtension"));
54
+
55
+ rb_undef_method(mArrayExtension, "find_max");
56
+ rb_define_method(mArrayExtension, "find_max", ary_find_max, 0);
57
+
58
+ rb_undef_method(mArrayExtension, "find_min");
59
+ rb_define_method(mArrayExtension, "find_min", ary_find_min, 0);
60
+ }
@@ -44,7 +44,7 @@ struct RRational {
44
44
  #endif
45
45
 
46
46
  #ifndef RRATIONAL
47
- # define RRATIONAL(obj) (R_CAST(RRational)(obj))
47
+ # define RRATIONAL(obj) ((struct RRational *)(obj))
48
48
  #endif
49
49
 
50
50
  #ifndef RRATIONAL_SET_NUM
@@ -64,7 +64,7 @@ struct RComplex {
64
64
  #endif
65
65
 
66
66
  #ifndef RCOMPLEX
67
- # define RCOMPLEX(obj) (R_CAST(RComplex)(obj))
67
+ # define RCOMPLEX(obj) ((struct RComplex *)(obj))
68
68
  #endif
69
69
 
70
70
  #ifndef RCOMPLEX_SET_REAL
@@ -96,11 +96,14 @@ static VALUE half_in_rational;
96
96
  static ID idPow, idPLUS, idMINUS, idSTAR, idDIV, idGE;
97
97
  static ID id_eqeq_p, id_idiv, id_negate, id_to_f, id_cmp, id_nan_p;
98
98
  static ID id_each, id_real_p, id_sum, id_population, id_closed, id_edge;
99
+ static ID id_skip_na;
99
100
 
100
- static VALUE sym_left, sym_right;
101
+ static VALUE sym_auto, sym_left, sym_right, sym_sturges;
101
102
 
102
103
  static VALUE cHistogram;
103
104
 
105
+ static VALUE orig_enum_sum, orig_ary_sum;
106
+
104
107
  inline static VALUE
105
108
  f_add(VALUE x, VALUE y)
106
109
  {
@@ -135,7 +138,7 @@ complex_new(VALUE klass, VALUE real, VALUE imag)
135
138
  {
136
139
  assert(!RB_TYPE_P(real, T_COMPLEX));
137
140
 
138
- NEWOBJ_OF(obj, struct RComplex, klass, T_COMPLEX | (RGENGC_WB_PROTECTED_COMPLEX ? FL_WB_PROTECTED : 0));
141
+ VALUE obj = rb_get_alloc_func(klass)(klass);
139
142
 
140
143
  RCOMPLEX_SET_REAL(obj, real);
141
144
  RCOMPLEX_SET_IMAG(obj, imag);
@@ -535,9 +538,11 @@ f_gcd(VALUE x, VALUE y)
535
538
  inline static VALUE
536
539
  nurat_s_new_internal(VALUE klass, VALUE num, VALUE den)
537
540
  {
538
- NEWOBJ_OF(obj, struct RRational, klass, T_RATIONAL | (RGENGC_WB_PROTECTED_RATIONAL ? FL_WB_PROTECTED : 0));
541
+ VALUE obj = rb_get_alloc_func(klass)(klass);
542
+
539
543
  RRATIONAL_SET_NUM(obj, num);
540
544
  RRATIONAL_SET_DEN(obj, den);
545
+
541
546
  return (VALUE)obj;
542
547
  }
543
548
 
@@ -632,39 +637,67 @@ rb_rational_plus(VALUE self, VALUE other)
632
637
  }
633
638
  #endif
634
639
 
635
- /* call-seq:
636
- * ary.sum
637
- *
638
- * Calculate the sum of the values in `ary`.
639
- * This method utilizes
640
- * [Kahan summation algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm)
641
- * to compensate the result precision when the `ary` includes Float values.
642
- *
643
- * Note that This library does not redefine `sum` method introduced in Ruby 2.4.
644
- *
645
- * @return [Number] A summation value
646
- */
647
- static VALUE
648
- ary_sum(int argc, VALUE* argv, VALUE ary)
640
+ static inline int
641
+ is_na(VALUE v)
642
+ {
643
+ if (NIL_P(v))
644
+ return 1;
645
+
646
+ if (RB_FLOAT_TYPE_P(v) && isnan(RFLOAT_VALUE(v)))
647
+ return 1;
648
+
649
+ if (rb_respond_to(v, id_nan_p) && RTEST(rb_funcall(v, id_nan_p, 0)))
650
+ return 1;
651
+
652
+ return 0;
653
+ }
654
+
655
+ static int opt_skip_na(VALUE opts)
656
+ {
657
+ VALUE skip_na = Qfalse;
658
+
659
+ if (!NIL_P(opts)) {
660
+ #ifdef HAVE_RB_GET_KWARGS
661
+ ID kwargs = id_skip_na;
662
+ rb_get_kwargs(opts, &kwargs, 0, 1, &skip_na);
663
+ #else
664
+ VALUE val = rb_hash_aref(opts, ID2SYM(id_skip_na));
665
+ skip_na = NIL_P(val) ? skip_na : val;
666
+ #endif
667
+ }
668
+
669
+ return RTEST(skip_na);
670
+ }
671
+
672
+ VALUE
673
+ ary_calculate_sum(VALUE ary, VALUE init, int skip_na, long *na_count_out)
649
674
  {
650
675
  VALUE e, v, r;
651
676
  long i, n;
652
677
  int block_given;
653
-
654
- if (rb_scan_args(argc, argv, "01", &v) == 0)
655
- v = LONG2FIX(0);
678
+ long na_count = 0;
656
679
 
657
680
  block_given = rb_block_given_p();
658
681
 
659
- if (RARRAY_LEN(ary) == 0)
660
- return v;
682
+ if (RARRAY_LEN(ary) == 0) {
683
+ if (na_count_out != NULL) {
684
+ *na_count_out = 0;
685
+ }
686
+ return init;
687
+ }
661
688
 
662
689
  n = 0;
663
690
  r = Qundef;
691
+ v = init;
664
692
  for (i = 0; i < RARRAY_LEN(ary); i++) {
665
693
  e = RARRAY_AREF(ary, i);
666
694
  if (block_given)
667
695
  e = rb_yield(e);
696
+ if (skip_na && is_na(e)) {
697
+ ++na_count;
698
+ continue;
699
+ }
700
+
668
701
  if (FIXNUM_P(e)) {
669
702
  n += FIX2LONG(e); /* should not overflow long type */
670
703
  if (!FIXABLE(n)) {
@@ -688,7 +721,7 @@ ary_sum(int argc, VALUE* argv, VALUE ary)
688
721
  v = rb_fix_plus(LONG2FIX(n), v);
689
722
  if (r != Qundef)
690
723
  v = rb_rational_plus(r, v);
691
- return v;
724
+ goto finish;
692
725
 
693
726
  not_exact:
694
727
  if (n != 0)
@@ -708,6 +741,11 @@ not_exact:
708
741
  e = RARRAY_AREF(ary, i);
709
742
  if (block_given)
710
743
  e = rb_yield(e);
744
+ if (skip_na && is_na(e)) {
745
+ ++na_count;
746
+ continue;
747
+ }
748
+
711
749
  if (RB_FLOAT_TYPE_P(e))
712
750
  has_float_value:
713
751
  x = RFLOAT_VALUE(e);
@@ -725,7 +763,9 @@ not_exact:
725
763
  c = (t - f) - y;
726
764
  f = t;
727
765
  }
728
- return DBL2NUM(f);
766
+
767
+ v = DBL2NUM(f);
768
+ goto finish;
729
769
 
730
770
  not_float:
731
771
  v = DBL2NUM(f);
@@ -736,13 +776,53 @@ not_exact:
736
776
  e = RARRAY_AREF(ary, i);
737
777
  if (block_given)
738
778
  e = rb_yield(e);
779
+ if (skip_na && is_na(e)) {
780
+ ++na_count;
781
+ continue;
782
+ }
739
783
  has_some_value:
740
784
  v = rb_funcall(v, idPLUS, 1, e);
741
785
  }
742
786
 
787
+ finish:
788
+ if (na_count_out != NULL) {
789
+ *na_count_out = na_count;
790
+ }
743
791
  return v;
744
792
  }
745
793
 
794
+ /* call-seq:
795
+ * ary.sum(skip_na: false)
796
+ *
797
+ * Calculate the sum of the values in `ary`.
798
+ * This method utilizes
799
+ * [Kahan summation algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm)
800
+ * to compensate the result precision when the `ary` includes Float values.
801
+ *
802
+ * Note that This library does not redefine `sum` method introduced in Ruby 2.4.
803
+ *
804
+ * @return [Number] A summation value
805
+ */
806
+ static VALUE
807
+ ary_sum(int argc, VALUE* argv, VALUE ary)
808
+ {
809
+ VALUE v, opts;
810
+ int skip_na;
811
+
812
+ if (rb_scan_args(argc, argv, "01:", &v, &opts) == 0) {
813
+ v = LONG2FIX(0);
814
+ }
815
+ skip_na = opt_skip_na(opts);
816
+
817
+ #ifndef HAVE_ENUM_SUM
818
+ if (!skip_na) {
819
+ return rb_funcall(orig_ary_sum, rb_intern("call"), argc, &v);
820
+ }
821
+ #endif
822
+
823
+ return ary_calculate_sum(ary, v, skip_na, NULL);
824
+ }
825
+
746
826
  static void
747
827
  calculate_and_set_mean(VALUE *mean_ptr, VALUE sum, long const n)
748
828
  {
@@ -771,9 +851,10 @@ calculate_and_set_mean(VALUE *mean_ptr, VALUE sum, long const n)
771
851
  }
772
852
 
773
853
  static void
774
- ary_mean_variance(VALUE ary, VALUE *mean_ptr, VALUE *variance_ptr, size_t ddof)
854
+ ary_mean_variance(VALUE ary, VALUE *mean_ptr, VALUE *variance_ptr, size_t ddof, int skip_na)
775
855
  {
776
856
  long i;
857
+ long na_count;
777
858
  size_t n = 0;
778
859
  double m = 0.0, m2 = 0.0, f = 0.0, c = 0.0;
779
860
 
@@ -797,8 +878,8 @@ ary_mean_variance(VALUE ary, VALUE *mean_ptr, VALUE *variance_ptr, size_t ddof)
797
878
 
798
879
  if (variance_ptr == NULL) {
799
880
  VALUE init = DBL2NUM(0.0);
800
- VALUE const sum = ary_sum(1, &init, ary);
801
- long const n = RARRAY_LEN(ary);
881
+ VALUE const sum = ary_calculate_sum(ary, init, skip_na, &na_count);
882
+ long const n = RARRAY_LEN(ary) - na_count;
802
883
  calculate_and_set_mean(mean_ptr, sum, n);
803
884
  return;
804
885
  }
@@ -839,26 +920,46 @@ ary_mean_variance(VALUE ary, VALUE *mean_ptr, VALUE *variance_ptr, size_t ddof)
839
920
  }
840
921
  }
841
922
 
842
- static int
843
- opt_population_p(VALUE opts)
923
+ struct variance_opts {
924
+ int population;
925
+ int skip_na;
926
+ };
927
+
928
+ static void
929
+ get_variance_opts(VALUE opts, struct variance_opts *out)
844
930
  {
845
- VALUE population = Qfalse;
931
+ assert(out != NULL);
932
+
933
+ out->population = 0;
934
+ out->skip_na = 0;
846
935
 
847
936
  if (!NIL_P(opts)) {
848
937
  #ifdef HAVE_RB_GET_KWARGS
849
- ID kwargs = id_population;
850
- rb_get_kwargs(opts, &kwargs, 0, 1, &population);
938
+ static ID kwarg_keys[2];
939
+ VALUE kwarg_vals;
940
+
941
+ if (!kwarg_keys[0]) {
942
+ kwarg_keys[0] = id_population;
943
+ kwarg_keys[1] = id_skip_na;
944
+ }
945
+
946
+ rb_get_kwargs(opts, &kwarg_keys, 0, 2, kwarg_vals);
947
+ out->population = (kwarg_vals[0] != Qundef) ? RTEST(kwarg_vals[0]) : out->population;
948
+ out->skip_na = (kwarg_vals[1] != Qundef) ? RTEST(kwarg_vals[1]) : out->skip_na;
851
949
  #else
852
- VALUE val = rb_hash_aref(opts, ID2SYM(id_population));
853
- population = NIL_P(val) ? population : val;
950
+ VALUE val;
951
+
952
+ val = rb_hash_aref(opts, ID2SYM(id_population));
953
+ out->population = NIL_P(val) ? out->population : RTEST(val);
954
+
955
+ val = rb_hash_aref(opts, ID2SYM(id_skip_na));
956
+ out->skip_na = NIL_P(val) ? out->skip_na : RTEST(val);
854
957
  #endif
855
958
  }
856
-
857
- return RTEST(population);
858
959
  }
859
960
 
860
961
  /* call-seq:
861
- * ary.mean_variance(population: false)
962
+ * ary.mean_variance(population: false, skip_na: false)
862
963
  *
863
964
  * Calculate a mean and a variance of the values in `ary`.
864
965
  * The first element of the result array is the mean, and the second is the variance.
@@ -876,19 +977,21 @@ opt_population_p(VALUE opts)
876
977
  static VALUE
877
978
  ary_mean_variance_m(int argc, VALUE* argv, VALUE ary)
878
979
  {
879
- VALUE opts, mean, variance;
980
+ struct variance_opts options;
981
+ VALUE opts, mean = Qnil, variance = Qnil;
880
982
  size_t ddof = 1;
881
983
 
882
984
  rb_scan_args(argc, argv, "0:", &opts);
883
- if (opt_population_p(opts))
985
+ get_variance_opts(opts, &options);
986
+ if (options.population)
884
987
  ddof = 0;
885
988
 
886
- ary_mean_variance(ary, &mean, &variance, ddof);
989
+ ary_mean_variance(ary, &mean, &variance, ddof, options.skip_na);
887
990
  return rb_assoc_new(mean, variance);
888
991
  }
889
992
 
890
993
  /* call-seq:
891
- * ary.mean
994
+ * ary.mean(skip_na: false)
892
995
  *
893
996
  * Calculate a mean of the values in `ary`.
894
997
  * This method utilizes
@@ -898,15 +1001,20 @@ ary_mean_variance_m(int argc, VALUE* argv, VALUE ary)
898
1001
  * @return [Number] A mean value
899
1002
  */
900
1003
  static VALUE
901
- ary_mean(VALUE ary)
1004
+ ary_mean(int argc, VALUE *argv, VALUE ary)
902
1005
  {
903
- VALUE mean;
904
- ary_mean_variance(ary, &mean, NULL, 1);
1006
+ VALUE mean = Qnil, opts;
1007
+ int skip_na;
1008
+
1009
+ rb_scan_args(argc, argv, ":", &opts);
1010
+ skip_na = opt_skip_na(opts);
1011
+
1012
+ ary_mean_variance(ary, &mean, NULL, 1, skip_na);
905
1013
  return mean;
906
1014
  }
907
1015
 
908
1016
  /* call-seq:
909
- * ary.variance(population: false)
1017
+ * ary.variance(population: false, skip_na: false)
910
1018
  *
911
1019
  * Calculate a variance of the values in `ary`.
912
1020
  * This method scan values in `ary` only once,
@@ -922,14 +1030,16 @@ ary_mean(VALUE ary)
922
1030
  static VALUE
923
1031
  ary_variance(int argc, VALUE* argv, VALUE ary)
924
1032
  {
1033
+ struct variance_opts options;
925
1034
  VALUE opts, variance;
926
1035
  size_t ddof = 1;
927
1036
 
928
1037
  rb_scan_args(argc, argv, "0:", &opts);
929
- if (opt_population_p(opts))
1038
+ get_variance_opts(opts, &options);
1039
+ if (options.population)
930
1040
  ddof = 0;
931
1041
 
932
- ary_mean_variance(ary, NULL, &variance, ddof);
1042
+ ary_mean_variance(ary, NULL, &variance, ddof, options.skip_na);
933
1043
  return variance;
934
1044
  }
935
1045
 
@@ -943,6 +1053,7 @@ struct enum_sum_memo {
943
1053
  double f, c;
944
1054
  int block_given;
945
1055
  int float_value;
1056
+ int skip_na;
946
1057
  };
947
1058
 
948
1059
  static void
@@ -956,8 +1067,12 @@ sum_iter(VALUE e, struct enum_sum_memo *memo)
956
1067
  double f = memo->f;
957
1068
  double c = memo->c;
958
1069
 
959
- if (memo->block_given)
1070
+ if (memo->block_given) {
960
1071
  e = rb_yield(e);
1072
+ }
1073
+ if (memo->skip_na && is_na(e)) {
1074
+ return;
1075
+ }
961
1076
 
962
1077
  memo->count += 1;
963
1078
 
@@ -1090,7 +1205,7 @@ int_range_sum_count(VALUE beg, VALUE end, int excl,
1090
1205
  }
1091
1206
 
1092
1207
  static void
1093
- enum_sum_count(VALUE obj, VALUE init, VALUE *sum_ptr, long *count_ptr)
1208
+ enum_sum_count(VALUE obj, VALUE init, int skip_na, VALUE *sum_ptr, long *count_ptr)
1094
1209
  {
1095
1210
  struct enum_sum_memo memo;
1096
1211
  VALUE beg, end;
@@ -1101,6 +1216,7 @@ enum_sum_count(VALUE obj, VALUE init, VALUE *sum_ptr, long *count_ptr)
1101
1216
  memo.block_given = rb_block_given_p();
1102
1217
  memo.n = 0;
1103
1218
  memo.r = Qundef;
1219
+ memo.skip_na = skip_na;
1104
1220
 
1105
1221
  if ((memo.float_value = RB_FLOAT_TYPE_P(memo.v))) {
1106
1222
  memo.f = RFLOAT_VALUE(memo.v);
@@ -1138,9 +1254,8 @@ enum_sum_count(VALUE obj, VALUE init, VALUE *sum_ptr, long *count_ptr)
1138
1254
  *count_ptr = memo.count;
1139
1255
  }
1140
1256
 
1141
- #ifndef HAVE_ENUM_SUM
1142
1257
  /* call-seq:
1143
- * enum.sum
1258
+ * enum.sum(skip_na: false)
1144
1259
  *
1145
1260
  * Calculate the sum of the values in `enum`.
1146
1261
  * This method utilizes
@@ -1154,16 +1269,27 @@ enum_sum_count(VALUE obj, VALUE init, VALUE *sum_ptr, long *count_ptr)
1154
1269
  static VALUE
1155
1270
  enum_sum(int argc, VALUE* argv, VALUE obj)
1156
1271
  {
1157
- VALUE sum, init;
1272
+ VALUE sum, init, opts;
1273
+ int skip_na;
1158
1274
 
1159
- if (rb_scan_args(argc, argv, "01", &init) == 0)
1275
+ if (rb_scan_args(argc, argv, "01:", &init, &opts) == 0) {
1160
1276
  init = LONG2FIX(0);
1277
+ }
1278
+ skip_na = opt_skip_na(opts);
1161
1279
 
1162
- enum_sum_count(obj, init, &sum, NULL);
1280
+ #ifndef HAVE_ENUM_SUM
1281
+ if (skip_na) {
1282
+ enum_sum_count(obj, init, skip_na, &sum, NULL);
1283
+ }
1284
+ else {
1285
+ rb_funcall(orig_enum_sum, rb_intern("call"), argc, &init);
1286
+ }
1287
+ #else
1288
+ enum_sum_count(obj, init, skip_na, &sum, NULL);
1289
+ #endif
1163
1290
 
1164
1291
  return sum;
1165
1292
  }
1166
- #endif
1167
1293
 
1168
1294
  struct enum_mean_variance_memo {
1169
1295
  int block_given;
@@ -1253,7 +1379,7 @@ enum_mean_variance(VALUE obj, VALUE *mean_ptr, VALUE *variance_ptr, size_t ddof)
1253
1379
  long n;
1254
1380
  VALUE sum;
1255
1381
  VALUE init = DBL2NUM(0.0);
1256
- enum_sum_count(obj, init, &sum, &n);
1382
+ enum_sum_count(obj, init, 0, &sum, &n); /* TODO: skip_na */
1257
1383
  if (n > 0)
1258
1384
  calculate_and_set_mean(mean_ptr, sum, n);
1259
1385
  return;
@@ -1303,11 +1429,13 @@ enum_mean_variance(VALUE obj, VALUE *mean_ptr, VALUE *variance_ptr, size_t ddof)
1303
1429
  static VALUE
1304
1430
  enum_mean_variance_m(int argc, VALUE* argv, VALUE obj)
1305
1431
  {
1432
+ struct variance_opts options;
1306
1433
  VALUE opts, mean, variance;
1307
1434
  size_t ddof = 1;
1308
1435
 
1309
1436
  rb_scan_args(argc, argv, "0:", &opts);
1310
- if (opt_population_p(opts))
1437
+ get_variance_opts(opts, &options);
1438
+ if (options.population)
1311
1439
  ddof = 0;
1312
1440
 
1313
1441
  enum_mean_variance(obj, &mean, &variance, ddof);
@@ -1349,11 +1477,13 @@ enum_mean(VALUE obj)
1349
1477
  static VALUE
1350
1478
  enum_variance(int argc, VALUE* argv, VALUE obj)
1351
1479
  {
1480
+ struct variance_opts options;
1352
1481
  VALUE opts, variance;
1353
1482
  size_t ddof = 1;
1354
1483
 
1355
1484
  rb_scan_args(argc, argv, "0:", &opts);
1356
- if (opt_population_p(opts))
1485
+ get_variance_opts(opts, &options);
1486
+ if (options.population)
1357
1487
  ddof = 0;
1358
1488
 
1359
1489
  enum_mean_variance(obj, NULL, &variance, ddof);
@@ -1392,11 +1522,13 @@ sqrt_value(VALUE x)
1392
1522
  static VALUE
1393
1523
  enum_mean_stdev(int argc, VALUE* argv, VALUE obj)
1394
1524
  {
1525
+ struct variance_opts options;
1395
1526
  VALUE opts, mean, variance;
1396
1527
  size_t ddof = 1;
1397
1528
 
1398
1529
  rb_scan_args(argc, argv, "0:", &opts);
1399
- if (opt_population_p(opts))
1530
+ get_variance_opts(opts, &options);
1531
+ if (options.population)
1400
1532
  ddof = 0;
1401
1533
 
1402
1534
  enum_mean_variance(obj, &mean, &variance, ddof);
@@ -1446,14 +1578,16 @@ enum_stdev(int argc, VALUE* argv, VALUE obj)
1446
1578
  static VALUE
1447
1579
  ary_mean_stdev(int argc, VALUE* argv, VALUE ary)
1448
1580
  {
1581
+ struct variance_opts options;
1449
1582
  VALUE opts, mean, variance;
1450
1583
  size_t ddof = 1;
1451
1584
 
1452
1585
  rb_scan_args(argc, argv, "0:", &opts);
1453
- if (opt_population_p(opts))
1586
+ get_variance_opts(opts, &options);
1587
+ if (options.population)
1454
1588
  ddof = 0;
1455
1589
 
1456
- ary_mean_variance(ary, &mean, &variance, ddof);
1590
+ ary_mean_variance(ary, &mean, &variance, ddof, options.skip_na);
1457
1591
  VALUE stdev = sqrt_value(variance);
1458
1592
  return rb_assoc_new(mean, stdev);
1459
1593
  }
@@ -1479,21 +1613,6 @@ ary_stdev(int argc, VALUE* argv, VALUE ary)
1479
1613
  return stdev;
1480
1614
  }
1481
1615
 
1482
- static inline int
1483
- is_na(VALUE v)
1484
- {
1485
- if (NIL_P(v))
1486
- return 1;
1487
-
1488
- if (RB_FLOAT_TYPE_P(v) && isnan(RFLOAT_VALUE(v)))
1489
- return 1;
1490
-
1491
- if (rb_respond_to(v, id_nan_p) && RTEST(rb_funcall(v, id_nan_p, 0)))
1492
- return 1;
1493
-
1494
- return 0;
1495
- }
1496
-
1497
1616
  static int
1498
1617
  ary_percentile_sort_cmp(const void *ap, const void *bp, void *dummy)
1499
1618
  {
@@ -1900,7 +2019,7 @@ any_value_counts(int argc, VALUE *argv, VALUE obj,
1900
2019
  struct value_counts_opts opts;
1901
2020
  struct value_counts_memo memo;
1902
2021
 
1903
- rb_scan_args(argc, argv, ":", &kwargs);
2022
+ rb_scan_args(argc, argv, "0:", &kwargs);
1904
2023
  value_counts_extract_opts(kwargs, &opts);
1905
2024
 
1906
2025
  memo.result = rb_hash_new();
@@ -2102,50 +2221,67 @@ histogram_edge_bin_index(VALUE edge, VALUE rb_x, int left_p)
2102
2221
  }
2103
2222
 
2104
2223
  static void
2105
- histogram_weights_push_values(VALUE weights, VALUE edge, VALUE values, int left_p)
2224
+ histogram_weights_push_values(VALUE bin_weights, VALUE edge, VALUE values, VALUE weight_array, int left_p)
2106
2225
  {
2226
+ const VALUE one = INT2FIX(1);
2227
+ long bi, i, n, n_bins, weighted = 0;
2107
2228
  VALUE x, cur;
2108
- long i, n, bi;
2229
+
2230
+ assert(RB_TYPE_P(edge, T_ARRAY));
2231
+ assert(RB_TYPE_P(values, T_ARRAY));
2109
2232
 
2110
2233
  n = RARRAY_LEN(values);
2234
+ n_bins = RARRAY_LEN(edge) - 1;
2235
+
2236
+ if (! NIL_P(weight_array)) {
2237
+ assert(RB_TYPE_P(weight_array, T_ARRAY));
2238
+ assert(RARRAY_LEN(weight_array) == n);
2239
+ weighted = 1;
2240
+ }
2241
+
2111
2242
  for (i = 0; i < n; ++i) {
2112
2243
  x = RARRAY_AREF(values, i);
2113
2244
 
2114
- bi = histogram_edge_bin_index(edge, x, left_p);
2115
-
2116
- cur = rb_ary_entry(weights, bi);
2117
- if (NIL_P(cur)) {
2118
- cur = INT2FIX(1);
2245
+ VALUE w;
2246
+ if (weighted) {
2247
+ w = RARRAY_AREF(weight_array, i);
2248
+ if (RB_TYPE_P(w, T_COMPLEX)) {
2249
+ VALUE imag = RCOMPLEX(w)->imag;
2250
+ if (! RTEST(f_zero_p(imag))) {
2251
+ goto type_error;
2252
+ }
2253
+ }
2254
+ else if (rb_obj_is_kind_of(w, rb_cNumeric)) {
2255
+ if (!RTEST(f_real_p(w))) {
2256
+ goto type_error;
2257
+ }
2258
+ }
2259
+ else {
2260
+ goto type_error;
2261
+ }
2119
2262
  }
2120
2263
  else {
2121
- cur = rb_funcall(cur, idPLUS, 1, INT2FIX(1));
2264
+ w = one;
2122
2265
  }
2123
2266
 
2124
- rb_ary_store(weights, bi, cur);
2125
- }
2126
- }
2267
+ bi = histogram_edge_bin_index(edge, x, left_p);
2127
2268
 
2128
- static int
2129
- opt_closed_left_p(VALUE opts)
2130
- {
2131
- int left_p = 1;
2269
+ if (0 <= bi && bi < n_bins) {
2270
+ cur = rb_ary_entry(bin_weights, bi);
2271
+ if (NIL_P(cur)) {
2272
+ cur = w;
2273
+ }
2274
+ else {
2275
+ cur = rb_funcall(cur, idPLUS, 1, w);
2276
+ }
2132
2277
 
2133
- if (!NIL_P(opts)) {
2134
- VALUE closed;
2135
- #ifdef HAVE_RB_GET_KWARGS
2136
- ID kwargs = id_closed;
2137
- rb_get_kwargs(opts, &kwargs, 0, 1, &closed);
2138
- #else
2139
- closed = rb_hash_lookup2(opts, ID2SYM(id_closed), sym_left);
2140
- #endif
2141
- left_p = (closed != sym_right);
2142
- if (left_p && closed != sym_left) {
2143
- rb_raise(rb_eArgError, "invalid value for :closed keyword "
2144
- "(%"PRIsVALUE" for :left or :right)", closed);
2278
+ rb_ary_store(bin_weights, bi, cur);
2145
2279
  }
2146
2280
  }
2281
+ return;
2147
2282
 
2148
- return left_p;
2283
+ type_error:
2284
+ rb_raise(rb_eTypeError, "weight array must have only real numbers");
2149
2285
  }
2150
2286
 
2151
2287
  static inline long
@@ -2238,9 +2374,9 @@ ary_histogram_calculate_edge_lo_hi(const double lo, const double hi, const long
2238
2374
  }
2239
2375
 
2240
2376
  static VALUE
2241
- ary_histogram_calculate_edge(VALUE ary, const long nbins, const int left_p)
2377
+ ary_histogram_calculate_edge(VALUE ary, VALUE arg0, const int left_p)
2242
2378
  {
2243
- long n;
2379
+ long n, nbins;
2244
2380
  VALUE minmax;
2245
2381
  VALUE edge = Qnil;
2246
2382
  double lo, hi;
@@ -2248,6 +2384,22 @@ ary_histogram_calculate_edge(VALUE ary, const long nbins, const int left_p)
2248
2384
  Check_Type(ary, T_ARRAY);
2249
2385
  n = RARRAY_LEN(ary);
2250
2386
 
2387
+ if (NIL_P(arg0)) {
2388
+ arg0 = sym_auto;
2389
+ }
2390
+
2391
+ if (RB_TYPE_P(arg0, T_SYMBOL)) {
2392
+ if (arg0 != sym_auto && arg0 != sym_sturges) {
2393
+ rb_raise(rb_eArgError, "Unknown method to calculate bin width: %+"PRIsVALUE, arg0);
2394
+ }
2395
+ else {
2396
+ nbins = sturges(n);
2397
+ }
2398
+ }
2399
+ else {
2400
+ nbins = NUM2LONG(arg0);
2401
+ }
2402
+
2251
2403
  if (n == 0 && nbins < 0) {
2252
2404
  rb_raise(rb_eArgError, "nbins must be >= 0 for an empty array, got %ld", nbins);
2253
2405
  }
@@ -2269,10 +2421,47 @@ ary_histogram_calculate_edge(VALUE ary, const long nbins, const int left_p)
2269
2421
  return edge;
2270
2422
  }
2271
2423
 
2424
+ static VALUE
2425
+ check_histogram_weight_array(VALUE weight_array, const long ary_len)
2426
+ {
2427
+ if (weight_array == Qundef) return Qnil;
2428
+
2429
+ weight_array = rb_check_convert_type(weight_array, T_ARRAY, "Array", "to_ary");
2430
+ if (RARRAY_LEN(weight_array) != ary_len) {
2431
+ rb_raise(rb_eArgError, "weight array must have the same number of items as the receiver array");
2432
+ }
2433
+
2434
+ return weight_array;
2435
+ }
2436
+
2437
+ static VALUE
2438
+ check_histogram_edges(VALUE edges)
2439
+ {
2440
+ if (edges == Qundef) return Qnil;
2441
+ return rb_check_convert_type(edges, T_ARRAY, "Array", "to_ary");
2442
+ }
2443
+
2444
+ static int
2445
+ check_histogram_left_p(VALUE closed)
2446
+ {
2447
+ int left_p = (closed != sym_right);
2448
+ if (left_p && closed != Qundef && closed != sym_left) {
2449
+ rb_raise(rb_eArgError, "invalid value for :closed keyword "
2450
+ "(%"PRIsVALUE" for :left or :right)", closed);
2451
+ }
2452
+ return left_p;
2453
+ }
2454
+
2272
2455
  /* call-seq:
2273
- * ary.histogram(nbins=:auto, closed: :left)
2456
+ * ary.histogram(nbins=:auto, weight: nil, closed: :left)
2274
2457
  *
2275
2458
  * @param [Integer] nbins The approximate number of bins
2459
+ * @params [Array<Numeric>] weights
2460
+ * An optional weight array, that has the same length as the receiver.
2461
+ * `weight[i]` means the weight value of the i-th element in the receiver.
2462
+ * @params [Array<Numeric>] edges
2463
+ * An optional edge array, that specify the bin edges.
2464
+ * This array must be sorted.
2276
2465
  * @param [:left, :right] closed
2277
2466
  * If :left (the default), the bin interval are left-closed.
2278
2467
  * If :right, the bin interval are right-closed.
@@ -2282,30 +2471,49 @@ ary_histogram_calculate_edge(VALUE ary, const long nbins, const int left_p)
2282
2471
  static VALUE
2283
2472
  ary_histogram(int argc, VALUE *argv, VALUE ary)
2284
2473
  {
2285
- VALUE arg0, opts, edge, weights;
2286
- int left_p;
2287
- long nbins, nweights, i;
2474
+ VALUE arg0, kwargs, bin_weights;
2475
+ long n_bin_weights, i;
2288
2476
 
2289
- rb_scan_args(argc, argv, "01:", &arg0, &opts);
2290
- if (NIL_P(arg0)) {
2291
- nbins = sturges(RARRAY_LEN(ary));
2292
- }
2293
- else {
2294
- nbins = NUM2LONG(arg0);
2477
+ VALUE weight_array = Qnil;
2478
+ VALUE edges = Qnil;
2479
+ int left_p = 1;
2480
+
2481
+ rb_scan_args(argc, argv, "01:", &arg0, &kwargs);
2482
+
2483
+ if (!NIL_P(kwargs)) {
2484
+ enum { kw_weights, kw_edges, kw_closed };
2485
+ static ID kwarg_keys[3];
2486
+ VALUE kwarg_vals[3];
2487
+
2488
+ if (!kwarg_keys[0]) {
2489
+ kwarg_keys[kw_weights] = rb_intern("weights");
2490
+ kwarg_keys[kw_edges] = rb_intern("edges");
2491
+ kwarg_keys[kw_closed] = rb_intern("closed");
2492
+ }
2493
+
2494
+ rb_get_kwargs(kwargs, kwarg_keys, 0, 3, kwarg_vals);
2495
+
2496
+ weight_array = check_histogram_weight_array(kwarg_vals[kw_weights], RARRAY_LEN(ary));
2497
+ edges = check_histogram_edges(kwarg_vals[kw_edges]);
2498
+ left_p = check_histogram_left_p(kwarg_vals[kw_closed]);
2295
2499
  }
2296
- left_p = opt_closed_left_p(opts);
2297
2500
 
2298
- edge = ary_histogram_calculate_edge(ary, nbins, left_p);
2501
+ if (NIL_P(edges)) {
2502
+ edges = ary_histogram_calculate_edge(ary, arg0, left_p);
2503
+ }
2504
+ else if (! NIL_P(arg0)) {
2505
+ rb_raise(rb_eArgError, "Unable to use both `nbins` and `edges` together");
2506
+ }
2299
2507
 
2300
- nweights = RARRAY_LEN(edge) - 1;
2301
- weights = rb_ary_new_capa(nweights);
2302
- for (i = 0; i < nweights; ++i) {
2303
- rb_ary_store(weights, i, INT2FIX(0));
2508
+ n_bin_weights = RARRAY_LEN(edges) - 1;
2509
+ bin_weights = rb_ary_new_capa(n_bin_weights);
2510
+ for (i = 0; i < n_bin_weights; ++i) {
2511
+ rb_ary_store(bin_weights, i, INT2FIX(0));
2304
2512
  }
2305
2513
 
2306
- histogram_weights_push_values(weights, edge, ary, left_p);
2514
+ histogram_weights_push_values(bin_weights, edges, ary, weight_array, left_p);
2307
2515
 
2308
- return rb_struct_new(cHistogram, edge, weights,
2516
+ return rb_struct_new(cHistogram, edges, bin_weights,
2309
2517
  left_p ? sym_left : sym_right,
2310
2518
  Qfalse);
2311
2519
  }
@@ -2315,10 +2523,16 @@ Init_extension(void)
2315
2523
  {
2316
2524
  VALUE mEnumerableStatistics;
2317
2525
 
2318
- #ifndef HAVE_ENUM_SUM
2319
- rb_define_method(rb_mEnumerable, "sum", enum_sum, -1);
2526
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
2527
+ rb_ext_ractor_safe(true);
2320
2528
  #endif
2321
2529
 
2530
+ mEnumerableStatistics = rb_const_get_at(rb_cObject, rb_intern("EnumerableStatistics"));
2531
+
2532
+ orig_enum_sum = rb_funcall(rb_mEnumerable, rb_intern("public_instance_method"), 1, rb_str_new_cstr("sum"));
2533
+ orig_ary_sum = rb_funcall(rb_cArray, rb_intern("public_instance_method"), 1, rb_str_new_cstr("sum"));
2534
+
2535
+ rb_define_method(rb_mEnumerable, "sum", enum_sum, -1);
2322
2536
  rb_define_method(rb_mEnumerable, "mean_variance", enum_mean_variance_m, -1);
2323
2537
  rb_define_method(rb_mEnumerable, "mean", enum_mean, 0);
2324
2538
  rb_define_method(rb_mEnumerable, "variance", enum_variance, -1);
@@ -2326,11 +2540,9 @@ Init_extension(void)
2326
2540
  rb_define_method(rb_mEnumerable, "stdev", enum_stdev, -1);
2327
2541
  rb_define_method(rb_mEnumerable, "value_counts", enum_value_counts, -1);
2328
2542
 
2329
- #ifndef HAVE_ARRAY_SUM
2330
2543
  rb_define_method(rb_cArray, "sum", ary_sum, -1);
2331
- #endif
2332
2544
  rb_define_method(rb_cArray, "mean_variance", ary_mean_variance_m, -1);
2333
- rb_define_method(rb_cArray, "mean", ary_mean, 0);
2545
+ rb_define_method(rb_cArray, "mean", ary_mean, -1);
2334
2546
  rb_define_method(rb_cArray, "variance", ary_variance, -1);
2335
2547
  rb_define_method(rb_cArray, "mean_stdev", ary_mean_stdev, -1);
2336
2548
  rb_define_method(rb_cArray, "stdev", ary_stdev, -1);
@@ -2343,11 +2555,13 @@ Init_extension(void)
2343
2555
  half_in_rational = nurat_s_new_internal(rb_cRational, INT2FIX(1), INT2FIX(2));
2344
2556
  rb_gc_register_mark_object(half_in_rational);
2345
2557
 
2346
- mEnumerableStatistics = rb_const_get_at(rb_cObject, rb_intern("EnumerableStatistics"));
2347
2558
  cHistogram = rb_const_get_at(mEnumerableStatistics, rb_intern("Histogram"));
2348
2559
 
2349
2560
  rb_define_method(rb_cArray, "histogram", ary_histogram, -1);
2350
2561
 
2562
+ void Init_array_extension(void);
2563
+ Init_array_extension();
2564
+
2351
2565
  idPLUS = '+';
2352
2566
  idMINUS = '-';
2353
2567
  idSTAR = '*';
@@ -2366,7 +2580,9 @@ Init_extension(void)
2366
2580
  id_population = rb_intern("population");
2367
2581
  id_closed = rb_intern("closed");
2368
2582
  id_edge = rb_intern("edge");
2583
+ id_skip_na = rb_intern("skip_na");
2369
2584
 
2585
+ sym_auto = ID2SYM(rb_intern("auto"));
2370
2586
  sym_left = ID2SYM(rb_intern("left"));
2371
2587
  sym_right = ID2SYM(rb_intern("right"));
2372
2588
  }
@@ -0,0 +1,37 @@
1
+ module EnumerableStatistics
2
+ module ArrayExtension
3
+ def find_max
4
+ n = size
5
+ return nil if n == 0
6
+
7
+ imax, i = 0, 1
8
+ while i < n
9
+ imax = i if self[i] > self[imax]
10
+ i += 1
11
+ end
12
+ [self[imax], imax]
13
+ end
14
+
15
+ def argmax
16
+ find_max[1]
17
+ end
18
+
19
+ def find_min
20
+ n = size
21
+ return nil if n == 0
22
+
23
+ imin, i = 0, 1
24
+ while i < n
25
+ imin = i if self[i] < self[imax]
26
+ i += 1
27
+ end
28
+ [self[imin], imin]
29
+ end
30
+
31
+ def argmin
32
+ find_min[1]
33
+ end
34
+ end
35
+
36
+ Array.include ArrayExtension
37
+ end
@@ -1,5 +1,6 @@
1
1
  module EnumerableStatistics
2
- class Histogram < Struct.new(:edge, :weights, :closed, :isdensity)
2
+ class Histogram < Struct.new(:edges, :weights, :closed, :isdensity)
3
+ alias edge edges
3
4
  alias density? isdensity
4
5
  end
5
6
  end
@@ -1,5 +1,5 @@
1
1
  module EnumerableStatistics
2
- VERSION = '2.0.1'
2
+ VERSION = '2.0.8'
3
3
 
4
4
  module Version
5
5
  numbers, TAG = VERSION.split('-', 2)
@@ -1,2 +1,3 @@
1
1
  require_relative "enumerable_statistics/version"
2
+ require_relative "enumerable_statistics/array_ext"
2
3
  require_relative "enumerable_statistics/histogram"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enumerable-statistics
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenta Murata
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-11 00:00:00.000000000 Z
11
+ date: 2024-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.17.2
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.17.2
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: test-unit
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: fuubar
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -114,12 +128,11 @@ email:
114
128
  executables: []
115
129
  extensions:
116
130
  - ext/enumerable/statistics/extension/extconf.rb
117
- - ext/-bench-/extconf.rb
118
131
  extra_rdoc_files: []
119
132
  files:
133
+ - ".github/workflows/ci.yml"
120
134
  - ".gitignore"
121
135
  - ".rspec"
122
- - ".travis.yml"
123
136
  - ".yardopts"
124
137
  - CHANGELOG.md
125
138
  - Gemfile
@@ -136,12 +149,13 @@ files:
136
149
  - bin/rspec
137
150
  - bin/setup
138
151
  - enumerable-statistics.gemspec
139
- - ext/-bench-/extconf.rb
152
+ - ext/enumerable/statistics/extension/array_ext.c
140
153
  - ext/enumerable/statistics/extension/extconf.rb
141
154
  - ext/enumerable/statistics/extension/statistics.c
142
155
  - images/benchmark.png
143
156
  - lib/enumerable/statistics.rb
144
157
  - lib/enumerable_statistics.rb
158
+ - lib/enumerable_statistics/array_ext.rb
145
159
  - lib/enumerable_statistics/histogram.rb
146
160
  - lib/enumerable_statistics/version.rb
147
161
  - templates/default/layout/html/headers.erb
@@ -275,7 +289,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
275
289
  - !ruby/object:Gem::Version
276
290
  version: '0'
277
291
  requirements: []
278
- rubygems_version: 3.1.2
292
+ rubygems_version: 3.5.9
279
293
  signing_key:
280
294
  specification_version: 4
281
295
  summary: Statistics features for Enumerable
data/.travis.yml DELETED
@@ -1,32 +0,0 @@
1
- ---
2
- notification:
3
- email:
4
- - mrkn@ruby-lang.org
5
-
6
- language: ruby
7
-
8
- before_install:
9
- - yes | gem update --system
10
- - gem install bundler
11
-
12
- install:
13
- - bundle install
14
-
15
- script:
16
- - bundle exec rake --trace clobber compile
17
- - bundle exec rake spec
18
-
19
- matrix:
20
- include:
21
- - name: "2.3"
22
- rvm: 2.3
23
- - name: "2.4"
24
- rvm: 2.4.5
25
- - name: "2.5"
26
- rvm: 2.5.2
27
- - name: "2.6"
28
- rvm: 2.6
29
- - name: "trunk"
30
- rvm: ruby-head
31
- allow_failures:
32
- - rvm: 2.3
@@ -1,3 +0,0 @@
1
- require 'mkmf'
2
-
3
- create_makefile('-bench-')