carray 3.0.1 → 3.0.3
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 +824 -0
- data/README.md +5 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_dispatch.c +258 -4
- data/ext/ca_axis_group.c +368 -184
- data/ext/ca_binop_dispatch.c +54 -32
- data/ext/ca_binop_dispatch.h +1 -0
- data/ext/ca_categorical_iterator.c +90 -41
- data/ext/ca_compare.c +8 -2
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +27 -11
- data/ext/ca_kernel_iterator.c +960 -245
- data/ext/ca_kernel_iterator.h +352 -181
- data/ext/ca_monop_dispatch.c +4 -4
- data/ext/ca_monop_dispatch.h +4 -0
- data/ext/ca_obj_array.c +194 -42
- data/ext/ca_obj_bincmp.c +152 -121
- data/ext/ca_obj_binop.c +107 -210
- data/ext/ca_obj_bitarray.c +37 -24
- data/ext/ca_obj_bitfield.c +95 -62
- data/ext/ca_obj_block.c +5 -4
- data/ext/ca_obj_byte_swap.c +40 -40
- data/ext/ca_obj_const_string.c +180 -50
- data/ext/ca_obj_face.c +428 -62
- data/ext/ca_obj_face.h +107 -47
- data/ext/ca_obj_fake.c +21 -50
- data/ext/ca_obj_farray.c +1 -0
- data/ext/ca_obj_field.c +16 -3
- data/ext/ca_obj_fixlen_string.c +39 -26
- data/ext/ca_obj_grid.c +181 -124
- data/ext/ca_obj_meld.c +235 -55
- data/ext/ca_obj_moncmp.c +61 -61
- data/ext/ca_obj_monop.c +125 -107
- data/ext/ca_obj_object.c +551 -233
- data/ext/ca_obj_record.c +51 -16
- data/ext/ca_obj_reduce.c +5 -8
- data/ext/ca_obj_refer.c +117 -33
- data/ext/ca_obj_remap.c +57 -17
- data/ext/ca_obj_repeat.c +21 -5
- data/ext/ca_obj_roll.c +115 -11
- data/ext/ca_obj_select.c +88 -75
- data/ext/ca_obj_select_axis.c +58 -60
- data/ext/ca_obj_shift.c +22 -102
- data/ext/ca_obj_stack.c +223 -123
- data/ext/ca_obj_stride.c +267 -35
- data/ext/ca_obj_string.c +25 -22
- data/ext/ca_obj_tile.c +32 -16
- data/ext/ca_obj_time.c +23 -25
- data/ext/ca_obj_timedelta.c +21 -23
- data/ext/ca_obj_transpose.c +12 -3
- data/ext/ca_obj_triop.c +110 -117
- data/ext/ca_obj_window.c +157 -29
- data/ext/ca_op_ipower.c +25 -13
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +385 -198
- data/ext/ca_sweep_engine.h +31 -23
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +463 -0
- data/ext/carray.h +90 -28
- data/ext/carray_access.c +487 -231
- data/ext/carray_address_basis.c +731 -0
- data/ext/carray_attribute.c +45 -3
- data/ext/carray_bincount.c +32 -2
- data/ext/carray_broadcast.c +49 -17
- data/ext/carray_call_cfunc.c +667 -511
- data/ext/carray_cast.c +1556 -247
- data/ext/carray_cast_func.rb +34 -21
- data/ext/carray_conversion.c +197 -73
- data/ext/carray_copy.c +84 -38
- data/ext/carray_core.c +591 -119
- data/ext/carray_count.c +148 -96
- data/ext/carray_element.c +18 -27
- data/ext/carray_factorize.c +604 -291
- data/ext/carray_generate.c +76 -40
- data/ext/carray_histogram.c +152 -94
- data/ext/carray_hold.c +2 -1
- data/ext/carray_index_classifier.c +63 -96
- data/ext/carray_internal.h +400 -1
- data/ext/carray_lazy.c +834 -79
- data/ext/carray_loop.c +88 -66
- data/ext/carray_mask.c +705 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +263 -63
- data/ext/carray_memory_view.c +254 -248
- data/ext/carray_operator.c +1093 -363
- data/ext/carray_order.c +133 -69
- data/ext/carray_partition.c +102 -56
- data/ext/carray_random.c +582 -204
- data/ext/carray_scatter.c +308 -65
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +183 -70
- data/ext/carray_sort.c +235 -240
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +99 -21
- data/ext/carray_test.c +167 -64
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_utils.c +363 -98
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +103 -118
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1349 -851
- data/ext/ruby_carray.c +17 -2
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +39 -0
- data/lib/carray/autoload_carray.rb +24 -3
- data/lib/carray/autoload_method_extension.rb +18 -0
- data/lib/carray/axis_group.rb +245 -20
- data/lib/carray/basics.rb +95 -25
- data/lib/carray/bincount_nd.rb +6 -0
- data/lib/carray/block_iterator.rb +200 -54
- data/lib/carray/boolean_reduce.rb +21 -29
- data/lib/carray/categorical.rb +244 -59
- data/lib/carray/categorical_iterator.rb +391 -757
- data/lib/carray/complex.rb +36 -29
- data/lib/carray/conditional.rb +94 -7
- data/lib/carray/const_string.rb +177 -27
- data/lib/carray/construct.rb +40 -0
- data/lib/carray/data_type_extension.rb +3 -0
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +13 -7
- data/lib/carray/frame/csv_parser.rb +590 -76
- data/lib/carray/frame/describe.rb +79 -0
- data/lib/carray/frame/frame.rb +205 -35
- data/lib/carray/frame/group.rb +199 -40
- data/lib/carray/frame/io.rb +452 -60
- data/lib/carray/frame/join.rb +134 -46
- data/lib/carray/frame/records.rb +54 -19
- data/lib/carray/frame/reshape.rb +448 -0
- data/lib/carray/frame/sort.rb +26 -2
- data/lib/carray/frame/verbs.rb +726 -56
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +111 -2
- data/lib/carray/fusion.rb +229 -38
- data/lib/carray/inspect.rb +71 -20
- data/lib/carray/iterator.rb +157 -2
- data/lib/carray/lazy.rb +54 -67
- data/lib/carray/mask_gap_fill.rb +66 -50
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +40 -7
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bincount.rb +2 -2
- data/lib/carray/methods/bit_string.rb +14 -3
- data/lib/carray/methods/composition.rb +16 -10
- data/lib/carray/methods/discovery_along.rb +74 -0
- data/lib/carray/methods/factorize.rb +50 -0
- data/lib/carray/methods/gather_nd.rb +13 -2
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_in.rb +130 -6
- data/lib/carray/methods/join.rb +1 -1
- data/lib/carray/methods/locate_addr.rb +235 -21
- data/lib/carray/methods/mask_duplicates.rb +35 -1
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +22 -1
- data/lib/carray/methods/repeat.rb +91 -0
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +52 -3
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/runtime.rb +14 -11
- data/lib/carray/segment_iterator.rb +990 -0
- data/lib/carray/serialize.rb +197 -27
- data/lib/carray/slab_iterator.rb +109 -40
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string_operation_extension.rb +9 -4
- data/lib/carray/struct.rb +142 -51
- data/lib/carray/struct_builder.rb +110 -14
- data/lib/carray/table.rb +2 -2
- data/lib/carray/time.rb +535 -105
- data/lib/carray/window_iterator.rb +259 -82
- data/lib/carray.rb +4 -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_block.rb +2 -7
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +1 -1
- data/yard-stubs/ca_obj_refer.rb +3 -3
- data/yard-stubs/ca_obj_roll.rb +0 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +11 -4
- data/yard-stubs/carray_access.rb +6 -5
- data/yard-stubs/carray_broadcast.rb +2 -2
- data/yard-stubs/carray_cast.rb +78 -43
- data/yard-stubs/carray_conversion.rb +13 -1
- data/yard-stubs/carray_copy.rb +8 -3
- data/yard-stubs/carray_core.rb +3 -83
- data/yard-stubs/carray_count.rb +16 -2
- data/yard-stubs/carray_lazy.rb +210 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +34 -10
- data/yard-stubs/carray_math.rb +1499 -4
- data/yard-stubs/carray_median_percentile.rb +26 -8
- data/yard-stubs/carray_order.rb +43 -82
- data/yard-stubs/carray_scatter.rb +10 -3
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +11 -8
- data/yard-stubs/carray_sort.rb +50 -8
- data/yard-stubs/carray_test.rb +10 -0
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -19
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_build_flags.h +0 -3
- data/ext/carray_config.h +0 -28
- data/ext/carray_kernels_bincmp.c +0 -4446
- data/ext/carray_kernels_binop.c +0 -11001
- data/ext/carray_kernels_init.c +0 -1131
- data/ext/carray_kernels_map.c +0 -3467
- data/ext/carray_kernels_moncmp.c +0 -2097
- data/ext/carray_kernels_monop.c +0 -18313
- data/ext/carray_kernels_reduce_aggregate.c +0 -25837
- data/ext/carray_kernels_reduce_boolean.c +0 -330
- data/ext/carray_kernels_reduce_cumulative.c +0 -14593
- data/ext/carray_kernels_reduce_extreme.c +0 -16948
- data/ext/carray_kernels_reduce_variance.c +0 -3910
- data/ext/carray_kernels_scan.c +0 -3693
- data/ext/carray_kernels_search.c +0 -32138
- data/ext/carray_kernels_sort.c +0 -10626
- data/ext/carray_kernels_triop.c +0 -1392
data/ext/carray_order.c
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#include "ruby.h"
|
|
2
2
|
#include "carray.h"
|
|
3
|
+
#include "carray_internal.h" /* ca_integer_arg */
|
|
3
4
|
#include "ca_kernel_iterator.h"
|
|
4
5
|
#include "ca_obj_face.h"
|
|
5
6
|
#include <math.h>
|
|
@@ -120,7 +121,7 @@ ca_project (CArray *ca, CArray *ci, char *lfill, char *ufill)
|
|
|
120
121
|
{
|
|
121
122
|
CArray *co;
|
|
122
123
|
|
|
123
|
-
ca_attach_n(2, ca, ci); /*
|
|
124
|
+
ca_attach_n(2, ca, ci); /* window: nothing raises inside */
|
|
124
125
|
|
|
125
126
|
co = carray_new(ca->data_type, ci->ndim, ci->dim, ca->bytes, NULL);
|
|
126
127
|
ca_project_loop(co, ca, ci, lfill, ufill);
|
|
@@ -130,6 +131,96 @@ ca_project (CArray *ca, CArray *ci, char *lfill, char *ufill)
|
|
|
130
131
|
return co;
|
|
131
132
|
}
|
|
132
133
|
|
|
134
|
+
/* rk.__count_below__(q, inclusive) -- for each cell of q, how many values
|
|
135
|
+
* of the sorted array rk are below it (at or below it when inclusive).
|
|
136
|
+
* rk is 1-D, ascending, with no masked or NaN value; q has rk's data type
|
|
137
|
+
* (any shape, read in address order). The count is the insertion position
|
|
138
|
+
* of the cell among rk's values, found by binary search; a masked or NaN
|
|
139
|
+
* cell gets an arbitrary count, for the caller to mask. Returns an int64
|
|
140
|
+
* array of q's shape. Numeric and boolean types only. */
|
|
141
|
+
|
|
142
|
+
/* The search keeps a base and a length and moves the base by a comparison
|
|
143
|
+
rather than branching on it, which keeps the loop free of mispredicted
|
|
144
|
+
branches; the last comparison adds the cell at the base. */
|
|
145
|
+
#define CA_COUNT_BELOW_LOOP(T, CMP) \
|
|
146
|
+
{ \
|
|
147
|
+
const T *r = (const T *) cr->ptr; \
|
|
148
|
+
const T *x = (const T *) cq->ptr; \
|
|
149
|
+
for ( i = 0; i < m; i++ ) { \
|
|
150
|
+
T v = x[i]; \
|
|
151
|
+
const T *base = r; \
|
|
152
|
+
ca_size_t len = n; \
|
|
153
|
+
if ( len == 0 ) { out[i] = 0; continue; } \
|
|
154
|
+
while ( len > 1 ) { \
|
|
155
|
+
ca_size_t half = len / 2; \
|
|
156
|
+
base = (base[half] CMP v) ? base + half : base; \
|
|
157
|
+
len -= half; \
|
|
158
|
+
} \
|
|
159
|
+
out[i] = (int64_t) (base - r) + ((*base CMP v) ? 1 : 0); \
|
|
160
|
+
} \
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
#define CA_COUNT_BELOW(T) \
|
|
164
|
+
if ( inclusive ) CA_COUNT_BELOW_LOOP(T, <=) \
|
|
165
|
+
else CA_COUNT_BELOW_LOOP(T, <)
|
|
166
|
+
|
|
167
|
+
static VALUE
|
|
168
|
+
rb_ca_count_below (VALUE self, VALUE vq, VALUE vinclusive)
|
|
169
|
+
{
|
|
170
|
+
volatile VALUE vout;
|
|
171
|
+
CArray *cr, *cq, *co;
|
|
172
|
+
ca_size_t n, m, i;
|
|
173
|
+
int64_t *out;
|
|
174
|
+
int inclusive = RTEST(vinclusive);
|
|
175
|
+
|
|
176
|
+
GetCArray(self, cr);
|
|
177
|
+
rb_check_carray_object(vq);
|
|
178
|
+
GetCArray(vq, cq);
|
|
179
|
+
if ( cr->ndim != 1 ) {
|
|
180
|
+
rb_raise(rb_eArgError, "__count_below__: the reference must be 1-D");
|
|
181
|
+
}
|
|
182
|
+
if ( cr->data_type != cq->data_type ) {
|
|
183
|
+
rb_raise(rb_eCADataTypeError,
|
|
184
|
+
"__count_below__: the reference and the query must have one data type");
|
|
185
|
+
}
|
|
186
|
+
switch ( cr->data_type ) {
|
|
187
|
+
case CA_BOOLEAN: case CA_INT8: case CA_UINT8: case CA_INT16: case CA_UINT16:
|
|
188
|
+
case CA_INT32: case CA_UINT32: case CA_INT64: case CA_UINT64:
|
|
189
|
+
case CA_FLOAT32: case CA_FLOAT64:
|
|
190
|
+
break;
|
|
191
|
+
default:
|
|
192
|
+
rb_raise(rb_eCADataTypeError, "__count_below__: no order for %s",
|
|
193
|
+
ca_type_name[cr->data_type]);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
n = cr->elements;
|
|
197
|
+
m = cq->elements;
|
|
198
|
+
vout = rb_carray_new(CA_INT64, cq->ndim, cq->dim, 0, NULL);
|
|
199
|
+
GetCArray(vout, co);
|
|
200
|
+
out = (int64_t *) co->ptr;
|
|
201
|
+
|
|
202
|
+
ca_attach_n(2, cr, cq); /* window: nothing raises inside */
|
|
203
|
+
switch ( cr->data_type ) {
|
|
204
|
+
case CA_BOOLEAN:
|
|
205
|
+
case CA_UINT8: CA_COUNT_BELOW(uint8_t); break;
|
|
206
|
+
case CA_INT8: CA_COUNT_BELOW(int8_t); break;
|
|
207
|
+
case CA_INT16: CA_COUNT_BELOW(int16_t); break;
|
|
208
|
+
case CA_UINT16: CA_COUNT_BELOW(uint16_t); break;
|
|
209
|
+
case CA_INT32: CA_COUNT_BELOW(int32_t); break;
|
|
210
|
+
case CA_UINT32: CA_COUNT_BELOW(uint32_t); break;
|
|
211
|
+
case CA_INT64: CA_COUNT_BELOW(int64_t); break;
|
|
212
|
+
case CA_UINT64: CA_COUNT_BELOW(uint64_t); break;
|
|
213
|
+
case CA_FLOAT32: CA_COUNT_BELOW(float); break;
|
|
214
|
+
case CA_FLOAT64: CA_COUNT_BELOW(double); break;
|
|
215
|
+
}
|
|
216
|
+
ca_detach_n(2, cr, cq);
|
|
217
|
+
|
|
218
|
+
return vout;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
#undef CA_COUNT_BELOW
|
|
222
|
+
#undef CA_COUNT_BELOW_LOOP
|
|
223
|
+
|
|
133
224
|
/* project(idx, lval=nil, uval=nil) — gather: for each element of `idx`,
|
|
134
225
|
* pick `self[idx[i]]`. Returns an entity CArray shaped like `idx`.
|
|
135
226
|
*
|
|
@@ -142,6 +233,7 @@ VALUE
|
|
|
142
233
|
rb_ca_project (int argc, VALUE *argv, VALUE self)
|
|
143
234
|
{
|
|
144
235
|
volatile VALUE obj, ridx, vlfval, vufval, vstorage;
|
|
236
|
+
volatile VALUE hlfval = 0, hufval = 0;
|
|
145
237
|
CArray *ca, *ci, *co;
|
|
146
238
|
char *lfval, *ufval;
|
|
147
239
|
int self_is_face;
|
|
@@ -152,14 +244,15 @@ rb_ca_project (int argc, VALUE *argv, VALUE self)
|
|
|
152
244
|
self_is_face = ca_is_face(ca);
|
|
153
245
|
|
|
154
246
|
rb_check_carray_object(ridx);
|
|
247
|
+
ca_check_index_array(ridx);
|
|
155
248
|
ci = ca_wrap_readonly(ridx, CA_SIZE);
|
|
156
249
|
|
|
157
250
|
/* The fill args arrive as surface values. rb_ca_obj2ptr owns the
|
|
158
|
-
surface->storage conversion: for a Face self it fires the
|
|
251
|
+
surface->storage conversion: for a Face self it fires the element_to_storage
|
|
159
252
|
write hook (a datetime scalar / Time is reconciled to the Face's unit),
|
|
160
253
|
for a plain array it writes the storage bytes directly. */
|
|
161
|
-
lfval =
|
|
162
|
-
ufval =
|
|
254
|
+
lfval = ALLOCV_N(char, hlfval, ca->bytes); /* converting a fill value */
|
|
255
|
+
ufval = ALLOCV_N(char, hufval, ca->bytes); /* can raise; the unwind frees */
|
|
163
256
|
|
|
164
257
|
if ( ! NIL_P(vlfval) ) {
|
|
165
258
|
rb_ca_obj2ptr(self, vlfval, lfval);
|
|
@@ -185,8 +278,8 @@ rb_ca_project (int argc, VALUE *argv, VALUE self)
|
|
|
185
278
|
( ! NIL_P(vlfval) ) ? lfval : NULL,
|
|
186
279
|
( ( ! NIL_P(vufval) ) || ( ! NIL_P(vlfval) ) ) ? ufval : NULL);
|
|
187
280
|
|
|
188
|
-
|
|
189
|
-
|
|
281
|
+
ALLOCV_END(hlfval);
|
|
282
|
+
ALLOCV_END(hufval);
|
|
190
283
|
|
|
191
284
|
obj = ca_wrap_struct(co);
|
|
192
285
|
|
|
@@ -255,7 +348,7 @@ extern VALUE rb_ca_reshape (int argc, VALUE *argv, VALUE self)
|
|
|
255
348
|
* through rb_funcall + kwarg hash construction. */
|
|
256
349
|
extern VALUE rb_ca_sort_index_ki_quick (VALUE self, VALUE vaxis);
|
|
257
350
|
extern VALUE rb_ca_partition_index_ki (VALUE self, VALUE vaxis, VALUE vkth);
|
|
258
|
-
extern VALUE
|
|
351
|
+
extern VALUE rb_ca_rank_index_ki_kind_dense (VALUE self, VALUE vaxis, int stable, int dense);
|
|
259
352
|
|
|
260
353
|
/* ---- no-axis (flat) search helper -----------------------------------
|
|
261
354
|
*
|
|
@@ -473,7 +566,7 @@ rb_ca_max_by_key (int argc, VALUE *argv, VALUE self)
|
|
|
473
566
|
else {
|
|
474
567
|
VALUE kw = rb_hash_new();
|
|
475
568
|
rb_hash_aset(kw, ID2SYM(id_axis), raxis);
|
|
476
|
-
addrs =
|
|
569
|
+
addrs = rb_funcallv_kw(rkey, rb_intern("max_addr"), 1, &kw, RB_PASS_KEYWORDS);
|
|
477
570
|
}
|
|
478
571
|
return rb_ca_fetch(self, addrs);
|
|
479
572
|
}
|
|
@@ -498,7 +591,7 @@ rb_ca_min_by_key (int argc, VALUE *argv, VALUE self)
|
|
|
498
591
|
else {
|
|
499
592
|
VALUE kw = rb_hash_new();
|
|
500
593
|
rb_hash_aset(kw, ID2SYM(id_axis), raxis);
|
|
501
|
-
addrs =
|
|
594
|
+
addrs = rb_funcallv_kw(rkey, rb_intern("min_addr"), 1, &kw, RB_PASS_KEYWORDS);
|
|
502
595
|
}
|
|
503
596
|
return rb_ca_fetch(self, addrs);
|
|
504
597
|
}
|
|
@@ -515,6 +608,11 @@ rb_ca_take_along_axis_c (VALUE self, VALUE indices, VALUE raxis)
|
|
|
515
608
|
raxis = INT2FIX(0);
|
|
516
609
|
}
|
|
517
610
|
VALUE addrs = rb_ca_axis2addr_c(self, indices, raxis);
|
|
611
|
+
/* A masked index reads as UNDEF: project carries the mask of its
|
|
612
|
+
addresses into the result. */
|
|
613
|
+
if ( RTEST(rb_ca_has_mask(addrs)) ) {
|
|
614
|
+
return rb_funcall(self, rb_intern("project"), 1, addrs);
|
|
615
|
+
}
|
|
518
616
|
return rb_ca_fetch(self, addrs);
|
|
519
617
|
}
|
|
520
618
|
|
|
@@ -539,6 +637,12 @@ rb_ca_put_along_axis (int argc, VALUE *argv, VALUE self)
|
|
|
539
637
|
raxis = INT2FIX(0);
|
|
540
638
|
}
|
|
541
639
|
VALUE addrs = rb_ca_axis2addr_c(self, argv[0], raxis);
|
|
640
|
+
/* A masked index writes nothing: scatter_replace! skips a masked
|
|
641
|
+
address (and writes the rest last-write-wins, as the store does). */
|
|
642
|
+
if ( RTEST(rb_ca_has_mask(addrs)) ) {
|
|
643
|
+
rb_funcall(self, rb_intern("scatter_replace!"), 2, addrs, argv[1]);
|
|
644
|
+
return self;
|
|
645
|
+
}
|
|
542
646
|
rb_ca_store(self, addrs, argv[1]);
|
|
543
647
|
return self;
|
|
544
648
|
}
|
|
@@ -611,12 +715,14 @@ rb_ca_topk_index (VALUE self, VALUE rn, VALUE raxis, int desc, const char *name)
|
|
|
611
715
|
CArray *ca;
|
|
612
716
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
613
717
|
long a = rb_ca_normalize_axis_value(self, raxis, name);
|
|
614
|
-
long n_val =
|
|
718
|
+
long n_val = ca_integer_arg(rn, "n", name);
|
|
615
719
|
long dim_a = (long) ca->dim[a];
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
720
|
+
/* As Array#max(n): a negative count is an error, one past the length
|
|
721
|
+
gives the whole fiber. */
|
|
722
|
+
if ( n_val < 0 ) {
|
|
723
|
+
rb_raise(rb_eArgError, "%s: n must be non-negative (got %ld)", name, n_val);
|
|
619
724
|
}
|
|
725
|
+
long cap = (n_val < dim_a) ? n_val : dim_a;
|
|
620
726
|
if ( cap == 0 ) {
|
|
621
727
|
/* Return zero-along-axis int64 array via the C carray constructor. */
|
|
622
728
|
ca_size_t out_dim[CA_RANK_MAX];
|
|
@@ -711,29 +817,20 @@ static VALUE
|
|
|
711
817
|
rb_ca_order (int argc, VALUE *argv, VALUE self)
|
|
712
818
|
{
|
|
713
819
|
VALUE ropt = rb_pop_options(&argc, &argv);
|
|
714
|
-
VALUE raxis = Qnil, rdesc = Qfalse, rmethod = Qnil;
|
|
715
|
-
rb_scan_options(ropt, "axis,descending,method", &raxis, &rdesc, &rmethod);
|
|
820
|
+
VALUE raxis = Qnil, rdesc = Qfalse, rmethod = Qnil, rkind = Qnil;
|
|
821
|
+
rb_scan_options(ropt, "axis,descending,method,kind", &raxis, &rdesc, &rmethod, &rkind);
|
|
716
822
|
rb_check_arity(argc, 0, 0);
|
|
717
823
|
|
|
718
|
-
int dense =
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
if ( ! sym_dense ) sym_dense = rb_intern("dense");
|
|
723
|
-
ID method_id = SYM2ID(rmethod);
|
|
724
|
-
if ( method_id == sym_ordinal ) dense = 0;
|
|
725
|
-
else if ( method_id == sym_dense ) dense = 1;
|
|
726
|
-
else {
|
|
727
|
-
rb_raise(rb_eArgError, "order: unknown method %s (expected :ordinal or :dense)",
|
|
728
|
-
rb_id2name(method_id));
|
|
729
|
-
}
|
|
730
|
-
}
|
|
824
|
+
int dense = NIL_P(rmethod) ? 0
|
|
825
|
+
: ca_symbol_choice(rmethod, "method", "ordinal", "dense", NULL);
|
|
826
|
+
int do_stable = NIL_P(rkind) ? 0
|
|
827
|
+
: ca_symbol_choice(rkind, "kind", "quick", "stable", NULL);
|
|
731
828
|
|
|
732
829
|
VALUE asc, n;
|
|
733
830
|
if ( NIL_P(raxis) ) {
|
|
734
831
|
VALUE flat = rb_ca_flatten(self);
|
|
735
832
|
/* Direct C-level dispatch via c_callable: true extern (mkkernel). */
|
|
736
|
-
VALUE ranked =
|
|
833
|
+
VALUE ranked = rb_ca_rank_index_ki_kind_dense(flat, INT2FIX(0), do_stable, dense);
|
|
737
834
|
/* reshape(*shape) */
|
|
738
835
|
CArray *ca;
|
|
739
836
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
@@ -748,7 +845,7 @@ rb_ca_order (int argc, VALUE *argv, VALUE self)
|
|
|
748
845
|
} else {
|
|
749
846
|
long axis_norm = rb_ca_normalize_axis_value(self, raxis, "order");
|
|
750
847
|
VALUE raxis_norm = LONG2NUM(axis_norm);
|
|
751
|
-
asc =
|
|
848
|
+
asc = rb_ca_rank_index_ki_kind_dense(self, raxis_norm, do_stable, dense);
|
|
752
849
|
if ( RTEST(rb_ca_has_mask(self)) ) {
|
|
753
850
|
n = rb_ca_count_not_masked_c(self, raxis_norm);
|
|
754
851
|
} else {
|
|
@@ -800,10 +897,7 @@ ca_linear_prep (VALUE self, VALUE raxis, const char *name, long *axis_out)
|
|
|
800
897
|
float-numeric flag is needed. */
|
|
801
898
|
if ( ca_is_face(ca) ) {
|
|
802
899
|
if ( ! ca_test_flag(ca, CA_FLAG_FACE_ORDERABLE_STORAGE) ) {
|
|
803
|
-
|
|
804
|
-
"%s: Face-typed input (%s) is not orderable by storage; "
|
|
805
|
-
"use ca.parent to descend to storage",
|
|
806
|
-
name, rb_obj_classname(self));
|
|
900
|
+
ca_face_refuse_order(name, self, "order");
|
|
807
901
|
}
|
|
808
902
|
self = rb_ca_strip_face_value(self);
|
|
809
903
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
@@ -831,44 +925,13 @@ rb_ca_linear_section_m (int argc, VALUE *argv, VALUE self)
|
|
|
831
925
|
rb_check_arity(argc, 1, 1);
|
|
832
926
|
VALUE val = argv[0];
|
|
833
927
|
|
|
834
|
-
/* Query gate
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
-> strip a Face query, take a plain query as-is. A non-COMPARABLE Face
|
|
838
|
-
axis calls its own to_comparable(query) for ANY query type (Face CArray,
|
|
839
|
-
our Scalar, a Ruby Time / DateTime, ...), then strips; it raises if it
|
|
840
|
-
cannot reconcile the query. `self` is still the pre-strip axis Face
|
|
841
|
-
here, so it carries the unit for to_comparable and its COMPARABLE flag. */
|
|
842
|
-
{
|
|
843
|
-
int val_is_face = 0, self_is_face = 0, self_comparable = 0;
|
|
928
|
+
/* Query gate: the reference axis, still a Face here, reconciles the query
|
|
929
|
+
into its own space (ca_face_reconcile_operand). */
|
|
930
|
+
if ( rb_obj_is_carray(self) ) {
|
|
844
931
|
CArray *sca;
|
|
845
|
-
if ( rb_obj_is_kind_of(val, rb_cCArray) ) {
|
|
846
|
-
CArray *vca;
|
|
847
|
-
TypedData_Get_Struct(val, CArray, &carray_data_type, vca);
|
|
848
|
-
val_is_face = ca_is_face(vca);
|
|
849
|
-
}
|
|
850
932
|
TypedData_Get_Struct(self, CArray, &carray_data_type, sca);
|
|
851
933
|
if ( ca_is_face(sca) ) {
|
|
852
|
-
|
|
853
|
-
self_comparable = ca_test_flag(sca, CA_FLAG_FACE_COMPARABLE_STORAGE);
|
|
854
|
-
}
|
|
855
|
-
if ( self_comparable ) {
|
|
856
|
-
if ( val_is_face ) {
|
|
857
|
-
val = rb_ca_strip_face_value(val);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
else if ( self_is_face ) {
|
|
861
|
-
if ( rb_respond_to(self, rb_intern("to_comparable")) ) {
|
|
862
|
-
val = rb_funcall(self, rb_intern("to_comparable"), 1, val);
|
|
863
|
-
val = rb_ca_strip_face_value(val);
|
|
864
|
-
}
|
|
865
|
-
else {
|
|
866
|
-
rb_raise(rb_eArgError,
|
|
867
|
-
"linear_section: non-comparable Face axis (%s) has no "
|
|
868
|
-
"to_comparable to reconcile the query; use ca.parent to "
|
|
869
|
-
"search the hidden storage explicitly",
|
|
870
|
-
rb_obj_classname(self));
|
|
871
|
-
}
|
|
934
|
+
val = ca_face_reconcile_operand(self, val, "linear_section");
|
|
872
935
|
}
|
|
873
936
|
}
|
|
874
937
|
|
|
@@ -925,6 +988,7 @@ Init_carray_order (void)
|
|
|
925
988
|
id_sym_linear = rb_intern("linear");
|
|
926
989
|
|
|
927
990
|
rb_define_method(rb_cCArray, "project", rb_ca_project, -1);
|
|
991
|
+
rb_define_private_method(rb_cCArray, "__count_below__", rb_ca_count_below, 2);
|
|
928
992
|
|
|
929
993
|
/* Search family (dual API: index / addr) -- see the trampoline
|
|
930
994
|
comment block above for the axis: kwarg dispatch contract. */
|
data/ext/carray_partition.c
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
#include "ruby.h"
|
|
16
16
|
#include "carray.h"
|
|
17
|
+
#include "carray_internal.h" /* ca_axis_integer */
|
|
17
18
|
#include "ca_kernel_iterator.h" /* CA_FOR_EACH_FIBER_INOUT */
|
|
18
19
|
#include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE */
|
|
19
20
|
#include "ca_sort_kernels.h" /* ca_partition_quick_* / ca_partition_nan_* */
|
|
@@ -23,7 +24,6 @@
|
|
|
23
24
|
/* External entries reached at link time (extern declarations rather than
|
|
24
25
|
carray.h additions to keep the public header lean): */
|
|
25
26
|
extern VALUE rb_ca_remap_new (VALUE cary, VALUE rmapper); /* ca_obj_remap.c */
|
|
26
|
-
extern VALUE rb_ca_partition_addr_ki (VALUE self, VALUE vaxis, VALUE vkth); /* carray_kernels.c (generated, bind_ruby: false) */
|
|
27
27
|
/* _mp ("masked position") twin: explicit masked_last, used by `partition`
|
|
28
28
|
/ `partition_copy` to pass masked_position: through (see MASKED_POSITION
|
|
29
29
|
rev1 in mkkernel.rb's MkKernel.sort doc). */
|
|
@@ -111,7 +111,21 @@ ca_quickselect_bytes (char *buf, ca_size_t lo, ca_size_t hi,
|
|
|
111
111
|
#undef QSCMP
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
/*
|
|
114
|
+
/* The kth of a partition along a fiber of length n: an Integer in
|
|
115
|
+
-n <= kth < n, negative counting from the end. */
|
|
116
|
+
static ca_size_t
|
|
117
|
+
partition_kth (ca_size_t n, VALUE vkth)
|
|
118
|
+
{
|
|
119
|
+
ca_size_t raw = (ca_size_t) ca_integer_arg(vkth, "kth", NULL);
|
|
120
|
+
ca_size_t kth = ( raw < 0 ) ? raw + n : raw;
|
|
121
|
+
if ( kth < 0 || kth >= n ) {
|
|
122
|
+
rb_raise(rb_eArgError, "%s: kth %lld out of range for length %lld",
|
|
123
|
+
ca_calling_method_name(), (long long) raw, (long long) n);
|
|
124
|
+
}
|
|
125
|
+
return kth;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* partition_copy(kth, axis:) — eager counterpart to `partition(kth,
|
|
115
129
|
* axis:)`. Returns a fresh entity CArray with the kth fiber-local
|
|
116
130
|
* position holding the kth-smallest value. Average O(n) per fiber via
|
|
117
131
|
* quickselect. Mask handling, axis kwarg, kth validation: identical to
|
|
@@ -141,22 +155,10 @@ rb_ca_partition_copy_c (VALUE self, VALUE vkth, VALUE vaxis)
|
|
|
141
155
|
}
|
|
142
156
|
|
|
143
157
|
/* Normalize axis. */
|
|
144
|
-
int axis =
|
|
145
|
-
if ( axis < 0 ) axis += cat->ndim;
|
|
146
|
-
if ( axis < 0 || axis >= cat->ndim ) {
|
|
147
|
-
rb_raise(rb_eArgError, "partition_copy: axis %d out of range for ndim %d",
|
|
148
|
-
NUM2INT(vaxis), cat->ndim);
|
|
149
|
-
}
|
|
158
|
+
int axis = rb_ca_normalize_axis_for_ndim(ca_axis_integer(vaxis, NULL), cat->ndim, NULL);
|
|
150
159
|
|
|
151
|
-
/* Normalize kth (-dim[axis] <= kth < dim[axis], negative counts from end). */
|
|
152
160
|
ca_size_t fiber_n = cat->dim[axis];
|
|
153
|
-
ca_size_t kth = (
|
|
154
|
-
if ( kth < 0 ) kth += fiber_n;
|
|
155
|
-
if ( kth < 0 || kth >= fiber_n ) {
|
|
156
|
-
rb_raise(rb_eArgError,
|
|
157
|
-
"partition_copy: kth %ld out of range for axis %d (dim=%ld)",
|
|
158
|
-
(long) NUM2SSIZET(vkth), axis, (long) fiber_n);
|
|
159
|
-
}
|
|
161
|
+
ca_size_t kth = partition_kth(fiber_n, vkth);
|
|
160
162
|
|
|
161
163
|
/* CA_OBJECT branch: partition_index_ki carries the rb_funcall(<=>)
|
|
162
164
|
* comparator. Build the entity via partition_index_ki ->
|
|
@@ -193,8 +195,10 @@ rb_ca_partition_copy_c (VALUE self, VALUE vkth, VALUE vaxis)
|
|
|
193
195
|
INT2NUM((int) fbytes));
|
|
194
196
|
CArray *cao;
|
|
195
197
|
TypedData_Get_Struct(vout, CArray, &carray_data_type, cao);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
+
/* Two cells of scratch. ALLOCV, not the stack: a cell can be wide. */
|
|
199
|
+
volatile VALUE scratch_holder = 0;
|
|
200
|
+
char *swap_tmp = ALLOCV_N(char, scratch_holder, 2 * (size_t) fbytes);
|
|
201
|
+
char *pivot = swap_tmp + fbytes;
|
|
198
202
|
ca_iter_state st_in, st_out;
|
|
199
203
|
char *pi, *po;
|
|
200
204
|
ca_size_t n;
|
|
@@ -205,15 +209,16 @@ rb_ca_partition_copy_c (VALUE self, VALUE vkth, VALUE vaxis)
|
|
|
205
209
|
ca_quickselect_bytes(po, 0, n - 1, kth, fbytes, NULL, swap_tmp, pivot);
|
|
206
210
|
}
|
|
207
211
|
}
|
|
212
|
+
ALLOCV_END(scratch_holder);
|
|
208
213
|
return vout;
|
|
209
214
|
}
|
|
210
215
|
|
|
211
216
|
if ( cat->data_type != CA_BOOLEAN &&
|
|
212
217
|
(cat->data_type < CA_INT8 || cat->data_type > CA_FLOAT64) ) {
|
|
213
218
|
rb_raise(rb_eCADataTypeError,
|
|
214
|
-
"partition_copy: data_type
|
|
215
|
-
"(expected
|
|
216
|
-
cat->data_type);
|
|
219
|
+
"partition_copy: source data_type :%s not supported "
|
|
220
|
+
"(expected boolean, an integer or float type, or object)",
|
|
221
|
+
ca_type_name[cat->data_type]);
|
|
217
222
|
}
|
|
218
223
|
|
|
219
224
|
volatile VALUE vout = rb_ca_template_with_type(target,
|
|
@@ -289,6 +294,13 @@ rb_ca_partition_copy_c_mp (VALUE self, VALUE vkth, VALUE vaxis, int masked_last)
|
|
|
289
294
|
if ( ! ca_has_mask(ca) ) {
|
|
290
295
|
return rb_ca_partition_copy_c(self, vkth, vaxis);
|
|
291
296
|
}
|
|
297
|
+
/* Check axis and kth here, so a bad one is reported as partition_copy's
|
|
298
|
+
rather than as the partition this delegates to. */
|
|
299
|
+
{
|
|
300
|
+
int axis = rb_ca_normalize_axis_for_ndim(ca_axis_integer(vaxis, NULL),
|
|
301
|
+
ca->ndim, NULL);
|
|
302
|
+
partition_kth(ca->dim[axis], vkth);
|
|
303
|
+
}
|
|
292
304
|
/* rb_ca_partitioned_view's rb_scan_args "1:" pattern needs call-frame
|
|
293
305
|
keyword-splat state, only set by full Ruby method dispatch -- a raw
|
|
294
306
|
C call segfaults/misparses (same constraint documented on
|
|
@@ -307,34 +319,56 @@ rb_ca_partition_copy_c_mp (VALUE self, VALUE vkth, VALUE vaxis, int masked_last)
|
|
|
307
319
|
return obj;
|
|
308
320
|
}
|
|
309
321
|
|
|
310
|
-
/* Ruby entry: partition_copy(kth, axis:
|
|
322
|
+
/* Ruby entry: partition_copy(kth, axis: nil, masked_position: :last).
|
|
323
|
+
No axis means the whole array, as for sort_copy: flatten first. */
|
|
311
324
|
static VALUE
|
|
312
|
-
|
|
325
|
+
rb_ca_partition_copy_body (int argc, VALUE *argv, VALUE self)
|
|
313
326
|
{
|
|
314
327
|
VALUE vkth, rkw = Qnil;
|
|
315
|
-
VALUE vaxis =
|
|
328
|
+
VALUE vaxis = Qnil;
|
|
316
329
|
VALUE vmasked_position = Qnil;
|
|
317
330
|
rb_scan_args(argc, argv, "1:", &vkth, &rkw);
|
|
318
331
|
rb_scan_options(rkw, "axis,masked_position", &vaxis, &vmasked_position);
|
|
332
|
+
if ( NIL_P(vaxis) ) {
|
|
333
|
+
self = rb_ca_flatten(self);
|
|
334
|
+
vaxis = INT2NUM(0);
|
|
335
|
+
}
|
|
319
336
|
|
|
320
|
-
int masked_last = 1
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
337
|
+
int masked_last = NIL_P(vmasked_position) ? 1
|
|
338
|
+
: ca_symbol_choice(vmasked_position, "masked_position", "first", "last", NULL);
|
|
339
|
+
|
|
340
|
+
/* Face gate, the same policy as the sort family's: a fixlen storage
|
|
341
|
+
partitions by memcmp, a numeric storage only when ORDERABLE (its order
|
|
342
|
+
is the surface order). The selection runs on the storage and the Face
|
|
343
|
+
is put back on the result. Without this the surface fixlen bytes were
|
|
344
|
+
selected by memcmp, which is not the order of a little-endian integer
|
|
345
|
+
(CATime) and not the label order of a code (CACategorical). */
|
|
346
|
+
volatile VALUE face = Qnil;
|
|
347
|
+
{
|
|
348
|
+
CArray *ca;
|
|
349
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
350
|
+
if ( ca_is_face(ca) ) {
|
|
351
|
+
VALUE st = rb_ca_strip_face_value(self);
|
|
352
|
+
CArray *sc;
|
|
353
|
+
TypedData_Get_Struct(st, CArray, &carray_data_type, sc);
|
|
354
|
+
if ( sc->data_type != CA_FIXLEN
|
|
355
|
+
&& ! ca_test_flag(ca, CA_FLAG_FACE_ORDERABLE_STORAGE) ) {
|
|
356
|
+
ca_face_refuse_order("partition_copy", self, "order");
|
|
357
|
+
}
|
|
358
|
+
face = self;
|
|
359
|
+
self = st;
|
|
332
360
|
}
|
|
333
361
|
}
|
|
334
|
-
|
|
362
|
+
|
|
363
|
+
VALUE out = rb_ca_partition_copy_c_mp(self, vkth, vaxis, masked_last);
|
|
364
|
+
|
|
365
|
+
if ( face != Qnil ) {
|
|
366
|
+
out = ca_face_relift_entity(face, out);
|
|
367
|
+
}
|
|
368
|
+
return out;
|
|
335
369
|
}
|
|
336
370
|
|
|
337
|
-
/* partition(kth, axis:
|
|
371
|
+
/* partition(kth, axis: nil, masked_position: :last)
|
|
338
372
|
*
|
|
339
373
|
* Returns a CARemap view of +self+ partitioned along +axis+ such that
|
|
340
374
|
* the cell at the kth fiber-local position contains the kth-smallest
|
|
@@ -344,7 +378,7 @@ rb_ca_partition_copy (int argc, VALUE *argv, VALUE self)
|
|
|
344
378
|
* :partition).
|
|
345
379
|
*
|
|
346
380
|
* Signature mirrors rb_ca_sorted_view: positional kth + optional axis: /
|
|
347
|
-
* masked_position: kwargs (default
|
|
381
|
+
* masked_position: kwargs (default nil = whole array / :last). Mask handling mirrors
|
|
348
382
|
* {sort}: masked cells are an incomparable sentinel clustered at
|
|
349
383
|
* masked_position:, excluded from the kth-selection; a kth landing in
|
|
350
384
|
* the masked cluster needs no selection (unspecified order, same
|
|
@@ -356,33 +390,27 @@ static VALUE
|
|
|
356
390
|
rb_ca_partitioned_view (int argc, VALUE *argv, VALUE self)
|
|
357
391
|
{
|
|
358
392
|
VALUE vkth, rkw = Qnil;
|
|
359
|
-
VALUE vaxis =
|
|
393
|
+
VALUE vaxis = Qnil;
|
|
360
394
|
VALUE vmasked_position = Qnil;
|
|
361
395
|
|
|
362
396
|
rb_scan_args(argc, argv, "1:", &vkth, &rkw);
|
|
363
397
|
rb_scan_options(rkw, "axis,masked_position", &vaxis, &vmasked_position);
|
|
364
398
|
|
|
365
|
-
int masked_last = 1
|
|
366
|
-
|
|
367
|
-
static ID sym_first = 0, sym_last = 0;
|
|
368
|
-
if ( !sym_first ) sym_first = rb_intern("first");
|
|
369
|
-
if ( !sym_last ) sym_last = rb_intern("last");
|
|
370
|
-
ID mp_id = SYM2ID(vmasked_position);
|
|
371
|
-
if ( mp_id == sym_last ) masked_last = 1;
|
|
372
|
-
else if ( mp_id == sym_first ) masked_last = 0;
|
|
373
|
-
else {
|
|
374
|
-
rb_raise(rb_eArgError,
|
|
375
|
-
"partition: unknown masked_position %s (expected :first or :last)",
|
|
376
|
-
rb_id2name(mp_id));
|
|
377
|
-
}
|
|
378
|
-
}
|
|
399
|
+
int masked_last = NIL_P(vmasked_position) ? 1
|
|
400
|
+
: ca_symbol_choice(vmasked_position, "masked_position", "first", "last", NULL);
|
|
379
401
|
|
|
380
402
|
CArray *ca;
|
|
381
403
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
382
404
|
|
|
383
405
|
/* CA_FIXLEN flows through the same partition_addr_ki fixlen dialect
|
|
384
|
-
as numeric; masked_position: applies uniformly across data types.
|
|
385
|
-
|
|
406
|
+
as numeric; masked_position: applies uniformly across data types.
|
|
407
|
+
No axis means the whole array, as for sort: partition the flattened
|
|
408
|
+
view. */
|
|
409
|
+
volatile VALUE target = self;
|
|
410
|
+
if ( NIL_P(vaxis) ) {
|
|
411
|
+
target = rb_ca_flatten(self);
|
|
412
|
+
vaxis = INT2NUM(0);
|
|
413
|
+
}
|
|
386
414
|
|
|
387
415
|
/* partition_addr_ki_mp validates axis + kth, splits masked cells to
|
|
388
416
|
masked_position:, and quickselects per fiber over the unmasked
|
|
@@ -400,6 +428,24 @@ rb_ca_partitioned_view (int argc, VALUE *argv, VALUE self)
|
|
|
400
428
|
|
|
401
429
|
/* ----------------------------------------------------------------------- */
|
|
402
430
|
|
|
431
|
+
|
|
432
|
+
typedef struct { int argc; VALUE *argv; VALUE self; } pc_call_t;
|
|
433
|
+
|
|
434
|
+
static VALUE
|
|
435
|
+
pc_answer_body (VALUE p)
|
|
436
|
+
{
|
|
437
|
+
pc_call_t *c = (pc_call_t *) p;
|
|
438
|
+
return rb_ca_partition_copy_body(c->argc, c->argv, c->self);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/* An error raised by the methods this one calls names this one. */
|
|
442
|
+
static VALUE
|
|
443
|
+
rb_ca_partition_copy (int argc, VALUE *argv, VALUE self)
|
|
444
|
+
{
|
|
445
|
+
pc_call_t c = { argc, argv, self };
|
|
446
|
+
return ca_answer_as_caller(pc_answer_body, (VALUE) &c);
|
|
447
|
+
}
|
|
448
|
+
|
|
403
449
|
void
|
|
404
450
|
Init_carray_partition (void)
|
|
405
451
|
{
|