carray 3.0.4 → 3.0.6

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.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +438 -0
  3. data/README.md +1 -1
  4. data/carray.gemspec +3 -2
  5. data/ext/ca_array_pool.c +25 -1
  6. data/ext/ca_axis_dispatch.c +19 -20
  7. data/ext/ca_axis_group.c +1 -1
  8. data/ext/ca_categorical_iterator.c +34 -27
  9. data/ext/ca_compare.c +4 -4
  10. data/ext/ca_composite_dispatch.c +9 -9
  11. data/ext/ca_kernel_iterator.c +122 -237
  12. data/ext/ca_kernel_iterator.h +522 -337
  13. data/ext/ca_obj_array.c +69 -19
  14. data/ext/ca_obj_bincmp.c +10 -1
  15. data/ext/ca_obj_binop.c +11 -1
  16. data/ext/ca_obj_bitarray.c +5 -1
  17. data/ext/ca_obj_bitfield.c +60 -43
  18. data/ext/ca_obj_byte_swap.c +4 -1
  19. data/ext/ca_obj_const_string.c +15 -3
  20. data/ext/ca_obj_face.c +44 -1
  21. data/ext/ca_obj_fake.c +3 -1
  22. data/ext/ca_obj_field.c +13 -3
  23. data/ext/ca_obj_grid.c +219 -17
  24. data/ext/ca_obj_meld.c +69 -113
  25. data/ext/ca_obj_moncmp.c +9 -1
  26. data/ext/ca_obj_monop.c +86 -12
  27. data/ext/ca_obj_object.c +118 -32
  28. data/ext/ca_obj_record.c +3 -0
  29. data/ext/ca_obj_reduce.c +19 -1
  30. data/ext/ca_obj_refer.c +80 -26
  31. data/ext/ca_obj_remap.c +69 -10
  32. data/ext/ca_obj_roll.c +27 -6
  33. data/ext/ca_obj_select.c +38 -6
  34. data/ext/ca_obj_select_axis.c +1 -0
  35. data/ext/ca_obj_shift.c +32 -7
  36. data/ext/ca_obj_stack.c +311 -111
  37. data/ext/ca_obj_stride.c +159 -64
  38. data/ext/ca_obj_string.c +27 -2
  39. data/ext/ca_obj_tile.c +28 -7
  40. data/ext/ca_obj_transpose.c +8 -4
  41. data/ext/ca_obj_triop.c +12 -1
  42. data/ext/ca_obj_window.c +80 -50
  43. data/ext/ca_op_ipower.c +12 -12
  44. data/ext/ca_sort_kernels.h +6 -3
  45. data/ext/caframe_csv_reader.c +1 -1
  46. data/ext/carray.h +35 -1
  47. data/ext/carray_access.c +43 -67
  48. data/ext/carray_address_basis.c +134 -0
  49. data/ext/carray_attribute.c +32 -0
  50. data/ext/carray_broadcast.c +3 -4
  51. data/ext/carray_build_flags.h +1 -1
  52. data/ext/carray_cast.c +251 -93
  53. data/ext/carray_cast_func.rb +56 -26
  54. data/ext/carray_conversion.c +11 -7
  55. data/ext/carray_core.c +814 -72
  56. data/ext/carray_count.c +6 -0
  57. data/ext/carray_element.c +22 -13
  58. data/ext/carray_factorize.c +20 -20
  59. data/ext/carray_generate.c +8 -2
  60. data/ext/carray_histogram.c +26 -4
  61. data/ext/carray_index_classifier.c +4 -4
  62. data/ext/carray_internal.h +159 -12
  63. data/ext/carray_kernels_bincmp.c +2174 -170
  64. data/ext/carray_kernels_binop.c +25653 -5487
  65. data/ext/carray_kernels_init.c +8 -8
  66. data/ext/carray_kernels_moncmp.c +96 -96
  67. data/ext/carray_kernels_monop.c +12253 -5235
  68. data/ext/carray_kernels_reduce_aggregate.c +6150 -2423
  69. data/ext/carray_kernels_reduce_boolean.c +1533 -15
  70. data/ext/carray_kernels_reduce_cumulative.c +2442 -882
  71. data/ext/carray_kernels_reduce_extreme.c +5658 -1661
  72. data/ext/carray_kernels_reduce_variance.c +2534 -402
  73. data/ext/carray_kernels_scan.c +368 -368
  74. data/ext/carray_kernels_search.c +4551 -604
  75. data/ext/carray_kernels_sort.c +659 -751
  76. data/ext/carray_kernels_triop.c +114 -114
  77. data/ext/carray_key_windows.c +4 -0
  78. data/ext/carray_lazy.c +47 -0
  79. data/ext/carray_loop.c +1 -1
  80. data/ext/carray_mask.c +175 -161
  81. data/ext/carray_median_percentile.c +4 -4
  82. data/ext/carray_memory_view.c +15 -9
  83. data/ext/carray_operator.c +152 -49
  84. data/ext/carray_order.c +230 -10
  85. data/ext/carray_random.c +22 -19
  86. data/ext/carray_scatter.c +24 -7
  87. data/ext/carray_slab.c +128 -29
  88. data/ext/carray_sort.c +224 -16
  89. data/ext/carray_sort_kernel.c +5 -7
  90. data/ext/carray_struct.c +35 -43
  91. data/ext/carray_test.c +74 -19
  92. data/ext/carray_time_text.c +6 -4
  93. data/ext/carray_utils.c +63 -21
  94. data/ext/extconf.rb +11 -0
  95. data/ext/mkkernel.rb +546 -199
  96. data/ext/ruby_carray.c +4 -1
  97. data/ext/version.h +4 -4
  98. data/lib/carray/attribute.rb +42 -5
  99. data/lib/carray/autoload_carray.rb +3 -3
  100. data/lib/carray/autoload_method_extension.rb +5 -3
  101. data/lib/carray/axis_group.rb +13 -7
  102. data/lib/carray/basics.rb +28 -8
  103. data/lib/carray/block_iterator.rb +17 -3
  104. data/lib/carray/categorical.rb +35 -23
  105. data/lib/carray/categorical_iterator.rb +8 -8
  106. data/lib/carray/complex.rb +2 -2
  107. data/lib/carray/conditional.rb +3 -2
  108. data/lib/carray/const_string.rb +10 -0
  109. data/lib/carray/data_type_extension.rb +8 -1
  110. data/lib/carray/fixlen_string.rb +41 -2
  111. data/lib/carray/frame/column_verbs.rb +48 -16
  112. data/lib/carray/frame/concat.rb +17 -3
  113. data/lib/carray/frame/convert.rb +19 -0
  114. data/lib/carray/frame/csv_parser.rb +32 -32
  115. data/lib/carray/frame/describe.rb +4 -2
  116. data/lib/carray/frame/frame.rb +405 -85
  117. data/lib/carray/frame/group.rb +777 -64
  118. data/lib/carray/frame/io.rb +212 -72
  119. data/lib/carray/frame/join.rb +146 -37
  120. data/lib/carray/frame/records.rb +3 -3
  121. data/lib/carray/frame/reshape.rb +89 -11
  122. data/lib/carray/frame/sort.rb +57 -9
  123. data/lib/carray/frame/verbs.rb +384 -49
  124. data/lib/carray/frame/windows.rb +44 -6
  125. data/lib/carray/fuse_source.rb +31 -2
  126. data/lib/carray/inspect.rb +7 -2
  127. data/lib/carray/iterator.rb +32 -0
  128. data/lib/carray/lazy.rb +52 -8
  129. data/lib/carray/mask_gap_fill.rb +37 -17
  130. data/lib/carray/meld_reduce.rb +1 -1
  131. data/lib/carray/methods/choose.rb +3 -2
  132. data/lib/carray/methods/is_in.rb +8 -1
  133. data/lib/carray/methods/meshgrid.rb +3 -1
  134. data/lib/carray/runtime.rb +47 -8
  135. data/lib/carray/segment_iterator.rb +35 -16
  136. data/lib/carray/serialize.rb +53 -19
  137. data/lib/carray/stack.rb +33 -18
  138. data/lib/carray/string.rb +8 -0
  139. data/lib/carray/string_operation_extension.rb +13 -5
  140. data/lib/carray/struct_builder.rb +5 -3
  141. data/lib/carray/time.rb +112 -68
  142. data/lib/carray/window_iterator.rb +16 -4
  143. data/yard-stubs/ca_obj_array.rb +26 -1
  144. data/yard-stubs/ca_obj_transpose.rb +5 -4
  145. data/yard-stubs/carray_attribute.rb +3 -1
  146. data/yard-stubs/carray_cast.rb +10 -5
  147. data/yard-stubs/carray_conversion.rb +13 -3
  148. data/yard-stubs/carray_element.rb +7 -6
  149. data/yard-stubs/carray_mask.rb +28 -4
  150. data/yard-stubs/carray_math.rb +45 -20
  151. data/yard-stubs/carray_memory_view.rb +7 -0
  152. data/yard-stubs/carray_order.rb +100 -4
  153. data/yard-stubs/carray_scatter.rb +7 -5
  154. data/yard-stubs/carray_test.rb +7 -4
  155. metadata +18 -4
@@ -457,20 +457,23 @@ rb_ca_reduceat_percentile (VALUE self, VALUE roffsets, VALUE rp, VALUE rout)
457
457
 
458
458
  /* ---------------------------------------------------------------------------
459
459
 
460
- __reduceat_variance__ — centred two-pass SAMPLE variance (ddof=1) reduceat.
461
- The means (from the cached moments: sum/count) drive a second walk that
462
- accumulates the per-segment centred sum of squares; variance = SS / (n-1).
463
- Centred (not the one-pass sum-of-squares) so the ε-close contract holds — a
464
- one-pass formula cancels catastrophically. Matches CArray#variance per group:
465
- count 0 or 1 -> masked (the sample variance is undefined), count >= 2 ->
466
- SS / (count-1).
467
-
468
- Surface (private): grouped.__reduceat_variance__(offsets, means, counts, out)
460
+ __reduceat_variance__ — centred two-pass variance reduceat, sample (ddof=1)
461
+ or population (ddof=0). The means (from the cached moments: sum/count)
462
+ drive a second walk that accumulates the per-segment centred sum of
463
+ squares; variance = SS / (n - ddof). Centred (not the one-pass
464
+ sum-of-squares) so the ε-close contract holds — a one-pass formula cancels
465
+ catastrophically. Matches CArray#variance / #variancep per group: count
466
+ <= ddof (or 0) -> masked, otherwise SS / (count - ddof), divided once as
467
+ the core does.
468
+
469
+ Surface (private):
470
+ grouped.__reduceat_variance__(offsets, means, counts, out, ddof)
469
471
  self = grouped (numeric value data type, may carry a mask)
470
472
  offsets = int64[k] segment STARTS
471
473
  means = float64[k] per-segment mean (ignored where count < 2)
472
474
  counts = int64[k] per-segment present count
473
- out = float64[k] output: variance; count 0 or 1 masked
475
+ out = float64[k] output: variance; count <= ddof masked
476
+ ddof = 1 (sample) or 0 (population)
474
477
 
475
478
  --------------------------------------------------------------------------- */
476
479
 
@@ -479,7 +482,7 @@ rb_ca_reduceat_percentile (VALUE self, VALUE roffsets, VALUE rp, VALUE rout)
479
482
  const T *gp = (const T *) grouped->ptr; \
480
483
  for ( c = 0; c < k; c++ ) { \
481
484
  int64_t cnt = countp[c]; \
482
- if ( cnt < 2 ) { outp[c] = 0.0; outm[c] = 1; continue; } /* undefined */ \
485
+ if ( cnt <= ddof || cnt < 1 ) { outp[c] = 0.0; outm[c] = 1; continue; } \
483
486
  { double mean = meanp[c], ss = 0.0; \
484
487
  ca_size_t lo = (ca_size_t) offs[c]; \
485
488
  ca_size_t hi = (c + 1 < k) ? (ca_size_t) offs[c+1] : n, j; \
@@ -494,14 +497,15 @@ rb_ca_reduceat_percentile (VALUE self, VALUE roffsets, VALUE rp, VALUE rout)
494
497
  double d = (double) gp[j] - mean; ss += d * d; \
495
498
  } \
496
499
  } \
497
- outp[c] = ss / (double) (cnt - 1); } \
500
+ outp[c] = ss / (double) (cnt - ddof); } \
498
501
  } \
499
502
  } while (0)
500
503
 
501
504
  static VALUE
502
505
  rb_ca_reduceat_variance (VALUE self, VALUE roffsets, VALUE rmeans,
503
- VALUE rcounts, VALUE rout)
506
+ VALUE rcounts, VALUE rout, VALUE rddof)
504
507
  {
508
+ int64_t ddof = NUM2LL(rddof);
505
509
  CArray *grouped, *offsets, *means, *counts, *out;
506
510
  int64_t k, *offs, *countp;
507
511
  ca_size_t n, c;
@@ -518,8 +522,9 @@ rb_ca_reduceat_variance (VALUE self, VALUE roffsets, VALUE rmeans,
518
522
  n = grouped->elements;
519
523
  if ( offsets->data_type != CA_INT64 || counts->data_type != CA_INT64 ||
520
524
  means->data_type != CA_FLOAT64 || out->data_type != CA_FLOAT64 ||
521
- means->elements != k || counts->elements != k || out->elements != k ) {
522
- rb_raise(rb_eArgError, "__reduceat_variance__: offsets/counts int64, means/out float64[k]");
525
+ means->elements != k || counts->elements != k || out->elements != k ||
526
+ ( ddof != 0 && ddof != 1 ) ) {
527
+ rb_raise(rb_eArgError, "__reduceat_variance__: offsets/counts int64, means/out float64[k], ddof 0 or 1");
523
528
  }
524
529
 
525
530
  offs = (int64_t *) offsets->ptr;
@@ -845,9 +850,8 @@ rb_ca_reduceat_quantile (VALUE self, VALUE roffsets, VALUE rp0, VALUE rp25,
845
850
  group order (float64, weight mask propagated). A cell contributes iff its
846
851
  value AND its weight are present. wsum_out = Sum(v*w) (0.0 for a segment with
847
852
  no present pair, the additive identity). wmean_out = Sum(v*w)/Sum(w), masked
848
- when the segment has no present pair (matching CArray#wmean UNDEF); a present
849
- segment whose weights sum to zero yields NaN/Inf from the division (core's
850
- 0/0 contract). */
853
+ when the segment has no present pair or its weights sum to zero, as
854
+ CArray#wmean leaves both undefined. */
851
855
  #define REDUCEAT_WSUM_BODY(T) \
852
856
  do { \
853
857
  const T *gp = (const T *) grouped->ptr; \
@@ -861,7 +865,7 @@ rb_ca_reduceat_quantile (VALUE self, VALUE roffsets, VALUE rp0, VALUE rp25,
861
865
  { double wv = wp[j]; svw += (double) gp[j] * wv; sw += wv; cnt++; } \
862
866
  } \
863
867
  wsp[c] = svw; \
864
- if ( cnt == 0 ) { wmp[c] = 0.0; wmm[c] = 1; } /* no present pair */ \
868
+ if ( cnt == 0 || sw == 0.0 ) { wmp[c] = 0.0; wmm[c] = 1; } /* undefined */ \
865
869
  else wmp[c] = svw / sw; \
866
870
  } \
867
871
  } while (0)
@@ -1104,8 +1108,13 @@ rb_ca_fiber_scatter_moments (VALUE self, VALUE rcodes, VALUE raxis, VALUE rk,
1104
1108
  h->data_type);
1105
1109
  }
1106
1110
 
1111
+ ca_detach(h);
1112
+ ca_detach(codes);
1113
+
1107
1114
  /* Mask empty (count == 0) cells in mins/maxs: value slot is 0 but meaningless.
1108
- Matches __reduceat_moments__ contract for empty segments. */
1115
+ Matches __reduceat_moments__ contract for empty segments. After the
1116
+ detach: creating a mask allocates, and a raise must not leave h and
1117
+ codes attached. */
1109
1118
  ca_create_mask(mins);
1110
1119
  ca_create_mask(maxs);
1111
1120
  minm = (boolean8_t *) mins->mask->ptr;
@@ -1113,9 +1122,6 @@ rb_ca_fiber_scatter_moments (VALUE self, VALUE rcodes, VALUE raxis, VALUE rk,
1113
1122
  for ( cell = 0; cell < total; cell++ ) {
1114
1123
  if ( countp[cell] == 0 ) { minm[cell] = 1; maxm[cell] = 1; }
1115
1124
  }
1116
-
1117
- ca_detach(h);
1118
- ca_detach(codes);
1119
1125
  return Qnil;
1120
1126
  }
1121
1127
 
@@ -1445,15 +1451,16 @@ rb_ca_fiber_scatter_wsum_wmean (VALUE self, VALUE rcodes, VALUE rweights,
1445
1451
  h->data_type);
1446
1452
  }
1447
1453
 
1448
- /* Compute wmean = wsum / sum-of-weights; mask cells with no present pair. */
1454
+ /* Compute wmean = wsum / sum-of-weights; mask cells with no present pair
1455
+ and cells whose weights sum to zero, as CArray#wmean does. */
1449
1456
  ca_create_mask(wmean);
1450
1457
  wmm = (boolean8_t *) wmean->mask->ptr;
1451
1458
  for ( cell = 0; cell < total; cell++ ) {
1452
- if ( cntp[cell] == 0 ) {
1459
+ if ( cntp[cell] == 0 || wsw[cell] == 0.0 ) {
1453
1460
  wmp[cell] = 0.0;
1454
1461
  wmm[cell] = 1;
1455
1462
  } else {
1456
- wmp[cell] = wsp[cell] / wsw[cell]; /* 0/0 -> NaN naturally (core contract) */
1463
+ wmp[cell] = wsp[cell] / wsw[cell];
1457
1464
  }
1458
1465
  }
1459
1466
 
@@ -1481,7 +1488,7 @@ Init_ca_categorical_iterator (void)
1481
1488
  rb_define_private_method(rb_cCArray, "__reduceat_percentile__",
1482
1489
  rb_ca_reduceat_percentile, 3);
1483
1490
  rb_define_private_method(rb_cCArray, "__reduceat_variance__",
1484
- rb_ca_reduceat_variance, 4);
1491
+ rb_ca_reduceat_variance, 5);
1485
1492
  rb_define_private_method(rb_cCArray, "__reduceat_prod__",
1486
1493
  rb_ca_reduceat_prod, 2);
1487
1494
  rb_define_private_method(rb_cCArray, "__reduceat_argminmax__",
data/ext/ca_compare.c CHANGED
@@ -21,8 +21,8 @@
21
21
  static int \
22
22
  elem_cmp_## type (const void *va, const void *vb) \
23
23
  { \
24
- const type *a = (const type *) va; \
25
- const type *b = (const type *) vb; \
24
+ const CA_U(type) *a = (const CA_U(type) *) va; \
25
+ const CA_U(type) *b = (const CA_U(type) *) vb; \
26
26
  if ( *a > *b ) return 1; \
27
27
  if ( *a < *b ) return -1; \
28
28
  return 0; \
@@ -33,8 +33,8 @@ elem_cmp_## type (const void *va, const void *vb) \
33
33
  static int \
34
34
  elem_cmp_## type (const void *va, const void *vb) \
35
35
  { \
36
- const type a = *(const type *) va; \
37
- const type b = *(const type *) vb; \
36
+ const type a = *(const CA_U(type) *) va; \
37
+ const type b = *(const CA_U(type) *) vb; \
38
38
  return CA_FLOAT_ORDER_CMP(a, b); \
39
39
  }
40
40
 
@@ -32,29 +32,29 @@ ca_fill_typed (char *dst, const char *val, ca_size_t bytes, ca_size_t n)
32
32
  break;
33
33
  }
34
34
  case 2: {
35
- uint16_t v = *(const uint16_t *)val;
36
- uint16_t *p = (uint16_t *)dst;
35
+ uint16_t v = *(const ca_u_uint16_t *)val;
36
+ ca_u_uint16_t *p = (ca_u_uint16_t *)dst;
37
37
  for ( i = 0; i < n; i++ ) p[i] = v;
38
38
  break;
39
39
  }
40
40
  case 4: {
41
- uint32_t v = *(const uint32_t *)val;
42
- uint32_t *p = (uint32_t *)dst;
41
+ uint32_t v = *(const ca_u_uint32_t *)val;
42
+ ca_u_uint32_t *p = (ca_u_uint32_t *)dst;
43
43
  for ( i = 0; i < n; i++ ) p[i] = v;
44
44
  break;
45
45
  }
46
46
  case 8: {
47
- uint64_t v = *(const uint64_t *)val;
48
- uint64_t *p = (uint64_t *)dst;
47
+ uint64_t v = *(const ca_u_uint64_t *)val;
48
+ ca_u_uint64_t *p = (ca_u_uint64_t *)dst;
49
49
  for ( i = 0; i < n; i++ ) p[i] = v;
50
50
  break;
51
51
  }
52
52
  case 16: {
53
53
  /* complex128 etc. Two uint64_t stores per element. Compiler
54
54
  pairs them into a NEON 128-bit or SSE2 store. */
55
- uint64_t v0 = ((const uint64_t *)val)[0];
56
- uint64_t v1 = ((const uint64_t *)val)[1];
57
- uint64_t *p = (uint64_t *)dst;
55
+ uint64_t v0 = ((const ca_u_uint64_t *)val)[0];
56
+ uint64_t v1 = ((const ca_u_uint64_t *)val)[1];
57
+ ca_u_uint64_t *p = (ca_u_uint64_t *)dst;
58
58
  for ( i = 0; i < n; i++ ) {
59
59
  p[2*i] = v0;
60
60
  p[2*i + 1] = v1;