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_generate.c
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
#include "ruby.h"
|
|
11
11
|
#include "carray.h"
|
|
12
|
+
#include "carray_internal.h" /* ca_attach_window, ca_axis_integer */
|
|
12
13
|
|
|
13
14
|
/* ----------------------------------------------------------------- */
|
|
14
15
|
|
|
@@ -32,7 +33,7 @@ rb_ca_where (VALUE self)
|
|
|
32
33
|
|
|
33
34
|
TypedData_Get_Struct(bool0, CArray, &carray_data_type, ca);
|
|
34
35
|
|
|
35
|
-
ca_attach(ca);
|
|
36
|
+
ca_attach(ca); /* window: nothing raises inside */
|
|
36
37
|
|
|
37
38
|
/* calculate elements of output array */
|
|
38
39
|
p = (boolean8_t *) ca->ptr;
|
|
@@ -179,16 +180,10 @@ ca_seq_resolve_axis (CArray *ca, VALUE raxis)
|
|
|
179
180
|
}
|
|
180
181
|
if ( TYPE(raxis) == T_ARRAY ) {
|
|
181
182
|
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);
|
|
183
|
+
"%s: axis must be a single Integer (a seq over several axes is not supported)",
|
|
184
|
+
ca_calling_method_name());
|
|
191
185
|
}
|
|
186
|
+
axis = rb_ca_normalize_axis_for_ndim(ca_axis_integer(raxis, NULL), ca->ndim, NULL);
|
|
192
187
|
return axis;
|
|
193
188
|
}
|
|
194
189
|
|
|
@@ -208,23 +203,30 @@ ca_seq_geometry (CArray *ca, int axis,
|
|
|
208
203
|
*outer = out;
|
|
209
204
|
}
|
|
210
205
|
|
|
206
|
+
/* The object fill calls Ruby per cell (`+`, or the method given as the
|
|
207
|
+
step), which can raise part way, so it runs in a window that attaches:
|
|
208
|
+
the cells filled before the raise then reach the parent with the rest
|
|
209
|
+
left as they were, as they would for an entity. */
|
|
210
|
+
|
|
211
|
+
typedef struct {
|
|
212
|
+
CArray *ca;
|
|
213
|
+
VALUE roffset;
|
|
214
|
+
VALUE rstep;
|
|
215
|
+
VALUE rmethod;
|
|
216
|
+
int axis;
|
|
217
|
+
} ca_seq_ctx_t;
|
|
218
|
+
|
|
211
219
|
static VALUE
|
|
212
|
-
|
|
220
|
+
ca_seq_bang_object_body (VALUE arg)
|
|
213
221
|
{
|
|
214
|
-
|
|
215
|
-
CArray *ca;
|
|
222
|
+
ca_seq_ctx_t *c = (ca_seq_ctx_t *) arg;
|
|
223
|
+
CArray *ca = c->ca;
|
|
224
|
+
volatile VALUE rval;
|
|
225
|
+
VALUE roffset = c->roffset, rstep = c->rstep, rmethod = c->rmethod;
|
|
226
|
+
int axis = c->axis;
|
|
216
227
|
VALUE *p;
|
|
217
228
|
ca_size_t i;
|
|
218
229
|
|
|
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
230
|
if ( ca_has_mask(ca) ) {
|
|
229
231
|
ca_clear_mask(ca); /* clear all mask */
|
|
230
232
|
}
|
|
@@ -318,12 +320,54 @@ rb_ca_seq_bang_object (VALUE self, VALUE roffset, VALUE rstep, int axis)
|
|
|
318
320
|
}
|
|
319
321
|
}
|
|
320
322
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
+
return Qnil;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
static VALUE
|
|
327
|
+
rb_ca_seq_bang_object (VALUE self, VALUE roffset, VALUE rstep, int axis)
|
|
328
|
+
{
|
|
329
|
+
ca_seq_ctx_t c;
|
|
330
|
+
|
|
331
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, c.ca);
|
|
332
|
+
|
|
333
|
+
c.rmethod = Qnil;
|
|
334
|
+
if ( TYPE(rstep) == T_SYMBOL ) { /* e.g. a.seq("a", :succ) */
|
|
335
|
+
c.rmethod = rstep;
|
|
336
|
+
rstep = Qnil;
|
|
337
|
+
}
|
|
338
|
+
c.roffset = roffset;
|
|
339
|
+
c.rstep = rstep;
|
|
340
|
+
c.axis = axis;
|
|
341
|
+
|
|
342
|
+
ca_attach_window(1, &c.ca, "w", ca_seq_bang_object_body, (VALUE) &c);
|
|
323
343
|
|
|
324
344
|
return self;
|
|
325
345
|
}
|
|
326
346
|
|
|
347
|
+
/* The numeric fill converts offset and step before it writes a cell, so
|
|
348
|
+
a raise there leaves nothing to push back: an allocate window. */
|
|
349
|
+
static VALUE
|
|
350
|
+
ca_seq_bang_numeric_body (VALUE arg)
|
|
351
|
+
{
|
|
352
|
+
ca_seq_ctx_t *c = (ca_seq_ctx_t *) arg;
|
|
353
|
+
CArray *ca = c->ca;
|
|
354
|
+
VALUE roffset = c->roffset, rstep = c->rstep;
|
|
355
|
+
|
|
356
|
+
if ( ca_has_mask(ca) ) {
|
|
357
|
+
ca_clear_mask(ca); /* clear all mask */
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if ( c->axis < 0 ) {
|
|
361
|
+
seq_bang_switch(proc_seq_bang);
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
ca_size_t len, inner_size, outer_size;
|
|
365
|
+
ca_seq_geometry(ca, c->axis, &len, &inner_size, &outer_size);
|
|
366
|
+
seq_bang_switch(proc_seq_bang_axis);
|
|
367
|
+
}
|
|
368
|
+
return Qnil;
|
|
369
|
+
}
|
|
370
|
+
|
|
327
371
|
/* CArray#seq!(init_val=0, step=1, axis: nil) -- arithmetic-progression
|
|
328
372
|
fill, in place. Without `axis:` the fill runs in row-major order
|
|
329
373
|
over the whole array; with `axis: k` the progression runs along axis
|
|
@@ -353,24 +397,16 @@ rb_ca_seq_bang_method (int argc, VALUE *argv, VALUE self)
|
|
|
353
397
|
return rb_ca_seq_bang_object(self, roffset, rstep, axis);
|
|
354
398
|
}
|
|
355
399
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
400
|
+
{
|
|
401
|
+
ca_seq_ctx_t c;
|
|
402
|
+
c.ca = ca;
|
|
403
|
+
c.roffset = roffset;
|
|
404
|
+
c.rstep = rstep;
|
|
405
|
+
c.rmethod = Qnil;
|
|
406
|
+
c.axis = axis;
|
|
407
|
+
ca_attach_window(1, &ca, "a", ca_seq_bang_numeric_body, (VALUE) &c);
|
|
360
408
|
}
|
|
361
409
|
|
|
362
|
-
if ( axis < 0 ) {
|
|
363
|
-
seq_bang_switch(proc_seq_bang);
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
ca_size_t len, inner_size, outer_size;
|
|
367
|
-
ca_seq_geometry(ca, axis, &len, &inner_size, &outer_size);
|
|
368
|
-
seq_bang_switch(proc_seq_bang_axis);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
ca_sync(ca);
|
|
372
|
-
ca_detach(ca);
|
|
373
|
-
|
|
374
410
|
return self;
|
|
375
411
|
}
|
|
376
412
|
|
data/ext/carray_histogram.c
CHANGED
|
@@ -23,13 +23,15 @@
|
|
|
23
23
|
---------------------------------------------------------------------------- */
|
|
24
24
|
|
|
25
25
|
#include "carray.h"
|
|
26
|
+
#include "carray_internal.h" /* ca_attach_window */
|
|
26
27
|
#include <math.h>
|
|
27
28
|
|
|
28
|
-
/* Resolve `redges` to a
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
/* Resolve `redges` to a 1-D float64 CArray of at least two edges. The
|
|
30
|
+
caller copies the edges out (ca_xfer_all into its own buffer) rather
|
|
31
|
+
than attaching them: the walk that follows reads the caller's array,
|
|
32
|
+
and a raise there must not leave the edges attached. */
|
|
31
33
|
static CArray *
|
|
32
|
-
|
|
34
|
+
histbin_resolve_edges (VALUE self, VALUE redges)
|
|
33
35
|
{
|
|
34
36
|
CArray *ce;
|
|
35
37
|
|
|
@@ -49,9 +51,6 @@ histbin_attach_edges (VALUE self, VALUE redges, double **ep_out, ca_size_t *ne_o
|
|
|
49
51
|
rb_raise(rb_eArgError, "histbin_ki: edges needs at least 2 values");
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
ca_attach(ce);
|
|
53
|
-
*ep_out = (double *) ce->ptr;
|
|
54
|
-
*ne_out = ce->elements;
|
|
55
54
|
return ce;
|
|
56
55
|
}
|
|
57
56
|
|
|
@@ -105,19 +104,24 @@ histbin_index (const histbin_axis_t *ax, double v)
|
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
static void
|
|
108
|
-
histbin_axis_setup (histbin_axis_t *ax,
|
|
107
|
+
histbin_axis_setup (histbin_axis_t *ax, const double *ep, ca_size_t ne,
|
|
108
|
+
int include_max)
|
|
109
109
|
{
|
|
110
|
-
ca_size_t
|
|
110
|
+
ca_size_t kk;
|
|
111
111
|
double dx, tol;
|
|
112
112
|
|
|
113
|
-
ax->ep =
|
|
113
|
+
ax->ep = ep;
|
|
114
114
|
ax->n = ne - 1;
|
|
115
115
|
ax->lo = ax->ep[0];
|
|
116
116
|
ax->hi = ax->ep[ne - 1];
|
|
117
117
|
dx = (ax->hi - ax->lo) / (double) ax->n;
|
|
118
118
|
tol = fabs(dx) * 1e-9 + 1e-12;
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
/* The linearised index needs a width and its reciprocal that are both
|
|
120
|
+
finite and nonzero: edges spanning more than a double holds make the
|
|
121
|
+
width infinite, and a subnormal width makes the reciprocal infinite.
|
|
122
|
+
Either turns the position into NaN, which has no integer. */
|
|
123
|
+
ax->uniform = isfinite(dx) && dx != 0.0 && isfinite(1.0 / dx);
|
|
124
|
+
for ( kk = 0; ax->uniform && kk <= ax->n; kk++ ) {
|
|
121
125
|
if ( fabs(ax->ep[kk] - (ax->lo + (double) kk * dx)) > tol ) { ax->uniform = 0; break; }
|
|
122
126
|
}
|
|
123
127
|
ax->inv_dx = (dx != 0.0) ? 1.0 / dx : 0.0;
|
|
@@ -129,8 +133,8 @@ rb_ca_histbin_ki (VALUE self, VALUE redges, VALUE rinclude_max)
|
|
|
129
133
|
{
|
|
130
134
|
CArray *ca, *co, *ce;
|
|
131
135
|
VALUE vout;
|
|
136
|
+
volatile VALUE hedges = 0;
|
|
132
137
|
double *ep;
|
|
133
|
-
ca_size_t ne;
|
|
134
138
|
histbin_axis_t ax;
|
|
135
139
|
|
|
136
140
|
GetCArray(self, ca);
|
|
@@ -140,9 +144,10 @@ rb_ca_histbin_ki (VALUE self, VALUE redges, VALUE rinclude_max)
|
|
|
140
144
|
ca_type_name[ca->data_type]);
|
|
141
145
|
}
|
|
142
146
|
|
|
143
|
-
ce =
|
|
144
|
-
|
|
145
|
-
|
|
147
|
+
ce = histbin_resolve_edges(self, redges);
|
|
148
|
+
ep = ALLOCV_N(double, hedges, ce->elements);
|
|
149
|
+
ca_xfer_all(ce, ep, CA_XFER_GET);
|
|
150
|
+
histbin_axis_setup(&ax, ep, ce->elements, RTEST(rinclude_max));
|
|
146
151
|
|
|
147
152
|
/* output: fresh contiguous int64, same shape as self. */
|
|
148
153
|
vout = rb_carray_new(CA_INT64, ca->ndim, ca->dim, 0, NULL);
|
|
@@ -179,7 +184,7 @@ rb_ca_histbin_ki (VALUE self, VALUE redges, VALUE rinclude_max)
|
|
|
179
184
|
}
|
|
180
185
|
}
|
|
181
186
|
|
|
182
|
-
|
|
187
|
+
ALLOCV_END(hedges);
|
|
183
188
|
|
|
184
189
|
return vout;
|
|
185
190
|
}
|
|
@@ -201,6 +206,125 @@ rb_ca_histbin_ki (VALUE self, VALUE redges, VALUE rinclude_max)
|
|
|
201
206
|
off = fiber_base + Σ_k histbin_index(axis_k, v_{a,k}) * ext_stride[k]
|
|
202
207
|
counts[off] += 1 (or += weight when weighted)
|
|
203
208
|
=========================================================================== */
|
|
209
|
+
/* histogram_scatter_ki reads its edges inside an attach window and walks
|
|
210
|
+
the samples (and the weights) with two kernel iterators, whose states
|
|
211
|
+
live here, outside the walk: a sample view that raises as it is read --
|
|
212
|
+
a lazy source meeting a cell it cannot compute -- leaves neither the
|
|
213
|
+
edges nor the other walk open. */
|
|
214
|
+
typedef struct {
|
|
215
|
+
ca_iter_state states[2]; /* the samples, the weights */
|
|
216
|
+
CArray *ca, *cc, *cw;
|
|
217
|
+
long M, nf;
|
|
218
|
+
int weighted;
|
|
219
|
+
CArray **edge_ca;
|
|
220
|
+
VALUE rincmax;
|
|
221
|
+
histbin_axis_t *axes;
|
|
222
|
+
ca_size_t *ext_stride;
|
|
223
|
+
ca_size_t *fiber_stride;
|
|
224
|
+
} histogram_scatter_t;
|
|
225
|
+
|
|
226
|
+
static VALUE
|
|
227
|
+
histogram_scatter_walk (VALUE arg)
|
|
228
|
+
{
|
|
229
|
+
histogram_scatter_t *c = (histogram_scatter_t *) arg;
|
|
230
|
+
CArray *ca = c->ca, *cc = c->cc, *cw = c->cw;
|
|
231
|
+
long M = c->M, k;
|
|
232
|
+
int weighted = c->weighted;
|
|
233
|
+
histbin_axis_t *axes = c->axes;
|
|
234
|
+
ca_size_t *ext_stride = c->ext_stride;
|
|
235
|
+
ca_size_t *fiber_stride = c->fiber_stride;
|
|
236
|
+
#define st (c->states[0])
|
|
237
|
+
#define stw (c->states[1])
|
|
238
|
+
int64_t *cpi = (int64_t *) cc->ptr; /* unweighted */
|
|
239
|
+
double *cpd = (double *) cc->ptr; /* weighted */
|
|
240
|
+
char *p, *pw = NULL;
|
|
241
|
+
boolean8_t *m, *mw = NULL;
|
|
242
|
+
ca_size_t cur_outer_idx[CA_RANK_MAX];
|
|
243
|
+
int8_t slab_axes[2] = { (int8_t)(ca->ndim - 2), (int8_t)(ca->ndim - 1) };
|
|
244
|
+
int8_t w_slab_axes[1] = { (int8_t)(ca->ndim - 2) }; /* weights sample axis */
|
|
245
|
+
int8_t mm;
|
|
246
|
+
int rc;
|
|
247
|
+
|
|
248
|
+
rc = ca_iter_state_init_l2(&st, ca, CA_SLAB_AXES, slab_axes, 2, 0);
|
|
249
|
+
if ( rc != CA_ITER_OK ) {
|
|
250
|
+
rb_raise(rb_eRuntimeError, "histogram_scatter_ki: iter init failed rc=%d", rc);
|
|
251
|
+
}
|
|
252
|
+
if ( weighted ) {
|
|
253
|
+
rc = ca_iter_state_init_l2(&stw, cw, CA_SLAB_AXES, w_slab_axes, 1, 0);
|
|
254
|
+
if ( rc != CA_ITER_OK ) {
|
|
255
|
+
rb_raise(rb_eRuntimeError, "histogram_scatter_ki: weights iter init failed rc=%d", rc);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
for ( mm = 0; mm < st.outer_ndim; mm++ ) cur_outer_idx[mm] = 0;
|
|
259
|
+
|
|
260
|
+
while ( ca_iter_state_next_slab_axes(&st, &p, &m) ) {
|
|
261
|
+
ca_size_t fiber_base = 0;
|
|
262
|
+
ca_size_t A, a, kk;
|
|
263
|
+
ca_size_t ss, cs, sms, cms, ws = 0, wms = 0;
|
|
264
|
+
|
|
265
|
+
if ( weighted && ! ca_iter_state_next_slab_axes(&stw, &pw, &mw) ) break;
|
|
266
|
+
|
|
267
|
+
for ( mm = 0; mm < st.outer_ndim; mm++ )
|
|
268
|
+
fiber_base += cur_outer_idx[mm] * fiber_stride[mm];
|
|
269
|
+
|
|
270
|
+
A = st.slab_dims[0]; /* samples */
|
|
271
|
+
ss = st.slab_strides[0]; /* sample byte stride */
|
|
272
|
+
cs = st.slab_strides[1]; /* channel byte stride */
|
|
273
|
+
sms = st.slab_mask_strides[0];
|
|
274
|
+
cms = st.slab_mask_strides[1];
|
|
275
|
+
if ( weighted ) {
|
|
276
|
+
ws = stw.slab_strides[0];
|
|
277
|
+
wms = stw.slab_mask_strides[0];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
for ( a = 0; a < A; a++ ) {
|
|
281
|
+
ca_size_t off = fiber_base;
|
|
282
|
+
int masked = 0;
|
|
283
|
+
for ( kk = 0; kk < (ca_size_t) M; kk++ ) {
|
|
284
|
+
double v = *(const double *)(p + a * ss + kk * cs);
|
|
285
|
+
if ( (m && m[a * sms + kk * cms]) || isnan(v) ) { masked = 1; break; }
|
|
286
|
+
off += histbin_index(&axes[kk], v) * ext_stride[kk];
|
|
287
|
+
}
|
|
288
|
+
if ( masked ) continue;
|
|
289
|
+
if ( weighted ) {
|
|
290
|
+
double w = *(const double *)(pw + a * ws);
|
|
291
|
+
if ( (mw && mw[a * wms]) || isnan(w) ) continue; /* skip masked / NaN weight */
|
|
292
|
+
cpd[off] += w;
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
cpi[off] += 1;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
for ( mm = (int8_t)(st.outer_ndim - 1); mm >= 0; mm-- ) {
|
|
300
|
+
if ( ++cur_outer_idx[mm] < st.outer_dims[mm] ) break;
|
|
301
|
+
cur_outer_idx[mm] = 0;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
ca_iter_state_finish(&st);
|
|
305
|
+
if ( weighted ) ca_iter_state_finish(&stw);
|
|
306
|
+
#undef st
|
|
307
|
+
#undef stw
|
|
308
|
+
(void) k;
|
|
309
|
+
return Qnil;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
static VALUE
|
|
313
|
+
histogram_scatter_edges (VALUE arg)
|
|
314
|
+
{
|
|
315
|
+
histogram_scatter_t *c = (histogram_scatter_t *) arg;
|
|
316
|
+
long k;
|
|
317
|
+
for ( k = 0; k < c->M; k++ ) {
|
|
318
|
+
histbin_axis_setup(&c->axes[k], (const double *) c->edge_ca[k]->ptr,
|
|
319
|
+
c->edge_ca[k]->elements,
|
|
320
|
+
RTEST(RARRAY_AREF(c->rincmax, k)));
|
|
321
|
+
}
|
|
322
|
+
if ( c->ca->elements > 0 ) {
|
|
323
|
+
ca_iter_ensure(2, c->states, histogram_scatter_walk, arg);
|
|
324
|
+
}
|
|
325
|
+
return Qnil;
|
|
326
|
+
}
|
|
327
|
+
|
|
204
328
|
static VALUE
|
|
205
329
|
rb_ca_histogram_scatter_ki (VALUE self, VALUE rcounts, VALUE redges,
|
|
206
330
|
VALUE rincmax, VALUE rweights)
|
|
@@ -258,8 +382,6 @@ rb_ca_histogram_scatter_ki (VALUE self, VALUE rcounts, VALUE redges,
|
|
|
258
382
|
for ( k = 0; k < M; k++ ) {
|
|
259
383
|
VALUE e = RARRAY_AREF(redges, k);
|
|
260
384
|
GetCArray(e, edge_ca[k]);
|
|
261
|
-
ca_attach(edge_ca[k]);
|
|
262
|
-
histbin_axis_setup(&axes[k], edge_ca[k], RTEST(RARRAY_AREF(rincmax, k)));
|
|
263
385
|
}
|
|
264
386
|
|
|
265
387
|
/* ext strides (row-major within the trailing M bin axes of counts). */
|
|
@@ -275,83 +397,19 @@ rb_ca_histogram_scatter_ki (VALUE self, VALUE rcounts, VALUE redges,
|
|
|
275
397
|
s *= cc->dim[k];
|
|
276
398
|
}
|
|
277
399
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
rc = ca_iter_state_init_l2(&st, ca, CA_SLAB_AXES, slab_axes, 2, 0);
|
|
291
|
-
if ( rc != CA_ITER_OK ) {
|
|
292
|
-
for ( k = 0; k < M; k++ ) ca_detach(edge_ca[k]);
|
|
293
|
-
rb_raise(rb_eRuntimeError, "histogram_scatter_ki: iter init failed rc=%d", rc);
|
|
294
|
-
}
|
|
295
|
-
if ( weighted ) {
|
|
296
|
-
rc = ca_iter_state_init_l2(&stw, cw, CA_SLAB_AXES, w_slab_axes, 1, 0);
|
|
297
|
-
if ( rc != CA_ITER_OK ) {
|
|
298
|
-
ca_iter_state_finish(&st);
|
|
299
|
-
for ( k = 0; k < M; k++ ) ca_detach(edge_ca[k]);
|
|
300
|
-
rb_raise(rb_eRuntimeError, "histogram_scatter_ki: weights iter init failed rc=%d", rc);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
for ( mm = 0; mm < st.outer_ndim; mm++ ) cur_outer_idx[mm] = 0;
|
|
304
|
-
|
|
305
|
-
while ( ca_iter_state_next_slab_axes(&st, &p, &m) ) {
|
|
306
|
-
ca_size_t fiber_base = 0;
|
|
307
|
-
ca_size_t A, a, kk;
|
|
308
|
-
ca_size_t ss, cs, sms, cms, ws = 0, wms = 0;
|
|
309
|
-
|
|
310
|
-
if ( weighted && ! ca_iter_state_next_slab_axes(&stw, &pw, &mw) ) break;
|
|
311
|
-
|
|
312
|
-
for ( mm = 0; mm < st.outer_ndim; mm++ )
|
|
313
|
-
fiber_base += cur_outer_idx[mm] * fiber_stride[mm];
|
|
314
|
-
|
|
315
|
-
A = st.slab_dims[0]; /* samples */
|
|
316
|
-
ss = st.slab_strides[0]; /* sample byte stride */
|
|
317
|
-
cs = st.slab_strides[1]; /* channel byte stride */
|
|
318
|
-
sms = st.slab_mask_strides[0];
|
|
319
|
-
cms = st.slab_mask_strides[1];
|
|
320
|
-
if ( weighted ) {
|
|
321
|
-
ws = stw.slab_strides[0];
|
|
322
|
-
wms = stw.slab_mask_strides[0];
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
for ( a = 0; a < A; a++ ) {
|
|
326
|
-
ca_size_t off = fiber_base;
|
|
327
|
-
int masked = 0;
|
|
328
|
-
for ( kk = 0; kk < (ca_size_t) M; kk++ ) {
|
|
329
|
-
double v = *(const double *)(p + a * ss + kk * cs);
|
|
330
|
-
if ( (m && m[a * sms + kk * cms]) || isnan(v) ) { masked = 1; break; }
|
|
331
|
-
off += histbin_index(&axes[kk], v) * ext_stride[kk];
|
|
332
|
-
}
|
|
333
|
-
if ( masked ) continue;
|
|
334
|
-
if ( weighted ) {
|
|
335
|
-
double w = *(const double *)(pw + a * ws);
|
|
336
|
-
if ( (mw && mw[a * wms]) || isnan(w) ) continue; /* skip masked / NaN weight */
|
|
337
|
-
cpd[off] += w;
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
cpi[off] += 1;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
for ( mm = (int8_t)(st.outer_ndim - 1); mm >= 0; mm-- ) {
|
|
345
|
-
if ( ++cur_outer_idx[mm] < st.outer_dims[mm] ) break;
|
|
346
|
-
cur_outer_idx[mm] = 0;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
ca_iter_state_finish(&st);
|
|
350
|
-
if ( weighted ) ca_iter_state_finish(&stw);
|
|
400
|
+
{
|
|
401
|
+
histogram_scatter_t c;
|
|
402
|
+
char modes[CA_RANK_MAX + 1];
|
|
403
|
+
for ( k = 0; k < M; k++ ) modes[k] = 'r';
|
|
404
|
+
modes[M] = '\0';
|
|
405
|
+
c.ca = ca; c.cc = cc; c.cw = cw;
|
|
406
|
+
c.M = M; c.nf = nf; c.weighted = weighted;
|
|
407
|
+
c.edge_ca = edge_ca; c.rincmax = rincmax; c.axes = axes;
|
|
408
|
+
c.ext_stride = ext_stride; c.fiber_stride = fiber_stride;
|
|
409
|
+
ca_attach_window((int32_t) M, edge_ca, modes, histogram_scatter_edges,
|
|
410
|
+
(VALUE) &c);
|
|
351
411
|
}
|
|
352
412
|
|
|
353
|
-
for ( k = 0; k < M; k++ ) ca_detach(edge_ca[k]);
|
|
354
|
-
|
|
355
413
|
return rcounts;
|
|
356
414
|
}
|
|
357
415
|
|
data/ext/carray_hold.c
CHANGED
|
@@ -49,7 +49,8 @@ rb_ca_hold_forward (VALUE self, int axis)
|
|
|
49
49
|
if ( rc != CA_ITER_OK ) {
|
|
50
50
|
rb_raise(rb_eRuntimeError, "__hold__: input init failed rc=%d", rc);
|
|
51
51
|
}
|
|
52
|
-
rc =
|
|
52
|
+
rc = ca_iter_state_init_l2_paired(&st_out, &st_in, co, CA_SLAB_AXES,
|
|
53
|
+
slab_axes, 1,
|
|
53
54
|
CA_KERNEL_WRITE);
|
|
54
55
|
if ( rc != CA_ITER_OK ) {
|
|
55
56
|
ca_iter_state_finish(&st_in);
|