carray 3.0.3 → 3.0.5
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 +469 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_array_pool.c +25 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +14 -26
- 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 +231 -153
- data/ext/ca_compare.c +9 -20
- data/ext/ca_composite_dispatch.c +9 -9
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1240 -2000
- data/ext/ca_kernel_iterator.h +502 -519
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +152 -45
- data/ext/ca_obj_bincmp.c +25 -21
- data/ext/ca_obj_binop.c +16 -26
- data/ext/ca_obj_bitarray.c +8 -3
- data/ext/ca_obj_bitfield.c +63 -49
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +7 -7
- data/ext/ca_obj_const_string.c +188 -22
- data/ext/ca_obj_face.c +280 -58
- 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 +30 -8
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +455 -134
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +113 -67
- data/ext/ca_obj_object.c +210 -52
- data/ext/ca_obj_record.c +15 -7
- data/ext/ca_obj_reduce.c +17 -8
- data/ext/ca_obj_refer.c +42 -35
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +31 -10
- data/ext/ca_obj_select.c +48 -14
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +41 -7
- data/ext/ca_obj_stack.c +180 -34
- data/ext/ca_obj_stride.c +190 -134
- data/ext/ca_obj_string.c +80 -4
- data/ext/ca_obj_tile.c +32 -11
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +13 -7
- data/ext/ca_obj_triop.c +26 -32
- data/ext/ca_obj_window.c +267 -74
- data/ext/ca_op_ipower.c +4 -4
- data/ext/ca_sort_kernels.h +6 -3
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +214 -75
- data/ext/carray_access.c +200 -99
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +113 -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 +375 -96
- data/ext/carray_cast_func.rb +90 -20
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +18 -9
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +150 -55
- data/ext/carray_count.c +56 -20
- data/ext/carray_element.c +81 -33
- data/ext/carray_factorize.c +138 -84
- data/ext/carray_generate.c +199 -52
- data/ext/carray_histogram.c +63 -18
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +348 -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 +10897 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +220 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +337 -94
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +129 -52
- data/ext/carray_order.c +604 -77
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +85 -31
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +87 -45
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +123 -37
- data/ext/carray_sort.c +259 -51
- data/ext/carray_sort_kernel.c +5 -7
- data/ext/carray_struct.c +54 -61
- data/ext/carray_test.c +26 -5
- data/ext/carray_time_text.c +4 -2
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +309 -66
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +403 -350
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +139 -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 +105 -17
- 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 +195 -59
- data/lib/carray/categorical_iterator.rb +132 -29
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +24 -5
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +9 -1
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +48 -3
- data/lib/carray/frame/column_verbs.rb +71 -0
- data/lib/carray/frame/concat.rb +17 -3
- 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 +252 -28
- data/lib/carray/frame/group.rb +603 -101
- data/lib/carray/frame/io.rb +117 -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 +42 -6
- 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 +217 -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 +61 -37
- 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 +323 -88
- data/lib/carray/serialize.rb +45 -14
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/stack.rb +15 -12
- data/lib/carray/string.rb +113 -5
- data/lib/carray/string_operation_extension.rb +21 -6
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +24 -11
- data/lib/carray/time.rb +819 -158
- 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_transpose.rb +5 -4
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +3 -6
- data/yard-stubs/carray_cast.rb +12 -0
- data/yard-stubs/carray_conversion.rb +7 -2
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +17 -10
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +32 -3
- data/yard-stubs/carray_math.rb +41 -5
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +129 -22
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +17 -10
- 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_partition.c
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
#include "ruby.h"
|
|
16
16
|
#include "carray.h"
|
|
17
|
-
#include "carray_internal.h" /*
|
|
17
|
+
#include "carray_internal.h" /* ca_normalize_axis_arg */
|
|
18
18
|
#include "ca_kernel_iterator.h" /* CA_FOR_EACH_FIBER_INOUT */
|
|
19
19
|
#include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE */
|
|
20
20
|
#include "ca_sort_kernels.h" /* ca_partition_quick_* / ca_partition_nan_* */
|
|
@@ -155,7 +155,7 @@ rb_ca_partition_copy_c (VALUE self, VALUE vkth, VALUE vaxis)
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
/* Normalize axis. */
|
|
158
|
-
int axis =
|
|
158
|
+
int axis = ca_normalize_axis_arg(vaxis, cat->ndim, NULL);
|
|
159
159
|
|
|
160
160
|
ca_size_t fiber_n = cat->dim[axis];
|
|
161
161
|
ca_size_t kth = partition_kth(fiber_n, vkth);
|
|
@@ -166,14 +166,9 @@ rb_ca_partition_copy_c (VALUE self, VALUE vkth, VALUE vaxis)
|
|
|
166
166
|
* but the cost is the per-pair rb_funcall, not an architectural
|
|
167
167
|
* penalty. */
|
|
168
168
|
if ( cat->data_type == CA_OBJECT ) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if ( !id_partition_index_ki ) {
|
|
173
|
-
id_partition_index_ki = rb_intern("partition_index_ki");
|
|
174
|
-
id_take_along_axis = rb_intern("take_along_axis");
|
|
175
|
-
id_axis_sym = rb_intern("axis");
|
|
176
|
-
}
|
|
169
|
+
ID id_partition_index_ki = rb_intern("partition_index_ki");
|
|
170
|
+
ID id_take_along_axis = rb_intern("take_along_axis");
|
|
171
|
+
ID id_axis_sym = rb_intern("axis");
|
|
177
172
|
VALUE idx = rb_funcall(target, id_partition_index_ki, 2,
|
|
178
173
|
INT2NUM(axis), SIZET2NUM(kth));
|
|
179
174
|
VALUE kw = rb_hash_new();
|
|
@@ -297,8 +292,7 @@ rb_ca_partition_copy_c_mp (VALUE self, VALUE vkth, VALUE vaxis, int masked_last)
|
|
|
297
292
|
/* Check axis and kth here, so a bad one is reported as partition_copy's
|
|
298
293
|
rather than as the partition this delegates to. */
|
|
299
294
|
{
|
|
300
|
-
int axis =
|
|
301
|
-
ca->ndim, NULL);
|
|
295
|
+
int axis = ca_normalize_axis_arg(vaxis, ca->ndim, NULL);
|
|
302
296
|
partition_kth(ca->dim[axis], vkth);
|
|
303
297
|
}
|
|
304
298
|
/* rb_ca_partitioned_view's rb_scan_args "1:" pattern needs call-frame
|
|
@@ -337,26 +331,30 @@ rb_ca_partition_copy_body (int argc, VALUE *argv, VALUE self)
|
|
|
337
331
|
int masked_last = NIL_P(vmasked_position) ? 1
|
|
338
332
|
: ca_symbol_choice(vmasked_position, "masked_position", "first", "last", NULL);
|
|
339
333
|
|
|
340
|
-
/* Face gate, the same policy as the sort family's
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
(CATime) and not the label order of a code (CACategorical). */
|
|
334
|
+
/* Face gate, the same policy as the sort family's. An ORDERABLE Face
|
|
335
|
+
is selected on its storage and put back on the result. A Face that
|
|
336
|
+
orders by itself (ca_face_orders_by_itself) is partitioned by the view,
|
|
337
|
+
which orders by that order (ca_order_key), and its copy is the answer.
|
|
338
|
+
Any other Face raises. */
|
|
346
339
|
volatile VALUE face = Qnil;
|
|
347
340
|
{
|
|
348
341
|
CArray *ca;
|
|
349
342
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
350
343
|
if ( ca_is_face(ca) ) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
344
|
+
if ( ca_face_orders_by_itself(self) ) {
|
|
345
|
+
VALUE kw = rb_hash_new();
|
|
346
|
+
VALUE pv_argv[2];
|
|
347
|
+
rb_hash_aset(kw, ID2SYM(rb_intern("axis")), vaxis);
|
|
348
|
+
rb_hash_aset(kw, ID2SYM(rb_intern("masked_position")),
|
|
349
|
+
masked_last ? ID2SYM(rb_intern("last")) : ID2SYM(rb_intern("first")));
|
|
350
|
+
pv_argv[0] = vkth;
|
|
351
|
+
pv_argv[1] = kw;
|
|
352
|
+
return rb_ca_copy(rb_funcallv_kw(self, rb_intern("partition"), 2, pv_argv,
|
|
353
|
+
RB_PASS_KEYWORDS));
|
|
357
354
|
}
|
|
355
|
+
ca_face_require_orderable(self, "partition_copy", "order");
|
|
358
356
|
face = self;
|
|
359
|
-
self =
|
|
357
|
+
self = rb_ca_strip_face_value(self);
|
|
360
358
|
}
|
|
361
359
|
}
|
|
362
360
|
|
|
@@ -418,7 +416,8 @@ rb_ca_partitioned_view (int argc, VALUE *argv, VALUE self)
|
|
|
418
416
|
suitable for direct ca_remap_new wrap; the remap gather carries
|
|
419
417
|
target's mask bits through so masked cells stay masked at their
|
|
420
418
|
clustered position (no extra output-mask step needed here). */
|
|
421
|
-
volatile VALUE sigma_addr =
|
|
419
|
+
volatile VALUE sigma_addr =
|
|
420
|
+
rb_ca_partition_addr_ki_mp(target, vaxis, vkth, masked_last);
|
|
422
421
|
{
|
|
423
422
|
VALUE obj = rb_ca_remap_new(target, sigma_addr);
|
|
424
423
|
CA_FACE_LIFT_IF_FACE(obj, self, ca);
|
|
@@ -443,7 +442,9 @@ static VALUE
|
|
|
443
442
|
rb_ca_partition_copy (int argc, VALUE *argv, VALUE self)
|
|
444
443
|
{
|
|
445
444
|
pc_call_t c = { argc, argv, self };
|
|
446
|
-
|
|
445
|
+
VALUE out = ca_answer_as_caller(pc_answer_body, (VALUE) &c);
|
|
446
|
+
rb_ca_inherit_attr(out, self);
|
|
447
|
+
return out;
|
|
447
448
|
}
|
|
448
449
|
|
|
449
450
|
void
|
data/ext/carray_random.c
CHANGED
|
@@ -88,16 +88,18 @@ typedef struct {
|
|
|
88
88
|
long low_long;
|
|
89
89
|
unsigned long limit;
|
|
90
90
|
int axis; /* shuffle!: -1 = all cells */
|
|
91
|
+
CArray *mask; /* shuffle!: self's mask, moved with the values */
|
|
91
92
|
} ca_random_ctx_t;
|
|
92
93
|
|
|
93
94
|
static void
|
|
94
95
|
ca_random_run (ca_random_ctx_t *c, VALUE rng, VALUE (*fill)(VALUE))
|
|
95
96
|
{
|
|
96
|
-
CArray *list[
|
|
97
|
+
CArray *list[3];
|
|
97
98
|
ca_rng_resolve(rng, &c->source);
|
|
98
99
|
list[0] = c->ca;
|
|
99
100
|
list[1] = c->source.state;
|
|
100
|
-
|
|
101
|
+
list[2] = c->mask;
|
|
102
|
+
ca_attach_window(c->mask ? 3 : 2, list, "www", fill, (VALUE) c);
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
/* The state is attached once the window is open. */
|
|
@@ -163,7 +165,7 @@ ca_random_bang_fill (VALUE arg)
|
|
|
163
165
|
ca_rng_bind(&c->source);
|
|
164
166
|
switch (ca->data_type) {
|
|
165
167
|
case CA_FLOAT64: {
|
|
166
|
-
double *p = (double *)ca->ptr;
|
|
168
|
+
CA_U(double) *p = (CA_U(double) *)ca->ptr;
|
|
167
169
|
if (is_default) {
|
|
168
170
|
for (i = 0; i < n; i++)
|
|
169
171
|
p[i] = ca_random_real(&c->source);
|
|
@@ -175,7 +177,7 @@ ca_random_bang_fill (VALUE arg)
|
|
|
175
177
|
break;
|
|
176
178
|
}
|
|
177
179
|
case CA_FLOAT32: {
|
|
178
|
-
float *p = (float *)ca->ptr;
|
|
180
|
+
CA_U(float) *p = (CA_U(float) *)ca->ptr;
|
|
179
181
|
if (is_default) {
|
|
180
182
|
for (i = 0; i < n; i++)
|
|
181
183
|
p[i] = (float)ca_random_real(&c->source);
|
|
@@ -187,7 +189,7 @@ ca_random_bang_fill (VALUE arg)
|
|
|
187
189
|
break;
|
|
188
190
|
}
|
|
189
191
|
case CA_CMPLX128: {
|
|
190
|
-
|
|
192
|
+
ca_u_cmplx128_t *p = (ca_u_cmplx128_t *)ca->ptr;
|
|
191
193
|
if (is_default) {
|
|
192
194
|
for (i = 0; i < n; i++)
|
|
193
195
|
p[i] = ca_random_real(&c->source) + ca_random_real(&c->source) * I;
|
|
@@ -200,7 +202,7 @@ ca_random_bang_fill (VALUE arg)
|
|
|
200
202
|
break;
|
|
201
203
|
}
|
|
202
204
|
case CA_CMPLX64: {
|
|
203
|
-
|
|
205
|
+
ca_u_cmplx64_t *p = (ca_u_cmplx64_t *)ca->ptr;
|
|
204
206
|
if (is_default) {
|
|
205
207
|
for (i = 0; i < n; i++)
|
|
206
208
|
p[i] = (float)ca_random_real(&c->source) + (float)ca_random_real(&c->source) * I;
|
|
@@ -240,37 +242,37 @@ ca_random_bang_fill (VALUE arg)
|
|
|
240
242
|
break;
|
|
241
243
|
}
|
|
242
244
|
case CA_INT16: {
|
|
243
|
-
int16_t *p = (int16_t *)ca->ptr;
|
|
245
|
+
CA_U(int16_t) *p = (CA_U(int16_t) *)ca->ptr;
|
|
244
246
|
for (i = 0; i < n; i++)
|
|
245
247
|
p[i] = (int16_t)(low_long + ca_random_ulong_limited(&c->source, limit));
|
|
246
248
|
break;
|
|
247
249
|
}
|
|
248
250
|
case CA_UINT16: {
|
|
249
|
-
uint16_t *p = (uint16_t *)ca->ptr;
|
|
251
|
+
CA_U(uint16_t) *p = (CA_U(uint16_t) *)ca->ptr;
|
|
250
252
|
for (i = 0; i < n; i++)
|
|
251
253
|
p[i] = (uint16_t)(low_long + ca_random_ulong_limited(&c->source, limit));
|
|
252
254
|
break;
|
|
253
255
|
}
|
|
254
256
|
case CA_INT32: {
|
|
255
|
-
int32_t *p = (int32_t *)ca->ptr;
|
|
257
|
+
CA_U(int32_t) *p = (CA_U(int32_t) *)ca->ptr;
|
|
256
258
|
for (i = 0; i < n; i++)
|
|
257
259
|
p[i] = (int32_t)(low_long + ca_random_ulong_limited(&c->source, limit));
|
|
258
260
|
break;
|
|
259
261
|
}
|
|
260
262
|
case CA_UINT32: {
|
|
261
|
-
uint32_t *p = (uint32_t *)ca->ptr;
|
|
263
|
+
CA_U(uint32_t) *p = (CA_U(uint32_t) *)ca->ptr;
|
|
262
264
|
for (i = 0; i < n; i++)
|
|
263
265
|
p[i] = (uint32_t)(low_long + ca_random_ulong_limited(&c->source, limit));
|
|
264
266
|
break;
|
|
265
267
|
}
|
|
266
268
|
case CA_INT64: {
|
|
267
|
-
int64_t *p = (int64_t *)ca->ptr;
|
|
269
|
+
CA_U(int64_t) *p = (CA_U(int64_t) *)ca->ptr;
|
|
268
270
|
for (i = 0; i < n; i++)
|
|
269
271
|
p[i] = (int64_t)(low_long + ca_random_ulong_limited(&c->source, limit));
|
|
270
272
|
break;
|
|
271
273
|
}
|
|
272
274
|
case CA_UINT64: {
|
|
273
|
-
uint64_t *p = (uint64_t *)ca->ptr;
|
|
275
|
+
CA_U(uint64_t) *p = (CA_U(uint64_t) *)ca->ptr;
|
|
274
276
|
for (i = 0; i < n; i++)
|
|
275
277
|
p[i] = (uint64_t)(low_long + ca_random_ulong_limited(&c->source, limit));
|
|
276
278
|
break;
|
|
@@ -359,19 +361,55 @@ rb_ca_random_bang(int argc, VALUE *argv, VALUE self)
|
|
|
359
361
|
int is_integer_type = (ca->data_type >= CA_INT8
|
|
360
362
|
&& ca->data_type <= CA_UINT64);
|
|
361
363
|
if (is_integer_type) {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
364
|
+
/* The bounds stay Ruby Integers until they are known to fit: the
|
|
365
|
+
last value drawn is high (closed) or high - 1, and every value
|
|
366
|
+
from low to it must be one of the type's. The draw is low plus
|
|
367
|
+
an offset up to last - low, which holds even the whole int64 or
|
|
368
|
+
uint64 range. */
|
|
369
|
+
VALUE last, type_min, type_max;
|
|
370
|
+
if (!RB_INTEGER_TYPE_P(low_val) || !RB_INTEGER_TYPE_P(high_val)) {
|
|
371
|
+
rb_raise(rb_eTypeError,
|
|
372
|
+
"random: an integer array takes Integer bounds "
|
|
373
|
+
"(got %"PRIsVALUE", %"PRIsVALUE")",
|
|
374
|
+
rb_inspect(low_val), rb_inspect(high_val));
|
|
375
|
+
}
|
|
376
|
+
last = high_is_closed ? high_val
|
|
377
|
+
: rb_funcall(high_val, '-', 1, INT2FIX(1));
|
|
378
|
+
if (RTEST(rb_funcall(low_val, '>', 1, last))) {
|
|
366
379
|
rb_raise(rb_eArgError,
|
|
367
380
|
"random: low must be less than high "
|
|
368
|
-
"(got low=%
|
|
369
|
-
|
|
381
|
+
"(got low=%"PRIsVALUE", high=%"PRIsVALUE")",
|
|
382
|
+
low_val, high_val);
|
|
383
|
+
}
|
|
384
|
+
switch (ca->data_type) {
|
|
385
|
+
case CA_INT8: type_min = INT2FIX(INT8_MIN); type_max = INT2FIX(INT8_MAX); break;
|
|
386
|
+
case CA_UINT8: type_min = INT2FIX(0); type_max = INT2FIX(UINT8_MAX); break;
|
|
387
|
+
case CA_INT16: type_min = INT2FIX(INT16_MIN); type_max = INT2FIX(INT16_MAX); break;
|
|
388
|
+
case CA_UINT16: type_min = INT2FIX(0); type_max = INT2FIX(UINT16_MAX); break;
|
|
389
|
+
case CA_INT32: type_min = LL2NUM(INT32_MIN); type_max = LL2NUM(INT32_MAX); break;
|
|
390
|
+
case CA_UINT32: type_min = INT2FIX(0); type_max = ULL2NUM(UINT32_MAX); break;
|
|
391
|
+
case CA_INT64: type_min = LL2NUM(INT64_MIN); type_max = LL2NUM(INT64_MAX); break;
|
|
392
|
+
default: type_min = INT2FIX(0); type_max = ULL2NUM(UINT64_MAX); break;
|
|
393
|
+
}
|
|
394
|
+
if (RTEST(rb_funcall(low_val, '<', 1, type_min)) ||
|
|
395
|
+
RTEST(rb_funcall(last, '>', 1, type_max))) {
|
|
396
|
+
rb_raise(rb_eRangeError,
|
|
397
|
+
"random: the values %"PRIsVALUE"..%"PRIsVALUE" are not all %s "
|
|
398
|
+
"(%"PRIsVALUE"..%"PRIsVALUE")",
|
|
399
|
+
low_val, last, ca_type_name[ca->data_type], type_min, type_max);
|
|
370
400
|
}
|
|
371
|
-
|
|
401
|
+
low_long = RTEST(rb_funcall(low_val, '<', 1, INT2FIX(0)))
|
|
402
|
+
? (long) NUM2LL(low_val) : (long) NUM2ULL(low_val);
|
|
403
|
+
limit = (unsigned long) NUM2ULL(rb_funcall(last, '-', 1, low_val));
|
|
404
|
+
(void) high_long;
|
|
372
405
|
} else {
|
|
373
406
|
low_dbl = NUM2DBL(low_val);
|
|
374
407
|
high_dbl = NUM2DBL(high_val);
|
|
408
|
+
if (!isfinite(low_dbl) || !isfinite(high_dbl)) {
|
|
409
|
+
rb_raise(rb_eArgError,
|
|
410
|
+
"random: the bounds are finite numbers "
|
|
411
|
+
"(got low=%g, high=%g)", low_dbl, high_dbl);
|
|
412
|
+
}
|
|
375
413
|
if (low_dbl >= high_dbl) {
|
|
376
414
|
rb_raise(rb_eArgError,
|
|
377
415
|
"random: low must be less than high "
|
|
@@ -382,7 +420,7 @@ rb_ca_random_bang(int argc, VALUE *argv, VALUE self)
|
|
|
382
420
|
}
|
|
383
421
|
|
|
384
422
|
{
|
|
385
|
-
ca_random_ctx_t c;
|
|
423
|
+
ca_random_ctx_t c = { 0 };
|
|
386
424
|
c.ca = ca;
|
|
387
425
|
c.n = ca->elements;
|
|
388
426
|
c.is_default = is_default;
|
|
@@ -392,6 +430,8 @@ rb_ca_random_bang(int argc, VALUE *argv, VALUE self)
|
|
|
392
430
|
c.limit = limit;
|
|
393
431
|
ca_random_run(&c, rng, ca_random_bang_fill);
|
|
394
432
|
}
|
|
433
|
+
/* Every cell now holds a value, as after seq! or fill. */
|
|
434
|
+
ca_clear_mask(ca);
|
|
395
435
|
return self;
|
|
396
436
|
}
|
|
397
437
|
|
|
@@ -443,19 +483,19 @@ ca_randomn_bang_fill (VALUE arg)
|
|
|
443
483
|
if (c->source.kind == CA_RNG_OWN) {
|
|
444
484
|
switch (ca->data_type) {
|
|
445
485
|
case CA_FLOAT64: {
|
|
446
|
-
double *p = (double *)ca->ptr;
|
|
486
|
+
CA_U(double) *p = (CA_U(double) *)ca->ptr;
|
|
447
487
|
for (i = 0; i < n; i++)
|
|
448
488
|
p[i] = ca_random_normal(&c->source);
|
|
449
489
|
break;
|
|
450
490
|
}
|
|
451
491
|
case CA_FLOAT32: {
|
|
452
|
-
float *p = (float *)ca->ptr;
|
|
492
|
+
CA_U(float) *p = (CA_U(float) *)ca->ptr;
|
|
453
493
|
for (i = 0; i < n; i++)
|
|
454
494
|
p[i] = (float) ca_random_normal(&c->source);
|
|
455
495
|
break;
|
|
456
496
|
}
|
|
457
497
|
case CA_CMPLX128: {
|
|
458
|
-
|
|
498
|
+
ca_u_cmplx128_t *p = (ca_u_cmplx128_t *)ca->ptr;
|
|
459
499
|
for (i = 0; i < n; i++) {
|
|
460
500
|
/* Into locals first: C does not say which order a call's
|
|
461
501
|
arguments are evaluated in, and these two advance a state. */
|
|
@@ -466,7 +506,7 @@ ca_randomn_bang_fill (VALUE arg)
|
|
|
466
506
|
break;
|
|
467
507
|
}
|
|
468
508
|
case CA_CMPLX64: {
|
|
469
|
-
|
|
509
|
+
ca_u_cmplx64_t *p = (ca_u_cmplx64_t *)ca->ptr;
|
|
470
510
|
for (i = 0; i < n; i++) {
|
|
471
511
|
double re = ca_random_normal(&c->source);
|
|
472
512
|
double im = ca_random_normal(&c->source);
|
|
@@ -482,7 +522,7 @@ ca_randomn_bang_fill (VALUE arg)
|
|
|
482
522
|
|
|
483
523
|
switch (ca->data_type) {
|
|
484
524
|
case CA_FLOAT64: {
|
|
485
|
-
double *p = (double *)ca->ptr;
|
|
525
|
+
CA_U(double) *p = (CA_U(double) *)ca->ptr;
|
|
486
526
|
ca_size_t pairs = n / 2;
|
|
487
527
|
for (i = 0; i < pairs; i++) {
|
|
488
528
|
box_muller_pair(&c->source, &p[2*i], &p[2*i+1]);
|
|
@@ -495,7 +535,7 @@ ca_randomn_bang_fill (VALUE arg)
|
|
|
495
535
|
break;
|
|
496
536
|
}
|
|
497
537
|
case CA_FLOAT32: {
|
|
498
|
-
float *p = (float *)ca->ptr;
|
|
538
|
+
CA_U(float) *p = (CA_U(float) *)ca->ptr;
|
|
499
539
|
ca_size_t pairs = n / 2;
|
|
500
540
|
for (i = 0; i < pairs; i++) {
|
|
501
541
|
double r1, r2;
|
|
@@ -511,7 +551,7 @@ ca_randomn_bang_fill (VALUE arg)
|
|
|
511
551
|
break;
|
|
512
552
|
}
|
|
513
553
|
case CA_CMPLX128: {
|
|
514
|
-
|
|
554
|
+
ca_u_cmplx128_t *p = (ca_u_cmplx128_t *)ca->ptr;
|
|
515
555
|
for (i = 0; i < n; i++) {
|
|
516
556
|
double r1, r2;
|
|
517
557
|
box_muller_pair(&c->source, &r1, &r2);
|
|
@@ -520,7 +560,7 @@ ca_randomn_bang_fill (VALUE arg)
|
|
|
520
560
|
break;
|
|
521
561
|
}
|
|
522
562
|
case CA_CMPLX64: {
|
|
523
|
-
|
|
563
|
+
ca_u_cmplx64_t *p = (ca_u_cmplx64_t *)ca->ptr;
|
|
524
564
|
for (i = 0; i < n; i++) {
|
|
525
565
|
double r1, r2;
|
|
526
566
|
box_muller_pair(&c->source, &r1, &r2);
|
|
@@ -560,11 +600,13 @@ rb_ca_randomn_bang(int argc, VALUE *argv, VALUE self)
|
|
|
560
600
|
}
|
|
561
601
|
|
|
562
602
|
{
|
|
563
|
-
ca_random_ctx_t c;
|
|
603
|
+
ca_random_ctx_t c = { 0 };
|
|
564
604
|
c.ca = ca;
|
|
565
605
|
c.n = ca->elements;
|
|
566
606
|
ca_random_run(&c, rng, ca_randomn_bang_fill);
|
|
567
607
|
}
|
|
608
|
+
/* Every cell now holds a value, as after seq! or fill. */
|
|
609
|
+
ca_clear_mask(ca);
|
|
568
610
|
return self;
|
|
569
611
|
}
|
|
570
612
|
|
|
@@ -600,12 +642,16 @@ ca_shuffle_bang_fill (VALUE arg)
|
|
|
600
642
|
ca_size_t elem_bytes = ca->bytes;
|
|
601
643
|
char *tmp = ALLOCV_N(char, tmp_holder, elem_bytes);
|
|
602
644
|
char *p = ca->ptr;
|
|
645
|
+
char *m = c->mask ? c->mask->ptr : NULL;
|
|
603
646
|
|
|
604
647
|
n = ca->elements;
|
|
605
648
|
for (ca_size_t i = n - 1; i > 0; i--) {
|
|
606
649
|
unsigned long j = ca_random_ulong_limited(&c->source, (unsigned long)i);
|
|
607
650
|
if ((ca_size_t)j != i) {
|
|
608
651
|
swap_chunks(p + i * elem_bytes, p + j * elem_bytes, elem_bytes, tmp);
|
|
652
|
+
if ( m ) {
|
|
653
|
+
char b = m[i]; m[i] = m[j]; m[j] = b;
|
|
654
|
+
}
|
|
609
655
|
}
|
|
610
656
|
}
|
|
611
657
|
ALLOCV_END(tmp_holder);
|
|
@@ -630,12 +676,16 @@ ca_shuffle_bang_fill (VALUE arg)
|
|
|
630
676
|
|
|
631
677
|
for (ca_size_t o = 0; o < outer; o++) {
|
|
632
678
|
char *base = ca->ptr + o * stride;
|
|
679
|
+
char *mbase = c->mask ? c->mask->ptr + o * n * inner : NULL;
|
|
633
680
|
for (ca_size_t i = n - 1; i > 0; i--) {
|
|
634
681
|
unsigned long j = ca_random_ulong_limited(&c->source, (unsigned long)i);
|
|
635
682
|
if ((ca_size_t)j != i) {
|
|
636
683
|
swap_chunks(base + i * chunk_bytes,
|
|
637
684
|
base + j * chunk_bytes,
|
|
638
685
|
chunk_bytes, tmp);
|
|
686
|
+
if ( mbase ) {
|
|
687
|
+
swap_chunks(mbase + i * inner, mbase + j * inner, inner, tmp);
|
|
688
|
+
}
|
|
639
689
|
}
|
|
640
690
|
}
|
|
641
691
|
}
|
|
@@ -650,7 +700,7 @@ rb_ca_shuffle_bang(int argc, VALUE *argv, VALUE self)
|
|
|
650
700
|
CArray *ca;
|
|
651
701
|
VALUE opts = Qnil, v_axis = Qnil;
|
|
652
702
|
int axis = -1;
|
|
653
|
-
ca_random_ctx_t c;
|
|
703
|
+
ca_random_ctx_t c = { 0 };
|
|
654
704
|
|
|
655
705
|
rb_scan_args(argc, argv, "0:", &opts);
|
|
656
706
|
VALUE rng = Qnil;
|
|
@@ -662,7 +712,7 @@ rb_ca_shuffle_bang(int argc, VALUE *argv, VALUE self)
|
|
|
662
712
|
if (ca->elements <= 1) return self;
|
|
663
713
|
|
|
664
714
|
if (!NIL_P(v_axis)) {
|
|
665
|
-
axis =
|
|
715
|
+
axis = ca_normalize_axis_arg(v_axis, ca->ndim, NULL);
|
|
666
716
|
if (ca->dim[axis] <= 1) {
|
|
667
717
|
return self;
|
|
668
718
|
}
|
|
@@ -670,6 +720,10 @@ rb_ca_shuffle_bang(int argc, VALUE *argv, VALUE self)
|
|
|
670
720
|
|
|
671
721
|
c.ca = ca;
|
|
672
722
|
c.axis = axis;
|
|
723
|
+
/* The mask moves with the values: a masked cell stays masked wherever
|
|
724
|
+
it lands. */
|
|
725
|
+
ca_update_mask(ca);
|
|
726
|
+
c.mask = ca->mask;
|
|
673
727
|
ca_random_run(&c, rng, ca_shuffle_bang_fill);
|
|
674
728
|
return self;
|
|
675
729
|
}
|