enumerable-statistics 2.0.3 → 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|