carray 3.0.3 → 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 +264 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +1 -6
- data/ext/ca_axis_group.c +27 -27
- data/ext/ca_binop_dispatch.c +1 -29
- data/ext/ca_binop_dispatch.h +0 -1
- data/ext/ca_categorical_iterator.c +205 -134
- data/ext/ca_compare.c +7 -18
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1234 -1994
- data/ext/ca_kernel_iterator.h +391 -437
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +96 -39
- data/ext/ca_obj_bincmp.c +24 -21
- data/ext/ca_obj_binop.c +15 -26
- data/ext/ca_obj_bitarray.c +3 -2
- data/ext/ca_obj_bitfield.c +5 -6
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +5 -6
- data/ext/ca_obj_const_string.c +173 -19
- data/ext/ca_obj_face.c +238 -57
- data/ext/ca_obj_face.h +19 -0
- data/ext/ca_obj_fake.c +15 -29
- data/ext/ca_obj_farray.c +6 -3
- data/ext/ca_obj_field.c +17 -5
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +406 -132
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +67 -57
- data/ext/ca_obj_object.c +157 -51
- data/ext/ca_obj_record.c +12 -7
- data/ext/ca_obj_reduce.c +13 -8
- data/ext/ca_obj_refer.c +25 -27
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +6 -5
- data/ext/ca_obj_select.c +14 -9
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +11 -1
- data/ext/ca_obj_stack.c +179 -34
- data/ext/ca_obj_stride.c +162 -115
- data/ext/ca_obj_string.c +71 -4
- data/ext/ca_obj_tile.c +6 -5
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +5 -3
- data/ext/ca_obj_triop.c +23 -32
- data/ext/ca_obj_window.c +190 -26
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +181 -75
- data/ext/carray_access.c +184 -96
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +89 -6
- data/ext/carray_bincount.c +10 -8
- data/ext/carray_broadcast.c +13 -8
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +108 -0
- data/ext/carray_cast.c +142 -24
- data/ext/carray_cast_func.rb +46 -6
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +16 -7
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +147 -55
- data/ext/carray_count.c +50 -20
- data/ext/carray_element.c +76 -33
- data/ext/carray_factorize.c +118 -64
- data/ext/carray_generate.c +191 -50
- data/ext/carray_histogram.c +62 -17
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +336 -29
- data/ext/carray_kernels_bincmp.c +4453 -0
- data/ext/carray_kernels_binop.c +11368 -0
- data/ext/carray_kernels_init.c +1734 -0
- data/ext/carray_kernels_moncmp.c +2104 -0
- data/ext/carray_kernels_monop.c +18369 -0
- data/ext/carray_kernels_reduce_aggregate.c +23818 -0
- data/ext/carray_kernels_reduce_boolean.c +406 -0
- data/ext/carray_kernels_reduce_cumulative.c +10086 -0
- data/ext/carray_kernels_reduce_extreme.c +17634 -0
- data/ext/carray_kernels_reduce_variance.c +3849 -0
- data/ext/carray_kernels_scan.c +4302 -0
- data/ext/carray_kernels_search.c +33829 -0
- data/ext/carray_kernels_sort.c +10906 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +292 -72
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +124 -47
- data/ext/carray_order.c +384 -76
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +67 -13
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +63 -38
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +91 -28
- data/ext/carray_sort.c +35 -35
- data/ext/carray_struct.c +19 -18
- data/ext/carray_test.c +26 -5
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +246 -45
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +198 -240
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +126 -22
- data/lib/carray/autoload_carray.rb +8 -31
- data/lib/carray/autoload_method_extension.rb +14 -5
- data/lib/carray/axis_group.rb +255 -106
- data/lib/carray/basics.rb +78 -10
- data/lib/carray/bincount_nd.rb +12 -2
- data/lib/carray/block_iterator.rb +126 -23
- data/lib/carray/boolean_reduce.rb +17 -17
- data/lib/carray/categorical.rb +165 -43
- data/lib/carray/categorical_iterator.rb +130 -27
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +14 -5
- 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/convert.rb +69 -0
- data/lib/carray/frame/csv_parser.rb +111 -17
- data/lib/carray/frame/describe.rb +3 -2
- data/lib/carray/frame/frame.rb +246 -21
- data/lib/carray/frame/group.rb +510 -95
- data/lib/carray/frame/io.rb +115 -28
- data/lib/carray/frame/join.rb +312 -51
- data/lib/carray/frame/records.rb +83 -7
- data/lib/carray/frame/reshape.rb +42 -35
- data/lib/carray/frame/sort.rb +7 -19
- data/lib/carray/frame/verbs.rb +188 -48
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +11 -4
- data/lib/carray/fusion.rb +40 -16
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +31 -8
- data/lib/carray/iterator.rb +85 -7
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +182 -183
- data/lib/carray/mask_gap_fill.rb +63 -57
- data/lib/carray/meld_reduce.rb +12 -14
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +16 -0
- data/lib/carray/methods/bit_string.rb +1 -1
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +3 -1
- data/lib/carray/methods/gather_nd.rb +14 -5
- data/lib/carray/methods/insert_block.rb +2 -2
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +53 -36
- data/lib/carray/methods/join.rb +1 -6
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +47 -51
- data/lib/carray/methods/mode.rb +1 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/resize.rb +3 -3
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +3 -3
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +53 -8
- data/lib/carray/segment_iterator.rb +313 -82
- data/lib/carray/serialize.rb +24 -10
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +8 -1
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +19 -8
- data/lib/carray/time.rb +726 -104
- data/lib/carray/window_iterator.rb +122 -16
- data/lib/carray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +4 -0
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +2 -1
- data/yard-stubs/ca_obj_roll.rb +2 -2
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_cast.rb +10 -0
- data/yard-stubs/carray_conversion.rb +2 -1
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +26 -2
- data/yard-stubs/carray_math.rb +27 -1
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +29 -18
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +14 -9
- data/yard-stubs/carray_slab.rb +9 -2
- data/yard-stubs/carray_sort.rb +6 -5
- data/yard-stubs/carray_test.rb +5 -3
- metadata +25 -3
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/carray_access.c
CHANGED
|
@@ -76,7 +76,7 @@ rb_ca_fetch_index (VALUE self, ca_size_t *idx)
|
|
|
76
76
|
volatile VALUE holder;
|
|
77
77
|
char *v = ALLOCV_N(char, holder, ca->bytes);
|
|
78
78
|
ca_fetch_index(ca, idx, v);
|
|
79
|
-
out =
|
|
79
|
+
out = rb_ca_ptr2obj_storage(self, v);
|
|
80
80
|
ALLOCV_END(holder);
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -94,7 +94,7 @@ rb_ca_fetch_index (VALUE self, ca_size_t *idx)
|
|
|
94
94
|
CA_FACE_STORAGE_TO_ELEMENT_IF_FACE(out, self, ca);
|
|
95
95
|
|
|
96
96
|
/* Boolean scalar access yields true/false, not Integer 0/1. Bulk paths
|
|
97
|
-
(
|
|
97
|
+
(cast / serialize) keep 0/1. Gate on the raw
|
|
98
98
|
INT2FIX(0/1) so a boolean-storage Face that decoded to its own object is
|
|
99
99
|
left untouched; note INT2FIX(0) is truthy in Ruby, so map by value, not
|
|
100
100
|
by RTEST. */
|
|
@@ -158,7 +158,7 @@ rb_ca_fetch_addr (VALUE self, ca_size_t addr)
|
|
|
158
158
|
volatile VALUE holder;
|
|
159
159
|
char *v = ALLOCV_N(char, holder, ca->bytes);
|
|
160
160
|
ca_fetch_addr(ca, addr, v);
|
|
161
|
-
out =
|
|
161
|
+
out = rb_ca_ptr2obj_storage(self, v);
|
|
162
162
|
ALLOCV_END(holder);
|
|
163
163
|
}
|
|
164
164
|
|
|
@@ -229,9 +229,7 @@ static void
|
|
|
229
229
|
ary_guess_shape (VALUE ary, int level, int *max_level, ca_size_t *dim)
|
|
230
230
|
{
|
|
231
231
|
volatile VALUE ary0;
|
|
232
|
-
|
|
233
|
-
rb_raise(rb_eArgError, "too deep level array for conversion to carray");
|
|
234
|
-
}
|
|
232
|
+
ca_check_rank_fits(level + 1, NULL);
|
|
235
233
|
|
|
236
234
|
if ( TYPE(ary) == T_ARRAY ) {
|
|
237
235
|
if ( RARRAY_LEN(ary) == 0 && level == 0 ) {
|
|
@@ -476,26 +474,6 @@ ca_id_expression_evaluator (void)
|
|
|
476
474
|
return id;
|
|
477
475
|
}
|
|
478
476
|
|
|
479
|
-
/* `a[:sym, args] = v` computes the index by calling Ruby with self held
|
|
480
|
-
attached for the reads, then stores through it. */
|
|
481
|
-
|
|
482
|
-
typedef struct {
|
|
483
|
-
VALUE self;
|
|
484
|
-
VALUE dest; /* what is stored into: self, or a Face's storage */
|
|
485
|
-
ID mid;
|
|
486
|
-
int argc;
|
|
487
|
-
VALUE *argv;
|
|
488
|
-
VALUE rval;
|
|
489
|
-
} ca_store_method_call_ctx_t;
|
|
490
|
-
|
|
491
|
-
static VALUE
|
|
492
|
-
ca_store_method_call_body (VALUE arg)
|
|
493
|
-
{
|
|
494
|
-
ca_store_method_call_ctx_t *c = (ca_store_method_call_ctx_t *) arg;
|
|
495
|
-
volatile VALUE idx = rb_funcallv_public(c->self, c->mid, c->argc, c->argv);
|
|
496
|
-
return rb_ca_store(c->dest, idx, c->rval);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
477
|
/* The casting stores below convert into the destination inside a window,
|
|
500
478
|
and a conversion from Ruby objects can raise part way. Such a window
|
|
501
479
|
attaches rather than allocates: the cells converted before the raise
|
|
@@ -586,6 +564,10 @@ ca_store_all_list_body (VALUE arg)
|
|
|
586
564
|
(boolean8_t*)ca->mask->ptr);
|
|
587
565
|
}
|
|
588
566
|
else {
|
|
567
|
+
/* Every cell gets a value, so none stays masked. */
|
|
568
|
+
if ( ca->mask ) {
|
|
569
|
+
memset(ca->mask->ptr, 0, ca->elements);
|
|
570
|
+
}
|
|
589
571
|
ca_cast_block(ca->elements, c->ico, (VALUE *)RARRAY_CONST_PTR(list), cast_target, ca->ptr);
|
|
590
572
|
}
|
|
591
573
|
return Qnil;
|
|
@@ -654,6 +636,38 @@ ca_face_source_for_store (VALUE self, CArray *ca, VALUE rval)
|
|
|
654
636
|
return rb_funcall(rval, rb_intern("to_type"), 1, INT2NUM(CA_OBJECT));
|
|
655
637
|
}
|
|
656
638
|
|
|
639
|
+
/* A store into no cells writes nothing, but the value is checked as it
|
|
640
|
+
would be for any cells: the same statement does not raise or pass
|
|
641
|
+
depending on how many cells the index picks. */
|
|
642
|
+
static void
|
|
643
|
+
ca_store_all_check_empty (VALUE self, VALUE rval)
|
|
644
|
+
{
|
|
645
|
+
CArray *ca;
|
|
646
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
647
|
+
if ( rb_obj_is_cscalar(rval) ) {
|
|
648
|
+
rval = rb_ca_fetch_addr(rval, 0);
|
|
649
|
+
}
|
|
650
|
+
rval = ca_face_source_for_store(self, ca, rval);
|
|
651
|
+
if ( ! rb_obj_is_carray(rval) && TYPE(rval) != T_ARRAY &&
|
|
652
|
+
rb_respond_to(rval, id_to_ca) ) {
|
|
653
|
+
rval = rb_funcall(rval, id_to_ca, 0);
|
|
654
|
+
}
|
|
655
|
+
if ( rb_obj_is_carray(rval) ) {
|
|
656
|
+
ca_broadcast_to_destination(self, (volatile VALUE *) &rval);
|
|
657
|
+
}
|
|
658
|
+
else if ( TYPE(rval) == T_ARRAY ) {
|
|
659
|
+
if ( NIL_P(rb_ary_flatten_for_elements(rval, ca->elements, ca)) ) {
|
|
660
|
+
rb_raise(rb_eArgError, "failed to guess data size of given array");
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
else if ( rval != CA_UNDEF ) {
|
|
664
|
+
volatile VALUE holder;
|
|
665
|
+
char *fval = ALLOCV_N(char, holder, ca->bytes);
|
|
666
|
+
rb_ca_obj2ptr(self, rval, fval);
|
|
667
|
+
ALLOCV_END(holder);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
657
671
|
VALUE
|
|
658
672
|
rb_ca_store_all (VALUE self, VALUE rval)
|
|
659
673
|
{
|
|
@@ -661,10 +675,14 @@ rb_ca_store_all (VALUE self, VALUE rval)
|
|
|
661
675
|
|
|
662
676
|
rb_ca_modify(self);
|
|
663
677
|
|
|
664
|
-
if ( self == rval
|
|
678
|
+
if ( self == rval ) {
|
|
665
679
|
return rval;
|
|
666
680
|
}
|
|
667
|
-
|
|
681
|
+
if ( rb_ca_is_empty(self) ) {
|
|
682
|
+
ca_store_all_check_empty(self, rval);
|
|
683
|
+
return rval;
|
|
684
|
+
}
|
|
685
|
+
|
|
668
686
|
if ( rb_obj_is_cscalar(rval) ) {
|
|
669
687
|
rval = rb_ca_fetch_addr(rval, 0);
|
|
670
688
|
}
|
|
@@ -689,6 +707,7 @@ rb_ca_store_all (VALUE self, VALUE rval)
|
|
|
689
707
|
&& ca->data_type == cv->data_type
|
|
690
708
|
&& ca->ndim == cv->ndim
|
|
691
709
|
&& ca->elements == cv->elements
|
|
710
|
+
&& ca_in_main_ractor()
|
|
692
711
|
&& RTEST(rb_attr_get(rb_cCArray, ca_id_expression_evaluator())) ) {
|
|
693
712
|
int8_t k;
|
|
694
713
|
int same = 1;
|
|
@@ -1022,7 +1041,9 @@ extern VALUE rb_ca_remap_new (VALUE cary, VALUE rmapper);
|
|
|
1022
1041
|
(b) Otherwise -> normalize chain (a.flatten[mapper.flatten]
|
|
1023
1042
|
.reshape). A 1-D mapper is already routed to CAGrid upstream.
|
|
1024
1043
|
|
|
1025
|
-
|
|
1044
|
+
A masked mapper cell selects nothing: the cell keeps its position and
|
|
1045
|
+
reads as masked (a CAGrid hole); the same-shape fast path is left to a
|
|
1046
|
+
mapper with no masked cell. */
|
|
1026
1047
|
static VALUE
|
|
1027
1048
|
rb_ca_fancy_index_chain (VALUE self, VALUE rmapper)
|
|
1028
1049
|
{
|
|
@@ -1034,15 +1055,24 @@ rb_ca_fancy_index_chain (VALUE self, VALUE rmapper)
|
|
|
1034
1055
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1035
1056
|
TypedData_Get_Struct(rmapper, CArray, &carray_data_type, cm);
|
|
1036
1057
|
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1058
|
+
/* (a) same-shape fast path: ndim + per-axis dim + CA_SIZE data_type.
|
|
1059
|
+
The view reads the index array it is given, so it is given a copy: the
|
|
1060
|
+
indices are the ones the caller passed at this call, as every other
|
|
1061
|
+
route reads them, and each is checked against self now, so an index out
|
|
1062
|
+
of range raises here and not at the first read. */
|
|
1042
1063
|
if ( cm->data_type == CA_SIZE
|
|
1064
|
+
&& ! ca_is_any_masked(cm)
|
|
1043
1065
|
&& cm->ndim == ca->ndim
|
|
1044
1066
|
&& memcmp(cm->dim, ca->dim, ca->ndim * sizeof(ca_size_t)) == 0 ) {
|
|
1045
|
-
|
|
1067
|
+
volatile VALUE snapshot = rb_ca_copy(rmapper);
|
|
1068
|
+
CArray *cs;
|
|
1069
|
+
ca_size_t k, *p;
|
|
1070
|
+
TypedData_Get_Struct(snapshot, CArray, &carray_data_type, cs);
|
|
1071
|
+
p = (ca_size_t *) cs->ptr;
|
|
1072
|
+
for (k = 0; k < cs->elements; k++) {
|
|
1073
|
+
CA_CHECK_INDEX(p[k], ca->elements);
|
|
1074
|
+
}
|
|
1075
|
+
return rb_ca_remap_new(self, snapshot);
|
|
1046
1076
|
}
|
|
1047
1077
|
|
|
1048
1078
|
/* (b) Normalize chain fallback. A Face is flattened through its storage
|
|
@@ -1070,10 +1100,9 @@ rb_ca_fancy_index_chain (VALUE self, VALUE rmapper)
|
|
|
1070
1100
|
return result;
|
|
1071
1101
|
}
|
|
1072
1102
|
|
|
1073
|
-
/*
|
|
1074
|
-
the
|
|
1075
|
-
|
|
1076
|
-
class of the returned VALUE is CARefer (chain outermost), not CAMapping. */
|
|
1103
|
+
/* rb_ca_mapping_new and rb_ca_mapping index cary by a mapper array through
|
|
1104
|
+
rb_ca_fancy_index_chain: the result is a CAGrid over the flattened array,
|
|
1105
|
+
reshaped (CARefer, the outermost layer) to the mapper's shape. */
|
|
1077
1106
|
|
|
1078
1107
|
VALUE
|
|
1079
1108
|
rb_ca_mapping_new (VALUE cary, CArray *mapper)
|
|
@@ -1099,6 +1128,18 @@ rb_ca_mapping (int argc, VALUE *argv, VALUE self)
|
|
|
1099
1128
|
the optimal view class (CAStride for stride bases, CARefer for fancy
|
|
1100
1129
|
bases). */
|
|
1101
1130
|
|
|
1131
|
+
/* a[:name, args] calls a method of the array, and its arguments are the
|
|
1132
|
+
method's, whatever they are: the scans for :_, :> and group indices
|
|
1133
|
+
below look at index keys only. */
|
|
1134
|
+
static int
|
|
1135
|
+
ca_argv_is_method_call (int argc, VALUE *argv)
|
|
1136
|
+
{
|
|
1137
|
+
const char *name;
|
|
1138
|
+
if ( argc < 1 || ! SYMBOL_P(argv[0]) ) return 0;
|
|
1139
|
+
name = rb_id2name(SYM2ID(argv[0]));
|
|
1140
|
+
return ( name != NULL && strlen(name) > 1 );
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1102
1143
|
static int
|
|
1103
1144
|
ca_argv_has_newaxis (int argc, VALUE *argv)
|
|
1104
1145
|
{
|
|
@@ -1140,6 +1181,10 @@ rb_ca_fetch_method (int argc, VALUE *argv, VALUE self)
|
|
|
1140
1181
|
|
|
1141
1182
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1142
1183
|
|
|
1184
|
+
if ( ca_argv_is_method_call(argc, argv) ) {
|
|
1185
|
+
goto classify;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1143
1188
|
/* newaxis (:_) interception (cheap pointer scan; zero overhead beyond
|
|
1144
1189
|
the loop when no :_ is present). */
|
|
1145
1190
|
if ( ca_argv_has_newaxis(argc, argv) ) {
|
|
@@ -1163,6 +1208,7 @@ rb_ca_fetch_method (int argc, VALUE *argv, VALUE self)
|
|
|
1163
1208
|
return rb_ca_fetch_group(argc, argv, self);
|
|
1164
1209
|
}
|
|
1165
1210
|
|
|
1211
|
+
classify:
|
|
1166
1212
|
info.range_check = 1;
|
|
1167
1213
|
rb_ca_scan_index(ca->ndim, ca->dim, ca->elements, argc, argv, &info);
|
|
1168
1214
|
|
|
@@ -1244,11 +1290,6 @@ rb_ca_fetch_method (int argc, VALUE *argv, VALUE self)
|
|
|
1244
1290
|
}
|
|
1245
1291
|
break;
|
|
1246
1292
|
}
|
|
1247
|
-
case CA_REG_ATTRIBUTE: {
|
|
1248
|
-
obj = rb_funcall(self, rb_intern("attribute"), 0);
|
|
1249
|
-
obj = rb_hash_aref(obj, info.symbol);
|
|
1250
|
-
break;
|
|
1251
|
-
}
|
|
1252
1293
|
default:
|
|
1253
1294
|
rb_raise(rb_eIndexError, "invalid index specified");
|
|
1254
1295
|
}
|
|
@@ -1292,7 +1333,7 @@ rb_ca_fetch_newaxis (int argc, VALUE *argv, VALUE self, CArray *ca)
|
|
|
1292
1333
|
nunder++;
|
|
1293
1334
|
continue;
|
|
1294
1335
|
}
|
|
1295
|
-
if (
|
|
1336
|
+
if ( ca_index_key_is_scalar(a) ) {
|
|
1296
1337
|
nscalar++;
|
|
1297
1338
|
}
|
|
1298
1339
|
if ( a == sym_gt || a == sym_perc
|
|
@@ -1301,7 +1342,7 @@ rb_ca_fetch_newaxis (int argc, VALUE *argv, VALUE self, CArray *ca)
|
|
|
1301
1342
|
"newaxis (:_) cannot be combined with :>, :%%, "
|
|
1302
1343
|
"or rubber dim (false / :~)");
|
|
1303
1344
|
}
|
|
1304
|
-
if ( nclean >= CA_RANK_MAX ) {
|
|
1345
|
+
if ( nclean >= CA_RANK_MAX ) { /* rank-check: a count of indices */
|
|
1305
1346
|
rb_raise(rb_eIndexError, "too many indices");
|
|
1306
1347
|
}
|
|
1307
1348
|
clean[nclean++] = a;
|
|
@@ -1339,21 +1380,40 @@ rb_ca_fetch_newaxis (int argc, VALUE *argv, VALUE self, CArray *ca)
|
|
|
1339
1380
|
TypedData_Get_Struct(base, CArray, &carray_data_type, cb);
|
|
1340
1381
|
|
|
1341
1382
|
/* Reconstruct final shape: walk original argv. :_ -> size-1, scalar
|
|
1342
|
-
(Integer) -> dropped (skip), else -> base.dim[cursor].
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1383
|
+
(Integer) -> dropped (skip), else -> base.dim[cursor]. A key gives one
|
|
1384
|
+
axis, except an integer CArray read alone (a mapping), which gives as
|
|
1385
|
+
many as it has: the axes the base has beyond one per key are its. */
|
|
1386
|
+
{
|
|
1387
|
+
int nkeys = 0, extra, ncarray = 0;
|
|
1388
|
+
for (i = 0; i < nclean; i++) {
|
|
1389
|
+
if ( ! ca_index_key_is_scalar(clean[i]) ) {
|
|
1390
|
+
nkeys++;
|
|
1391
|
+
if ( rb_obj_is_carray(clean[i]) ) ncarray++;
|
|
1392
|
+
}
|
|
1351
1393
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1394
|
+
extra = cb->ndim - nkeys;
|
|
1395
|
+
base_cursor = ( extra != 0 && ncarray != 1 ) ? -1 : 0;
|
|
1396
|
+
for (i = 0; i < argc && base_cursor >= 0; i++) {
|
|
1397
|
+
VALUE a = argv[i];
|
|
1398
|
+
int take = 1, t;
|
|
1399
|
+
if ( a == sym_under ) {
|
|
1400
|
+
final_dims[nfinal++] = 1;
|
|
1401
|
+
continue;
|
|
1402
|
+
}
|
|
1403
|
+
if ( ca_index_key_is_scalar(a) ) {
|
|
1404
|
+
/* scalar index -> axis dropped in base; contributes no output axis */
|
|
1405
|
+
continue;
|
|
1406
|
+
}
|
|
1407
|
+
if ( rb_obj_is_carray(a) ) {
|
|
1408
|
+
take += extra;
|
|
1409
|
+
}
|
|
1410
|
+
for (t = 0; t < take; t++) {
|
|
1411
|
+
if ( base_cursor >= cb->ndim || nfinal >= CA_RANK_MAX ) { /* rank-check: a count of indices */
|
|
1412
|
+
base_cursor = -1;
|
|
1413
|
+
break;
|
|
1414
|
+
}
|
|
1415
|
+
final_dims[nfinal++] = cb->dim[base_cursor++];
|
|
1355
1416
|
}
|
|
1356
|
-
final_dims[nfinal++] = cb->dim[base_cursor++];
|
|
1357
1417
|
}
|
|
1358
1418
|
}
|
|
1359
1419
|
if ( base_cursor != cb->ndim ) {
|
|
@@ -1397,7 +1457,7 @@ rb_ca_slab_iter_new (VALUE self, CAIndexInfo *info)
|
|
|
1397
1457
|
align with the post-expansion ndim, replace :> with nil (full axis),
|
|
1398
1458
|
promote Integer to length-1 Range so the base view preserves ndim,
|
|
1399
1459
|
recurse through the regular indexer dispatch to build the base
|
|
1400
|
-
reference (CABlock / CASelectAxis / CAGrid /
|
|
1460
|
+
reference (CABlock / CASelectAxis / CAGrid / ...), then
|
|
1401
1461
|
wrap in CASlabIterator with the recorded slab_axes positions. */
|
|
1402
1462
|
static VALUE
|
|
1403
1463
|
rb_ca_fetch_slab_sigil (int argc, VALUE *argv, VALUE self)
|
|
@@ -1451,7 +1511,7 @@ rb_ca_fetch_slab_sigil (int argc, VALUE *argv, VALUE self)
|
|
|
1451
1511
|
eargv = expanded;
|
|
1452
1512
|
}
|
|
1453
1513
|
|
|
1454
|
-
if ( eargc > CA_RANK_MAX ) {
|
|
1514
|
+
if ( eargc > CA_RANK_MAX ) { /* rank-check: a count of indices */
|
|
1455
1515
|
rb_raise(rb_eIndexError, "too many indices");
|
|
1456
1516
|
}
|
|
1457
1517
|
|
|
@@ -1461,7 +1521,7 @@ rb_ca_fetch_slab_sigil (int argc, VALUE *argv, VALUE self)
|
|
|
1461
1521
|
rb_ary_push(slab_axes, INT2NUM(i));
|
|
1462
1522
|
clean[i] = Qnil;
|
|
1463
1523
|
}
|
|
1464
|
-
else if (
|
|
1524
|
+
else if ( ca_index_key_is_scalar(a) ) {
|
|
1465
1525
|
/* Promote Integer to length-1 Range so the recursed view keeps
|
|
1466
1526
|
the axis (matches the existing :> dispatcher semantics where
|
|
1467
1527
|
scalars become length-1 BLOCKs via finalize_reg). */
|
|
@@ -1545,11 +1605,6 @@ rb_cs_fetch_method (int argc, VALUE *argv, VALUE self)
|
|
|
1545
1605
|
}
|
|
1546
1606
|
break;
|
|
1547
1607
|
}
|
|
1548
|
-
case CA_REG_ATTRIBUTE: {
|
|
1549
|
-
obj = rb_funcall(self, rb_intern("attribute"), 0);
|
|
1550
|
-
obj = rb_hash_aref(obj, info.symbol);
|
|
1551
|
-
break;
|
|
1552
|
-
}
|
|
1553
1608
|
default:
|
|
1554
1609
|
rb_raise(rb_eIndexError, "invalid index specified");
|
|
1555
1610
|
}
|
|
@@ -1592,6 +1647,23 @@ ca_face_convert_store_rval (VALUE self, CArray *ca, VALUE val)
|
|
|
1592
1647
|
return ca_face_convert_store_rval(self, ca,
|
|
1593
1648
|
rb_funcall(val, rb_intern("to_a"), 0));
|
|
1594
1649
|
}
|
|
1650
|
+
/* A CAString takes Strings. A text Face goes in as the CAString its
|
|
1651
|
+
to_string gives, and an object array as itself wrapped in a CAString,
|
|
1652
|
+
which checks every cell that is not masked; either keeps its shape,
|
|
1653
|
+
so it meets the shape rule of a store as an object array would. Any
|
|
1654
|
+
other array goes in as its values, each through the write hook. */
|
|
1655
|
+
if ( ca->obj_type == CA_OBJ_STRING && cval->obj_type != CA_OBJ_STRING ) {
|
|
1656
|
+
if ( ca_is_face(cval) && rb_respond_to(val, rb_intern("to_string")) ) {
|
|
1657
|
+
return ca_face_convert_store_rval(self, ca,
|
|
1658
|
+
rb_funcall(val, rb_intern("to_string"), 0));
|
|
1659
|
+
}
|
|
1660
|
+
if ( ! ca_is_face(cval) && cval->data_type == CA_OBJECT ) {
|
|
1661
|
+
return ca_face_convert_store_rval(self, ca,
|
|
1662
|
+
rb_funcall(rb_obj_class(self), rb_intern("wrap"), 1, val));
|
|
1663
|
+
}
|
|
1664
|
+
return ca_face_convert_store_rval(self, ca,
|
|
1665
|
+
rb_funcall(val, rb_intern("to_a"), 0));
|
|
1666
|
+
}
|
|
1595
1667
|
/* Face RHS: reconcile to self's unit and descend to storage. Mirror of
|
|
1596
1668
|
the scalar path (ca_face_element_to_storage) for a bulk CArray source.
|
|
1597
1669
|
Guarded on self having to_comparable so a Face without a reconcile
|
|
@@ -1610,11 +1682,17 @@ ca_face_convert_store_rval (VALUE self, CArray *ca, VALUE val)
|
|
|
1610
1682
|
{
|
|
1611
1683
|
CArray *storage = ca_strip_face(ca);
|
|
1612
1684
|
if ( storage && ca_is_integer_type(storage) && ! ca_is_integer_type(cval) ) {
|
|
1685
|
+
const char *method = ca_face_storage_method(self);
|
|
1686
|
+
if ( method ) {
|
|
1687
|
+
rb_raise(rb_eTypeError,
|
|
1688
|
+
"%s cannot store a bare %s array as raw storage "
|
|
1689
|
+
"(write the %s storage, which #%s gives, directly)",
|
|
1690
|
+
rb_obj_classname(self), ca_type_name[cval->data_type],
|
|
1691
|
+
ca_type_name[storage->data_type], method);
|
|
1692
|
+
}
|
|
1613
1693
|
rb_raise(rb_eTypeError,
|
|
1614
|
-
"%s cannot store a bare %s array as raw storage
|
|
1615
|
-
|
|
1616
|
-
rb_obj_classname(self), ca_type_name[cval->data_type],
|
|
1617
|
-
ca_type_name[storage->data_type]);
|
|
1694
|
+
"%s cannot store a bare %s array as raw storage",
|
|
1695
|
+
rb_obj_classname(self), ca_type_name[cval->data_type]);
|
|
1618
1696
|
}
|
|
1619
1697
|
}
|
|
1620
1698
|
return val;
|
|
@@ -1676,7 +1754,7 @@ rb_ca_store_method (int argc, VALUE *argv, VALUE self)
|
|
|
1676
1754
|
/* newaxis (:_) interception on store. Build the newaxis view (a
|
|
1677
1755
|
writable reshape aliasing self), then assign rval into the whole view
|
|
1678
1756
|
(writes propagate to self). */
|
|
1679
|
-
if ( ca_argv_has_newaxis(argc, argv) ) {
|
|
1757
|
+
if ( ! ca_argv_is_method_call(argc, argv) && ca_argv_has_newaxis(argc, argv) ) {
|
|
1680
1758
|
volatile VALUE view = rb_ca_fetch_newaxis(argc, argv, self, ca);
|
|
1681
1759
|
rb_ca_store_all(view, rval);
|
|
1682
1760
|
return rval;
|
|
@@ -1685,7 +1763,7 @@ rb_ca_store_method (int argc, VALUE *argv, VALUE self)
|
|
|
1685
1763
|
/* slab sigil on store is rejected regardless of outer-slot type. Catch
|
|
1686
1764
|
:> before scan_index so mask/fancy outer slots get the same "not
|
|
1687
1765
|
supported" message instead of a misleading TypeError. */
|
|
1688
|
-
if ( ca_argv_has_slab_sigil(argc, argv) ) {
|
|
1766
|
+
if ( ! ca_argv_is_method_call(argc, argv) && ca_argv_has_slab_sigil(argc, argv) ) {
|
|
1689
1767
|
rb_raise(rb_eIndexError,
|
|
1690
1768
|
"assignment through a slab iterator (:>) is not supported "
|
|
1691
1769
|
"(use a block index, e.g. ca[range, nil] = val, or each_slab)");
|
|
@@ -1704,6 +1782,16 @@ rb_ca_store_method (int argc, VALUE *argv, VALUE self)
|
|
|
1704
1782
|
dest = rb_ca_strip_face_value(self);
|
|
1705
1783
|
}
|
|
1706
1784
|
|
|
1785
|
+
/* One cell of a CAString holds a String. Stored into the object storage,
|
|
1786
|
+
a Ruby Array would become the cell's value, which a plain object array
|
|
1787
|
+
allows. */
|
|
1788
|
+
if ( ca->obj_type == CA_OBJ_STRING && TYPE(rval) == T_ARRAY &&
|
|
1789
|
+
( info.type == CA_REG_ADDRESS || info.type == CA_REG_POINT ) ) {
|
|
1790
|
+
rb_raise(rb_eTypeError,
|
|
1791
|
+
"%s: an Array is not a String (one cell of a CAString holds "
|
|
1792
|
+
"a String; UNDEF masks a cell)", ca_calling_method_name());
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1707
1795
|
switch ( info.type ) {
|
|
1708
1796
|
case CA_REG_ADDRESS_COMPLEX:
|
|
1709
1797
|
self = rb_ca_refer_new_flatten(self);
|
|
@@ -1755,15 +1843,12 @@ rb_ca_store_method (int argc, VALUE *argv, VALUE self)
|
|
|
1755
1843
|
break;
|
|
1756
1844
|
}
|
|
1757
1845
|
case CA_REG_METHOD_CALL: {
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
c.argv = argv+1;
|
|
1765
|
-
c.rval = rval;
|
|
1766
|
-
obj = ca_attach_window(1, &ca, "r", ca_store_method_call_body, (VALUE) &c);
|
|
1846
|
+
/* a[:eq, 0] = v is a[a.eq(0)] = v: the index is computed first and the
|
|
1847
|
+
store then goes through it, as the read does -- only the cells it
|
|
1848
|
+
picks are written. */
|
|
1849
|
+
volatile VALUE idx;
|
|
1850
|
+
idx = rb_funcallv_public(self, SYM2ID(info.symbol), argc-1, argv+1);
|
|
1851
|
+
obj = rb_ca_store(dest, idx, rval);
|
|
1767
1852
|
break;
|
|
1768
1853
|
}
|
|
1769
1854
|
case CA_REG_MEMBER: {
|
|
@@ -1778,11 +1863,6 @@ rb_ca_store_method (int argc, VALUE *argv, VALUE self)
|
|
|
1778
1863
|
}
|
|
1779
1864
|
break;
|
|
1780
1865
|
}
|
|
1781
|
-
case CA_REG_ATTRIBUTE: {
|
|
1782
|
-
obj = rb_funcall(self, rb_intern("attribute"), 0);
|
|
1783
|
-
obj = rb_hash_aset(obj, info.symbol, rval);
|
|
1784
|
-
break;
|
|
1785
|
-
}
|
|
1786
1866
|
}
|
|
1787
1867
|
|
|
1788
1868
|
return obj;
|
|
@@ -1812,7 +1892,9 @@ rb_ca_store (VALUE self, VALUE index, VALUE rval)
|
|
|
1812
1892
|
case T_ARRAY:
|
|
1813
1893
|
index = rb_obj_clone(index);
|
|
1814
1894
|
rb_ary_push(index, rval);
|
|
1815
|
-
|
|
1895
|
+
rval = rb_ca_store_method((int)RARRAY_LEN(index), (VALUE *)RARRAY_CONST_PTR(index), self);
|
|
1896
|
+
RB_GC_GUARD(index); /* the store reads its arguments out of index */
|
|
1897
|
+
return rval;
|
|
1816
1898
|
default: {
|
|
1817
1899
|
VALUE rindex[2] = { index, rval };
|
|
1818
1900
|
return rb_ca_store_method(2, rindex, self);
|
|
@@ -1825,7 +1907,9 @@ rb_ca_store2 (VALUE self, int n, VALUE *rindex, VALUE rval)
|
|
|
1825
1907
|
{
|
|
1826
1908
|
volatile VALUE index = rb_ary_new4(n, rindex);
|
|
1827
1909
|
rb_ary_push(index, rval);
|
|
1828
|
-
|
|
1910
|
+
rval = rb_ca_store_method((int)RARRAY_LEN(index), (VALUE *)RARRAY_CONST_PTR(index), self);
|
|
1911
|
+
RB_GC_GUARD(index); /* the store reads its arguments out of index */
|
|
1912
|
+
return rval;
|
|
1829
1913
|
}
|
|
1830
1914
|
|
|
1831
1915
|
static VALUE
|
|
@@ -1842,11 +1926,11 @@ rb_ca_s_scan_index (VALUE self, VALUE rdim, VALUE ridx)
|
|
|
1842
1926
|
Check_Type(ridx, T_ARRAY);
|
|
1843
1927
|
|
|
1844
1928
|
ndim = (int) RARRAY_LEN(rdim);
|
|
1845
|
-
|
|
1929
|
+
CA_CHECK_RANK_GIVEN(ndim);
|
|
1846
1930
|
for (i=0; i<ndim; i++) {
|
|
1847
1931
|
dim[i] = NUM2SIZE(rb_ary_entry(rdim, i));
|
|
1848
1932
|
}
|
|
1849
|
-
|
|
1933
|
+
CA_CHECK_DIM_GIVEN(ndim, dim);
|
|
1850
1934
|
elements = ca_shape_elements(ndim, dim, 1);
|
|
1851
1935
|
|
|
1852
1936
|
info.range_check = 1;
|
|
@@ -1919,8 +2003,7 @@ rb_ca_s_scan_index (VALUE self, VALUE rdim, VALUE ridx)
|
|
|
1919
2003
|
case CA_REG_GRID:
|
|
1920
2004
|
case CA_REG_MAPPING:
|
|
1921
2005
|
case CA_REG_METHOD_CALL:
|
|
1922
|
-
case CA_REG_MEMBER:
|
|
1923
|
-
case CA_REG_ATTRIBUTE:
|
|
2006
|
+
case CA_REG_MEMBER:
|
|
1924
2007
|
break;
|
|
1925
2008
|
default:
|
|
1926
2009
|
rb_raise(rb_eArgError, "unknown index specification");
|
|
@@ -2016,10 +2099,11 @@ parse_shape_kwarg (VALUE rshape, int *out_ndim, ca_size_t *dim,
|
|
|
2016
2099
|
|
|
2017
2100
|
Check_Type(rshape, T_ARRAY);
|
|
2018
2101
|
ndim = (int) RARRAY_LEN(rshape);
|
|
2019
|
-
if ( ndim < 1
|
|
2102
|
+
if ( ndim < 1 ) {
|
|
2020
2103
|
rb_raise(rb_eArgError, "invalid shape ndim %d (must be 1..%d)",
|
|
2021
2104
|
ndim, CA_RANK_MAX);
|
|
2022
2105
|
}
|
|
2106
|
+
ca_check_rank_fits(ndim, NULL);
|
|
2023
2107
|
for (i = 0; i < ndim; i++) {
|
|
2024
2108
|
dim[i] = NUM2SIZE(rb_ary_entry(rshape, i));
|
|
2025
2109
|
if ( dim[i] < 0 ) {
|
|
@@ -2103,6 +2187,7 @@ addr2index_do (int ndim, ca_size_t *dim, ca_size_t elements, VALUE raddr)
|
|
|
2103
2187
|
}
|
|
2104
2188
|
|
|
2105
2189
|
ca_detach(cin);
|
|
2190
|
+
RB_GC_GUARD(raddr); /* the CA_SIZE view is reached only through cin */
|
|
2106
2191
|
return out;
|
|
2107
2192
|
}
|
|
2108
2193
|
}
|
|
@@ -2306,7 +2391,7 @@ rb_ca_s_addr2index (int argc, VALUE *argv, VALUE klass)
|
|
|
2306
2391
|
static VALUE
|
|
2307
2392
|
rb_ca_s_index2addr (int argc, VALUE *argv, VALUE klass)
|
|
2308
2393
|
{
|
|
2309
|
-
VALUE rest, opts;
|
|
2394
|
+
VALUE rest, opts, out;
|
|
2310
2395
|
ID kw_ids[1];
|
|
2311
2396
|
VALUE kw_vals[1];
|
|
2312
2397
|
int ndim;
|
|
@@ -2320,7 +2405,10 @@ rb_ca_s_index2addr (int argc, VALUE *argv, VALUE klass)
|
|
|
2320
2405
|
}
|
|
2321
2406
|
rb_get_kwargs(opts, kw_ids, 1, 0, kw_vals);
|
|
2322
2407
|
parse_shape_kwarg(kw_vals[0], &ndim, dim, &elements);
|
|
2323
|
-
|
|
2408
|
+
/* index2addr_do reads, and replaces, its arguments in rest */
|
|
2409
|
+
out = index2addr_do(ndim, dim, (int) RARRAY_LEN(rest), RARRAY_PTR(rest));
|
|
2410
|
+
RB_GC_GUARD(rest);
|
|
2411
|
+
return out;
|
|
2324
2412
|
}
|
|
2325
2413
|
|
|
2326
2414
|
|