carray 3.0.2 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +568 -0
- data/README.md +6 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +220 -0
- data/ext/ca_axis_group.c +201 -123
- data/ext/ca_binop_dispatch.c +46 -52
- data/ext/ca_binop_dispatch.h +1 -1
- data/ext/ca_categorical_iterator.c +249 -183
- data/ext/ca_compare.c +7 -12
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +38 -23
- data/ext/ca_kernel_iterator.c +1765 -2076
- data/ext/ca_kernel_iterator.h +584 -566
- data/ext/ca_monop_dispatch.c +86 -63
- data/ext/ca_monop_dispatch.h +5 -0
- data/ext/ca_obj_array.c +223 -56
- data/ext/ca_obj_bincmp.c +172 -138
- data/ext/ca_obj_binop.c +116 -230
- data/ext/ca_obj_bitarray.c +40 -26
- data/ext/ca_obj_bitfield.c +100 -68
- data/ext/ca_obj_block.c +19 -9
- data/ext/ca_obj_byte_swap.c +45 -46
- data/ext/ca_obj_const_string.c +269 -44
- data/ext/ca_obj_face.c +612 -89
- data/ext/ca_obj_face.h +111 -47
- data/ext/ca_obj_fake.c +36 -79
- data/ext/ca_obj_farray.c +7 -3
- data/ext/ca_obj_field.c +33 -8
- data/ext/ca_obj_fixlen_string.c +23 -24
- data/ext/ca_obj_grid.c +541 -210
- data/ext/ca_obj_meld.c +331 -111
- data/ext/ca_obj_moncmp.c +80 -65
- data/ext/ca_obj_monop.c +177 -149
- data/ext/ca_obj_object.c +664 -248
- data/ext/ca_obj_record.c +63 -23
- data/ext/ca_obj_reduce.c +18 -16
- data/ext/ca_obj_refer.c +140 -58
- data/ext/ca_obj_remap.c +85 -24
- data/ext/ca_obj_repeat.c +24 -9
- data/ext/ca_obj_roll.c +121 -16
- data/ext/ca_obj_select.c +61 -58
- data/ext/ca_obj_select_axis.c +73 -107
- data/ext/ca_obj_shift.c +32 -102
- data/ext/ca_obj_stack.c +372 -122
- data/ext/ca_obj_stride.c +348 -140
- data/ext/ca_obj_string.c +88 -22
- data/ext/ca_obj_tile.c +38 -21
- data/ext/ca_obj_time.c +45 -31
- data/ext/ca_obj_timedelta.c +43 -29
- data/ext/ca_obj_transpose.c +17 -6
- data/ext/ca_obj_triop.c +125 -141
- data/ext/ca_obj_window.c +330 -44
- data/ext/ca_op_ipower.c +24 -11
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +104 -81
- data/ext/ca_sweep_engine.h +7 -20
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +542 -0
- data/ext/carray.h +241 -92
- data/ext/carray_access.c +608 -276
- data/ext/carray_address_basis.c +494 -97
- data/ext/carray_attribute.c +129 -4
- data/ext/carray_bincount.c +39 -7
- data/ext/carray_broadcast.c +56 -19
- data/ext/carray_build_flags.h +1 -1
- data/ext/carray_call_cfunc.c +108 -28
- data/ext/carray_cast.c +1576 -223
- data/ext/carray_cast_func.rb +77 -24
- data/ext/carray_class.c +4 -3
- data/ext/carray_conversion.c +208 -75
- data/ext/carray_copy.c +82 -24
- data/ext/carray_core.c +646 -162
- data/ext/carray_count.c +171 -88
- data/ext/carray_element.c +94 -60
- data/ext/carray_factorize.c +670 -324
- data/ext/carray_generate.c +260 -83
- data/ext/carray_histogram.c +209 -106
- data/ext/carray_hold.c +14 -16
- data/ext/carray_index_classifier.c +422 -243
- data/ext/carray_internal.h +692 -3
- data/ext/carray_kernels_bincmp.c +7 -0
- data/ext/carray_kernels_binop.c +487 -120
- data/ext/carray_kernels_init.c +653 -50
- data/ext/carray_kernels_moncmp.c +15 -8
- data/ext/carray_kernels_monop.c +99 -43
- data/ext/carray_kernels_reduce_aggregate.c +3925 -6112
- data/ext/carray_kernels_reduce_boolean.c +112 -36
- data/ext/carray_kernels_reduce_cumulative.c +2127 -6903
- data/ext/carray_kernels_reduce_extreme.c +3032 -2892
- data/ext/carray_kernels_reduce_variance.c +439 -500
- data/ext/carray_kernels_scan.c +1097 -488
- data/ext/carray_kernels_search.c +3787 -2176
- data/ext/carray_kernels_sort.c +1200 -920
- data/ext/carray_kernels_triop.c +479 -7
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +967 -153
- data/ext/carray_loop.c +81 -65
- data/ext/carray_mask.c +910 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +299 -100
- data/ext/carray_memory_view.c +872 -758
- data/ext/carray_operator.c +1171 -364
- data/ext/carray_order.c +505 -133
- data/ext/carray_partition.c +112 -65
- data/ext/carray_random.c +327 -239
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +346 -78
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +249 -86
- data/ext/carray_sort.c +224 -227
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +118 -39
- data/ext/carray_test.c +193 -69
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +579 -113
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +19 -4
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1202 -1014
- data/ext/ruby_carray.c +17 -5
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +160 -17
- data/lib/carray/autoload_carray.rb +23 -27
- data/lib/carray/autoload_method_extension.rb +20 -5
- data/lib/carray/axis_group.rb +360 -63
- data/lib/carray/basics.rb +162 -28
- data/lib/carray/bincount_nd.rb +18 -2
- data/lib/carray/block_iterator.rb +231 -58
- data/lib/carray/boolean_reduce.rb +34 -42
- data/lib/carray/categorical.rb +242 -52
- data/lib/carray/categorical_iterator.rb +437 -827
- data/lib/carray/complex.rb +41 -34
- data/lib/carray/conditional.rb +150 -14
- data/lib/carray/const_string.rb +59 -4
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +7 -1
- data/lib/carray/frame/column_verbs.rb +70 -0
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +82 -7
- data/lib/carray/frame/csv_parser.rb +688 -87
- data/lib/carray/frame/describe.rb +80 -0
- data/lib/carray/frame/frame.rb +369 -45
- data/lib/carray/frame/group.rb +631 -90
- data/lib/carray/frame/io.rb +506 -79
- data/lib/carray/frame/join.rb +411 -62
- data/lib/carray/frame/records.rb +116 -19
- data/lib/carray/frame/reshape.rb +455 -0
- data/lib/carray/frame/sort.rb +30 -18
- data/lib/carray/frame/verbs.rb +868 -61
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +4 -0
- data/lib/carray/fuse_source.rb +118 -2
- data/lib/carray/fusion.rb +257 -42
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +54 -13
- data/lib/carray/iterator.rb +99 -9
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +216 -193
- data/lib/carray/mask_gap_fill.rb +112 -92
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +52 -21
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +18 -2
- data/lib/carray/methods/bit_string.rb +15 -4
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +18 -10
- data/lib/carray/methods/factorize.rb +2 -2
- data/lib/carray/methods/gather_nd.rb +25 -5
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +140 -10
- data/lib/carray/methods/join.rb +2 -7
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +182 -45
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/repeat.rb +1 -20
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +11 -2
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +65 -17
- data/lib/carray/segment_iterator.rb +1221 -0
- data/lib/carray/serialize.rb +214 -30
- data/lib/carray/slab_iterator.rb +101 -27
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +12 -4
- data/lib/carray/struct.rb +137 -58
- data/lib/carray/struct_builder.rb +124 -17
- data/lib/carray/time.rb +1222 -186
- data/lib/carray/window_iterator.rb +242 -81
- data/lib/carray.rb +9 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +5 -1
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +5 -4
- data/yard-stubs/ca_obj_roll.rb +2 -3
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +9 -5
- data/yard-stubs/carray_access.rb +11 -5
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_broadcast.rb +1 -1
- data/yard-stubs/carray_cast.rb +88 -43
- data/yard-stubs/carray_conversion.rb +15 -2
- data/yard-stubs/carray_copy.rb +12 -5
- data/yard-stubs/carray_core.rb +3 -3
- data/yard-stubs/carray_count.rb +9 -0
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_lazy.rb +5 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +60 -12
- data/yard-stubs/carray_math.rb +52 -14
- data/yard-stubs/carray_median_percentile.rb +15 -8
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +61 -29
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +21 -9
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +10 -2
- data/yard-stubs/carray_sort.rb +49 -8
- data/yard-stubs/carray_test.rb +15 -3
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -5
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_kernels_map.c +0 -3467
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/carray_generate.c
CHANGED
|
@@ -9,13 +9,16 @@
|
|
|
9
9
|
|
|
10
10
|
#include "ruby.h"
|
|
11
11
|
#include "carray.h"
|
|
12
|
+
#include "carray_internal.h" /* ca_attach_window, ca_normalize_axis_arg */
|
|
13
|
+
#include "ca_obj_face.h" /* ca_face_element_to_storage */
|
|
12
14
|
|
|
13
15
|
/* ----------------------------------------------------------------- */
|
|
14
16
|
|
|
15
17
|
/* CArray#where -- collect the flat addresses of all non-zero (or
|
|
16
|
-
true) cells in self into a fresh 1-D CA_SIZE array.
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
true) cells in self into a fresh 1-D CA_SIZE array. An integer,
|
|
19
|
+
float or complex array selects its non-zero cells (NaN is non-zero);
|
|
20
|
+
any other non-boolean array is cast to boolean, which takes only
|
|
21
|
+
0 / 1 / true / false. Masked cells are excluded.
|
|
19
22
|
|
|
20
23
|
Also used internally by ext/ca_obj_grid.c when it needs to extract
|
|
21
24
|
the addresses of true cells from a boolean axis selector. */
|
|
@@ -26,28 +29,44 @@ rb_ca_where (VALUE self)
|
|
|
26
29
|
CArray *ca, *co;
|
|
27
30
|
boolean8_t *p, *m;
|
|
28
31
|
ca_size_t *q;
|
|
29
|
-
ca_size_t i, count;
|
|
32
|
+
ca_size_t i, j, n, last, count;
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
35
|
+
if ( ca_is_boolean_type(ca) ) {
|
|
36
|
+
bool0 = self;
|
|
37
|
+
}
|
|
38
|
+
else if ( ! ca_is_face(ca) &&
|
|
39
|
+
( ca_is_integer_type(ca) || ca_is_float_type(ca) ||
|
|
40
|
+
ca_is_complex_type(ca) ) ) {
|
|
41
|
+
bool0 = rb_funcall(self, rb_intern("ne"), 1, INT2FIX(0));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
bool0 = rb_ca_to_boolean(self);
|
|
45
|
+
}
|
|
32
46
|
|
|
33
47
|
TypedData_Get_Struct(bool0, CArray, &carray_data_type, ca);
|
|
34
48
|
|
|
35
|
-
ca_attach(ca);
|
|
49
|
+
ca_attach(ca); /* window: nothing raises inside */
|
|
36
50
|
|
|
37
|
-
/* calculate elements of output array */
|
|
51
|
+
/* calculate elements of output array, and the last selected cell */
|
|
38
52
|
p = (boolean8_t *) ca->ptr;
|
|
39
53
|
m = ca_mask_ptr(ca);
|
|
54
|
+
n = ca->elements;
|
|
40
55
|
count = 0;
|
|
41
56
|
if ( m ) {
|
|
42
|
-
for (i=0; i<
|
|
43
|
-
|
|
44
|
-
m++; p++;
|
|
57
|
+
for (i=0; i<n; i++) {
|
|
58
|
+
count += ( ! m[i] ) & ( p[i] != 0 ); /* not-masked && true */
|
|
45
59
|
}
|
|
46
60
|
}
|
|
47
61
|
else {
|
|
48
|
-
for (i=0; i<
|
|
49
|
-
|
|
50
|
-
|
|
62
|
+
for (i=0; i<n; i++) {
|
|
63
|
+
count += ( p[i] != 0 ); /* true */
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
last = n - 1;
|
|
67
|
+
if ( count > 0 ) {
|
|
68
|
+
while ( m ? ( m[last] || ! p[last] ) : ! p[last] ) {
|
|
69
|
+
last--;
|
|
51
70
|
}
|
|
52
71
|
}
|
|
53
72
|
|
|
@@ -55,20 +74,25 @@ rb_ca_where (VALUE self)
|
|
|
55
74
|
obj = rb_carray_new(CA_SIZE, 1, &count, 0, NULL);
|
|
56
75
|
TypedData_Get_Struct(obj, CArray, &carray_data_type, co);
|
|
57
76
|
|
|
58
|
-
/*
|
|
59
|
-
|
|
77
|
+
/* Store the address of each selected cell. Every cell up to the last
|
|
78
|
+
selected one is written and the output position advances only on a
|
|
79
|
+
selected cell, so a selection with true and false mixed at random
|
|
80
|
+
does not mispredict a branch on most cells. Stopping at the last
|
|
81
|
+
selected cell keeps the writes inside the count slots. */
|
|
60
82
|
q = (ca_size_t *) co->ptr;
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
83
|
+
j = 0;
|
|
84
|
+
if ( count > 0 ) {
|
|
85
|
+
if ( m ) {
|
|
86
|
+
for (i=0; i<=last; i++) { /* not-masked && true */
|
|
87
|
+
q[j] = i;
|
|
88
|
+
j += ( ! m[i] ) & ( p[i] != 0 );
|
|
89
|
+
}
|
|
66
90
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
91
|
+
else { /* true */
|
|
92
|
+
for (i=0; i<=last; i++) {
|
|
93
|
+
q[j] = i;
|
|
94
|
+
j += ( p[i] != 0 );
|
|
95
|
+
}
|
|
72
96
|
}
|
|
73
97
|
}
|
|
74
98
|
|
|
@@ -79,6 +103,17 @@ rb_ca_where (VALUE self)
|
|
|
79
103
|
|
|
80
104
|
/* ----------------------------------------------------------------- */
|
|
81
105
|
|
|
106
|
+
/* A number that is not an Integer (a Float, a Rational, a BigDecimal) makes
|
|
107
|
+
the progression a real one: every cell is offset + step*i computed in
|
|
108
|
+
double, and an integer array takes it as a store takes a float (cut
|
|
109
|
+
toward zero; the run is checked to fit before anything is written). */
|
|
110
|
+
static int
|
|
111
|
+
ca_seq_is_real (VALUE v)
|
|
112
|
+
{
|
|
113
|
+
return ! NIL_P(v) && ! RB_INTEGER_TYPE_P(v) && ! RB_TYPE_P(v, T_COMPLEX)
|
|
114
|
+
&& RTEST(rb_obj_is_kind_of(v, rb_cNumeric));
|
|
115
|
+
}
|
|
116
|
+
|
|
82
117
|
/* Fill the whole array in row-major order with `step*i + offset`. */
|
|
83
118
|
#define proc_seq_bang(type, from, to) \
|
|
84
119
|
{ \
|
|
@@ -89,9 +124,8 @@ rb_ca_where (VALUE self)
|
|
|
89
124
|
*p++ = (type) to(i); \
|
|
90
125
|
} \
|
|
91
126
|
} \
|
|
92
|
-
else if (
|
|
93
|
-
|
|
94
|
-
type offset = (NIL_P(roffset)) ? (type) 0 : (type) from(roffset); \
|
|
127
|
+
else if ( ca_seq_is_real(rstep) || ca_seq_is_real(roffset) ) { \
|
|
128
|
+
double offset = (NIL_P(roffset)) ? 0 : NUM2DBL(roffset); \
|
|
95
129
|
double step = (NIL_P(rstep)) ? 1 : NUM2DBL(rstep); \
|
|
96
130
|
for (i=0; i<ca->elements; i++) { \
|
|
97
131
|
*p++ = (type) to(step*i+offset); \
|
|
@@ -117,9 +151,8 @@ rb_ca_where (VALUE self)
|
|
|
117
151
|
{ \
|
|
118
152
|
type *p = (type *)ca->ptr; \
|
|
119
153
|
ca_size_t o, k, in; \
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
type offset = (NIL_P(roffset)) ? (type) 0 : (type) from(roffset); \
|
|
154
|
+
if ( ca_seq_is_real(rstep) || ca_seq_is_real(roffset) ) { \
|
|
155
|
+
double offset = (NIL_P(roffset)) ? 0 : NUM2DBL(roffset); \
|
|
123
156
|
double step = (NIL_P(rstep)) ? 1 : NUM2DBL(rstep); \
|
|
124
157
|
for (o=0; o<outer_size; o++) { \
|
|
125
158
|
for (k=0; k<len; k++) { \
|
|
@@ -179,16 +212,10 @@ ca_seq_resolve_axis (CArray *ca, VALUE raxis)
|
|
|
179
212
|
}
|
|
180
213
|
if ( TYPE(raxis) == T_ARRAY ) {
|
|
181
214
|
rb_raise(rb_eArgError,
|
|
182
|
-
"
|
|
183
|
-
|
|
184
|
-
axis = NUM2INT(raxis);
|
|
185
|
-
if ( axis < 0 ) {
|
|
186
|
-
axis += ca->ndim;
|
|
187
|
-
}
|
|
188
|
-
if ( axis < 0 || axis >= ca->ndim ) {
|
|
189
|
-
rb_raise(rb_eArgError,
|
|
190
|
-
"axis out of range for seq (0...%d)", ca->ndim);
|
|
215
|
+
"%s: axis must be a single Integer (a seq over several axes is not supported)",
|
|
216
|
+
ca_calling_method_name());
|
|
191
217
|
}
|
|
218
|
+
axis = ca_normalize_axis_arg(raxis, ca->ndim, NULL);
|
|
192
219
|
return axis;
|
|
193
220
|
}
|
|
194
221
|
|
|
@@ -208,27 +235,39 @@ ca_seq_geometry (CArray *ca, int axis,
|
|
|
208
235
|
*outer = out;
|
|
209
236
|
}
|
|
210
237
|
|
|
238
|
+
/* The object fill calls Ruby per cell (`+`, or the method given as the
|
|
239
|
+
step), which can raise part way, so it runs in a window that attaches:
|
|
240
|
+
the cells filled before the raise then reach the parent with the rest
|
|
241
|
+
left as they were, as they would for an entity. */
|
|
242
|
+
|
|
243
|
+
typedef struct {
|
|
244
|
+
VALUE self;
|
|
245
|
+
CArray *ca;
|
|
246
|
+
VALUE roffset;
|
|
247
|
+
VALUE rstep;
|
|
248
|
+
VALUE rmethod;
|
|
249
|
+
int axis;
|
|
250
|
+
} ca_seq_ctx_t;
|
|
251
|
+
|
|
252
|
+
/* A value of the progression as it goes into a cell: a Face receiver (a
|
|
253
|
+
CAString) checks it as it checks any value stored into it. */
|
|
211
254
|
static VALUE
|
|
212
|
-
|
|
255
|
+
ca_seq_cell (ca_seq_ctx_t *c, VALUE v)
|
|
213
256
|
{
|
|
214
|
-
|
|
215
|
-
|
|
257
|
+
return ca_face_element_to_storage(c->self, c->ca, v);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
static VALUE
|
|
261
|
+
ca_seq_bang_object_body (VALUE arg)
|
|
262
|
+
{
|
|
263
|
+
ca_seq_ctx_t *c = (ca_seq_ctx_t *) arg;
|
|
264
|
+
CArray *ca = c->ca;
|
|
265
|
+
volatile VALUE rval;
|
|
266
|
+
VALUE roffset = c->roffset, rstep = c->rstep, rmethod = c->rmethod;
|
|
267
|
+
int axis = c->axis;
|
|
216
268
|
VALUE *p;
|
|
217
269
|
ca_size_t i;
|
|
218
270
|
|
|
219
|
-
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
220
|
-
|
|
221
|
-
if ( TYPE(rstep) == T_SYMBOL ) { /* e.g. a.seq("a", :succ) */
|
|
222
|
-
rmethod = rstep;
|
|
223
|
-
rstep = Qnil;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
ca_allocate(ca);
|
|
227
|
-
|
|
228
|
-
if ( ca_has_mask(ca) ) {
|
|
229
|
-
ca_clear_mask(ca); /* clear all mask */
|
|
230
|
-
}
|
|
231
|
-
|
|
232
271
|
if ( axis < 0 ) { /* flat fill */
|
|
233
272
|
p = (VALUE *)ca->ptr;
|
|
234
273
|
if ( rb_obj_is_kind_of(roffset, rb_cFloat) ||
|
|
@@ -236,7 +275,7 @@ rb_ca_seq_bang_object (VALUE self, VALUE roffset, VALUE rstep, int axis)
|
|
|
236
275
|
double offset = ( NIL_P(roffset) ) ? 0 : NUM2DBL(roffset);
|
|
237
276
|
double step = ( NIL_P(rstep) ) ? 1 : NUM2DBL(rstep);
|
|
238
277
|
for (i=0; i<ca->elements; i++) {
|
|
239
|
-
*p++ = rb_float_new(step*i+offset);
|
|
278
|
+
*p++ = ca_seq_cell(c, rb_float_new(step*i+offset));
|
|
240
279
|
}
|
|
241
280
|
}
|
|
242
281
|
else if ( NIL_P(roffset) ) {
|
|
@@ -245,22 +284,22 @@ rb_ca_seq_bang_object (VALUE self, VALUE roffset, VALUE rstep, int axis)
|
|
|
245
284
|
"nil is invalid as offset for seq([offset[,step])");
|
|
246
285
|
}
|
|
247
286
|
for (i=0; i<ca->elements; i++) { /* a.seq() */
|
|
248
|
-
*p++ = LL2NUM(i);
|
|
287
|
+
*p++ = ca_seq_cell(c, LL2NUM(i));
|
|
249
288
|
}
|
|
250
289
|
}
|
|
251
290
|
else if ( ! NIL_P(rmethod) ) { /* a.seq(obj, :method) */
|
|
252
291
|
ID id_method = SYM2ID(rmethod);
|
|
253
|
-
*p++ = rval = roffset;
|
|
292
|
+
*p++ = ca_seq_cell(c, rval = roffset);
|
|
254
293
|
for (i=1; i<ca->elements; i++) {
|
|
255
|
-
*p++ = rval = rb_funcall(rval, id_method, 0);
|
|
294
|
+
*p++ = ca_seq_cell(c, rval = rb_funcall(rval, id_method, 0));
|
|
256
295
|
}
|
|
257
296
|
}
|
|
258
297
|
else { /* a.seq(obj, step) */
|
|
259
298
|
ID id_plus = rb_intern("+");
|
|
260
299
|
rstep = ( NIL_P(rstep) ) ? INT2NUM(1) : rstep;
|
|
261
|
-
*p++ = rval = roffset;
|
|
300
|
+
*p++ = ca_seq_cell(c, rval = roffset);
|
|
262
301
|
for (i=1; i<ca->elements; i++) {
|
|
263
|
-
*p++ = rval = rb_funcall(rval, id_plus, 1, rstep);
|
|
302
|
+
*p++ = ca_seq_cell(c, rval = rb_funcall(rval, id_plus, 1, rstep));
|
|
264
303
|
}
|
|
265
304
|
}
|
|
266
305
|
}
|
|
@@ -278,7 +317,7 @@ rb_ca_seq_bang_object (VALUE self, VALUE roffset, VALUE rstep, int axis)
|
|
|
278
317
|
double offset = ( NIL_P(roffset) ) ? 0 : NUM2DBL(roffset);
|
|
279
318
|
double step = ( NIL_P(rstep) ) ? 1 : NUM2DBL(rstep);
|
|
280
319
|
for (k=0; k<len; k++) {
|
|
281
|
-
rb_ary_push(vtbl, rb_float_new(step*k+offset));
|
|
320
|
+
rb_ary_push(vtbl, ca_seq_cell(c, rb_float_new(step*k+offset)));
|
|
282
321
|
}
|
|
283
322
|
}
|
|
284
323
|
else if ( NIL_P(roffset) ) {
|
|
@@ -287,26 +326,26 @@ rb_ca_seq_bang_object (VALUE self, VALUE roffset, VALUE rstep, int axis)
|
|
|
287
326
|
"nil is invalid as offset for seq([offset[,step])");
|
|
288
327
|
}
|
|
289
328
|
for (k=0; k<len; k++) {
|
|
290
|
-
rb_ary_push(vtbl, LL2NUM(k));
|
|
329
|
+
rb_ary_push(vtbl, ca_seq_cell(c, LL2NUM(k)));
|
|
291
330
|
}
|
|
292
331
|
}
|
|
293
332
|
else if ( ! NIL_P(rmethod) ) {
|
|
294
333
|
ID id_method = SYM2ID(rmethod);
|
|
295
334
|
rval = roffset;
|
|
296
|
-
rb_ary_push(vtbl, rval);
|
|
335
|
+
rb_ary_push(vtbl, ca_seq_cell(c, rval));
|
|
297
336
|
for (k=1; k<len; k++) {
|
|
298
337
|
rval = rb_funcall(rval, id_method, 0);
|
|
299
|
-
rb_ary_push(vtbl, rval);
|
|
338
|
+
rb_ary_push(vtbl, ca_seq_cell(c, rval));
|
|
300
339
|
}
|
|
301
340
|
}
|
|
302
341
|
else {
|
|
303
342
|
ID id_plus = rb_intern("+");
|
|
304
343
|
rstep = ( NIL_P(rstep) ) ? INT2NUM(1) : rstep;
|
|
305
344
|
rval = roffset;
|
|
306
|
-
rb_ary_push(vtbl, rval);
|
|
345
|
+
rb_ary_push(vtbl, ca_seq_cell(c, rval));
|
|
307
346
|
for (k=1; k<len; k++) {
|
|
308
347
|
rval = rb_funcall(rval, id_plus, 1, rstep);
|
|
309
|
-
rb_ary_push(vtbl, rval);
|
|
348
|
+
rb_ary_push(vtbl, ca_seq_cell(c, rval));
|
|
310
349
|
}
|
|
311
350
|
}
|
|
312
351
|
p = (VALUE *)ca->ptr;
|
|
@@ -318,12 +357,130 @@ rb_ca_seq_bang_object (VALUE self, VALUE roffset, VALUE rstep, int axis)
|
|
|
318
357
|
}
|
|
319
358
|
}
|
|
320
359
|
|
|
321
|
-
|
|
322
|
-
|
|
360
|
+
/* Cleared last, so a fill that raises leaves the mask as it was. */
|
|
361
|
+
if ( ca_has_mask(ca) ) {
|
|
362
|
+
ca_clear_mask(ca);
|
|
363
|
+
}
|
|
364
|
+
return Qnil;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
static VALUE
|
|
368
|
+
rb_ca_seq_bang_object (VALUE self, VALUE roffset, VALUE rstep, int axis)
|
|
369
|
+
{
|
|
370
|
+
ca_seq_ctx_t c;
|
|
371
|
+
|
|
372
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, c.ca);
|
|
373
|
+
|
|
374
|
+
c.self = self;
|
|
375
|
+
c.rmethod = Qnil;
|
|
376
|
+
if ( TYPE(rstep) == T_SYMBOL ) { /* e.g. a.seq("a", :succ) */
|
|
377
|
+
c.rmethod = rstep;
|
|
378
|
+
rstep = Qnil;
|
|
379
|
+
}
|
|
380
|
+
c.roffset = roffset;
|
|
381
|
+
c.rstep = rstep;
|
|
382
|
+
c.axis = axis;
|
|
383
|
+
|
|
384
|
+
ca_attach_window(1, &c.ca, "w", ca_seq_bang_object_body, (VALUE) &c);
|
|
323
385
|
|
|
324
386
|
return self;
|
|
325
387
|
}
|
|
326
388
|
|
|
389
|
+
/* The numeric fill runs in an allocate window, which clears an entity's
|
|
390
|
+
mask as it opens (an entity has no separate buffer), so nothing in it may
|
|
391
|
+
raise: offset and step are checked to be numbers before it opens. */
|
|
392
|
+
static VALUE
|
|
393
|
+
ca_seq_bang_numeric_body (VALUE arg)
|
|
394
|
+
{
|
|
395
|
+
ca_seq_ctx_t *c = (ca_seq_ctx_t *) arg;
|
|
396
|
+
CArray *ca = c->ca;
|
|
397
|
+
VALUE roffset = c->roffset, rstep = c->rstep;
|
|
398
|
+
|
|
399
|
+
if ( ca_has_mask(ca) ) {
|
|
400
|
+
ca_clear_mask(ca); /* clear all mask */
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if ( c->axis < 0 ) {
|
|
404
|
+
seq_bang_switch(proc_seq_bang);
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
ca_size_t len, inner_size, outer_size;
|
|
408
|
+
ca_seq_geometry(ca, c->axis, &len, &inner_size, &outer_size);
|
|
409
|
+
seq_bang_switch(proc_seq_bang_axis);
|
|
410
|
+
}
|
|
411
|
+
return Qnil;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/* An integer array refuses a first value it cannot hold, as a store does,
|
|
415
|
+
and an Integer step whose size it cannot hold. An unsigned array takes
|
|
416
|
+
a negative step (a descending run). A run that passes the end of the
|
|
417
|
+
type wraps, as integer arithmetic does. */
|
|
418
|
+
static void
|
|
419
|
+
ca_seq_check_integer_args (CArray *ca, VALUE roffset, VALUE rstep)
|
|
420
|
+
{
|
|
421
|
+
int8_t dt = ca->data_type;
|
|
422
|
+
/* Only a number is checked here; anything else is left to the fill's
|
|
423
|
+
own conversion, which refuses it with TypeError. */
|
|
424
|
+
if ( RB_INTEGER_TYPE_P(roffset) || RB_FLOAT_TYPE_P(roffset) ) {
|
|
425
|
+
VALUE first = RB_INTEGER_TYPE_P(roffset) ? roffset : rb_Integer(roffset);
|
|
426
|
+
if ( ca_integer_range_side(first, dt) != 0 ) {
|
|
427
|
+
rb_raise(rb_eRangeError, "%s: first value %"PRIsVALUE" is out of range for %s",
|
|
428
|
+
ca_calling_method_name(), rb_inspect(roffset), ca_type_name[dt]);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if ( RB_INTEGER_TYPE_P(rstep) ) {
|
|
432
|
+
int is_unsigned = ( dt == CA_UINT8 || dt == CA_UINT16 ||
|
|
433
|
+
dt == CA_UINT32 || dt == CA_UINT64 );
|
|
434
|
+
VALUE size = rstep;
|
|
435
|
+
if ( is_unsigned && RTEST(rb_funcall(rstep, rb_intern("negative?"), 0)) ) {
|
|
436
|
+
size = rb_funcall(rstep, rb_intern("-@"), 0);
|
|
437
|
+
}
|
|
438
|
+
if ( ca_integer_range_side(size, dt) != 0 ) {
|
|
439
|
+
rb_raise(rb_eRangeError, "%s: step %"PRIsVALUE" is out of range for %s",
|
|
440
|
+
ca_calling_method_name(), rb_inspect(rstep), ca_type_name[dt]);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/* A real progression on an integer array: each cell takes offset + step*i
|
|
446
|
+
cut toward zero, as a store takes a float, so the first and the last
|
|
447
|
+
value (the extremes of a linear run) must fit the type, and NaN raises
|
|
448
|
+
as it does in a store. Checked before the fill writes anything. */
|
|
449
|
+
static void
|
|
450
|
+
ca_seq_check_real_run (CArray *ca, VALUE roffset, VALUE rstep, ca_size_t n)
|
|
451
|
+
{
|
|
452
|
+
int8_t dt = ca->data_type;
|
|
453
|
+
double offset = NIL_P(roffset) ? 0.0 : NUM2DBL(roffset);
|
|
454
|
+
double step = NIL_P(rstep) ? 1.0 : NUM2DBL(rstep);
|
|
455
|
+
double ends[2];
|
|
456
|
+
double lo, hi_excl;
|
|
457
|
+
int k;
|
|
458
|
+
if ( n == 0 ) return;
|
|
459
|
+
ends[0] = offset;
|
|
460
|
+
ends[1] = step * (double) (n - 1) + offset;
|
|
461
|
+
switch ( dt ) {
|
|
462
|
+
case CA_INT8: lo = INT8_MIN; hi_excl = (double) INT8_MAX + 1; break;
|
|
463
|
+
case CA_UINT8: lo = 0; hi_excl = (double) UINT8_MAX + 1; break;
|
|
464
|
+
case CA_INT16: lo = INT16_MIN; hi_excl = (double) INT16_MAX + 1; break;
|
|
465
|
+
case CA_UINT16: lo = 0; hi_excl = (double) UINT16_MAX + 1; break;
|
|
466
|
+
case CA_INT32: lo = INT32_MIN; hi_excl = (double) INT32_MAX + 1; break;
|
|
467
|
+
case CA_UINT32: lo = 0; hi_excl = (double) UINT32_MAX + 1; break;
|
|
468
|
+
case CA_INT64: lo = -ldexp(1.0, 63); hi_excl = ldexp(1.0, 63); break;
|
|
469
|
+
default: lo = 0; hi_excl = ldexp(1.0, 64); break;
|
|
470
|
+
}
|
|
471
|
+
for (k = 0; k < 2; k++) {
|
|
472
|
+
double t = trunc(ends[k]);
|
|
473
|
+
if ( isnan(ends[k]) || ( step != 0.0 && isnan(step) ) ) {
|
|
474
|
+
rb_raise(rb_eFloatDomainError, "%s: the run has NaN",
|
|
475
|
+
ca_calling_method_name());
|
|
476
|
+
}
|
|
477
|
+
if ( ! ( t >= lo && t < hi_excl ) ) {
|
|
478
|
+
rb_raise(rb_eRangeError, "%s: value %g is out of range for %s",
|
|
479
|
+
ca_calling_method_name(), ends[k], ca_type_name[dt]);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
327
484
|
/* CArray#seq!(init_val=0, step=1, axis: nil) -- arithmetic-progression
|
|
328
485
|
fill, in place. Without `axis:` the fill runs in row-major order
|
|
329
486
|
over the whole array; with `axis: k` the progression runs along axis
|
|
@@ -353,23 +510,43 @@ rb_ca_seq_bang_method (int argc, VALUE *argv, VALUE self)
|
|
|
353
510
|
return rb_ca_seq_bang_object(self, roffset, rstep, axis);
|
|
354
511
|
}
|
|
355
512
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
513
|
+
{
|
|
514
|
+
VALUE args[2];
|
|
515
|
+
const char *names[2] = { "offset", "step" };
|
|
516
|
+
int k;
|
|
517
|
+
args[0] = roffset;
|
|
518
|
+
args[1] = rstep;
|
|
519
|
+
for (k = 0; k < 2; k++) {
|
|
520
|
+
VALUE v = args[k];
|
|
521
|
+
if ( NIL_P(v) ) continue;
|
|
522
|
+
if ( ! RTEST(rb_obj_is_kind_of(v, rb_cNumeric)) ||
|
|
523
|
+
( RB_TYPE_P(v, T_COMPLEX) && ! ca_is_complex_type(ca) ) ) {
|
|
524
|
+
rb_raise(rb_eTypeError, "%s: %s must be a %snumber (got %"PRIsVALUE")",
|
|
525
|
+
ca_calling_method_name(), names[k],
|
|
526
|
+
ca_is_complex_type(ca) ? "" : "real ", rb_inspect(v));
|
|
527
|
+
}
|
|
528
|
+
}
|
|
360
529
|
}
|
|
361
530
|
|
|
362
|
-
if (
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
531
|
+
if ( ca_is_integer_type(ca) ) {
|
|
532
|
+
if ( ca_seq_is_real(roffset) || ca_seq_is_real(rstep) ) {
|
|
533
|
+
ca_seq_check_real_run(ca, roffset, rstep,
|
|
534
|
+
axis < 0 ? ca->elements : ca->dim[axis]);
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
ca_seq_check_integer_args(ca, roffset, rstep);
|
|
538
|
+
}
|
|
369
539
|
}
|
|
370
540
|
|
|
371
|
-
|
|
372
|
-
|
|
541
|
+
{
|
|
542
|
+
ca_seq_ctx_t c;
|
|
543
|
+
c.ca = ca;
|
|
544
|
+
c.roffset = roffset;
|
|
545
|
+
c.rstep = rstep;
|
|
546
|
+
c.rmethod = Qnil;
|
|
547
|
+
c.axis = axis;
|
|
548
|
+
ca_attach_window(1, &ca, "a", ca_seq_bang_numeric_body, (VALUE) &c);
|
|
549
|
+
}
|
|
373
550
|
|
|
374
551
|
return self;
|
|
375
552
|
}
|