enumerable-statistics 2.0.3 → 2.0.5
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 +4 -4
- data/CHANGELOG.md +9 -0
- data/ext/enumerable/statistics/extension/array_ext.c +60 -0
- data/ext/enumerable/statistics/extension/statistics.c +93 -42
- data/lib/enumerable_statistics.rb +1 -0
- data/lib/enumerable_statistics/array_ext.rb +37 -0
- data/lib/enumerable_statistics/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3fa86766eb3c5369422d08bac77705368b0bde5faa216eecd9f78115eb7548b6
|
4
|
+
data.tar.gz: 313dc69fe5d6b193278489b576af4bb90679eebf6814c36a2924a1241cd5c8be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13fd8a73ae4e83aa85210cbbec1882a2129802aa377f7100ffa72e48ec7df685ba5eff1553cd2ef0b29eddd2b13715769de822adcc881c6d57122212d4c8c13a
|
7
|
+
data.tar.gz: d4dc08f32d2d9a43d743e213b2725f0bc41ac7d6d14c68ccecd1b3563d022c8c1c8b60eea682bce554bc7b5425e3c4b552766bb8b3a7faa386164ee8f00303b7
|
data/CHANGELOG.md
CHANGED
@@ -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
|
+
}
|
@@ -97,7 +97,7 @@ 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
99
|
|
100
|
-
static VALUE sym_left, sym_right;
|
100
|
+
static VALUE sym_auto, sym_left, sym_right;
|
101
101
|
|
102
102
|
static VALUE cHistogram;
|
103
103
|
|
@@ -2102,50 +2102,61 @@ histogram_edge_bin_index(VALUE edge, VALUE rb_x, int left_p)
|
|
2102
2102
|
}
|
2103
2103
|
|
2104
2104
|
static void
|
2105
|
-
histogram_weights_push_values(VALUE
|
2105
|
+
histogram_weights_push_values(VALUE bin_weights, VALUE edge, VALUE values, VALUE weight_array, int left_p)
|
2106
2106
|
{
|
2107
2107
|
VALUE x, cur;
|
2108
|
-
long i, n, bi;
|
2108
|
+
long i, n, bi, one, weighted = 0;
|
2109
2109
|
|
2110
2110
|
n = RARRAY_LEN(values);
|
2111
|
+
|
2112
|
+
if (! NIL_P(weight_array)) {
|
2113
|
+
assert(RB_TYPE_P(weight_array, T_ARRAY));
|
2114
|
+
assert(RARRAY_LEN(weight_array) == n);
|
2115
|
+
weighted = 1;
|
2116
|
+
}
|
2117
|
+
|
2118
|
+
one = INT2FIX(1);
|
2111
2119
|
for (i = 0; i < n; ++i) {
|
2112
2120
|
x = RARRAY_AREF(values, i);
|
2113
2121
|
|
2122
|
+
VALUE w;
|
2123
|
+
if (weighted) {
|
2124
|
+
w = RARRAY_AREF(weight_array, i);
|
2125
|
+
if (RB_TYPE_P(w, T_COMPLEX)) {
|
2126
|
+
VALUE imag = RCOMPLEX(w)->imag;
|
2127
|
+
if (! RTEST(f_zero_p(imag))) {
|
2128
|
+
goto type_error;
|
2129
|
+
}
|
2130
|
+
}
|
2131
|
+
else if (rb_obj_is_kind_of(w, rb_cNumeric)) {
|
2132
|
+
if (!RTEST(f_real_p(w))) {
|
2133
|
+
goto type_error;
|
2134
|
+
}
|
2135
|
+
}
|
2136
|
+
else {
|
2137
|
+
goto type_error;
|
2138
|
+
}
|
2139
|
+
}
|
2140
|
+
else {
|
2141
|
+
w = one;
|
2142
|
+
}
|
2143
|
+
|
2114
2144
|
bi = histogram_edge_bin_index(edge, x, left_p);
|
2115
2145
|
|
2116
|
-
cur = rb_ary_entry(
|
2146
|
+
cur = rb_ary_entry(bin_weights, bi);
|
2117
2147
|
if (NIL_P(cur)) {
|
2118
|
-
cur =
|
2148
|
+
cur = w;
|
2119
2149
|
}
|
2120
2150
|
else {
|
2121
|
-
cur = rb_funcall(cur, idPLUS, 1,
|
2151
|
+
cur = rb_funcall(cur, idPLUS, 1, w);
|
2122
2152
|
}
|
2123
2153
|
|
2124
|
-
rb_ary_store(
|
2125
|
-
}
|
2126
|
-
}
|
2127
|
-
|
2128
|
-
static int
|
2129
|
-
opt_closed_left_p(VALUE opts)
|
2130
|
-
{
|
2131
|
-
int left_p = 1;
|
2132
|
-
|
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);
|
2145
|
-
}
|
2154
|
+
rb_ary_store(bin_weights, bi, cur);
|
2146
2155
|
}
|
2156
|
+
return;
|
2147
2157
|
|
2148
|
-
|
2158
|
+
type_error:
|
2159
|
+
rb_raise(rb_eTypeError, "weight array must have only real numbers");
|
2149
2160
|
}
|
2150
2161
|
|
2151
2162
|
static inline long
|
@@ -2270,9 +2281,12 @@ ary_histogram_calculate_edge(VALUE ary, const long nbins, const int left_p)
|
|
2270
2281
|
}
|
2271
2282
|
|
2272
2283
|
/* call-seq:
|
2273
|
-
* ary.histogram(nbins=:auto, closed: :left)
|
2284
|
+
* ary.histogram(nbins=:auto, weight: nil, closed: :left)
|
2274
2285
|
*
|
2275
2286
|
* @param [Integer] nbins The approximate number of bins
|
2287
|
+
* @params [Array<Numeric>] weight
|
2288
|
+
* An optional weight array, that has the same length as the receiver.
|
2289
|
+
* `weight[i]` means the weight value of the i-th element in the receiver.
|
2276
2290
|
* @param [:left, :right] closed
|
2277
2291
|
* If :left (the default), the bin interval are left-closed.
|
2278
2292
|
* If :right, the bin interval are right-closed.
|
@@ -2282,30 +2296,63 @@ ary_histogram_calculate_edge(VALUE ary, const long nbins, const int left_p)
|
|
2282
2296
|
static VALUE
|
2283
2297
|
ary_histogram(int argc, VALUE *argv, VALUE ary)
|
2284
2298
|
{
|
2285
|
-
VALUE arg0,
|
2286
|
-
|
2287
|
-
long nbins, nweights, i;
|
2299
|
+
VALUE arg0, kwargs, edge, bin_weights;
|
2300
|
+
long nbins, n_bin_weights, i;
|
2288
2301
|
|
2289
|
-
|
2290
|
-
|
2302
|
+
VALUE weight_array = Qnil;
|
2303
|
+
int left_p = 1;
|
2304
|
+
|
2305
|
+
rb_scan_args(argc, argv, "01:", &arg0, &kwargs);
|
2306
|
+
if (NIL_P(arg0) || arg0 == sym_auto) {
|
2291
2307
|
nbins = sturges(RARRAY_LEN(ary));
|
2292
2308
|
}
|
2293
2309
|
else {
|
2294
2310
|
nbins = NUM2LONG(arg0);
|
2295
2311
|
}
|
2296
|
-
|
2312
|
+
|
2313
|
+
if (!NIL_P(kwargs)) {
|
2314
|
+
enum { kw_weight, kw_closed };
|
2315
|
+
static ID kwarg_keys[2];
|
2316
|
+
VALUE kwarg_vals[2];
|
2317
|
+
VALUE closed;
|
2318
|
+
|
2319
|
+
if (!kwarg_keys[0]) {
|
2320
|
+
kwarg_keys[kw_weight] = rb_intern("weight");
|
2321
|
+
kwarg_keys[kw_closed] = rb_intern("closed");
|
2322
|
+
}
|
2323
|
+
|
2324
|
+
rb_get_kwargs(kwargs, kwarg_keys, 0, 2, kwarg_vals);
|
2325
|
+
|
2326
|
+
weight_array = kwarg_vals[kw_weight];
|
2327
|
+
if (weight_array != Qundef) {
|
2328
|
+
weight_array = rb_check_convert_type(weight_array, T_ARRAY, "Array", "to_ary");
|
2329
|
+
if (RARRAY_LEN(weight_array) != RARRAY_LEN(ary)) {
|
2330
|
+
rb_raise(rb_eArgError, "weight array must have the same number of items as the receiver array");
|
2331
|
+
}
|
2332
|
+
}
|
2333
|
+
else {
|
2334
|
+
weight_array = Qnil;
|
2335
|
+
}
|
2336
|
+
|
2337
|
+
closed = kwarg_vals[kw_closed];
|
2338
|
+
left_p = (closed != sym_right);
|
2339
|
+
if (left_p && closed != Qundef && closed != sym_left) {
|
2340
|
+
rb_raise(rb_eArgError, "invalid value for :closed keyword "
|
2341
|
+
"(%"PRIsVALUE" for :left or :right)", closed);
|
2342
|
+
}
|
2343
|
+
}
|
2297
2344
|
|
2298
2345
|
edge = ary_histogram_calculate_edge(ary, nbins, left_p);
|
2299
2346
|
|
2300
|
-
|
2301
|
-
|
2302
|
-
for (i = 0; i <
|
2303
|
-
rb_ary_store(
|
2347
|
+
n_bin_weights = RARRAY_LEN(edge) - 1;
|
2348
|
+
bin_weights = rb_ary_new_capa(n_bin_weights);
|
2349
|
+
for (i = 0; i < n_bin_weights; ++i) {
|
2350
|
+
rb_ary_store(bin_weights, i, INT2FIX(0));
|
2304
2351
|
}
|
2305
2352
|
|
2306
|
-
histogram_weights_push_values(
|
2353
|
+
histogram_weights_push_values(bin_weights, edge, ary, weight_array, left_p);
|
2307
2354
|
|
2308
|
-
return rb_struct_new(cHistogram, edge,
|
2355
|
+
return rb_struct_new(cHistogram, edge, bin_weights,
|
2309
2356
|
left_p ? sym_left : sym_right,
|
2310
2357
|
Qfalse);
|
2311
2358
|
}
|
@@ -2352,6 +2399,9 @@ Init_extension(void)
|
|
2352
2399
|
|
2353
2400
|
rb_define_method(rb_cArray, "histogram", ary_histogram, -1);
|
2354
2401
|
|
2402
|
+
void Init_array_extension(void);
|
2403
|
+
Init_array_extension();
|
2404
|
+
|
2355
2405
|
idPLUS = '+';
|
2356
2406
|
idMINUS = '-';
|
2357
2407
|
idSTAR = '*';
|
@@ -2371,6 +2421,7 @@ Init_extension(void)
|
|
2371
2421
|
id_closed = rb_intern("closed");
|
2372
2422
|
id_edge = rb_intern("edge");
|
2373
2423
|
|
2424
|
+
sym_auto = ID2SYM(rb_intern("auto"));
|
2374
2425
|
sym_left = ID2SYM(rb_intern("left"));
|
2375
2426
|
sym_right = ID2SYM(rb_intern("right"));
|
2376
2427
|
}
|
@@ -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
|
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.
|
4
|
+
version: 2.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenta Murata
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -149,11 +149,13 @@ files:
|
|
149
149
|
- bin/rspec
|
150
150
|
- bin/setup
|
151
151
|
- enumerable-statistics.gemspec
|
152
|
+
- ext/enumerable/statistics/extension/array_ext.c
|
152
153
|
- ext/enumerable/statistics/extension/extconf.rb
|
153
154
|
- ext/enumerable/statistics/extension/statistics.c
|
154
155
|
- images/benchmark.png
|
155
156
|
- lib/enumerable/statistics.rb
|
156
157
|
- lib/enumerable_statistics.rb
|
158
|
+
- lib/enumerable_statistics/array_ext.rb
|
157
159
|
- lib/enumerable_statistics/histogram.rb
|
158
160
|
- lib/enumerable_statistics/version.rb
|
159
161
|
- templates/default/layout/html/headers.erb
|