carray 3.0.2 → 3.0.4
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 +568 -0
- data/README.md +6 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +220 -0
- data/ext/ca_axis_group.c +201 -123
- data/ext/ca_binop_dispatch.c +46 -52
- data/ext/ca_binop_dispatch.h +1 -1
- data/ext/ca_categorical_iterator.c +249 -183
- data/ext/ca_compare.c +7 -12
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +38 -23
- data/ext/ca_kernel_iterator.c +1765 -2076
- data/ext/ca_kernel_iterator.h +584 -566
- data/ext/ca_monop_dispatch.c +86 -63
- data/ext/ca_monop_dispatch.h +5 -0
- data/ext/ca_obj_array.c +223 -56
- data/ext/ca_obj_bincmp.c +172 -138
- data/ext/ca_obj_binop.c +116 -230
- data/ext/ca_obj_bitarray.c +40 -26
- data/ext/ca_obj_bitfield.c +100 -68
- data/ext/ca_obj_block.c +19 -9
- data/ext/ca_obj_byte_swap.c +45 -46
- data/ext/ca_obj_const_string.c +269 -44
- data/ext/ca_obj_face.c +612 -89
- data/ext/ca_obj_face.h +111 -47
- data/ext/ca_obj_fake.c +36 -79
- data/ext/ca_obj_farray.c +7 -3
- data/ext/ca_obj_field.c +33 -8
- data/ext/ca_obj_fixlen_string.c +23 -24
- data/ext/ca_obj_grid.c +541 -210
- data/ext/ca_obj_meld.c +331 -111
- data/ext/ca_obj_moncmp.c +80 -65
- data/ext/ca_obj_monop.c +177 -149
- data/ext/ca_obj_object.c +664 -248
- data/ext/ca_obj_record.c +63 -23
- data/ext/ca_obj_reduce.c +18 -16
- data/ext/ca_obj_refer.c +140 -58
- data/ext/ca_obj_remap.c +85 -24
- data/ext/ca_obj_repeat.c +24 -9
- data/ext/ca_obj_roll.c +121 -16
- data/ext/ca_obj_select.c +61 -58
- data/ext/ca_obj_select_axis.c +73 -107
- data/ext/ca_obj_shift.c +32 -102
- data/ext/ca_obj_stack.c +372 -122
- data/ext/ca_obj_stride.c +348 -140
- data/ext/ca_obj_string.c +88 -22
- data/ext/ca_obj_tile.c +38 -21
- data/ext/ca_obj_time.c +45 -31
- data/ext/ca_obj_timedelta.c +43 -29
- data/ext/ca_obj_transpose.c +17 -6
- data/ext/ca_obj_triop.c +125 -141
- data/ext/ca_obj_window.c +330 -44
- data/ext/ca_op_ipower.c +24 -11
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +104 -81
- data/ext/ca_sweep_engine.h +7 -20
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +542 -0
- data/ext/carray.h +241 -92
- data/ext/carray_access.c +608 -276
- data/ext/carray_address_basis.c +494 -97
- data/ext/carray_attribute.c +129 -4
- data/ext/carray_bincount.c +39 -7
- data/ext/carray_broadcast.c +56 -19
- data/ext/carray_build_flags.h +1 -1
- data/ext/carray_call_cfunc.c +108 -28
- data/ext/carray_cast.c +1576 -223
- data/ext/carray_cast_func.rb +77 -24
- data/ext/carray_class.c +4 -3
- data/ext/carray_conversion.c +208 -75
- data/ext/carray_copy.c +82 -24
- data/ext/carray_core.c +646 -162
- data/ext/carray_count.c +171 -88
- data/ext/carray_element.c +94 -60
- data/ext/carray_factorize.c +670 -324
- data/ext/carray_generate.c +260 -83
- data/ext/carray_histogram.c +209 -106
- data/ext/carray_hold.c +14 -16
- data/ext/carray_index_classifier.c +422 -243
- data/ext/carray_internal.h +692 -3
- data/ext/carray_kernels_bincmp.c +7 -0
- data/ext/carray_kernels_binop.c +487 -120
- data/ext/carray_kernels_init.c +653 -50
- data/ext/carray_kernels_moncmp.c +15 -8
- data/ext/carray_kernels_monop.c +99 -43
- data/ext/carray_kernels_reduce_aggregate.c +3925 -6112
- data/ext/carray_kernels_reduce_boolean.c +112 -36
- data/ext/carray_kernels_reduce_cumulative.c +2127 -6903
- data/ext/carray_kernels_reduce_extreme.c +3032 -2892
- data/ext/carray_kernels_reduce_variance.c +439 -500
- data/ext/carray_kernels_scan.c +1097 -488
- data/ext/carray_kernels_search.c +3787 -2176
- data/ext/carray_kernels_sort.c +1200 -920
- data/ext/carray_kernels_triop.c +479 -7
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +967 -153
- data/ext/carray_loop.c +81 -65
- data/ext/carray_mask.c +910 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +299 -100
- data/ext/carray_memory_view.c +872 -758
- data/ext/carray_operator.c +1171 -364
- data/ext/carray_order.c +505 -133
- data/ext/carray_partition.c +112 -65
- data/ext/carray_random.c +327 -239
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +346 -78
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +249 -86
- data/ext/carray_sort.c +224 -227
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +118 -39
- data/ext/carray_test.c +193 -69
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +579 -113
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +19 -4
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1202 -1014
- data/ext/ruby_carray.c +17 -5
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +160 -17
- data/lib/carray/autoload_carray.rb +23 -27
- data/lib/carray/autoload_method_extension.rb +20 -5
- data/lib/carray/axis_group.rb +360 -63
- data/lib/carray/basics.rb +162 -28
- data/lib/carray/bincount_nd.rb +18 -2
- data/lib/carray/block_iterator.rb +231 -58
- data/lib/carray/boolean_reduce.rb +34 -42
- data/lib/carray/categorical.rb +242 -52
- data/lib/carray/categorical_iterator.rb +437 -827
- data/lib/carray/complex.rb +41 -34
- data/lib/carray/conditional.rb +150 -14
- data/lib/carray/const_string.rb +59 -4
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +7 -1
- data/lib/carray/frame/column_verbs.rb +70 -0
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +82 -7
- data/lib/carray/frame/csv_parser.rb +688 -87
- data/lib/carray/frame/describe.rb +80 -0
- data/lib/carray/frame/frame.rb +369 -45
- data/lib/carray/frame/group.rb +631 -90
- data/lib/carray/frame/io.rb +506 -79
- data/lib/carray/frame/join.rb +411 -62
- data/lib/carray/frame/records.rb +116 -19
- data/lib/carray/frame/reshape.rb +455 -0
- data/lib/carray/frame/sort.rb +30 -18
- data/lib/carray/frame/verbs.rb +868 -61
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +4 -0
- data/lib/carray/fuse_source.rb +118 -2
- data/lib/carray/fusion.rb +257 -42
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +54 -13
- data/lib/carray/iterator.rb +99 -9
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +216 -193
- data/lib/carray/mask_gap_fill.rb +112 -92
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +52 -21
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +18 -2
- data/lib/carray/methods/bit_string.rb +15 -4
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +18 -10
- data/lib/carray/methods/factorize.rb +2 -2
- data/lib/carray/methods/gather_nd.rb +25 -5
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +140 -10
- data/lib/carray/methods/join.rb +2 -7
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +182 -45
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/repeat.rb +1 -20
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +11 -2
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +65 -17
- data/lib/carray/segment_iterator.rb +1221 -0
- data/lib/carray/serialize.rb +214 -30
- data/lib/carray/slab_iterator.rb +101 -27
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +12 -4
- data/lib/carray/struct.rb +137 -58
- data/lib/carray/struct_builder.rb +124 -17
- data/lib/carray/time.rb +1222 -186
- data/lib/carray/window_iterator.rb +242 -81
- data/lib/carray.rb +9 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +5 -1
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +5 -4
- data/yard-stubs/ca_obj_roll.rb +2 -3
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +9 -5
- data/yard-stubs/carray_access.rb +11 -5
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_broadcast.rb +1 -1
- data/yard-stubs/carray_cast.rb +88 -43
- data/yard-stubs/carray_conversion.rb +15 -2
- data/yard-stubs/carray_copy.rb +12 -5
- data/yard-stubs/carray_core.rb +3 -3
- data/yard-stubs/carray_count.rb +9 -0
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_lazy.rb +5 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +60 -12
- data/yard-stubs/carray_math.rb +52 -14
- data/yard-stubs/carray_median_percentile.rb +15 -8
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +61 -29
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +21 -9
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +10 -2
- data/yard-stubs/carray_sort.rb +49 -8
- data/yard-stubs/carray_test.rb +15 -3
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -5
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_kernels_map.c +0 -3467
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
|
@@ -1,120 +1,109 @@
|
|
|
1
1
|
/* ---------------------------------------------------------------------------
|
|
2
2
|
|
|
3
|
-
ca_categorical_iterator.c —
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
The output position is data-dependent (cursor[code]++), which the aligned
|
|
21
|
-
kernel_iterator macros do not model, so the flat inputs are materialised here:
|
|
22
|
-
ca_attach aliases a contiguous entity (codes / a contiguous value) and gathers
|
|
23
|
-
a view. Codes dispatch on their native integer type (no coercion); the value
|
|
24
|
-
move is a bytes-wide memcpy (grouped shares the value data type, so no value-type
|
|
25
|
-
dispatch is needed).
|
|
26
|
-
|
|
27
|
-
Surface (private): codes.__categorical_scatter__(value, cursor, grouped, k)
|
|
3
|
+
ca_categorical_iterator.c — kernels for CACategorical and CACategoricalIterator.
|
|
4
|
+
|
|
5
|
+
addresses_by_category orders the cells of a categorical by category, the
|
|
6
|
+
counting sort behind CACategorical#sort_addr: one pass over the codes
|
|
7
|
+
writes each cell's address at its category's cursor (a mutable copy of the
|
|
8
|
+
segment starts), so every cell of category 0 comes first, then 1, ..., in
|
|
9
|
+
source order within a category (stable). A cell in no category -- a masked
|
|
10
|
+
code, or a code outside 0...k -- is written in the same pass at a second
|
|
11
|
+
cursor that starts after the last category, so the excluded cells follow
|
|
12
|
+
in source order.
|
|
13
|
+
|
|
14
|
+
The output position depends on the code, which the aligned kernel_iterator
|
|
15
|
+
macros do not model, so the codes are materialised here: ca_attach aliases a
|
|
16
|
+
contiguous entity and gathers a view.
|
|
17
|
+
|
|
18
|
+
Surface (private): codes.addresses_by_category(cursor, k, nvalid)
|
|
28
19
|
self = codes (integer, carries the exclusion mask), read flat
|
|
29
|
-
value = payload (any data type, may carry a mask), read flat, same length
|
|
30
20
|
cursor = int64 length-k segment starts (mutated in place, consumed)
|
|
31
|
-
grouped = pre-allocated contiguous entity of the value data type, length nvalid
|
|
32
21
|
k = number of categories
|
|
33
|
-
|
|
22
|
+
nvalid = number of cells in a category (where the excluded cells start)
|
|
23
|
+
Returns a new int64 CArray of codes.elements addresses.
|
|
34
24
|
|
|
35
25
|
--------------------------------------------------------------------------- */
|
|
36
26
|
|
|
37
27
|
#include "carray.h"
|
|
28
|
+
#include "carray_internal.h" /* CA_EXTREMUM_REPLACES */
|
|
29
|
+
#include "ca_sort_kernels.h" /* ca_partition_nan_f64 */
|
|
38
30
|
#include <stdlib.h> /* qsort */
|
|
39
31
|
#include <math.h> /* floor */
|
|
40
32
|
|
|
41
|
-
#define
|
|
33
|
+
#define ADDRESSES_BY_CATEGORY_BODY(CODE_T) \
|
|
42
34
|
do { \
|
|
43
35
|
const CODE_T *cp = (const CODE_T *) codes->ptr; \
|
|
44
36
|
for ( j = 0; j < n; j++ ) { \
|
|
45
|
-
if ( cmask && cmask[j] ) continue; /* excluded by codes mask */ \
|
|
46
37
|
c = (int64_t) cp[j]; \
|
|
47
|
-
if ( c < 0 || c >= k )
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
38
|
+
if ( ( cmask && cmask[j] ) || c < 0 || c >= k ) { \
|
|
39
|
+
if ( tail >= (int64_t) n ) { overrun = 1; break; } \
|
|
40
|
+
out[tail++] = (int64_t) j; /* in no category */ \
|
|
41
|
+
continue; \
|
|
42
|
+
} \
|
|
43
|
+
if ( cur[c] < 0 || cur[c] >= nvalid ) { overrun = 1; break; } \
|
|
44
|
+
out[cur[c]++] = (int64_t) j; \
|
|
52
45
|
} \
|
|
53
46
|
} while (0)
|
|
54
47
|
|
|
55
48
|
static VALUE
|
|
56
|
-
|
|
57
|
-
VALUE rgrouped, VALUE rk)
|
|
49
|
+
rb_ca_addresses_by_category (VALUE self, VALUE rcursor, VALUE rk, VALUE rnvalid)
|
|
58
50
|
{
|
|
59
|
-
CArray *codes, *
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
GetCArray(
|
|
67
|
-
GetCArray(rcursor,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
rb_raise(rb_eArgError,
|
|
75
|
-
"__categorical_scatter__: value length %lld != codes length %lld",
|
|
76
|
-
(long long) value->elements, (long long) n);
|
|
77
|
-
}
|
|
78
|
-
if ( cursor->data_type != CA_INT64 || cursor->elements != k ) {
|
|
79
|
-
rb_raise(rb_eArgError, "__categorical_scatter__: cursor must be int64[k]");
|
|
80
|
-
}
|
|
81
|
-
if ( grouped->bytes != bytes ) {
|
|
82
|
-
rb_raise(rb_eArgError, "__categorical_scatter__: grouped/value data type mismatch");
|
|
51
|
+
CArray *codes, *cursor, *result;
|
|
52
|
+
VALUE rresult;
|
|
53
|
+
int64_t k, c, *cur, *out, tail, nvalid;
|
|
54
|
+
ca_size_t n, j, dim;
|
|
55
|
+
int overrun = 0;
|
|
56
|
+
boolean8_t *cmask;
|
|
57
|
+
|
|
58
|
+
GetCArray(self, codes);
|
|
59
|
+
GetCArray(rcursor, cursor);
|
|
60
|
+
k = (int64_t) NUM2LL(rk);
|
|
61
|
+
nvalid = (int64_t) NUM2LL(rnvalid);
|
|
62
|
+
n = codes->elements;
|
|
63
|
+
|
|
64
|
+
if ( cursor->data_type != CA_INT64 || cursor->elements != k ||
|
|
65
|
+
! ca_is_entity(cursor) ) {
|
|
66
|
+
rb_raise(rb_eArgError, "addresses_by_category: cursor must be an int64[k] entity");
|
|
83
67
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
cmask = ca_mask_ptr(codes);
|
|
88
|
-
vmask = ca_mask_ptr(value);
|
|
89
|
-
cur = (int64_t *) cursor->ptr;
|
|
90
|
-
gp = grouped->ptr;
|
|
91
|
-
vp = value->ptr;
|
|
92
|
-
|
|
93
|
-
if ( vmask ) { /* grouped needs a mask to receive it */
|
|
94
|
-
ca_create_mask(grouped);
|
|
95
|
-
gmask = (boolean8_t *) grouped->mask->ptr;
|
|
68
|
+
if ( nvalid < 0 || nvalid > (int64_t) n ) {
|
|
69
|
+
rb_raise(rb_eArgError, "addresses_by_category: nvalid %lld out of 0..%lld",
|
|
70
|
+
(long long) nvalid, (long long) n);
|
|
96
71
|
}
|
|
97
|
-
|
|
98
72
|
switch ( codes->data_type ) {
|
|
99
|
-
case CA_INT8:
|
|
100
|
-
case
|
|
101
|
-
|
|
102
|
-
case CA_UINT16: CATEGORICAL_SCATTER_BODY(uint16_t); break;
|
|
103
|
-
case CA_INT32: CATEGORICAL_SCATTER_BODY(int32_t); break;
|
|
104
|
-
case CA_UINT32: CATEGORICAL_SCATTER_BODY(uint32_t); break;
|
|
105
|
-
case CA_INT64: CATEGORICAL_SCATTER_BODY(int64_t); break;
|
|
106
|
-
case CA_UINT64: CATEGORICAL_SCATTER_BODY(uint64_t); break;
|
|
73
|
+
case CA_INT8: case CA_UINT8: case CA_INT16: case CA_UINT16:
|
|
74
|
+
case CA_INT32: case CA_UINT32: case CA_INT64: case CA_UINT64:
|
|
75
|
+
break;
|
|
107
76
|
default:
|
|
108
|
-
ca_detach(codes);
|
|
109
|
-
ca_detach(value);
|
|
110
77
|
rb_raise(rb_eCADataTypeError,
|
|
111
|
-
"
|
|
78
|
+
"addresses_by_category: integer codes required (got data_type %d)",
|
|
112
79
|
codes->data_type);
|
|
113
80
|
}
|
|
114
81
|
|
|
82
|
+
dim = n;
|
|
83
|
+
rresult = rb_carray_new(CA_INT64, 1, &dim, 0, NULL);
|
|
84
|
+
GetCArray(rresult, result);
|
|
85
|
+
out = (int64_t *) result->ptr;
|
|
86
|
+
cur = (int64_t *) cursor->ptr;
|
|
87
|
+
tail = nvalid;
|
|
88
|
+
|
|
89
|
+
ca_attach(codes); /* window: nothing below raises */
|
|
90
|
+
cmask = ca_mask_ptr(codes);
|
|
91
|
+
switch ( codes->data_type ) {
|
|
92
|
+
case CA_INT8: ADDRESSES_BY_CATEGORY_BODY(int8_t); break;
|
|
93
|
+
case CA_UINT8: ADDRESSES_BY_CATEGORY_BODY(uint8_t); break;
|
|
94
|
+
case CA_INT16: ADDRESSES_BY_CATEGORY_BODY(int16_t); break;
|
|
95
|
+
case CA_UINT16: ADDRESSES_BY_CATEGORY_BODY(uint16_t); break;
|
|
96
|
+
case CA_INT32: ADDRESSES_BY_CATEGORY_BODY(int32_t); break;
|
|
97
|
+
case CA_UINT32: ADDRESSES_BY_CATEGORY_BODY(uint32_t); break;
|
|
98
|
+
case CA_INT64: ADDRESSES_BY_CATEGORY_BODY(int64_t); break;
|
|
99
|
+
case CA_UINT64: ADDRESSES_BY_CATEGORY_BODY(uint64_t); break;
|
|
100
|
+
}
|
|
115
101
|
ca_detach(codes);
|
|
116
|
-
|
|
117
|
-
|
|
102
|
+
if ( overrun ) {
|
|
103
|
+
rb_raise(rb_eArgError,
|
|
104
|
+
"addresses_by_category: the cursor and nvalid do not match the codes");
|
|
105
|
+
}
|
|
106
|
+
return rresult;
|
|
118
107
|
}
|
|
119
108
|
|
|
120
109
|
/* ---------------------------------------------------------------------------
|
|
@@ -151,7 +140,22 @@ rb_ca_categorical_scatter (VALUE self, VALUE rvalue, VALUE rcursor,
|
|
|
151
140
|
#define CAT_NAN_NEVER(v) (0)
|
|
152
141
|
#define CAT_NAN_CHECK(v) ((v) != (v))
|
|
153
142
|
|
|
154
|
-
|
|
143
|
+
/* Whether v takes the place of the accumulator acc: never when v is NaN,
|
|
144
|
+
always when acc is NaN and v is not. */
|
|
145
|
+
#define CAT_REPLACES(v, acc, CMP, ISNAN) \
|
|
146
|
+
( ! ISNAN(v) && ( ISNAN(acc) || (v) CMP (acc) ) )
|
|
147
|
+
|
|
148
|
+
/* A segment without masked cells of at least CAT_LANES_FROM cells is read
|
|
149
|
+
with eight independent sums and eight min / max lanes, so no add or
|
|
150
|
+
compare waits on the one before it; a shorter one would spend more on
|
|
151
|
+
setting up and merging the lanes than it saves.
|
|
152
|
+
Each lane starts from the segment's first value; a lane can end on NaN
|
|
153
|
+
only if every value it saw was NaN, so merging the lanes with the same
|
|
154
|
+
rule gives the answer one lane would. The sums are added in a different
|
|
155
|
+
order than the cells, which is the license every float reduction has. */
|
|
156
|
+
#define CAT_LANES_FROM 64
|
|
157
|
+
|
|
158
|
+
#define REDUCEAT_MOMENTS_BODY(T, ISNAN, LANES_FROM) \
|
|
155
159
|
do { \
|
|
156
160
|
const T *gp = (const T *) grouped->ptr; \
|
|
157
161
|
T *minv = (T *) minp, *maxv = (T *) maxp; \
|
|
@@ -160,18 +164,96 @@ rb_ca_categorical_scatter (VALUE self, VALUE rvalue, VALUE rcursor,
|
|
|
160
164
|
ca_size_t hi = (c + 1 < k) ? (ca_size_t) offs[c+1] : n; \
|
|
161
165
|
ca_size_t j, cnt = 0; \
|
|
162
166
|
double sacc = 0.0; \
|
|
163
|
-
T mn = 0, mx = 0; int seen = 0
|
|
164
|
-
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
167
|
+
T mn = 0, mx = 0; int seen = 0; \
|
|
168
|
+
if ( ! gm && hi - lo < (ca_size_t) (LANES_FROM) ) { \
|
|
169
|
+
if ( hi > lo ) { \
|
|
170
|
+
mn = mx = gp[lo]; \
|
|
171
|
+
for ( j = lo; j < hi; j++ ) { \
|
|
172
|
+
T v = gp[j]; \
|
|
173
|
+
sacc += (double) v; \
|
|
174
|
+
if ( CAT_REPLACES(v, mn, <, ISNAN) ) mn = v; \
|
|
175
|
+
if ( CAT_REPLACES(v, mx, >, ISNAN) ) mx = v; \
|
|
176
|
+
} \
|
|
177
|
+
cnt = hi - lo; seen = 1; \
|
|
178
|
+
} \
|
|
179
|
+
} \
|
|
180
|
+
else if ( ! gm ) { \
|
|
181
|
+
{ \
|
|
182
|
+
double s0 = 0, s1 = 0, s2 = 0, s3 = 0, s4 = 0, s5 = 0, s6 = 0, s7 = 0; \
|
|
183
|
+
T n0, n1, n2, n3, n4, n5, n6, n7, x0, x1, x2, x3, x4, x5, x6, x7; \
|
|
184
|
+
n0 = n1 = n2 = n3 = n4 = n5 = n6 = n7 = gp[lo]; \
|
|
185
|
+
x0 = x1 = x2 = x3 = x4 = x5 = x6 = x7 = gp[lo]; \
|
|
186
|
+
for ( j = lo; j + 8 <= hi; j += 8 ) { \
|
|
187
|
+
T v0 = gp[j], v1 = gp[j+1], v2 = gp[j+2], v3 = gp[j+3]; \
|
|
188
|
+
T v4 = gp[j+4], v5 = gp[j+5], v6 = gp[j+6], v7 = gp[j+7]; \
|
|
189
|
+
s0 += (double) v0; s1 += (double) v1; \
|
|
190
|
+
s2 += (double) v2; s3 += (double) v3; \
|
|
191
|
+
s4 += (double) v4; s5 += (double) v5; \
|
|
192
|
+
s6 += (double) v6; s7 += (double) v7; \
|
|
193
|
+
if ( CAT_REPLACES(v0, n0, <, ISNAN) ) n0 = v0; \
|
|
194
|
+
if ( CAT_REPLACES(v1, n1, <, ISNAN) ) n1 = v1; \
|
|
195
|
+
if ( CAT_REPLACES(v2, n2, <, ISNAN) ) n2 = v2; \
|
|
196
|
+
if ( CAT_REPLACES(v3, n3, <, ISNAN) ) n3 = v3; \
|
|
197
|
+
if ( CAT_REPLACES(v4, n4, <, ISNAN) ) n4 = v4; \
|
|
198
|
+
if ( CAT_REPLACES(v5, n5, <, ISNAN) ) n5 = v5; \
|
|
199
|
+
if ( CAT_REPLACES(v6, n6, <, ISNAN) ) n6 = v6; \
|
|
200
|
+
if ( CAT_REPLACES(v7, n7, <, ISNAN) ) n7 = v7; \
|
|
201
|
+
if ( CAT_REPLACES(v0, x0, >, ISNAN) ) x0 = v0; \
|
|
202
|
+
if ( CAT_REPLACES(v1, x1, >, ISNAN) ) x1 = v1; \
|
|
203
|
+
if ( CAT_REPLACES(v2, x2, >, ISNAN) ) x2 = v2; \
|
|
204
|
+
if ( CAT_REPLACES(v3, x3, >, ISNAN) ) x3 = v3; \
|
|
205
|
+
if ( CAT_REPLACES(v4, x4, >, ISNAN) ) x4 = v4; \
|
|
206
|
+
if ( CAT_REPLACES(v5, x5, >, ISNAN) ) x5 = v5; \
|
|
207
|
+
if ( CAT_REPLACES(v6, x6, >, ISNAN) ) x6 = v6; \
|
|
208
|
+
if ( CAT_REPLACES(v7, x7, >, ISNAN) ) x7 = v7; \
|
|
209
|
+
} \
|
|
210
|
+
for ( ; j < hi; j++ ) { \
|
|
211
|
+
T v = gp[j]; \
|
|
212
|
+
s0 += (double) v; \
|
|
213
|
+
if ( CAT_REPLACES(v, n0, <, ISNAN) ) n0 = v; \
|
|
214
|
+
if ( CAT_REPLACES(v, x0, >, ISNAN) ) x0 = v; \
|
|
215
|
+
} \
|
|
216
|
+
sacc = ((s0 + s1) + (s2 + s3)) + ((s4 + s5) + (s6 + s7)); \
|
|
217
|
+
mn = n0; \
|
|
218
|
+
if ( CAT_REPLACES(n1, mn, <, ISNAN) ) mn = n1; \
|
|
219
|
+
if ( CAT_REPLACES(n2, mn, <, ISNAN) ) mn = n2; \
|
|
220
|
+
if ( CAT_REPLACES(n3, mn, <, ISNAN) ) mn = n3; \
|
|
221
|
+
if ( CAT_REPLACES(n4, mn, <, ISNAN) ) mn = n4; \
|
|
222
|
+
if ( CAT_REPLACES(n5, mn, <, ISNAN) ) mn = n5; \
|
|
223
|
+
if ( CAT_REPLACES(n6, mn, <, ISNAN) ) mn = n6; \
|
|
224
|
+
if ( CAT_REPLACES(n7, mn, <, ISNAN) ) mn = n7; \
|
|
225
|
+
mx = x0; \
|
|
226
|
+
if ( CAT_REPLACES(x1, mx, >, ISNAN) ) mx = x1; \
|
|
227
|
+
if ( CAT_REPLACES(x2, mx, >, ISNAN) ) mx = x2; \
|
|
228
|
+
if ( CAT_REPLACES(x3, mx, >, ISNAN) ) mx = x3; \
|
|
229
|
+
if ( CAT_REPLACES(x4, mx, >, ISNAN) ) mx = x4; \
|
|
230
|
+
if ( CAT_REPLACES(x5, mx, >, ISNAN) ) mx = x5; \
|
|
231
|
+
if ( CAT_REPLACES(x6, mx, >, ISNAN) ) mx = x6; \
|
|
232
|
+
if ( CAT_REPLACES(x7, mx, >, ISNAN) ) mx = x7; \
|
|
233
|
+
/* Of equal values a lane keeps its first, but the merge does not \
|
|
234
|
+
know which lane saw its value first in cell order. Only 0.0 and \
|
|
235
|
+
-0.0 are equal and tell apart: take the first zero, as one loop \
|
|
236
|
+
over the cells does. */ \
|
|
237
|
+
if ( mn == 0 ) { \
|
|
238
|
+
for ( j = lo; j < hi; j++ ) { if ( gp[j] == 0 ) { mn = gp[j]; break; } } \
|
|
239
|
+
} \
|
|
240
|
+
if ( mx == 0 ) { \
|
|
241
|
+
for ( j = lo; j < hi; j++ ) { if ( gp[j] == 0 ) { mx = gp[j]; break; } } \
|
|
171
242
|
} \
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
243
|
+
cnt = hi - lo; seen = 1; \
|
|
244
|
+
} \
|
|
245
|
+
} \
|
|
246
|
+
else { \
|
|
247
|
+
for ( j = lo; j < hi && gm[j]; j++ ) ; /* skip to the first present */ \
|
|
248
|
+
if ( j < hi ) { mn = mx = gp[j]; seen = 1; } \
|
|
249
|
+
for ( ; j < hi; j++ ) { \
|
|
250
|
+
T v = gp[j]; \
|
|
251
|
+
if ( gm[j] ) continue; /* masked value cell */ \
|
|
252
|
+
sacc += (double) v; \
|
|
253
|
+
cnt++; \
|
|
254
|
+
if ( CAT_REPLACES(v, mn, <, ISNAN) ) mn = v; \
|
|
255
|
+
if ( CAT_REPLACES(v, mx, >, ISNAN) ) mx = v; \
|
|
256
|
+
} \
|
|
175
257
|
} \
|
|
176
258
|
countp[c] = (int64_t) cnt; \
|
|
177
259
|
sump[c] = sacc; \
|
|
@@ -222,16 +304,16 @@ rb_ca_reduceat_moments (VALUE self, VALUE roffsets, VALUE rcounts,
|
|
|
222
304
|
maxm = (boolean8_t *) maxs->mask->ptr;
|
|
223
305
|
|
|
224
306
|
switch ( grouped->data_type ) {
|
|
225
|
-
case CA_INT8: REDUCEAT_MOMENTS_BODY(int8_t, CAT_NAN_NEVER); break;
|
|
226
|
-
case CA_UINT8: REDUCEAT_MOMENTS_BODY(uint8_t, CAT_NAN_NEVER); break;
|
|
227
|
-
case CA_INT16: REDUCEAT_MOMENTS_BODY(int16_t, CAT_NAN_NEVER); break;
|
|
228
|
-
case CA_UINT16: REDUCEAT_MOMENTS_BODY(uint16_t, CAT_NAN_NEVER); break;
|
|
229
|
-
case CA_INT32: REDUCEAT_MOMENTS_BODY(int32_t, CAT_NAN_NEVER); break;
|
|
230
|
-
case CA_UINT32: REDUCEAT_MOMENTS_BODY(uint32_t, CAT_NAN_NEVER); break;
|
|
231
|
-
case CA_INT64: REDUCEAT_MOMENTS_BODY(int64_t, CAT_NAN_NEVER); break;
|
|
232
|
-
case CA_UINT64: REDUCEAT_MOMENTS_BODY(uint64_t, CAT_NAN_NEVER); break;
|
|
233
|
-
case CA_FLOAT32: REDUCEAT_MOMENTS_BODY(float32_t, CAT_NAN_CHECK); break;
|
|
234
|
-
case CA_FLOAT64: REDUCEAT_MOMENTS_BODY(float64_t, CAT_NAN_CHECK); break;
|
|
307
|
+
case CA_INT8: REDUCEAT_MOMENTS_BODY(int8_t, CAT_NAN_NEVER, CA_LENGTH_MAX); break;
|
|
308
|
+
case CA_UINT8: REDUCEAT_MOMENTS_BODY(uint8_t, CAT_NAN_NEVER, CA_LENGTH_MAX); break;
|
|
309
|
+
case CA_INT16: REDUCEAT_MOMENTS_BODY(int16_t, CAT_NAN_NEVER, CA_LENGTH_MAX); break;
|
|
310
|
+
case CA_UINT16: REDUCEAT_MOMENTS_BODY(uint16_t, CAT_NAN_NEVER, CA_LENGTH_MAX); break;
|
|
311
|
+
case CA_INT32: REDUCEAT_MOMENTS_BODY(int32_t, CAT_NAN_NEVER, CA_LENGTH_MAX); break;
|
|
312
|
+
case CA_UINT32: REDUCEAT_MOMENTS_BODY(uint32_t, CAT_NAN_NEVER, CA_LENGTH_MAX); break;
|
|
313
|
+
case CA_INT64: REDUCEAT_MOMENTS_BODY(int64_t, CAT_NAN_NEVER, CA_LENGTH_MAX); break;
|
|
314
|
+
case CA_UINT64: REDUCEAT_MOMENTS_BODY(uint64_t, CAT_NAN_NEVER, CA_LENGTH_MAX); break;
|
|
315
|
+
case CA_FLOAT32: REDUCEAT_MOMENTS_BODY(float32_t, CAT_NAN_CHECK, CAT_LANES_FROM); break;
|
|
316
|
+
case CA_FLOAT64: REDUCEAT_MOMENTS_BODY(float64_t, CAT_NAN_CHECK, CAT_LANES_FROM); break;
|
|
235
317
|
default:
|
|
236
318
|
rb_raise(rb_eCADataTypeError,
|
|
237
319
|
"__reduceat_moments__: numeric value required (got data_type %d)",
|
|
@@ -295,20 +377,12 @@ ca_nth_element_double (double *a, ca_size_t n, ca_size_t kth)
|
|
|
295
377
|
{ double f = (double) (m - 1) * p / 100.0; \
|
|
296
378
|
ca_size_t ki = (ca_size_t) floor(f); \
|
|
297
379
|
double vlo, vhi; \
|
|
298
|
-
/*
|
|
299
|
-
ki-th element here is the ki-th of the sorted segment.
|
|
300
|
-
runs on the numeric prefix
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
and answers vlo, which is why the median of [NaN, -9.0] is -9.0. */ \
|
|
305
|
-
ca_size_t nnum = m, t0 = 0; \
|
|
306
|
-
while ( t0 < nnum ) { \
|
|
307
|
-
if ( scratch[t0] != scratch[t0] ) { \
|
|
308
|
-
double tmp = scratch[--nnum]; \
|
|
309
|
-
scratch[nnum] = scratch[t0]; scratch[t0] = tmp; \
|
|
310
|
-
} else t0++; \
|
|
311
|
-
} \
|
|
380
|
+
/* NaN to the tail, where CArray's sort puts it (ca_partition_nan), \
|
|
381
|
+
so the ki-th element here is the ki-th of the sorted segment. \
|
|
382
|
+
Selection runs on the numeric prefix; a position or an upper \
|
|
383
|
+
neighbour landing in the tail is NaN. The blend is \
|
|
384
|
+
CArray#percentile's, so both answer alike for NaN and infinities. */\
|
|
385
|
+
ca_size_t nnum = ca_partition_nan_f64(scratch, m); \
|
|
312
386
|
if ( ki < nnum ) { \
|
|
313
387
|
ca_nth_element_double(scratch, nnum, ki); /* scratch[ki] = ki-th */ \
|
|
314
388
|
vlo = scratch[ki]; \
|
|
@@ -317,8 +391,8 @@ ca_nth_element_double (double *a, ca_size_t n, ca_size_t kth)
|
|
|
317
391
|
double mn = scratch[ki+1]; ca_size_t t; \
|
|
318
392
|
for ( t = ki + 2; t < nnum; t++ ) if ( scratch[t] < mn ) mn = scratch[t]; \
|
|
319
393
|
vhi = mn; \
|
|
320
|
-
} else vhi =
|
|
321
|
-
outp[c] = vlo
|
|
394
|
+
} else vhi = (double) NAN; \
|
|
395
|
+
outp[c] = ca_percentile_linear(vlo, vhi, f - (double) ki, ki, m); } \
|
|
322
396
|
} \
|
|
323
397
|
} while (0)
|
|
324
398
|
|
|
@@ -335,6 +409,11 @@ rb_ca_reduceat_percentile (VALUE self, VALUE roffsets, VALUE rp, VALUE rout)
|
|
|
335
409
|
GetCArray(roffsets, offsets);
|
|
336
410
|
GetCArray(rout, out);
|
|
337
411
|
p = NUM2DBL(rp);
|
|
412
|
+
if ( !(p >= 0.0 && p <= 100.0) ) {
|
|
413
|
+
rb_raise(rb_eArgError,
|
|
414
|
+
"percentile: p must be Numeric in [0,100] (got %"PRIsVALUE")",
|
|
415
|
+
rb_inspect(rp));
|
|
416
|
+
}
|
|
338
417
|
k = (int64_t) offsets->elements;
|
|
339
418
|
n = grouped->elements;
|
|
340
419
|
if ( offsets->data_type != CA_INT64 || out->data_type != CA_FLOAT64 ||
|
|
@@ -383,7 +462,7 @@ rb_ca_reduceat_percentile (VALUE self, VALUE roffsets, VALUE rp, VALUE rout)
|
|
|
383
462
|
accumulates the per-segment centred sum of squares; variance = SS / (n-1).
|
|
384
463
|
Centred (not the one-pass sum-of-squares) so the ε-close contract holds — a
|
|
385
464
|
one-pass formula cancels catastrophically. Matches CArray#variance per group:
|
|
386
|
-
count 0
|
|
465
|
+
count 0 or 1 -> masked (the sample variance is undefined), count >= 2 ->
|
|
387
466
|
SS / (count-1).
|
|
388
467
|
|
|
389
468
|
Surface (private): grouped.__reduceat_variance__(offsets, means, counts, out)
|
|
@@ -391,7 +470,7 @@ rb_ca_reduceat_percentile (VALUE self, VALUE roffsets, VALUE rp, VALUE rout)
|
|
|
391
470
|
offsets = int64[k] segment STARTS
|
|
392
471
|
means = float64[k] per-segment mean (ignored where count < 2)
|
|
393
472
|
counts = int64[k] per-segment present count
|
|
394
|
-
out = float64[k] output: variance; count 0
|
|
473
|
+
out = float64[k] output: variance; count 0 or 1 masked
|
|
395
474
|
|
|
396
475
|
--------------------------------------------------------------------------- */
|
|
397
476
|
|
|
@@ -400,8 +479,7 @@ rb_ca_reduceat_percentile (VALUE self, VALUE roffsets, VALUE rp, VALUE rout)
|
|
|
400
479
|
const T *gp = (const T *) grouped->ptr; \
|
|
401
480
|
for ( c = 0; c < k; c++ ) { \
|
|
402
481
|
int64_t cnt = countp[c]; \
|
|
403
|
-
if ( cnt
|
|
404
|
-
if ( cnt == 1 ) { outp[c] = 0.0; continue; } /* n=1 contract: 0.0 */ \
|
|
482
|
+
if ( cnt < 2 ) { outp[c] = 0.0; outm[c] = 1; continue; } /* undefined */ \
|
|
405
483
|
{ double mean = meanp[c], ss = 0.0; \
|
|
406
484
|
ca_size_t lo = (ca_size_t) offs[c]; \
|
|
407
485
|
ca_size_t hi = (c + 1 < k) ? (ca_size_t) offs[c+1] : n, j; \
|
|
@@ -689,19 +767,16 @@ cmp_double (const void *a, const void *b)
|
|
|
689
767
|
scratch[m++] = (double) gp[jj]; \
|
|
690
768
|
} \
|
|
691
769
|
if ( m == 0 ) { for ( t = 0; t < 5; t++ ) { outp[t][c] = 0.0; outm[t][c] = 1; } continue; } \
|
|
770
|
+
/* NaN sorts last, as in the core's sort, so a position or an upper \
|
|
771
|
+
neighbour in the tail is NaN, as the core answers. */ \
|
|
692
772
|
qsort(scratch, (size_t) m, sizeof(double), cmp_double); \
|
|
693
|
-
{ ca_size_t nnum = m; \
|
|
694
|
-
while ( nnum > 0 && scratch[nnum-1] != scratch[nnum-1] ) nnum--; \
|
|
695
773
|
for ( t = 0; t < 5; t++ ) { \
|
|
696
774
|
double f = (double) (m - 1) * P[t] / 100.0; \
|
|
697
775
|
ca_size_t ki = (ca_size_t) floor(f); \
|
|
698
|
-
double
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
double vhi = (ki + 1 < nnum) ? scratch[ki+1] : vlo; \
|
|
703
|
-
outp[t][c] = vlo + (f - (double) ki) * (vhi - vlo); \
|
|
704
|
-
} } \
|
|
776
|
+
double vhi = (ki + 1 < m) ? scratch[ki+1] : scratch[ki]; \
|
|
777
|
+
outp[t][c] = ca_percentile_linear(scratch[ki], vhi, f - (double) ki, \
|
|
778
|
+
ki, m); \
|
|
779
|
+
} \
|
|
705
780
|
} \
|
|
706
781
|
} while (0)
|
|
707
782
|
|
|
@@ -853,7 +928,7 @@ rb_ca_reduceat_wsum_wmean (VALUE self, VALUE roffsets, VALUE rwg,
|
|
|
853
928
|
|
|
854
929
|
Not aligned kernel_iterator: output position depends on the codes value
|
|
855
930
|
(data-dependent scatter), so ca_attach materialises the inputs into
|
|
856
|
-
contiguous flat buffers — same pattern as sibling
|
|
931
|
+
contiguous flat buffers — same pattern as sibling addresses_by_category.
|
|
857
932
|
|
|
858
933
|
Surface (private):
|
|
859
934
|
h.__fiber_scatter_moments__(codes, axis, K, counts_out, sums_out)
|
|
@@ -869,7 +944,7 @@ rb_ca_reduceat_wsum_wmean (VALUE self, VALUE roffsets, VALUE rwg,
|
|
|
869
944
|
(empty group cell → 0 + masked, matching __reduceat_moments__).
|
|
870
945
|
--------------------------------------------------------------------------- */
|
|
871
946
|
|
|
872
|
-
#define FIBER_SCATTER_BODY(H_T, C_T
|
|
947
|
+
#define FIBER_SCATTER_BODY(H_T, C_T) \
|
|
873
948
|
do { \
|
|
874
949
|
const H_T *hp = (const H_T *) h->ptr; \
|
|
875
950
|
const C_T *cp = (const C_T *) codes->ptr; \
|
|
@@ -891,18 +966,11 @@ rb_ca_reduceat_wsum_wmean (VALUE self, VALUE roffsets, VALUE rwg,
|
|
|
891
966
|
if ( c < 0 || c >= K ) continue; /* out-of-vocabulary */ \
|
|
892
967
|
out_off = c * band_size + out_outer + inn; \
|
|
893
968
|
v = hp[off]; \
|
|
894
|
-
/* NaN loses every contest, as in the flat twin and the core. min \
|
|
895
|
-
and max are seeded together and only ever move on a number, so a \
|
|
896
|
-
NaN sitting in min means this cell has met nothing but NaN yet. */\
|
|
897
969
|
if ( countp[out_off] == 0 ) { \
|
|
898
970
|
minv[out_off] = v; maxv[out_off] = v; \
|
|
899
|
-
} else
|
|
900
|
-
if (
|
|
901
|
-
|
|
902
|
-
} else { \
|
|
903
|
-
if ( v < minv[out_off] ) minv[out_off] = v; \
|
|
904
|
-
if ( v > maxv[out_off] ) maxv[out_off] = v; \
|
|
905
|
-
} \
|
|
971
|
+
} else { \
|
|
972
|
+
if ( CA_EXTREMUM_REPLACES(v, minv[out_off], <) ) minv[out_off] = v;\
|
|
973
|
+
if ( CA_EXTREMUM_REPLACES(v, maxv[out_off], >) ) maxv[out_off] = v;\
|
|
906
974
|
} \
|
|
907
975
|
countp[out_off]++; \
|
|
908
976
|
sump[out_off] += (double) v; \
|
|
@@ -911,16 +979,16 @@ rb_ca_reduceat_wsum_wmean (VALUE self, VALUE roffsets, VALUE rwg,
|
|
|
911
979
|
} \
|
|
912
980
|
} while (0)
|
|
913
981
|
|
|
914
|
-
#define FIBER_SCATTER_DISPATCH_C(H_T
|
|
982
|
+
#define FIBER_SCATTER_DISPATCH_C(H_T) \
|
|
915
983
|
switch ( codes->data_type ) { \
|
|
916
|
-
case CA_INT8: FIBER_SCATTER_BODY(H_T, int8_t
|
|
917
|
-
case CA_UINT8: FIBER_SCATTER_BODY(H_T, uint8_t
|
|
918
|
-
case CA_INT16: FIBER_SCATTER_BODY(H_T, int16_t
|
|
919
|
-
case CA_UINT16: FIBER_SCATTER_BODY(H_T, uint16_t
|
|
920
|
-
case CA_INT32: FIBER_SCATTER_BODY(H_T, int32_t
|
|
921
|
-
case CA_UINT32: FIBER_SCATTER_BODY(H_T, uint32_t
|
|
922
|
-
case CA_INT64: FIBER_SCATTER_BODY(H_T, int64_t
|
|
923
|
-
case CA_UINT64: FIBER_SCATTER_BODY(H_T, uint64_t
|
|
984
|
+
case CA_INT8: FIBER_SCATTER_BODY(H_T, int8_t); break; \
|
|
985
|
+
case CA_UINT8: FIBER_SCATTER_BODY(H_T, uint8_t); break; \
|
|
986
|
+
case CA_INT16: FIBER_SCATTER_BODY(H_T, int16_t); break; \
|
|
987
|
+
case CA_UINT16: FIBER_SCATTER_BODY(H_T, uint16_t); break; \
|
|
988
|
+
case CA_INT32: FIBER_SCATTER_BODY(H_T, int32_t); break; \
|
|
989
|
+
case CA_UINT32: FIBER_SCATTER_BODY(H_T, uint32_t); break; \
|
|
990
|
+
case CA_INT64: FIBER_SCATTER_BODY(H_T, int64_t); break; \
|
|
991
|
+
case CA_UINT64: FIBER_SCATTER_BODY(H_T, uint64_t); break; \
|
|
924
992
|
default: \
|
|
925
993
|
ca_detach(h); ca_detach(codes); \
|
|
926
994
|
rb_raise(rb_eCADataTypeError, \
|
|
@@ -1005,8 +1073,7 @@ rb_ca_fiber_scatter_moments (VALUE self, VALUE rcodes, VALUE raxis, VALUE rk,
|
|
|
1005
1073
|
band_size = outer_prod * inner_prod;
|
|
1006
1074
|
total = (ca_size_t)(K * band_size);
|
|
1007
1075
|
|
|
1008
|
-
|
|
1009
|
-
ca_attach(codes);
|
|
1076
|
+
ca_attach_n(2, h, codes); /* window: detached before each raise inside */
|
|
1010
1077
|
hm = ca_mask_ptr(h);
|
|
1011
1078
|
cm = ca_mask_ptr(codes);
|
|
1012
1079
|
countp = (int64_t *) counts->ptr;
|
|
@@ -1020,16 +1087,16 @@ rb_ca_fiber_scatter_moments (VALUE self, VALUE rcodes, VALUE raxis, VALUE rk,
|
|
|
1020
1087
|
memset(maxp, 0, (size_t) total * (size_t) h->bytes);
|
|
1021
1088
|
|
|
1022
1089
|
switch ( h->data_type ) {
|
|
1023
|
-
case CA_INT8: FIBER_SCATTER_DISPATCH_C(int8_t
|
|
1024
|
-
case CA_UINT8: FIBER_SCATTER_DISPATCH_C(uint8_t
|
|
1025
|
-
case CA_INT16: FIBER_SCATTER_DISPATCH_C(int16_t
|
|
1026
|
-
case CA_UINT16: FIBER_SCATTER_DISPATCH_C(uint16_t
|
|
1027
|
-
case CA_INT32: FIBER_SCATTER_DISPATCH_C(int32_t
|
|
1028
|
-
case CA_UINT32: FIBER_SCATTER_DISPATCH_C(uint32_t
|
|
1029
|
-
case CA_INT64: FIBER_SCATTER_DISPATCH_C(int64_t
|
|
1030
|
-
case CA_UINT64: FIBER_SCATTER_DISPATCH_C(uint64_t
|
|
1031
|
-
case CA_FLOAT32: FIBER_SCATTER_DISPATCH_C(float32_t
|
|
1032
|
-
case CA_FLOAT64: FIBER_SCATTER_DISPATCH_C(float64_t
|
|
1090
|
+
case CA_INT8: FIBER_SCATTER_DISPATCH_C(int8_t); break;
|
|
1091
|
+
case CA_UINT8: FIBER_SCATTER_DISPATCH_C(uint8_t); break;
|
|
1092
|
+
case CA_INT16: FIBER_SCATTER_DISPATCH_C(int16_t); break;
|
|
1093
|
+
case CA_UINT16: FIBER_SCATTER_DISPATCH_C(uint16_t); break;
|
|
1094
|
+
case CA_INT32: FIBER_SCATTER_DISPATCH_C(int32_t); break;
|
|
1095
|
+
case CA_UINT32: FIBER_SCATTER_DISPATCH_C(uint32_t); break;
|
|
1096
|
+
case CA_INT64: FIBER_SCATTER_DISPATCH_C(int64_t); break;
|
|
1097
|
+
case CA_UINT64: FIBER_SCATTER_DISPATCH_C(uint64_t); break;
|
|
1098
|
+
case CA_FLOAT32: FIBER_SCATTER_DISPATCH_C(float32_t); break;
|
|
1099
|
+
case CA_FLOAT64: FIBER_SCATTER_DISPATCH_C(float64_t); break;
|
|
1033
1100
|
default:
|
|
1034
1101
|
ca_detach(h); ca_detach(codes);
|
|
1035
1102
|
rb_raise(rb_eCADataTypeError,
|
|
@@ -1172,8 +1239,7 @@ rb_ca_fiber_scatter_prod (VALUE self, VALUE rcodes, VALUE raxis,
|
|
|
1172
1239
|
band_size = outer_prod * inner_prod;
|
|
1173
1240
|
total = (ca_size_t)(K * band_size);
|
|
1174
1241
|
|
|
1175
|
-
|
|
1176
|
-
ca_attach(codes);
|
|
1242
|
+
ca_attach_n(2, h, codes); /* window: detached before each raise inside */
|
|
1177
1243
|
hm = ca_mask_ptr(h);
|
|
1178
1244
|
cm = ca_mask_ptr(codes);
|
|
1179
1245
|
outp = (double *) out->ptr;
|
|
@@ -1281,6 +1347,7 @@ rb_ca_fiber_scatter_wsum_wmean (VALUE self, VALUE rcodes, VALUE rweights,
|
|
|
1281
1347
|
ca_size_t ax, inn, outer, cell;
|
|
1282
1348
|
ca_size_t axis_size, inner_prod, outer_prod, band_size, total;
|
|
1283
1349
|
double *wp, *wsp, *wsw, *wmp;
|
|
1350
|
+
volatile VALUE hwsw = 0, hcnt = 0;
|
|
1284
1351
|
boolean8_t *hm, *cm, *wm, *wmm;
|
|
1285
1352
|
int8_t i, j;
|
|
1286
1353
|
int64_t *cnt_scratch = NULL;
|
|
@@ -1341,9 +1408,7 @@ rb_ca_fiber_scatter_wsum_wmean (VALUE self, VALUE rcodes, VALUE rweights,
|
|
|
1341
1408
|
band_size = outer_prod * inner_prod;
|
|
1342
1409
|
total = (ca_size_t)(K * band_size);
|
|
1343
1410
|
|
|
1344
|
-
|
|
1345
|
-
ca_attach(codes);
|
|
1346
|
-
ca_attach(weights);
|
|
1411
|
+
ca_attach_n(3, h, codes, weights); /* window: detached before each raise inside */
|
|
1347
1412
|
hm = ca_mask_ptr(h);
|
|
1348
1413
|
cm = ca_mask_ptr(codes);
|
|
1349
1414
|
wm = ca_mask_ptr(weights);
|
|
@@ -1352,8 +1417,9 @@ rb_ca_fiber_scatter_wsum_wmean (VALUE self, VALUE rcodes, VALUE rweights,
|
|
|
1352
1417
|
wmp = (double *) wmean->ptr; /* wmean output (temp = sum-of-weights, then divide) */
|
|
1353
1418
|
|
|
1354
1419
|
/* Two auxiliary scratches: sum-of-weights (per cell) and present-pair count. */
|
|
1355
|
-
|
|
1356
|
-
|
|
1420
|
+
/* ALLOCV, so a raise below (codes of the wrong type) leaves nothing. */
|
|
1421
|
+
wsw = ALLOCV_N(double, hwsw, total);
|
|
1422
|
+
cnt_scratch = ALLOCV_N(int64_t, hcnt, total);
|
|
1357
1423
|
|
|
1358
1424
|
memset(wsp, 0, (size_t) total * sizeof(double));
|
|
1359
1425
|
memset(wsw, 0, (size_t) total * sizeof(double));
|
|
@@ -1372,7 +1438,7 @@ rb_ca_fiber_scatter_wsum_wmean (VALUE self, VALUE rcodes, VALUE rweights,
|
|
|
1372
1438
|
case CA_FLOAT32: FIBER_SCATTER_WSUM_DISPATCH_C(float32_t); break;
|
|
1373
1439
|
case CA_FLOAT64: FIBER_SCATTER_WSUM_DISPATCH_C(float64_t); break;
|
|
1374
1440
|
default:
|
|
1375
|
-
|
|
1441
|
+
ALLOCV_END(hwsw); ALLOCV_END(hcnt);
|
|
1376
1442
|
ca_detach(h); ca_detach(codes); ca_detach(weights);
|
|
1377
1443
|
rb_raise(rb_eCADataTypeError,
|
|
1378
1444
|
"__fiber_scatter_wsum_wmean__: numeric value required (got %d)",
|
|
@@ -1391,8 +1457,8 @@ rb_ca_fiber_scatter_wsum_wmean (VALUE self, VALUE rcodes, VALUE rweights,
|
|
|
1391
1457
|
}
|
|
1392
1458
|
}
|
|
1393
1459
|
|
|
1394
|
-
|
|
1395
|
-
|
|
1460
|
+
ALLOCV_END(hwsw);
|
|
1461
|
+
ALLOCV_END(hcnt);
|
|
1396
1462
|
ca_detach(h);
|
|
1397
1463
|
ca_detach(codes);
|
|
1398
1464
|
ca_detach(weights);
|
|
@@ -1402,8 +1468,8 @@ rb_ca_fiber_scatter_wsum_wmean (VALUE self, VALUE rcodes, VALUE rweights,
|
|
|
1402
1468
|
void
|
|
1403
1469
|
Init_ca_categorical_iterator (void)
|
|
1404
1470
|
{
|
|
1405
|
-
rb_define_private_method(rb_cCArray, "
|
|
1406
|
-
|
|
1471
|
+
rb_define_private_method(rb_cCArray, "addresses_by_category",
|
|
1472
|
+
rb_ca_addresses_by_category, 3);
|
|
1407
1473
|
rb_define_private_method(rb_cCArray, "__fiber_scatter_moments__",
|
|
1408
1474
|
rb_ca_fiber_scatter_moments, 7);
|
|
1409
1475
|
rb_define_private_method(rb_cCArray, "__fiber_scatter_prod__",
|