carray 3.0.1 → 3.0.2
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 +520 -0
- data/README.md +2 -2
- data/carray.gemspec +1 -1
- data/ext/ca_axis_dispatch.c +33 -4
- data/ext/ca_axis_group.c +202 -96
- data/ext/ca_categorical_iterator.c +108 -54
- data/ext/ca_kernel_iterator.c +317 -51
- data/ext/ca_kernel_iterator.h +142 -35
- data/ext/ca_obj_array.c +62 -20
- data/ext/ca_obj_block.c +4 -4
- data/ext/ca_obj_const_string.c +85 -26
- data/ext/ca_obj_face.c +24 -0
- data/ext/ca_obj_face.h +15 -0
- data/ext/ca_obj_fixlen_string.c +18 -5
- data/ext/ca_obj_meld.c +123 -25
- data/ext/ca_obj_object.c +8 -0
- data/ext/ca_obj_select.c +49 -34
- data/ext/ca_obj_stack.c +3 -8
- data/ext/ca_obj_stride.c +72 -1
- data/ext/ca_obj_string.c +8 -4
- data/ext/ca_obj_window.c +8 -2
- data/ext/ca_op_ipower.c +1 -2
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sweep_engine.c +307 -143
- data/ext/ca_sweep_engine.h +26 -5
- data/ext/carray.h +21 -2
- data/ext/carray_access.c +32 -20
- data/ext/carray_address_basis.c +590 -0
- data/ext/carray_broadcast.c +3 -3
- data/ext/carray_call_cfunc.c +667 -483
- data/ext/carray_cast.c +115 -41
- data/ext/carray_copy.c +55 -30
- data/ext/carray_core.c +83 -3
- data/ext/carray_count.c +9 -10
- data/ext/carray_factorize.c +46 -25
- data/ext/carray_internal.h +17 -0
- data/ext/carray_kernels_reduce_aggregate.c +168 -0
- data/ext/carray_kernels_reduce_cumulative.c +270 -1
- data/ext/carray_kernels_reduce_extreme.c +554 -8
- data/ext/carray_kernels_scan.c +4 -4
- data/ext/carray_kernels_search.c +94 -14
- data/ext/carray_loop.c +7 -1
- data/ext/carray_mask.c +23 -8
- data/ext/carray_median_percentile.c +55 -0
- data/ext/carray_operator.c +4 -4
- data/ext/carray_order.c +1 -1
- data/ext/carray_random.c +384 -40
- data/ext/carray_slab.c +13 -0
- data/ext/carray_sort.c +20 -22
- data/ext/mk_call_cfunc.rb +103 -116
- data/ext/mkkernel.rb +297 -29
- data/ext/ruby_carray.c +10 -1
- data/ext/version.h +4 -4
- data/lib/carray/autoload_carray.rb +5 -3
- data/lib/carray/autoload_method_extension.rb +12 -0
- data/lib/carray/axis_group.rb +77 -0
- data/lib/carray/basics.rb +4 -0
- data/lib/carray/block_iterator.rb +92 -16
- data/lib/carray/categorical.rb +150 -33
- data/lib/carray/categorical_iterator.rb +207 -80
- data/lib/carray/const_string.rb +131 -27
- data/lib/carray/construct.rb +40 -0
- data/lib/carray/data_type_extension.rb +3 -0
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/csv_parser.rb +11 -4
- data/lib/carray/frame/frame.rb +81 -10
- data/lib/carray/frame/group.rb +36 -3
- data/lib/carray/frame/io.rb +67 -15
- data/lib/carray/frame/records.rb +18 -4
- data/lib/carray/frame/verbs.rb +14 -11
- data/lib/carray/inspect.rb +42 -9
- data/lib/carray/iterator.rb +143 -0
- data/lib/carray/lazy.rb +0 -37
- data/lib/carray/mask_gap_fill.rb +3 -1
- data/lib/carray/methods/discovery_along.rb +74 -0
- data/lib/carray/methods/factorize.rb +50 -0
- data/lib/carray/methods/is_in.rb +13 -2
- data/lib/carray/methods/locate_addr.rb +75 -2
- data/lib/carray/methods/mask_duplicates.rb +35 -1
- data/lib/carray/methods/nunique.rb +22 -1
- data/lib/carray/methods/repeat.rb +110 -0
- data/lib/carray/methods/unique.rb +41 -1
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/slab_iterator.rb +58 -13
- data/lib/carray/string_operation_extension.rb +5 -1
- data/lib/carray/time.rb +18 -2
- data/lib/carray/window_iterator.rb +142 -20
- data/lib/carray.rb +2 -0
- data/yard-stubs/ca_obj_block.rb +2 -7
- data/yard-stubs/ca_obj_window.rb +10 -2
- data/yard-stubs/carray_access.rb +1 -1
- data/yard-stubs/carray_broadcast.rb +1 -1
- data/yard-stubs/carray_core.rb +0 -80
- data/yard-stubs/carray_count.rb +7 -2
- data/yard-stubs/carray_lazy.rb +205 -0
- data/yard-stubs/carray_math.rb +1486 -3
- data/yard-stubs/carray_median_percentile.rb +16 -2
- data/yard-stubs/carray_order.rb +9 -69
- data/yard-stubs/carray_slab.rb +9 -7
- data/yard-stubs/carray_sort.rb +7 -5
- metadata +9 -1
|
@@ -138,7 +138,20 @@ rb_ca_categorical_scatter (VALUE self, VALUE rvalue, VALUE rcursor,
|
|
|
138
138
|
|
|
139
139
|
--------------------------------------------------------------------------- */
|
|
140
140
|
|
|
141
|
-
#
|
|
141
|
+
/* NaN loses every contest, which is what CArray#min / #max do (mkkernel
|
|
142
|
+
declares it as `all_nan_result: :nan`): a NaN never displaces a number, the
|
|
143
|
+
first number displaces a NaN that seeded the accumulator, and a segment
|
|
144
|
+
holding nothing but NaN answers NaN. Without this the answer depends on
|
|
145
|
+
where in the segment the NaN sits, and a reduction that is order-free
|
|
146
|
+
stopped being order-free.
|
|
147
|
+
|
|
148
|
+
The predicate is passed per instantiation rather than written inline so an
|
|
149
|
+
integer body never compares a value with itself, which is a tautology the
|
|
150
|
+
compiler is right to warn about. */
|
|
151
|
+
#define CAT_NAN_NEVER(v) (0)
|
|
152
|
+
#define CAT_NAN_CHECK(v) ((v) != (v))
|
|
153
|
+
|
|
154
|
+
#define REDUCEAT_MOMENTS_BODY(T, ISNAN) \
|
|
142
155
|
do { \
|
|
143
156
|
const T *gp = (const T *) grouped->ptr; \
|
|
144
157
|
T *minv = (T *) minp, *maxv = (T *) maxp; \
|
|
@@ -147,13 +160,17 @@ rb_ca_categorical_scatter (VALUE self, VALUE rvalue, VALUE rcursor,
|
|
|
147
160
|
ca_size_t hi = (c + 1 < k) ? (ca_size_t) offs[c+1] : n; \
|
|
148
161
|
ca_size_t j, cnt = 0; \
|
|
149
162
|
double sacc = 0.0; \
|
|
150
|
-
T mn = 0, mx = 0; int seen = 0;
|
|
163
|
+
T mn = 0, mx = 0; int seen = 0, seen_num = 0; \
|
|
151
164
|
for ( j = lo; j < hi; j++ ) { \
|
|
152
165
|
if ( gm && gm[j] ) continue; /* masked value cell */ \
|
|
153
166
|
{ T v = gp[j]; \
|
|
154
167
|
sacc += (double) v; \
|
|
155
|
-
if ( !
|
|
156
|
-
|
|
168
|
+
if ( ! ISNAN(v) ) { \
|
|
169
|
+
if ( ! seen_num ) { mn = v; mx = v; seen_num = 1; } \
|
|
170
|
+
else { if ( v < mn ) mn = v; if ( v > mx ) mx = v; } \
|
|
171
|
+
} \
|
|
172
|
+
else if ( ! seen ) { mn = v; mx = v; } /* held until a number lands */\
|
|
173
|
+
seen = 1; \
|
|
157
174
|
cnt++; } \
|
|
158
175
|
} \
|
|
159
176
|
countp[c] = (int64_t) cnt; \
|
|
@@ -205,16 +222,16 @@ rb_ca_reduceat_moments (VALUE self, VALUE roffsets, VALUE rcounts,
|
|
|
205
222
|
maxm = (boolean8_t *) maxs->mask->ptr;
|
|
206
223
|
|
|
207
224
|
switch ( grouped->data_type ) {
|
|
208
|
-
case CA_INT8: REDUCEAT_MOMENTS_BODY(int8_t); break;
|
|
209
|
-
case CA_UINT8: REDUCEAT_MOMENTS_BODY(uint8_t); break;
|
|
210
|
-
case CA_INT16: REDUCEAT_MOMENTS_BODY(int16_t); break;
|
|
211
|
-
case CA_UINT16: REDUCEAT_MOMENTS_BODY(uint16_t); break;
|
|
212
|
-
case CA_INT32: REDUCEAT_MOMENTS_BODY(int32_t); break;
|
|
213
|
-
case CA_UINT32: REDUCEAT_MOMENTS_BODY(uint32_t); break;
|
|
214
|
-
case CA_INT64: REDUCEAT_MOMENTS_BODY(int64_t); break;
|
|
215
|
-
case CA_UINT64: REDUCEAT_MOMENTS_BODY(uint64_t); break;
|
|
216
|
-
case CA_FLOAT32: REDUCEAT_MOMENTS_BODY(float32_t); break;
|
|
217
|
-
case CA_FLOAT64: REDUCEAT_MOMENTS_BODY(float64_t); break;
|
|
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;
|
|
218
235
|
default:
|
|
219
236
|
rb_raise(rb_eCADataTypeError,
|
|
220
237
|
"__reduceat_moments__: numeric value required (got data_type %d)",
|
|
@@ -278,11 +295,27 @@ ca_nth_element_double (double *a, ca_size_t n, ca_size_t kth)
|
|
|
278
295
|
{ double f = (double) (m - 1) * p / 100.0; \
|
|
279
296
|
ca_size_t ki = (ca_size_t) floor(f); \
|
|
280
297
|
double vlo, vhi; \
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
298
|
+
/* Push NaN to the tail, which is where CArray's sort puts it, so the \
|
|
299
|
+
ki-th element here is the ki-th of the sorted segment. Selection \
|
|
300
|
+
runs on the numeric prefix, since a comparison-based quickselect \
|
|
301
|
+
has nothing to say about a NaN, and a position landing in the tail \
|
|
302
|
+
answers NaN. The upper neighbour is clamped into the prefix too: a \
|
|
303
|
+
position whose neighbour would be a NaN interpolates against itself \
|
|
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
|
+
} \
|
|
312
|
+
if ( ki < nnum ) { \
|
|
313
|
+
ca_nth_element_double(scratch, nnum, ki); /* scratch[ki] = ki-th */ \
|
|
314
|
+
vlo = scratch[ki]; \
|
|
315
|
+
} else vlo = (double) NAN; \
|
|
316
|
+
if ( ki + 1 < nnum ) { /* (ki+1)-th = min of upper partition */ \
|
|
284
317
|
double mn = scratch[ki+1]; ca_size_t t; \
|
|
285
|
-
for ( t = ki + 2; t <
|
|
318
|
+
for ( t = ki + 2; t < nnum; t++ ) if ( scratch[t] < mn ) mn = scratch[t]; \
|
|
286
319
|
vhi = mn; \
|
|
287
320
|
} else vhi = vlo; \
|
|
288
321
|
outp[c] = vlo + (f - (double) ki) * (vhi - vlo); } \
|
|
@@ -510,7 +543,7 @@ rb_ca_reduceat_prod (VALUE self, VALUE roffsets, VALUE rout)
|
|
|
510
543
|
/* __reduceat_argminmax__(offsets, min_idx, max_idx) — per-segment GROUP-LOCAL
|
|
511
544
|
index of the min / max (position within the segment, first occurrence on
|
|
512
545
|
ties). Empty / all-masked segments are masked. */
|
|
513
|
-
#define REDUCEAT_ARGMINMAX_BODY(T)
|
|
546
|
+
#define REDUCEAT_ARGMINMAX_BODY(T, ISNAN) \
|
|
514
547
|
do { \
|
|
515
548
|
const T *gp = (const T *) grouped->ptr; \
|
|
516
549
|
for ( c = 0; c < k; c++ ) { \
|
|
@@ -520,10 +553,13 @@ rb_ca_reduceat_prod (VALUE self, VALUE roffsets, VALUE rout)
|
|
|
520
553
|
for ( j = lo; j < hi; j++ ) { \
|
|
521
554
|
if ( gm && gm[j] ) continue; \
|
|
522
555
|
{ T v = gp[j]; ca_size_t li = j - lo; \
|
|
556
|
+
if ( ISNAN(v) ) continue; /* wins no contest, so marks no position */\
|
|
523
557
|
if ( ! seen ) { mn = mx = v; mni = mxi = li; seen = 1; } \
|
|
524
558
|
else { if ( v < mn ) { mn = v; mni = li; } \
|
|
525
559
|
if ( v > mx ) { mx = v; mxi = li; } } } \
|
|
526
560
|
} \
|
|
561
|
+
/* A segment of nothing but NaN has no position to report, the same as a \
|
|
562
|
+
segment with no present cell at all -- both are UNDEF, as in the core.*/\
|
|
527
563
|
if ( seen ) { minp[c] = (int64_t) mni; maxp[c] = (int64_t) mxi; } \
|
|
528
564
|
else { minp[c] = 0; maxp[c] = 0; minm[c] = 1; maxm[c] = 1; } \
|
|
529
565
|
} \
|
|
@@ -558,16 +594,16 @@ rb_ca_reduceat_argminmax (VALUE self, VALUE roffsets, VALUE rminidx, VALUE rmaxi
|
|
|
558
594
|
maxm = (boolean8_t *) maxidx->mask->ptr;
|
|
559
595
|
|
|
560
596
|
switch ( grouped->data_type ) {
|
|
561
|
-
case CA_INT8: REDUCEAT_ARGMINMAX_BODY(int8_t); break;
|
|
562
|
-
case CA_UINT8: REDUCEAT_ARGMINMAX_BODY(uint8_t); break;
|
|
563
|
-
case CA_INT16: REDUCEAT_ARGMINMAX_BODY(int16_t); break;
|
|
564
|
-
case CA_UINT16: REDUCEAT_ARGMINMAX_BODY(uint16_t); break;
|
|
565
|
-
case CA_INT32: REDUCEAT_ARGMINMAX_BODY(int32_t); break;
|
|
566
|
-
case CA_UINT32: REDUCEAT_ARGMINMAX_BODY(uint32_t); break;
|
|
567
|
-
case CA_INT64: REDUCEAT_ARGMINMAX_BODY(int64_t); break;
|
|
568
|
-
case CA_UINT64: REDUCEAT_ARGMINMAX_BODY(uint64_t); break;
|
|
569
|
-
case CA_FLOAT32: REDUCEAT_ARGMINMAX_BODY(float32_t); break;
|
|
570
|
-
case CA_FLOAT64: REDUCEAT_ARGMINMAX_BODY(float64_t); break;
|
|
597
|
+
case CA_INT8: REDUCEAT_ARGMINMAX_BODY(int8_t, CAT_NAN_NEVER); break;
|
|
598
|
+
case CA_UINT8: REDUCEAT_ARGMINMAX_BODY(uint8_t, CAT_NAN_NEVER); break;
|
|
599
|
+
case CA_INT16: REDUCEAT_ARGMINMAX_BODY(int16_t, CAT_NAN_NEVER); break;
|
|
600
|
+
case CA_UINT16: REDUCEAT_ARGMINMAX_BODY(uint16_t, CAT_NAN_NEVER); break;
|
|
601
|
+
case CA_INT32: REDUCEAT_ARGMINMAX_BODY(int32_t, CAT_NAN_NEVER); break;
|
|
602
|
+
case CA_UINT32: REDUCEAT_ARGMINMAX_BODY(uint32_t, CAT_NAN_NEVER); break;
|
|
603
|
+
case CA_INT64: REDUCEAT_ARGMINMAX_BODY(int64_t, CAT_NAN_NEVER); break;
|
|
604
|
+
case CA_UINT64: REDUCEAT_ARGMINMAX_BODY(uint64_t, CAT_NAN_NEVER); break;
|
|
605
|
+
case CA_FLOAT32: REDUCEAT_ARGMINMAX_BODY(float32_t, CAT_NAN_CHECK); break;
|
|
606
|
+
case CA_FLOAT64: REDUCEAT_ARGMINMAX_BODY(float64_t, CAT_NAN_CHECK); break;
|
|
571
607
|
default:
|
|
572
608
|
rb_raise(rb_eCADataTypeError,
|
|
573
609
|
"__reduceat_argminmax__: numeric value required (got data_type %d)",
|
|
@@ -631,6 +667,12 @@ static int
|
|
|
631
667
|
cmp_double (const void *a, const void *b)
|
|
632
668
|
{
|
|
633
669
|
double x = *(const double *) a, y = *(const double *) b;
|
|
670
|
+
/* NaN sorts last, which is where CArray's own sort puts it, so picking a
|
|
671
|
+
position out of the sorted segment gives the core's answer. A bare
|
|
672
|
+
< / > comparison returns 0 for every pair involving a NaN, which is not
|
|
673
|
+
a strict weak ordering and leaves qsort free to produce anything. */
|
|
674
|
+
if ( x != x ) return (y != y) ? 0 : 1;
|
|
675
|
+
if ( y != y ) return -1;
|
|
634
676
|
return (x < y) ? -1 : (x > y) ? 1 : 0;
|
|
635
677
|
}
|
|
636
678
|
|
|
@@ -648,13 +690,18 @@ cmp_double (const void *a, const void *b)
|
|
|
648
690
|
} \
|
|
649
691
|
if ( m == 0 ) { for ( t = 0; t < 5; t++ ) { outp[t][c] = 0.0; outm[t][c] = 1; } continue; } \
|
|
650
692
|
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--; \
|
|
651
695
|
for ( t = 0; t < 5; t++ ) { \
|
|
652
696
|
double f = (double) (m - 1) * P[t] / 100.0; \
|
|
653
697
|
ca_size_t ki = (ca_size_t) floor(f); \
|
|
654
698
|
double vlo = scratch[ki]; \
|
|
655
|
-
|
|
699
|
+
/* Clamp the upper neighbour into the numeric prefix: with NaN sorted \
|
|
700
|
+
last, a position whose neighbour is a NaN interpolates against \
|
|
701
|
+
itself, which is what the core answers. */ \
|
|
702
|
+
double vhi = (ki + 1 < nnum) ? scratch[ki+1] : vlo; \
|
|
656
703
|
outp[t][c] = vlo + (f - (double) ki) * (vhi - vlo); \
|
|
657
|
-
}
|
|
704
|
+
} } \
|
|
658
705
|
} \
|
|
659
706
|
} while (0)
|
|
660
707
|
|
|
@@ -822,7 +869,7 @@ rb_ca_reduceat_wsum_wmean (VALUE self, VALUE roffsets, VALUE rwg,
|
|
|
822
869
|
(empty group cell → 0 + masked, matching __reduceat_moments__).
|
|
823
870
|
--------------------------------------------------------------------------- */
|
|
824
871
|
|
|
825
|
-
#define FIBER_SCATTER_BODY(H_T, C_T)
|
|
872
|
+
#define FIBER_SCATTER_BODY(H_T, C_T, ISNAN) \
|
|
826
873
|
do { \
|
|
827
874
|
const H_T *hp = (const H_T *) h->ptr; \
|
|
828
875
|
const C_T *cp = (const C_T *) codes->ptr; \
|
|
@@ -844,11 +891,18 @@ rb_ca_reduceat_wsum_wmean (VALUE self, VALUE roffsets, VALUE rwg,
|
|
|
844
891
|
if ( c < 0 || c >= K ) continue; /* out-of-vocabulary */ \
|
|
845
892
|
out_off = c * band_size + out_outer + inn; \
|
|
846
893
|
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. */\
|
|
847
897
|
if ( countp[out_off] == 0 ) { \
|
|
848
898
|
minv[out_off] = v; maxv[out_off] = v; \
|
|
849
|
-
} else {
|
|
850
|
-
if (
|
|
851
|
-
|
|
899
|
+
} else if ( ! ISNAN(v) ) { \
|
|
900
|
+
if ( ISNAN(minv[out_off]) ) { \
|
|
901
|
+
minv[out_off] = v; maxv[out_off] = v; \
|
|
902
|
+
} else { \
|
|
903
|
+
if ( v < minv[out_off] ) minv[out_off] = v; \
|
|
904
|
+
if ( v > maxv[out_off] ) maxv[out_off] = v; \
|
|
905
|
+
} \
|
|
852
906
|
} \
|
|
853
907
|
countp[out_off]++; \
|
|
854
908
|
sump[out_off] += (double) v; \
|
|
@@ -857,16 +911,16 @@ rb_ca_reduceat_wsum_wmean (VALUE self, VALUE roffsets, VALUE rwg,
|
|
|
857
911
|
} \
|
|
858
912
|
} while (0)
|
|
859
913
|
|
|
860
|
-
#define FIBER_SCATTER_DISPATCH_C(H_T)
|
|
914
|
+
#define FIBER_SCATTER_DISPATCH_C(H_T, ISNAN) \
|
|
861
915
|
switch ( codes->data_type ) { \
|
|
862
|
-
case CA_INT8: FIBER_SCATTER_BODY(H_T, int8_t); break; \
|
|
863
|
-
case CA_UINT8: FIBER_SCATTER_BODY(H_T, uint8_t); break; \
|
|
864
|
-
case CA_INT16: FIBER_SCATTER_BODY(H_T, int16_t); break; \
|
|
865
|
-
case CA_UINT16: FIBER_SCATTER_BODY(H_T, uint16_t); break; \
|
|
866
|
-
case CA_INT32: FIBER_SCATTER_BODY(H_T, int32_t); break; \
|
|
867
|
-
case CA_UINT32: FIBER_SCATTER_BODY(H_T, uint32_t); break; \
|
|
868
|
-
case CA_INT64: FIBER_SCATTER_BODY(H_T, int64_t); break; \
|
|
869
|
-
case CA_UINT64: FIBER_SCATTER_BODY(H_T, uint64_t); break; \
|
|
916
|
+
case CA_INT8: FIBER_SCATTER_BODY(H_T, int8_t, ISNAN); break; \
|
|
917
|
+
case CA_UINT8: FIBER_SCATTER_BODY(H_T, uint8_t, ISNAN); break; \
|
|
918
|
+
case CA_INT16: FIBER_SCATTER_BODY(H_T, int16_t, ISNAN); break; \
|
|
919
|
+
case CA_UINT16: FIBER_SCATTER_BODY(H_T, uint16_t, ISNAN); break; \
|
|
920
|
+
case CA_INT32: FIBER_SCATTER_BODY(H_T, int32_t, ISNAN); break; \
|
|
921
|
+
case CA_UINT32: FIBER_SCATTER_BODY(H_T, uint32_t, ISNAN); break; \
|
|
922
|
+
case CA_INT64: FIBER_SCATTER_BODY(H_T, int64_t, ISNAN); break; \
|
|
923
|
+
case CA_UINT64: FIBER_SCATTER_BODY(H_T, uint64_t, ISNAN); break; \
|
|
870
924
|
default: \
|
|
871
925
|
ca_detach(h); ca_detach(codes); \
|
|
872
926
|
rb_raise(rb_eCADataTypeError, \
|
|
@@ -966,16 +1020,16 @@ rb_ca_fiber_scatter_moments (VALUE self, VALUE rcodes, VALUE raxis, VALUE rk,
|
|
|
966
1020
|
memset(maxp, 0, (size_t) total * (size_t) h->bytes);
|
|
967
1021
|
|
|
968
1022
|
switch ( h->data_type ) {
|
|
969
|
-
case CA_INT8: FIBER_SCATTER_DISPATCH_C(int8_t); break;
|
|
970
|
-
case CA_UINT8: FIBER_SCATTER_DISPATCH_C(uint8_t); break;
|
|
971
|
-
case CA_INT16: FIBER_SCATTER_DISPATCH_C(int16_t); break;
|
|
972
|
-
case CA_UINT16: FIBER_SCATTER_DISPATCH_C(uint16_t); break;
|
|
973
|
-
case CA_INT32: FIBER_SCATTER_DISPATCH_C(int32_t); break;
|
|
974
|
-
case CA_UINT32: FIBER_SCATTER_DISPATCH_C(uint32_t); break;
|
|
975
|
-
case CA_INT64: FIBER_SCATTER_DISPATCH_C(int64_t); break;
|
|
976
|
-
case CA_UINT64: FIBER_SCATTER_DISPATCH_C(uint64_t); break;
|
|
977
|
-
case CA_FLOAT32: FIBER_SCATTER_DISPATCH_C(float32_t); break;
|
|
978
|
-
case CA_FLOAT64: FIBER_SCATTER_DISPATCH_C(float64_t); break;
|
|
1023
|
+
case CA_INT8: FIBER_SCATTER_DISPATCH_C(int8_t, CAT_NAN_NEVER); break;
|
|
1024
|
+
case CA_UINT8: FIBER_SCATTER_DISPATCH_C(uint8_t, CAT_NAN_NEVER); break;
|
|
1025
|
+
case CA_INT16: FIBER_SCATTER_DISPATCH_C(int16_t, CAT_NAN_NEVER); break;
|
|
1026
|
+
case CA_UINT16: FIBER_SCATTER_DISPATCH_C(uint16_t, CAT_NAN_NEVER); break;
|
|
1027
|
+
case CA_INT32: FIBER_SCATTER_DISPATCH_C(int32_t, CAT_NAN_NEVER); break;
|
|
1028
|
+
case CA_UINT32: FIBER_SCATTER_DISPATCH_C(uint32_t, CAT_NAN_NEVER); break;
|
|
1029
|
+
case CA_INT64: FIBER_SCATTER_DISPATCH_C(int64_t, CAT_NAN_NEVER); break;
|
|
1030
|
+
case CA_UINT64: FIBER_SCATTER_DISPATCH_C(uint64_t, CAT_NAN_NEVER); break;
|
|
1031
|
+
case CA_FLOAT32: FIBER_SCATTER_DISPATCH_C(float32_t, CAT_NAN_CHECK); break;
|
|
1032
|
+
case CA_FLOAT64: FIBER_SCATTER_DISPATCH_C(float64_t, CAT_NAN_CHECK); break;
|
|
979
1033
|
default:
|
|
980
1034
|
ca_detach(h); ca_detach(codes);
|
|
981
1035
|
rb_raise(rb_eCADataTypeError,
|