carray 3.0.0 → 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/.yardopts +2 -1
- data/CHANGELOG.md +845 -3
- data/{NEWS.md → CHANGELOG.v1.md} +1 -1
- data/README.md +33 -33
- data/carray.gemspec +12 -8
- data/ext/ca_axis_dispatch.c +33 -4
- data/ext/ca_axis_group.c +256 -114
- data/ext/ca_binop_dispatch.c +5 -6
- data/ext/ca_binop_dispatch.h +0 -7
- data/ext/ca_categorical_iterator.c +121 -67
- data/ext/ca_for_each_element.h +6 -8
- data/ext/ca_group_iter.c +1 -1
- data/ext/ca_kernel_iterator.c +386 -74
- data/ext/ca_kernel_iterator.h +145 -45
- data/ext/ca_obj_array.c +62 -20
- data/ext/ca_obj_bincmp.c +57 -27
- data/ext/ca_obj_binop.c +86 -30
- data/ext/ca_obj_block.c +4 -4
- data/ext/ca_obj_const_string.c +88 -27
- data/ext/ca_obj_face.c +104 -0
- data/ext/ca_obj_face.h +48 -1
- data/ext/ca_obj_fake.c +11 -0
- data/ext/ca_obj_fixlen_string.c +21 -6
- data/ext/ca_obj_grid.c +11 -3
- data/ext/ca_obj_meld.c +125 -22
- data/ext/ca_obj_moncmp.c +33 -14
- data/ext/ca_obj_monop.c +19 -7
- data/ext/ca_obj_object.c +107 -4
- data/ext/ca_obj_record.c +3 -1
- data/ext/ca_obj_refer.c +30 -6
- data/ext/ca_obj_roll.c +13 -5
- data/ext/ca_obj_select.c +49 -34
- data/ext/ca_obj_select_axis.c +16 -6
- data/ext/ca_obj_shift.c +3 -3
- data/ext/ca_obj_stack.c +3 -8
- data/ext/ca_obj_stride.c +178 -24
- data/ext/ca_obj_string.c +11 -5
- data/ext/ca_obj_tile.c +13 -5
- data/ext/ca_obj_time.c +3 -1
- data/ext/ca_obj_timedelta.c +3 -1
- data/ext/ca_obj_transpose.c +1 -1
- data/ext/ca_obj_triop.c +62 -23
- data/ext/ca_obj_window.c +94 -19
- data/ext/ca_op_cmplx64.h +123 -0
- data/ext/ca_op_ipower.c +1 -5
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sort_kernels.h +5 -5
- data/ext/ca_sweep_engine.c +362 -155
- data/ext/ca_sweep_engine.h +39 -9
- data/ext/ca_transform_common.c +7 -0
- data/ext/carray.h +148 -132
- data/ext/carray_access.c +83 -49
- data/ext/carray_address_basis.c +590 -0
- data/ext/carray_bincount.c +8 -8
- data/ext/carray_broadcast.c +102 -9
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +2010 -335
- data/ext/carray_call_cfunc.h +153 -0
- data/ext/carray_cast.c +184 -72
- data/ext/carray_conversion.c +22 -22
- data/ext/carray_copy.c +67 -32
- data/ext/carray_core.c +140 -13
- data/ext/carray_count.c +10 -11
- data/ext/carray_element.c +7 -7
- data/ext/carray_factorize.c +72 -51
- data/ext/carray_hold.c +1 -1
- data/ext/carray_index_classifier.c +7 -21
- data/ext/carray_internal.h +36 -3
- data/ext/carray_kernels_bincmp.c +1 -0
- data/ext/carray_kernels_binop.c +320 -298
- data/ext/carray_kernels_init.c +1095 -0
- data/ext/carray_kernels_map.c +1 -0
- data/ext/carray_kernels_moncmp.c +1 -0
- data/ext/carray_kernels_monop.c +412 -411
- data/ext/carray_kernels_reduce_aggregate.c +256 -87
- data/ext/carray_kernels_reduce_boolean.c +1 -0
- data/ext/carray_kernels_reduce_cumulative.c +324 -54
- data/ext/carray_kernels_reduce_extreme.c +605 -58
- data/ext/carray_kernels_reduce_variance.c +1 -0
- data/ext/carray_kernels_scan.c +5 -4
- data/ext/carray_kernels_search.c +187 -106
- data/ext/carray_kernels_sort.c +1 -0
- data/ext/carray_kernels_triop.c +1 -0
- data/ext/carray_lazy.c +175 -5
- data/ext/carray_loop.c +7 -1
- data/ext/carray_mask.c +29 -13
- data/ext/carray_median_percentile.c +56 -1
- data/ext/carray_memory_view.c +46 -21
- data/ext/carray_operator.c +50 -53
- data/ext/carray_order.c +1 -1
- data/ext/carray_partition.c +4 -4
- data/ext/carray_random.c +391 -47
- data/ext/carray_scatter.c +1 -1
- data/ext/carray_slab.c +13 -0
- data/ext/carray_sort.c +22 -24
- data/ext/carray_sort_kernel.c +10 -10
- data/ext/carray_test.c +1 -1
- data/ext/extconf.rb +18 -0
- data/ext/mk_call_cfunc.rb +323 -145
- data/ext/mkkernel.rb +651 -129
- data/ext/ruby_carray.c +28 -17
- data/ext/version.h +4 -4
- data/lib/carray/autoload_carray.rb +24 -3
- data/lib/carray/autoload_method_extension.rb +14 -1
- data/lib/carray/axis_group.rb +84 -7
- data/lib/carray/basics.rb +63 -59
- data/lib/carray/bincount_nd.rb +12 -12
- data/lib/carray/block_iterator.rb +111 -25
- data/lib/carray/categorical.rb +154 -37
- data/lib/carray/categorical_iterator.rb +300 -151
- data/lib/carray/conditional.rb +14 -14
- data/lib/carray/const_string.rb +131 -27
- data/lib/carray/construct.rb +61 -0
- data/lib/carray/core_extensions.rb +62 -5
- data/lib/carray/data_type_extension.rb +21 -1
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/concat.rb +3 -3
- data/lib/carray/frame/convert.rb +1 -1
- data/lib/carray/frame/csv_parser.rb +11 -4
- data/lib/carray/frame/frame.rb +85 -21
- data/lib/carray/frame/group.rb +36 -3
- data/lib/carray/frame/io.rb +224 -15
- data/lib/carray/frame/records.rb +18 -4
- data/lib/carray/frame/sort.rb +1 -1
- data/lib/carray/frame/verbs.rb +32 -12
- data/lib/carray/fuse_source.rb +123 -0
- data/lib/carray/fusion.rb +218 -0
- data/lib/carray/histogram.rb +16 -16
- data/lib/carray/inspect.rb +43 -16
- data/lib/carray/iterator.rb +147 -3
- data/lib/carray/lazy.rb +88 -73
- data/lib/carray/mask_gap_fill.rb +3 -1
- data/lib/carray/meld_reduce.rb +2 -2
- data/lib/carray/methods/align_addr.rb +1 -1
- data/lib/carray/methods/composition.rb +1 -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 +25 -14
- data/lib/carray/methods/locate_addr.rb +81 -3
- data/lib/carray/methods/mask_duplicates.rb +36 -2
- data/lib/carray/methods/meshgrid.rb +4 -5
- data/lib/carray/methods/mode.rb +2 -2
- data/lib/carray/methods/nunique.rb +23 -2
- data/lib/carray/methods/repeat.rb +110 -0
- data/lib/carray/methods/snap.rb +7 -2
- data/lib/carray/methods/unique.rb +44 -4
- data/lib/carray/methods/value_counts.rb +2 -2
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/runtime.rb +0 -19
- data/lib/carray/slab_iterator.rb +77 -19
- data/lib/carray/string_operation_extension.rb +10 -6
- data/lib/carray/time.rb +906 -491
- data/lib/carray/window_iterator.rb +421 -27
- data/lib/carray.rb +7 -5
- data/yard-stubs/ca_obj_array.rb +385 -0
- data/yard-stubs/ca_obj_bitarray.rb +38 -0
- data/yard-stubs/ca_obj_bitfield.rb +43 -0
- data/yard-stubs/ca_obj_block.rb +68 -0
- data/yard-stubs/ca_obj_byte_swap.rb +56 -0
- data/yard-stubs/ca_obj_fake.rb +31 -0
- data/yard-stubs/ca_obj_farray.rb +32 -0
- data/yard-stubs/ca_obj_field.rb +45 -0
- data/yard-stubs/ca_obj_grid.rb +35 -0
- data/yard-stubs/ca_obj_refer.rb +72 -0
- data/yard-stubs/ca_obj_roll.rb +45 -0
- data/yard-stubs/ca_obj_shift.rb +43 -0
- data/yard-stubs/ca_obj_stride.rb +181 -0
- data/yard-stubs/ca_obj_tile.rb +29 -0
- data/yard-stubs/ca_obj_transpose.rb +40 -0
- data/yard-stubs/ca_obj_window.rb +57 -0
- data/yard-stubs/carray_access.rb +131 -0
- data/yard-stubs/carray_attribute.rb +246 -0
- data/yard-stubs/carray_broadcast.rb +37 -0
- data/yard-stubs/carray_cast.rb +489 -0
- data/yard-stubs/carray_class.rb +65 -0
- data/yard-stubs/carray_conversion.rb +76 -0
- data/yard-stubs/carray_copy.rb +79 -0
- data/yard-stubs/carray_core.rb +34 -0
- data/yard-stubs/carray_count.rb +84 -0
- data/yard-stubs/carray_element.rb +108 -0
- data/yard-stubs/carray_generate.rb +66 -0
- data/yard-stubs/carray_lazy.rb +228 -0
- data/yard-stubs/carray_loop.rb +140 -0
- data/yard-stubs/carray_mask.rb +259 -0
- data/yard-stubs/carray_math.rb +1615 -0
- data/yard-stubs/carray_mathfunc.rb +45 -0
- data/yard-stubs/carray_median_percentile.rb +103 -0
- data/yard-stubs/carray_memory_view.rb +163 -0
- data/yard-stubs/carray_order.rb +252 -0
- data/yard-stubs/carray_random.rb +89 -0
- data/yard-stubs/carray_scatter.rb +106 -0
- data/yard-stubs/carray_slab.rb +59 -0
- data/yard-stubs/carray_sort.rb +165 -0
- data/yard-stubs/carray_test.rb +85 -0
- data/yard-stubs/carray_undef.rb +64 -0
- data/yard-stubs/carray_utils.rb +97 -0
- data/yard-stubs/ruby_carray.rb +193 -0
- metadata +67 -10
- data/ext/ca_obj_unbound_repeat.c +0 -496
data/ext/carray_factorize.c
CHANGED
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
codes : narrow unsigned CArray (uint8 / uint16 / uint32), the code
|
|
60
60
|
storage; masked source cells store the type-max sentinel
|
|
61
61
|
(from_codes derives the mask from it, matching categorize).
|
|
62
|
-
levels : integer CArray (source
|
|
62
|
+
levels : integer CArray (source data type) of the k distinct values in
|
|
63
63
|
first-appearance order.
|
|
64
64
|
self.__mask_duplicates__(axis) -> boolean CArray of self.shape, true at
|
|
65
65
|
each cell that duplicates an earlier-seen one along axis (per-fiber
|
|
@@ -105,13 +105,27 @@
|
|
|
105
105
|
/* Descend `self` when it is an ORDERABLE Face; *pface keeps the pre-strip Face
|
|
106
106
|
for the re-lift (Qnil when there is nothing to put back). */
|
|
107
107
|
static VALUE
|
|
108
|
-
fz_face_descend (VALUE self, volatile VALUE *pface)
|
|
108
|
+
fz_face_descend (VALUE self, volatile VALUE *pface, const char *name)
|
|
109
109
|
{
|
|
110
110
|
CArray *ca;
|
|
111
111
|
GetCArray(self, ca);
|
|
112
|
-
if ( ca_is_face(ca)
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
if ( ca_is_face(ca) ) {
|
|
113
|
+
if ( ca_test_flag(ca, CA_FLAG_FACE_ORDERABLE_STORAGE) ) {
|
|
114
|
+
*pface = self;
|
|
115
|
+
return rb_ca_strip_face_value(self);
|
|
116
|
+
}
|
|
117
|
+
/* A Face that cannot be descended must not flow on undescended: whatever
|
|
118
|
+
reads it next reads its storage anyway, which is the encoding rather
|
|
119
|
+
than the values. A Face in this position normally never arrives --
|
|
120
|
+
CAConstString and CACategorical define their own members in Ruby -- but
|
|
121
|
+
the overrides only fire when the Face is the receiver, and this same
|
|
122
|
+
helper descends the *reference* for locate_addr, where it is the
|
|
123
|
+
argument. */
|
|
124
|
+
rb_raise(rb_eArgError,
|
|
125
|
+
"%s: %s is not orderable by storage (a cell encodes the value "
|
|
126
|
+
"rather than being it); convert it first -- #to_string for a "
|
|
127
|
+
"string Face -- or pass .parent to work in storage space",
|
|
128
|
+
name, rb_obj_classname(self));
|
|
115
129
|
}
|
|
116
130
|
*pface = Qnil;
|
|
117
131
|
return self;
|
|
@@ -140,15 +154,7 @@ fz_face_reconcile (VALUE reference, VALUE operand, const char *name)
|
|
|
140
154
|
rb_intern("to_comparable"),
|
|
141
155
|
1, operand));
|
|
142
156
|
}
|
|
143
|
-
|
|
144
|
-
CArray *op;
|
|
145
|
-
GetCArray(operand, op);
|
|
146
|
-
if ( ca_is_face(op) ) {
|
|
147
|
-
return rb_ca_strip_face_value(operand);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
(void) name;
|
|
151
|
-
return operand;
|
|
157
|
+
return ca_face_operand_descend(operand, name);
|
|
152
158
|
}
|
|
153
159
|
|
|
154
160
|
/* Put the Face back on a value-carrying output. */
|
|
@@ -487,7 +493,7 @@ fz_levels_free (fz_levels *l)
|
|
|
487
493
|
codes = narrow unsigned CArray; masked source cells store the type-max
|
|
488
494
|
sentinel (0xFF / 0xFFFF / 0xFFFFFFFF), so from_codes reconstructs
|
|
489
495
|
the mask exactly as the mask_duplicates path does.
|
|
490
|
-
levels = CArray (source
|
|
496
|
+
levels = CArray (source data type) of the k distinct values, in first-appearance
|
|
491
497
|
(row-major flatten) order.
|
|
492
498
|
*/
|
|
493
499
|
static VALUE
|
|
@@ -495,7 +501,7 @@ rb_ca_factorize_appearance (VALUE self)
|
|
|
495
501
|
{
|
|
496
502
|
CArray *ca;
|
|
497
503
|
volatile VALUE face;
|
|
498
|
-
self = fz_face_descend(self, &face);
|
|
504
|
+
self = fz_face_descend(self, &face, "categorize");
|
|
499
505
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
500
506
|
|
|
501
507
|
int8_t dt = ca->data_type;
|
|
@@ -508,7 +514,7 @@ rb_ca_factorize_appearance (VALUE self)
|
|
|
508
514
|
break;
|
|
509
515
|
default:
|
|
510
516
|
rb_raise(rb_eCADataTypeError,
|
|
511
|
-
"__factorize_appearance__: integer, float, object, or fixlen
|
|
517
|
+
"__factorize_appearance__: integer, float, object, or fixlen data type required (got %d)", dt);
|
|
512
518
|
}
|
|
513
519
|
if ( ca->ndim < 1 ) {
|
|
514
520
|
rb_raise(rb_eRuntimeError, "__factorize_appearance__: need ndim >= 1");
|
|
@@ -535,8 +541,8 @@ rb_ca_factorize_appearance (VALUE self)
|
|
|
535
541
|
boolean8_t *m;
|
|
536
542
|
ca_size_t n;
|
|
537
543
|
|
|
538
|
-
/* Fiber inner loop, monomorphised per
|
|
539
|
-
element to a 64-bit key; equality within one
|
|
544
|
+
/* Fiber inner loop, monomorphised per data type. WIDEN sign- or zero-extends the
|
|
545
|
+
element to a 64-bit key; equality within one data type is preserved. */
|
|
540
546
|
#define FZ_LOOP(T, WIDEN) \
|
|
541
547
|
do { \
|
|
542
548
|
const T *ip = (const T *) p_in; \
|
|
@@ -664,7 +670,7 @@ rb_ca_factorize_appearance (VALUE self)
|
|
|
664
670
|
}
|
|
665
671
|
}
|
|
666
672
|
|
|
667
|
-
/* Levels: the interned raw values, in source
|
|
673
|
+
/* Levels: the interned raw values, in source data type. CA_FIXLEN carries its
|
|
668
674
|
element width; numeric / object use bytes = 0. */
|
|
669
675
|
ca_size_t ldim[1];
|
|
670
676
|
ldim[0] = k;
|
|
@@ -715,7 +721,7 @@ rb_ca_mask_duplicates (VALUE self, VALUE vaxis)
|
|
|
715
721
|
break;
|
|
716
722
|
default:
|
|
717
723
|
rb_raise(rb_eCADataTypeError,
|
|
718
|
-
"__mask_duplicates__: numeric, object, or fixlen
|
|
724
|
+
"__mask_duplicates__: numeric, object, or fixlen data type required (got %d)", dt);
|
|
719
725
|
}
|
|
720
726
|
if ( ca->ndim < 1 ) {
|
|
721
727
|
rb_raise(rb_eRuntimeError, "__mask_duplicates__: need ndim >= 1");
|
|
@@ -740,8 +746,8 @@ rb_ca_mask_duplicates (VALUE self, VALUE vaxis)
|
|
|
740
746
|
boolean8_t *m;
|
|
741
747
|
ca_size_t n;
|
|
742
748
|
|
|
743
|
-
/* Fiber inner loop, monomorphised per
|
|
744
|
-
element to a 64-bit key; equality within one
|
|
749
|
+
/* Fiber inner loop, monomorphised per data type. WIDEN sign- or zero-extends the
|
|
750
|
+
element to a 64-bit key; equality within one data type is preserved. The hash
|
|
745
751
|
interns first appearances, so is_new == 0 flags a duplicate. */
|
|
746
752
|
#define MD_LOOP(T, WIDEN) \
|
|
747
753
|
do { \
|
|
@@ -839,7 +845,7 @@ rb_ca_mask_duplicates (VALUE self, VALUE vaxis)
|
|
|
839
845
|
|
|
840
846
|
INTERNAL (CArray#unique). Collect the distinct values of self in
|
|
841
847
|
first-appearance (row-major flatten) order, one linear pass, no sort. Returns
|
|
842
|
-
a 1-D CArray of source
|
|
848
|
+
a 1-D CArray of source data type. Masked cells do not participate.
|
|
843
849
|
|
|
844
850
|
Numeric (integer / float): distinctness follows `==` except NaN collapses to a
|
|
845
851
|
single distinct value (all NaN patterns map to one canonical hash key) and
|
|
@@ -863,7 +869,7 @@ rb_ca_unique_flat (VALUE self)
|
|
|
863
869
|
{
|
|
864
870
|
CArray *ca;
|
|
865
871
|
volatile VALUE face;
|
|
866
|
-
self = fz_face_descend(self, &face);
|
|
872
|
+
self = fz_face_descend(self, &face, "unique");
|
|
867
873
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
868
874
|
|
|
869
875
|
int8_t dt = ca->data_type;
|
|
@@ -876,7 +882,7 @@ rb_ca_unique_flat (VALUE self)
|
|
|
876
882
|
break;
|
|
877
883
|
default:
|
|
878
884
|
rb_raise(rb_eCADataTypeError,
|
|
879
|
-
"__unique_flat__: numeric, object, or fixlen
|
|
885
|
+
"__unique_flat__: numeric, object, or fixlen data type required (got %d)", dt);
|
|
880
886
|
}
|
|
881
887
|
if ( ca->ndim < 1 ) {
|
|
882
888
|
rb_raise(rb_eRuntimeError, "__unique_flat__: need ndim >= 1");
|
|
@@ -1098,8 +1104,8 @@ fz_intern_all (fz_hash *h, CArray *cv, fz_levels *lv)
|
|
|
1098
1104
|
seen-set). One pass to build the set from `values`, one pass to probe self;
|
|
1099
1105
|
no sort, peak memory O(distinct values).
|
|
1100
1106
|
|
|
1101
|
-
`values` must be a CArray of the same
|
|
1102
|
-
Array / Range / other-
|
|
1107
|
+
`values` must be a CArray of the same data type as self (the Ruby surface coerces
|
|
1108
|
+
Array / Range / other-type input first). Masked cells of `values` do not
|
|
1103
1109
|
enter the set. Masked cells of self stay masked in the output (membership is
|
|
1104
1110
|
unknown), reproducing the mask propagation of the retired `contains`
|
|
1105
1111
|
(self.eq(v)); their boolean payload is false.
|
|
@@ -1113,7 +1119,7 @@ rb_ca_is_in (VALUE self, VALUE rvalues)
|
|
|
1113
1119
|
{
|
|
1114
1120
|
CArray *ca, *cv;
|
|
1115
1121
|
volatile VALUE face;
|
|
1116
|
-
self = fz_face_descend(self, &face);
|
|
1122
|
+
self = fz_face_descend(self, &face, "is_in");
|
|
1117
1123
|
rvalues = fz_face_reconcile(face, rvalues, "is_in");
|
|
1118
1124
|
GetCArray(self, ca);
|
|
1119
1125
|
|
|
@@ -1127,7 +1133,7 @@ rb_ca_is_in (VALUE self, VALUE rvalues)
|
|
|
1127
1133
|
break;
|
|
1128
1134
|
default:
|
|
1129
1135
|
rb_raise(rb_eCADataTypeError,
|
|
1130
|
-
"__is_in__: numeric, object, or fixlen
|
|
1136
|
+
"__is_in__: numeric, object, or fixlen data type required (got %d)", dt);
|
|
1131
1137
|
}
|
|
1132
1138
|
if ( ca->ndim < 1 ) {
|
|
1133
1139
|
rb_raise(rb_eRuntimeError, "__is_in__: need ndim >= 1");
|
|
@@ -1137,9 +1143,16 @@ rb_ca_is_in (VALUE self, VALUE rvalues)
|
|
|
1137
1143
|
rb_raise(rb_eArgError, "__is_in__: values must be a CArray");
|
|
1138
1144
|
}
|
|
1139
1145
|
GetCArray(rvalues, cv);
|
|
1140
|
-
if ( cv->data_type != dt
|
|
1146
|
+
if ( cv->data_type != dt ) {
|
|
1147
|
+
rb_raise(rb_eCADataTypeError,
|
|
1148
|
+
"__is_in__: values data type (%s) must match self (%s)",
|
|
1149
|
+
ca_type_name[cv->data_type], ca_type_name[dt]);
|
|
1150
|
+
}
|
|
1151
|
+
if ( dt == CA_FIXLEN && cv->bytes != ca->bytes ) {
|
|
1141
1152
|
rb_raise(rb_eCADataTypeError,
|
|
1142
|
-
"__is_in__:
|
|
1153
|
+
"__is_in__: a fixlen value is a cell-width blob, so the values "
|
|
1154
|
+
"must be %ld bytes wide like self, not %ld",
|
|
1155
|
+
(long) ca->bytes, (long) cv->bytes);
|
|
1143
1156
|
}
|
|
1144
1157
|
if ( cv->ndim < 1 ) {
|
|
1145
1158
|
rb_raise(rb_eRuntimeError, "__is_in__: values need ndim >= 1");
|
|
@@ -1256,7 +1269,7 @@ rb_ca_is_in (VALUE self, VALUE rvalues)
|
|
|
1256
1269
|
through the discovery-family lanes (NaN collapse, rb_hash + rb_eql, byte
|
|
1257
1270
|
equality).
|
|
1258
1271
|
|
|
1259
|
-
`ref` must be a CArray of the same
|
|
1272
|
+
`ref` must be a CArray of the same data type as self (the Ruby surface coerces
|
|
1260
1273
|
first). Masked cells of `ref` do not enter the map but still occupy their
|
|
1261
1274
|
flat address (position counts). Masked cells of self, and cells whose value
|
|
1262
1275
|
is absent from `ref`, are UNDEF in the output. "First" occurrence is
|
|
@@ -1271,7 +1284,7 @@ rb_ca_locate_addr (VALUE self, VALUE rref)
|
|
|
1271
1284
|
output is an address, so nothing is lifted back. */
|
|
1272
1285
|
{
|
|
1273
1286
|
volatile VALUE ref_face;
|
|
1274
|
-
rref = fz_face_descend(rref, &ref_face);
|
|
1287
|
+
rref = fz_face_descend(rref, &ref_face, "locate_addr");
|
|
1275
1288
|
self = fz_face_reconcile(ref_face, self, "locate_addr");
|
|
1276
1289
|
}
|
|
1277
1290
|
GetCArray(self, ca);
|
|
@@ -1286,7 +1299,7 @@ rb_ca_locate_addr (VALUE self, VALUE rref)
|
|
|
1286
1299
|
break;
|
|
1287
1300
|
default:
|
|
1288
1301
|
rb_raise(rb_eCADataTypeError,
|
|
1289
|
-
"__locate_addr__: numeric, object, or fixlen
|
|
1302
|
+
"__locate_addr__: numeric, object, or fixlen data type required (got %d)", dt);
|
|
1290
1303
|
}
|
|
1291
1304
|
if ( ca->ndim < 1 ) {
|
|
1292
1305
|
rb_raise(rb_eRuntimeError, "__locate_addr__: need ndim >= 1");
|
|
@@ -1297,7 +1310,7 @@ rb_ca_locate_addr (VALUE self, VALUE rref)
|
|
|
1297
1310
|
GetCArray(rref, cr);
|
|
1298
1311
|
if ( cr->data_type != dt || (dt == CA_FIXLEN && cr->bytes != ca->bytes) ) {
|
|
1299
1312
|
rb_raise(rb_eCADataTypeError,
|
|
1300
|
-
"__locate_addr__: ref
|
|
1313
|
+
"__locate_addr__: ref data type must match self (%d)", dt);
|
|
1301
1314
|
}
|
|
1302
1315
|
if ( cr->ndim < 1 ) {
|
|
1303
1316
|
rb_raise(rb_eRuntimeError, "__locate_addr__: ref need ndim >= 1");
|
|
@@ -1521,7 +1534,7 @@ rb_ca_locate_addr (VALUE self, VALUE rref)
|
|
|
1521
1534
|
/* Shared body of __intersection__ (keep_when_hit = 1) and __difference__
|
|
1522
1535
|
(keep_when_hit = 0): the distinct values of self that are (resp. are not)
|
|
1523
1536
|
present in `other`, in self's first-appearance order, as a 1-D CArray of
|
|
1524
|
-
self's
|
|
1537
|
+
self's data type. Two seen-sets: `hoth` built from `other` is the probe set;
|
|
1525
1538
|
`hself` dedups self so each distinct value is decided once. Masked cells of
|
|
1526
1539
|
either array do not participate. Distinctness is the discovery family's per
|
|
1527
1540
|
lane (numeric `==` + NaN collapse + -0.0 == +0.0, object hash/eql? + NaN
|
|
@@ -1531,7 +1544,7 @@ fz_set_relation (VALUE self, VALUE rother, int keep_when_hit)
|
|
|
1531
1544
|
{
|
|
1532
1545
|
CArray *ca, *co;
|
|
1533
1546
|
volatile VALUE face;
|
|
1534
|
-
self = fz_face_descend(self, &face);
|
|
1547
|
+
self = fz_face_descend(self, &face, "set relation");
|
|
1535
1548
|
rother = fz_face_reconcile(face, rother, "set relation");
|
|
1536
1549
|
GetCArray(self, ca);
|
|
1537
1550
|
|
|
@@ -1545,7 +1558,7 @@ fz_set_relation (VALUE self, VALUE rother, int keep_when_hit)
|
|
|
1545
1558
|
break;
|
|
1546
1559
|
default:
|
|
1547
1560
|
rb_raise(rb_eCADataTypeError,
|
|
1548
|
-
"set relation: numeric, object, or fixlen
|
|
1561
|
+
"set relation: numeric, object, or fixlen data type required (got %d)", dt);
|
|
1549
1562
|
}
|
|
1550
1563
|
if ( ca->ndim < 1 ) {
|
|
1551
1564
|
rb_raise(rb_eRuntimeError, "set relation: need ndim >= 1");
|
|
@@ -1554,8 +1567,16 @@ fz_set_relation (VALUE self, VALUE rother, int keep_when_hit)
|
|
|
1554
1567
|
rb_raise(rb_eArgError, "set relation: other must be a CArray");
|
|
1555
1568
|
}
|
|
1556
1569
|
GetCArray(rother, co);
|
|
1557
|
-
if ( co->data_type != dt
|
|
1558
|
-
rb_raise(rb_eCADataTypeError,
|
|
1570
|
+
if ( co->data_type != dt ) {
|
|
1571
|
+
rb_raise(rb_eCADataTypeError,
|
|
1572
|
+
"set relation: other data type (%s) must match self (%s)",
|
|
1573
|
+
ca_type_name[co->data_type], ca_type_name[dt]);
|
|
1574
|
+
}
|
|
1575
|
+
if ( dt == CA_FIXLEN && co->bytes != ca->bytes ) {
|
|
1576
|
+
rb_raise(rb_eCADataTypeError,
|
|
1577
|
+
"set relation: a fixlen value is a cell-width blob, so other "
|
|
1578
|
+
"must be %ld bytes wide like self, not %ld",
|
|
1579
|
+
(long) ca->bytes, (long) co->bytes);
|
|
1559
1580
|
}
|
|
1560
1581
|
if ( co->ndim < 1 ) {
|
|
1561
1582
|
rb_raise(rb_eRuntimeError, "set relation: other need ndim >= 1");
|
|
@@ -1716,7 +1737,7 @@ rb_ca_set_union (VALUE self, VALUE rother)
|
|
|
1716
1737
|
{
|
|
1717
1738
|
CArray *ca, *co;
|
|
1718
1739
|
volatile VALUE face;
|
|
1719
|
-
self = fz_face_descend(self, &face);
|
|
1740
|
+
self = fz_face_descend(self, &face, "union");
|
|
1720
1741
|
rother = fz_face_reconcile(face, rother, "union");
|
|
1721
1742
|
GetCArray(self, ca);
|
|
1722
1743
|
|
|
@@ -1730,7 +1751,7 @@ rb_ca_set_union (VALUE self, VALUE rother)
|
|
|
1730
1751
|
break;
|
|
1731
1752
|
default:
|
|
1732
1753
|
rb_raise(rb_eCADataTypeError,
|
|
1733
|
-
"__union__: numeric, object, or fixlen
|
|
1754
|
+
"__union__: numeric, object, or fixlen data type required (got %d)", dt);
|
|
1734
1755
|
}
|
|
1735
1756
|
if ( ca->ndim < 1 ) {
|
|
1736
1757
|
rb_raise(rb_eRuntimeError, "__union__: need ndim >= 1");
|
|
@@ -1740,7 +1761,7 @@ rb_ca_set_union (VALUE self, VALUE rother)
|
|
|
1740
1761
|
}
|
|
1741
1762
|
GetCArray(rother, co);
|
|
1742
1763
|
if ( co->data_type != dt || (dt == CA_FIXLEN && co->bytes != ca->bytes) ) {
|
|
1743
|
-
rb_raise(rb_eCADataTypeError, "__union__: other
|
|
1764
|
+
rb_raise(rb_eCADataTypeError, "__union__: other data type must match self (%d)", dt);
|
|
1744
1765
|
}
|
|
1745
1766
|
if ( co->ndim < 1 ) {
|
|
1746
1767
|
rb_raise(rb_eRuntimeError, "__union__: other need ndim >= 1");
|
|
@@ -1779,7 +1800,7 @@ rb_ca_set_union (VALUE self, VALUE rother)
|
|
|
1779
1800
|
first-appearance (row-major flatten) order together with the number of times
|
|
1780
1801
|
each occurs, one linear pass, no sort.
|
|
1781
1802
|
Returns [levels, counts]:
|
|
1782
|
-
levels = 1-D CArray of source
|
|
1803
|
+
levels = 1-D CArray of source data type, the k distinct values in appearance
|
|
1783
1804
|
order (identical to __unique_flat__).
|
|
1784
1805
|
counts = 1-D CA_INT64 of length k, counts[i] = occurrences of levels[i].
|
|
1785
1806
|
Masked cells do not participate (skipped, not counted). Numeric distinctness
|
|
@@ -1793,7 +1814,7 @@ rb_ca_value_counts_flat (VALUE self)
|
|
|
1793
1814
|
{
|
|
1794
1815
|
CArray *ca;
|
|
1795
1816
|
volatile VALUE face;
|
|
1796
|
-
self = fz_face_descend(self, &face);
|
|
1817
|
+
self = fz_face_descend(self, &face, "value_counts");
|
|
1797
1818
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1798
1819
|
|
|
1799
1820
|
int8_t dt = ca->data_type;
|
|
@@ -1806,7 +1827,7 @@ rb_ca_value_counts_flat (VALUE self)
|
|
|
1806
1827
|
break;
|
|
1807
1828
|
default:
|
|
1808
1829
|
rb_raise(rb_eCADataTypeError,
|
|
1809
|
-
"__value_counts_flat__: numeric, object, or fixlen
|
|
1830
|
+
"__value_counts_flat__: numeric, object, or fixlen data type required (got %d)", dt);
|
|
1810
1831
|
}
|
|
1811
1832
|
if ( ca->ndim < 1 ) {
|
|
1812
1833
|
rb_raise(rb_eRuntimeError, "__value_counts_flat__: need ndim >= 1");
|
|
@@ -1979,7 +2000,7 @@ rb_ca_nunique (VALUE self, VALUE vaxis, VALUE vkeep)
|
|
|
1979
2000
|
break;
|
|
1980
2001
|
default:
|
|
1981
2002
|
rb_raise(rb_eCADataTypeError,
|
|
1982
|
-
"__nunique__: numeric, object, or fixlen
|
|
2003
|
+
"__nunique__: numeric, object, or fixlen data type required (got %d)", dt);
|
|
1983
2004
|
}
|
|
1984
2005
|
if ( ca->ndim < 1 ) {
|
|
1985
2006
|
rb_raise(rb_eRuntimeError, "__nunique__: need ndim >= 1");
|
|
@@ -2126,7 +2147,7 @@ rb_ca_is_mode (VALUE self, VALUE vaxis)
|
|
|
2126
2147
|
break;
|
|
2127
2148
|
default:
|
|
2128
2149
|
rb_raise(rb_eCADataTypeError,
|
|
2129
|
-
"__is_mode__: numeric, object, or fixlen
|
|
2150
|
+
"__is_mode__: numeric, object, or fixlen data type required (got %d)", dt);
|
|
2130
2151
|
}
|
|
2131
2152
|
if ( ca->ndim < 1 ) {
|
|
2132
2153
|
rb_raise(rb_eRuntimeError, "__is_mode__: need ndim >= 1");
|
|
@@ -2332,7 +2353,7 @@ rb_ca_mode_axis (VALUE self, VALUE vaxis)
|
|
|
2332
2353
|
{
|
|
2333
2354
|
CArray *ca;
|
|
2334
2355
|
volatile VALUE face;
|
|
2335
|
-
self = fz_face_descend(self, &face);
|
|
2356
|
+
self = fz_face_descend(self, &face, "mode");
|
|
2336
2357
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
2337
2358
|
|
|
2338
2359
|
int8_t dt = ca->data_type;
|
|
@@ -2344,7 +2365,7 @@ rb_ca_mode_axis (VALUE self, VALUE vaxis)
|
|
|
2344
2365
|
break;
|
|
2345
2366
|
default:
|
|
2346
2367
|
rb_raise(rb_eCADataTypeError,
|
|
2347
|
-
"__mode_axis__: numeric
|
|
2368
|
+
"__mode_axis__: numeric data type required (got %d)", dt);
|
|
2348
2369
|
}
|
|
2349
2370
|
if ( ca->ndim < 1 ) {
|
|
2350
2371
|
rb_raise(rb_eRuntimeError, "__mode_axis__: need ndim >= 1");
|
data/ext/carray_hold.c
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
(see devel/PROPOSAL_UNMASK_FILL_METHOD.md).
|
|
6
6
|
|
|
7
7
|
Hold copies a cell's bytes into masked cells with no arithmetic and no
|
|
8
|
-
per-
|
|
8
|
+
per-type behavior, so a single ca->bytes-width memcpy walk covers every
|
|
9
9
|
data_type -- numeric, complex, bool, object (VALUE-slot byte copy of an
|
|
10
10
|
already-live value), fixlen, and Face storage. This native does forward
|
|
11
11
|
hold along one axis only and returns a fresh same-shape entity; the
|
|
@@ -37,7 +37,6 @@ static ID ca_classifier_id_excl_end = 0;
|
|
|
37
37
|
/* Symbol cache — see the range-macro comment above for why this
|
|
38
38
|
file keeps its own copy independent of carray_access.c. */
|
|
39
39
|
|
|
40
|
-
static VALUE ca_classifier_sym_star = Qundef;
|
|
41
40
|
static VALUE ca_classifier_sym_perc = Qundef;
|
|
42
41
|
static VALUE ca_classifier_sym_under = Qundef;
|
|
43
42
|
static VALUE ca_classifier_sym_gt = Qundef; /* :> slab-iterator marker */
|
|
@@ -46,8 +45,7 @@ static VALUE ca_classifier_sym_tilde = Qundef; /* :~ rubber-dim alias for `fal
|
|
|
46
45
|
static inline void
|
|
47
46
|
ca_classifier_sym_cache_init (void)
|
|
48
47
|
{
|
|
49
|
-
if (
|
|
50
|
-
ca_classifier_sym_star = ID2SYM(rb_intern("*"));
|
|
48
|
+
if ( ca_classifier_sym_perc == Qundef ) {
|
|
51
49
|
ca_classifier_sym_perc = ID2SYM(rb_intern("%"));
|
|
52
50
|
ca_classifier_sym_under = ID2SYM(rb_intern("_"));
|
|
53
51
|
ca_classifier_sym_gt = ID2SYM(rb_intern(">"));
|
|
@@ -166,7 +164,7 @@ ca_classifier_try_address_fast_path (ca_classifier_ctx_t *ctx)
|
|
|
166
164
|
/* Single-character alphabetic Symbols (`:a`-`:z` / `:A`-`:Z`) are
|
|
167
165
|
reserved for future contraction notation. Raises
|
|
168
166
|
NotImplementedError rather than the generic IndexError. The
|
|
169
|
-
caller passes any Symbol that is not `:_` /
|
|
167
|
+
caller passes any Symbol that is not `:_` / `:%`; a
|
|
170
168
|
non-reserved Symbol returns without action. */
|
|
171
169
|
static inline void
|
|
172
170
|
ca_classifier_check_reserved_contraction_symbol (VALUE sym)
|
|
@@ -763,12 +761,6 @@ ca_classifier_try_argc1_special (ca_classifier_ctx_t *ctx)
|
|
|
763
761
|
ca_type_name[cs->data_type]);
|
|
764
762
|
}
|
|
765
763
|
|
|
766
|
-
/* :* → UNBOUND_REPEAT. */
|
|
767
|
-
if ( arg == ca_classifier_sym_star ) {
|
|
768
|
-
info->type = CA_REG_UNBOUND_REPEAT;
|
|
769
|
-
return 1;
|
|
770
|
-
}
|
|
771
|
-
|
|
772
764
|
/* ndim > 1 with Integer → ADDRESS. Fixnum was caught by the
|
|
773
765
|
fast path; this branch handles Bignum. */
|
|
774
766
|
if ( ctx->ca_ndim > 1 && rb_obj_is_kind_of(arg, rb_cInteger) ) {
|
|
@@ -832,7 +824,7 @@ rb_ca_scan_index_v2 (int ca_ndim, ca_size_t *ca_dim, ca_size_t ca_elements,
|
|
|
832
824
|
}
|
|
833
825
|
|
|
834
826
|
/* argv[0] = multi-char Symbol → METHOD_CALL. Single-char
|
|
835
|
-
specials (:_ /
|
|
827
|
+
specials (:_ / :%) fall through the strlen check and are
|
|
836
828
|
handled downstream (argc == 1 special / fast paths / main
|
|
837
829
|
loop). Single-char alphabetic reserved-contraction Symbols
|
|
838
830
|
also fall through here and are raised later by the per-axis
|
|
@@ -859,20 +851,15 @@ rb_ca_scan_index_v2 (int ca_ndim, ca_size_t *ca_dim, ca_size_t ca_elements,
|
|
|
859
851
|
when argc == 1 && ndim == 1 falls through to the POINT 1-D
|
|
860
852
|
classification below. */
|
|
861
853
|
|
|
862
|
-
/* CAREFUL: pre-scan for
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
recognised. */
|
|
854
|
+
/* CAREFUL: pre-scan for :%. The Symbol at any position pins the
|
|
855
|
+
final REG and short-circuits both the main loop and the argc /
|
|
856
|
+
ndim validation below — skipping the pre-scan lets the ndim
|
|
857
|
+
mismatch check fire before the Symbol is recognised. */
|
|
867
858
|
for (i = 0; i < ctx.argc; i++) {
|
|
868
859
|
if ( ctx.argv[i] == ca_classifier_sym_perc ) {
|
|
869
860
|
info->type = CA_REG_REPEAT;
|
|
870
861
|
return;
|
|
871
862
|
}
|
|
872
|
-
if ( ctx.argv[i] == ca_classifier_sym_star ) {
|
|
873
|
-
info->type = CA_REG_UNBOUND_REPEAT;
|
|
874
|
-
return;
|
|
875
|
-
}
|
|
876
863
|
}
|
|
877
864
|
|
|
878
865
|
ca_classifier_expand_rubber_dim(&ctx);
|
|
@@ -941,7 +928,6 @@ rb_ca_s_scan_index_v2 (VALUE self, VALUE rdim, VALUE ridx)
|
|
|
941
928
|
case CA_REG_GRID:
|
|
942
929
|
case CA_REG_MAPPING:
|
|
943
930
|
case CA_REG_METHOD_CALL:
|
|
944
|
-
case CA_REG_UNBOUND_REPEAT:
|
|
945
931
|
case CA_REG_MEMBER:
|
|
946
932
|
case CA_REG_ATTRIBUTE:
|
|
947
933
|
break;
|
data/ext/carray_internal.h
CHANGED
|
@@ -59,8 +59,41 @@ void ca_bit_pack (const boolean8_t *src, ca_size_t elements, ca_size_t pbytes,
|
|
|
59
59
|
void ca_lazy_arena_enter (void);
|
|
60
60
|
void ca_lazy_arena_exit (void);
|
|
61
61
|
void *ca_lazy_arena_acquire (ca_size_t bytes);
|
|
62
|
+
void *ca_lazy_arena_acquire_object (ca_size_t n_elements);
|
|
62
63
|
void ca_lazy_arena_release (void *ptr);
|
|
63
64
|
|
|
65
|
+
/* ---- CA_OBJECT GC guard (carray_lazy.c) ----------------------------------
|
|
66
|
+
|
|
67
|
+
A CA_OBJECT cell is a VALUE, and a materialise writes those cells into a
|
|
68
|
+
buffer no Ruby object owns. Object-lane kernels call rb_funcall per cell,
|
|
69
|
+
so a collection can happen halfway through and free what has been written
|
|
70
|
+
so far. Hold the buffer while it is exposed like that, and after the
|
|
71
|
+
materialise until a Ruby object takes ownership of it.
|
|
72
|
+
|
|
73
|
+
The cells must already be valid VALUEs, so a fresh buffer is Qnil-filled
|
|
74
|
+
before it is held. ca_gc_hold_push returns the depth to hand back to
|
|
75
|
+
ca_gc_hold_pop_to, so nested holds unwind in order. */
|
|
76
|
+
|
|
77
|
+
int ca_gc_hold_push (void *ptr, ca_size_t n_elements);
|
|
78
|
+
void ca_gc_hold_pop_to (int depth);
|
|
79
|
+
|
|
80
|
+
/* ---- Attaching several parents (carray_core.c) ---------------------------
|
|
81
|
+
|
|
82
|
+
Attach all of list[0..n-1] or none: if one attach raises, those already
|
|
83
|
+
attached are detached before the raise propagates. */
|
|
84
|
+
|
|
85
|
+
void ca_attach_all (CArray **list, int32_t n);
|
|
86
|
+
|
|
87
|
+
/* ---- Filling a result Ruby does not own yet (carray_copy.c) ---------------
|
|
88
|
+
|
|
89
|
+
A C builder that allocates its result with carray_new / ca_template and
|
|
90
|
+
then reads the source into it holds a struct no Ruby object owns until
|
|
91
|
+
ca_wrap_struct. A read that raises (a lazy conversion) would leave it
|
|
92
|
+
behind. ca_fill_or_free runs fill(arg) under rb_protect and, if it
|
|
93
|
+
raises, frees `co` before the raise propagates. */
|
|
94
|
+
|
|
95
|
+
void ca_fill_or_free (CArray *co, VALUE (*fill)(VALUE), VALUE arg);
|
|
96
|
+
|
|
64
97
|
/* Non-zero iff the object is an element-wise lazy view (CAMonOp / CABinOp /
|
|
65
98
|
CABinCmp / CAMonCmp / CALazyMarker). The streaming branch of the
|
|
66
99
|
mkkernel-generated reduction kernels tests this to decide whether it can
|
|
@@ -111,10 +144,10 @@ VALUE rb_ca_fake_new (VALUE cary, int8_t data_type, ca_size_t bytes);
|
|
|
111
144
|
CARepeat *ca_repeat_new (CArray *carray, int8_t ndim, ca_size_t *count);
|
|
112
145
|
VALUE rb_ca_repeat_new (VALUE cary, int8_t ndim, ca_size_t *count);
|
|
113
146
|
|
|
114
|
-
/* ca_obj_unbound_repeat.c */
|
|
115
|
-
VALUE rb_ca_ubrep_new (VALUE cary, int32_t rep_ndim, ca_size_t *rep_dim);
|
|
116
|
-
|
|
117
147
|
/* ca_obj_reduce.c */
|
|
118
148
|
CAReduce *ca_reduce_new (CArray *carray, ca_size_t count, ca_size_t offset);
|
|
119
149
|
|
|
150
|
+
/* carray_broadcast.c */
|
|
151
|
+
void ca_broadcast_to_destination (VALUE dst, volatile VALUE *src);
|
|
152
|
+
|
|
120
153
|
#endif /* CARRAY_INTERNAL_H */
|
data/ext/carray_kernels_bincmp.c
CHANGED