enumerable-statistics 2.0.1 → 2.0.8

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: 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-')