carray 3.0.2 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +568 -0
- data/README.md +6 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +220 -0
- data/ext/ca_axis_group.c +201 -123
- data/ext/ca_binop_dispatch.c +46 -52
- data/ext/ca_binop_dispatch.h +1 -1
- data/ext/ca_categorical_iterator.c +249 -183
- data/ext/ca_compare.c +7 -12
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +38 -23
- data/ext/ca_kernel_iterator.c +1765 -2076
- data/ext/ca_kernel_iterator.h +584 -566
- data/ext/ca_monop_dispatch.c +86 -63
- data/ext/ca_monop_dispatch.h +5 -0
- data/ext/ca_obj_array.c +223 -56
- data/ext/ca_obj_bincmp.c +172 -138
- data/ext/ca_obj_binop.c +116 -230
- data/ext/ca_obj_bitarray.c +40 -26
- data/ext/ca_obj_bitfield.c +100 -68
- data/ext/ca_obj_block.c +19 -9
- data/ext/ca_obj_byte_swap.c +45 -46
- data/ext/ca_obj_const_string.c +269 -44
- data/ext/ca_obj_face.c +612 -89
- data/ext/ca_obj_face.h +111 -47
- data/ext/ca_obj_fake.c +36 -79
- data/ext/ca_obj_farray.c +7 -3
- data/ext/ca_obj_field.c +33 -8
- data/ext/ca_obj_fixlen_string.c +23 -24
- data/ext/ca_obj_grid.c +541 -210
- data/ext/ca_obj_meld.c +331 -111
- data/ext/ca_obj_moncmp.c +80 -65
- data/ext/ca_obj_monop.c +177 -149
- data/ext/ca_obj_object.c +664 -248
- data/ext/ca_obj_record.c +63 -23
- data/ext/ca_obj_reduce.c +18 -16
- data/ext/ca_obj_refer.c +140 -58
- data/ext/ca_obj_remap.c +85 -24
- data/ext/ca_obj_repeat.c +24 -9
- data/ext/ca_obj_roll.c +121 -16
- data/ext/ca_obj_select.c +61 -58
- data/ext/ca_obj_select_axis.c +73 -107
- data/ext/ca_obj_shift.c +32 -102
- data/ext/ca_obj_stack.c +372 -122
- data/ext/ca_obj_stride.c +348 -140
- data/ext/ca_obj_string.c +88 -22
- data/ext/ca_obj_tile.c +38 -21
- data/ext/ca_obj_time.c +45 -31
- data/ext/ca_obj_timedelta.c +43 -29
- data/ext/ca_obj_transpose.c +17 -6
- data/ext/ca_obj_triop.c +125 -141
- data/ext/ca_obj_window.c +330 -44
- data/ext/ca_op_ipower.c +24 -11
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +104 -81
- data/ext/ca_sweep_engine.h +7 -20
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +542 -0
- data/ext/carray.h +241 -92
- data/ext/carray_access.c +608 -276
- data/ext/carray_address_basis.c +494 -97
- data/ext/carray_attribute.c +129 -4
- data/ext/carray_bincount.c +39 -7
- data/ext/carray_broadcast.c +56 -19
- data/ext/carray_build_flags.h +1 -1
- data/ext/carray_call_cfunc.c +108 -28
- data/ext/carray_cast.c +1576 -223
- data/ext/carray_cast_func.rb +77 -24
- data/ext/carray_class.c +4 -3
- data/ext/carray_conversion.c +208 -75
- data/ext/carray_copy.c +82 -24
- data/ext/carray_core.c +646 -162
- data/ext/carray_count.c +171 -88
- data/ext/carray_element.c +94 -60
- data/ext/carray_factorize.c +670 -324
- data/ext/carray_generate.c +260 -83
- data/ext/carray_histogram.c +209 -106
- data/ext/carray_hold.c +14 -16
- data/ext/carray_index_classifier.c +422 -243
- data/ext/carray_internal.h +692 -3
- data/ext/carray_kernels_bincmp.c +7 -0
- data/ext/carray_kernels_binop.c +487 -120
- data/ext/carray_kernels_init.c +653 -50
- data/ext/carray_kernels_moncmp.c +15 -8
- data/ext/carray_kernels_monop.c +99 -43
- data/ext/carray_kernels_reduce_aggregate.c +3925 -6112
- data/ext/carray_kernels_reduce_boolean.c +112 -36
- data/ext/carray_kernels_reduce_cumulative.c +2127 -6903
- data/ext/carray_kernels_reduce_extreme.c +3032 -2892
- data/ext/carray_kernels_reduce_variance.c +439 -500
- data/ext/carray_kernels_scan.c +1097 -488
- data/ext/carray_kernels_search.c +3787 -2176
- data/ext/carray_kernels_sort.c +1200 -920
- data/ext/carray_kernels_triop.c +479 -7
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +967 -153
- data/ext/carray_loop.c +81 -65
- data/ext/carray_mask.c +910 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +299 -100
- data/ext/carray_memory_view.c +872 -758
- data/ext/carray_operator.c +1171 -364
- data/ext/carray_order.c +505 -133
- data/ext/carray_partition.c +112 -65
- data/ext/carray_random.c +327 -239
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +346 -78
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +249 -86
- data/ext/carray_sort.c +224 -227
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +118 -39
- data/ext/carray_test.c +193 -69
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +579 -113
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +19 -4
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1202 -1014
- data/ext/ruby_carray.c +17 -5
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +160 -17
- data/lib/carray/autoload_carray.rb +23 -27
- data/lib/carray/autoload_method_extension.rb +20 -5
- data/lib/carray/axis_group.rb +360 -63
- data/lib/carray/basics.rb +162 -28
- data/lib/carray/bincount_nd.rb +18 -2
- data/lib/carray/block_iterator.rb +231 -58
- data/lib/carray/boolean_reduce.rb +34 -42
- data/lib/carray/categorical.rb +242 -52
- data/lib/carray/categorical_iterator.rb +437 -827
- data/lib/carray/complex.rb +41 -34
- data/lib/carray/conditional.rb +150 -14
- data/lib/carray/const_string.rb +59 -4
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +7 -1
- data/lib/carray/frame/column_verbs.rb +70 -0
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +82 -7
- data/lib/carray/frame/csv_parser.rb +688 -87
- data/lib/carray/frame/describe.rb +80 -0
- data/lib/carray/frame/frame.rb +369 -45
- data/lib/carray/frame/group.rb +631 -90
- data/lib/carray/frame/io.rb +506 -79
- data/lib/carray/frame/join.rb +411 -62
- data/lib/carray/frame/records.rb +116 -19
- data/lib/carray/frame/reshape.rb +455 -0
- data/lib/carray/frame/sort.rb +30 -18
- data/lib/carray/frame/verbs.rb +868 -61
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +4 -0
- data/lib/carray/fuse_source.rb +118 -2
- data/lib/carray/fusion.rb +257 -42
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +54 -13
- data/lib/carray/iterator.rb +99 -9
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +216 -193
- data/lib/carray/mask_gap_fill.rb +112 -92
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +52 -21
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +18 -2
- data/lib/carray/methods/bit_string.rb +15 -4
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +18 -10
- data/lib/carray/methods/factorize.rb +2 -2
- data/lib/carray/methods/gather_nd.rb +25 -5
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +140 -10
- data/lib/carray/methods/join.rb +2 -7
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +182 -45
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/repeat.rb +1 -20
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +11 -2
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +65 -17
- data/lib/carray/segment_iterator.rb +1221 -0
- data/lib/carray/serialize.rb +214 -30
- data/lib/carray/slab_iterator.rb +101 -27
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +12 -4
- data/lib/carray/struct.rb +137 -58
- data/lib/carray/struct_builder.rb +124 -17
- data/lib/carray/time.rb +1222 -186
- data/lib/carray/window_iterator.rb +242 -81
- data/lib/carray.rb +9 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +5 -1
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +5 -4
- data/yard-stubs/ca_obj_roll.rb +2 -3
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +9 -5
- data/yard-stubs/carray_access.rb +11 -5
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_broadcast.rb +1 -1
- data/yard-stubs/carray_cast.rb +88 -43
- data/yard-stubs/carray_conversion.rb +15 -2
- data/yard-stubs/carray_copy.rb +12 -5
- data/yard-stubs/carray_core.rb +3 -3
- data/yard-stubs/carray_count.rb +9 -0
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_lazy.rb +5 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +60 -12
- data/yard-stubs/carray_math.rb +52 -14
- data/yard-stubs/carray_median_percentile.rb +15 -8
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +61 -29
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +21 -9
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +10 -2
- data/yard-stubs/carray_sort.rb +49 -8
- data/yard-stubs/carray_test.rb +15 -3
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -5
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_kernels_map.c +0 -3467
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/carray_histogram.c
CHANGED
|
@@ -23,13 +23,42 @@
|
|
|
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
|
-
/*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
static
|
|
32
|
-
|
|
29
|
+
/* Edges are the bin boundaries and must read as such: no masked edge (its
|
|
30
|
+
stored value is no boundary), no NaN, and no edge below the one before
|
|
31
|
+
it. Equal edges (a bin of zero width) and infinite ones are kept. */
|
|
32
|
+
static void
|
|
33
|
+
histbin_check_edge_mask (CArray *ce, const char *name)
|
|
34
|
+
{
|
|
35
|
+
if ( ca_has_mask(ce) && ca_is_any_masked(ce) ) {
|
|
36
|
+
rb_raise(rb_eArgError, "%s: edges has a masked value", name);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static void
|
|
41
|
+
histbin_check_edge_order (const double *ep, ca_size_t n, const char *name)
|
|
42
|
+
{
|
|
43
|
+
ca_size_t i;
|
|
44
|
+
for (i = 0; i < n; i++) {
|
|
45
|
+
if ( isnan(ep[i]) ) {
|
|
46
|
+
rb_raise(rb_eArgError, "%s: edges has NaN at %lld", name, (long long) i);
|
|
47
|
+
}
|
|
48
|
+
if ( i > 0 && ep[i] < ep[i-1] ) {
|
|
49
|
+
rb_raise(rb_eArgError, "%s: edges must not decrease "
|
|
50
|
+
"(%g at %lld after %g)", name, ep[i], (long long) i, ep[i-1]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Resolve `redges` to a 1-D float64 CArray of at least two edges, and
|
|
56
|
+
return it: it may be a view made here, which only the caller can keep
|
|
57
|
+
alive. The caller copies the edges out (ca_xfer_all into its own
|
|
58
|
+
buffer) rather than attaching them: the walk that follows reads the
|
|
59
|
+
caller's array, and a raise there must not leave the edges attached. */
|
|
60
|
+
static VALUE
|
|
61
|
+
histbin_resolve_edges (VALUE self, VALUE redges)
|
|
33
62
|
{
|
|
34
63
|
CArray *ce;
|
|
35
64
|
|
|
@@ -48,11 +77,9 @@ histbin_attach_edges (VALUE self, VALUE redges, double **ep_out, ca_size_t *ne_o
|
|
|
48
77
|
if ( ce->elements < 2 ) {
|
|
49
78
|
rb_raise(rb_eArgError, "histbin_ki: edges needs at least 2 values");
|
|
50
79
|
}
|
|
80
|
+
histbin_check_edge_mask(ce, "bin_to");
|
|
51
81
|
|
|
52
|
-
|
|
53
|
-
*ep_out = (double *) ce->ptr;
|
|
54
|
-
*ne_out = ce->elements;
|
|
55
|
-
return ce;
|
|
82
|
+
return redges;
|
|
56
83
|
}
|
|
57
84
|
|
|
58
85
|
/* ---- shared binning helpers (used by histbin_ki + the fused kernel) ---- */
|
|
@@ -105,19 +132,24 @@ histbin_index (const histbin_axis_t *ax, double v)
|
|
|
105
132
|
}
|
|
106
133
|
|
|
107
134
|
static void
|
|
108
|
-
histbin_axis_setup (histbin_axis_t *ax,
|
|
135
|
+
histbin_axis_setup (histbin_axis_t *ax, const double *ep, ca_size_t ne,
|
|
136
|
+
int include_max)
|
|
109
137
|
{
|
|
110
|
-
ca_size_t
|
|
138
|
+
ca_size_t kk;
|
|
111
139
|
double dx, tol;
|
|
112
140
|
|
|
113
|
-
ax->ep =
|
|
141
|
+
ax->ep = ep;
|
|
114
142
|
ax->n = ne - 1;
|
|
115
143
|
ax->lo = ax->ep[0];
|
|
116
144
|
ax->hi = ax->ep[ne - 1];
|
|
117
145
|
dx = (ax->hi - ax->lo) / (double) ax->n;
|
|
118
146
|
tol = fabs(dx) * 1e-9 + 1e-12;
|
|
119
|
-
|
|
120
|
-
|
|
147
|
+
/* The linearised index needs a width and its reciprocal that are both
|
|
148
|
+
finite and nonzero: edges spanning more than a double holds make the
|
|
149
|
+
width infinite, and a subnormal width makes the reciprocal infinite.
|
|
150
|
+
Either turns the position into NaN, which has no integer. */
|
|
151
|
+
ax->uniform = isfinite(dx) && dx != 0.0 && isfinite(1.0 / dx);
|
|
152
|
+
for ( kk = 0; ax->uniform && kk <= ax->n; kk++ ) {
|
|
121
153
|
if ( fabs(ax->ep[kk] - (ax->lo + (double) kk * dx)) > tol ) { ax->uniform = 0; break; }
|
|
122
154
|
}
|
|
123
155
|
ax->inv_dx = (dx != 0.0) ? 1.0 / dx : 0.0;
|
|
@@ -129,8 +161,8 @@ rb_ca_histbin_ki (VALUE self, VALUE redges, VALUE rinclude_max)
|
|
|
129
161
|
{
|
|
130
162
|
CArray *ca, *co, *ce;
|
|
131
163
|
VALUE vout;
|
|
164
|
+
volatile VALUE hedges = 0;
|
|
132
165
|
double *ep;
|
|
133
|
-
ca_size_t ne;
|
|
134
166
|
histbin_axis_t ax;
|
|
135
167
|
|
|
136
168
|
GetCArray(self, ca);
|
|
@@ -140,9 +172,13 @@ rb_ca_histbin_ki (VALUE self, VALUE redges, VALUE rinclude_max)
|
|
|
140
172
|
ca_type_name[ca->data_type]);
|
|
141
173
|
}
|
|
142
174
|
|
|
143
|
-
|
|
144
|
-
(
|
|
145
|
-
|
|
175
|
+
redges = histbin_resolve_edges(self, redges);
|
|
176
|
+
GetCArray(redges, ce);
|
|
177
|
+
ep = ALLOCV_N(double, hedges, ce->elements);
|
|
178
|
+
ca_xfer_all(ce, ep, CA_XFER_GET);
|
|
179
|
+
histbin_check_edge_order(ep, ce->elements, "bin_to");
|
|
180
|
+
histbin_axis_setup(&ax, ep, ce->elements, RTEST(rinclude_max));
|
|
181
|
+
RB_GC_GUARD(redges); /* a view made by histbin_resolve_edges is read through ce */
|
|
146
182
|
|
|
147
183
|
/* output: fresh contiguous int64, same shape as self. */
|
|
148
184
|
vout = rb_carray_new(CA_INT64, ca->ndim, ca->dim, 0, NULL);
|
|
@@ -179,7 +215,7 @@ rb_ca_histbin_ki (VALUE self, VALUE redges, VALUE rinclude_max)
|
|
|
179
215
|
}
|
|
180
216
|
}
|
|
181
217
|
|
|
182
|
-
|
|
218
|
+
ALLOCV_END(hedges);
|
|
183
219
|
|
|
184
220
|
return vout;
|
|
185
221
|
}
|
|
@@ -201,6 +237,129 @@ rb_ca_histbin_ki (VALUE self, VALUE redges, VALUE rinclude_max)
|
|
|
201
237
|
off = fiber_base + Σ_k histbin_index(axis_k, v_{a,k}) * ext_stride[k]
|
|
202
238
|
counts[off] += 1 (or += weight when weighted)
|
|
203
239
|
=========================================================================== */
|
|
240
|
+
/* histogram_scatter_ki reads its edges inside an attach window and walks
|
|
241
|
+
the samples (and the weights) with two kernel iterators, whose states
|
|
242
|
+
live here, outside the walk: a sample view that raises as it is read --
|
|
243
|
+
a lazy source meeting a cell it cannot compute -- leaves neither the
|
|
244
|
+
edges nor the other walk open. */
|
|
245
|
+
typedef struct {
|
|
246
|
+
ca_iter_state states[2]; /* the samples, the weights */
|
|
247
|
+
CArray *ca, *cc, *cw;
|
|
248
|
+
long M, nf;
|
|
249
|
+
int weighted;
|
|
250
|
+
CArray **edge_ca;
|
|
251
|
+
VALUE rincmax;
|
|
252
|
+
histbin_axis_t *axes;
|
|
253
|
+
ca_size_t *ext_stride;
|
|
254
|
+
ca_size_t *fiber_stride;
|
|
255
|
+
} histogram_scatter_t;
|
|
256
|
+
|
|
257
|
+
static VALUE
|
|
258
|
+
histogram_scatter_walk (VALUE arg)
|
|
259
|
+
{
|
|
260
|
+
histogram_scatter_t *c = (histogram_scatter_t *) arg;
|
|
261
|
+
CArray *ca = c->ca, *cc = c->cc, *cw = c->cw;
|
|
262
|
+
long M = c->M, k;
|
|
263
|
+
int weighted = c->weighted;
|
|
264
|
+
histbin_axis_t *axes = c->axes;
|
|
265
|
+
ca_size_t *ext_stride = c->ext_stride;
|
|
266
|
+
ca_size_t *fiber_stride = c->fiber_stride;
|
|
267
|
+
#define st (c->states[0])
|
|
268
|
+
#define stw (c->states[1])
|
|
269
|
+
int64_t *cpi = (int64_t *) cc->ptr; /* unweighted */
|
|
270
|
+
double *cpd = (double *) cc->ptr; /* weighted */
|
|
271
|
+
char *p, *pw = NULL;
|
|
272
|
+
boolean8_t *m, *mw = NULL;
|
|
273
|
+
ca_size_t cur_outer_idx[CA_RANK_MAX];
|
|
274
|
+
int8_t slab_axes[2] = { (int8_t)(ca->ndim - 2), (int8_t)(ca->ndim - 1) };
|
|
275
|
+
int8_t w_slab_axes[1] = { (int8_t)(ca->ndim - 2) }; /* weights sample axis */
|
|
276
|
+
int8_t mm;
|
|
277
|
+
int rc;
|
|
278
|
+
|
|
279
|
+
rc = ca_iter_state_init_l2(&st, ca, CA_SLAB_AXES, slab_axes, 2, 0);
|
|
280
|
+
if ( rc != CA_ITER_OK ) {
|
|
281
|
+
rb_raise(rb_eRuntimeError, "histogram_scatter_ki: iter init failed rc=%d", rc);
|
|
282
|
+
}
|
|
283
|
+
if ( weighted ) {
|
|
284
|
+
rc = ca_iter_state_init_l2(&stw, cw, CA_SLAB_AXES, w_slab_axes, 1, 0);
|
|
285
|
+
if ( rc != CA_ITER_OK ) {
|
|
286
|
+
rb_raise(rb_eRuntimeError, "histogram_scatter_ki: weights iter init failed rc=%d", rc);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
for ( mm = 0; mm < st.outer_ndim; mm++ ) cur_outer_idx[mm] = 0;
|
|
290
|
+
|
|
291
|
+
while ( ca_iter_state_next_slab_axes(&st, &p, &m) ) {
|
|
292
|
+
ca_size_t fiber_base = 0;
|
|
293
|
+
ca_size_t A, a, kk;
|
|
294
|
+
ca_size_t ss, cs, sms, cms, ws = 0, wms = 0;
|
|
295
|
+
|
|
296
|
+
if ( weighted && ! ca_iter_state_next_slab_axes(&stw, &pw, &mw) ) break;
|
|
297
|
+
|
|
298
|
+
for ( mm = 0; mm < st.outer_ndim; mm++ )
|
|
299
|
+
fiber_base += cur_outer_idx[mm] * fiber_stride[mm];
|
|
300
|
+
|
|
301
|
+
A = st.slab_dims[0]; /* samples */
|
|
302
|
+
ss = st.slab_strides[0]; /* sample byte stride */
|
|
303
|
+
cs = st.slab_strides[1]; /* channel byte stride */
|
|
304
|
+
sms = st.slab_mask_strides[0];
|
|
305
|
+
cms = st.slab_mask_strides[1];
|
|
306
|
+
if ( weighted ) {
|
|
307
|
+
ws = stw.slab_strides[0];
|
|
308
|
+
wms = stw.slab_mask_strides[0];
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
for ( a = 0; a < A; a++ ) {
|
|
312
|
+
ca_size_t off = fiber_base;
|
|
313
|
+
int masked = 0;
|
|
314
|
+
for ( kk = 0; kk < (ca_size_t) M; kk++ ) {
|
|
315
|
+
double v = *(const double *)(p + a * ss + kk * cs);
|
|
316
|
+
if ( (m && m[a * sms + kk * cms]) || isnan(v) ) { masked = 1; break; }
|
|
317
|
+
off += histbin_index(&axes[kk], v) * ext_stride[kk];
|
|
318
|
+
}
|
|
319
|
+
if ( masked ) continue;
|
|
320
|
+
if ( weighted ) {
|
|
321
|
+
double w = *(const double *)(pw + a * ws);
|
|
322
|
+
if ( (mw && mw[a * wms]) || isnan(w) ) continue; /* skip masked / NaN weight */
|
|
323
|
+
cpd[off] += w;
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
cpi[off] += 1;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
for ( mm = (int8_t)(st.outer_ndim - 1); mm >= 0; mm-- ) {
|
|
331
|
+
if ( ++cur_outer_idx[mm] < st.outer_dims[mm] ) break;
|
|
332
|
+
cur_outer_idx[mm] = 0;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
ca_iter_state_finish(&st);
|
|
336
|
+
if ( weighted ) ca_iter_state_finish(&stw);
|
|
337
|
+
#undef st
|
|
338
|
+
#undef stw
|
|
339
|
+
(void) k;
|
|
340
|
+
return Qnil;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
static VALUE
|
|
344
|
+
histogram_scatter_edges (VALUE arg)
|
|
345
|
+
{
|
|
346
|
+
histogram_scatter_t *c = (histogram_scatter_t *) arg;
|
|
347
|
+
long k;
|
|
348
|
+
for ( k = 0; k < c->M; k++ ) {
|
|
349
|
+
histbin_check_edge_order((const double *) c->edge_ca[k]->ptr,
|
|
350
|
+
c->edge_ca[k]->elements, "histogram");
|
|
351
|
+
}
|
|
352
|
+
for ( k = 0; k < c->M; k++ ) {
|
|
353
|
+
histbin_axis_setup(&c->axes[k], (const double *) c->edge_ca[k]->ptr,
|
|
354
|
+
c->edge_ca[k]->elements,
|
|
355
|
+
RTEST(RARRAY_AREF(c->rincmax, k)));
|
|
356
|
+
}
|
|
357
|
+
if ( c->ca->elements > 0 ) {
|
|
358
|
+
ca_iter_ensure(2, c->states, histogram_scatter_walk, arg);
|
|
359
|
+
}
|
|
360
|
+
return Qnil;
|
|
361
|
+
}
|
|
362
|
+
|
|
204
363
|
static VALUE
|
|
205
364
|
rb_ca_histogram_scatter_ki (VALUE self, VALUE rcounts, VALUE redges,
|
|
206
365
|
VALUE rincmax, VALUE rweights)
|
|
@@ -258,8 +417,7 @@ rb_ca_histogram_scatter_ki (VALUE self, VALUE rcounts, VALUE redges,
|
|
|
258
417
|
for ( k = 0; k < M; k++ ) {
|
|
259
418
|
VALUE e = RARRAY_AREF(redges, k);
|
|
260
419
|
GetCArray(e, edge_ca[k]);
|
|
261
|
-
|
|
262
|
-
histbin_axis_setup(&axes[k], edge_ca[k], RTEST(RARRAY_AREF(rincmax, k)));
|
|
420
|
+
histbin_check_edge_mask(edge_ca[k], "histogram");
|
|
263
421
|
}
|
|
264
422
|
|
|
265
423
|
/* ext strides (row-major within the trailing M bin axes of counts). */
|
|
@@ -275,83 +433,19 @@ rb_ca_histogram_scatter_ki (VALUE self, VALUE rcounts, VALUE redges,
|
|
|
275
433
|
s *= cc->dim[k];
|
|
276
434
|
}
|
|
277
435
|
|
|
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);
|
|
436
|
+
{
|
|
437
|
+
histogram_scatter_t c;
|
|
438
|
+
char modes[CA_RANK_MAX + 1];
|
|
439
|
+
for ( k = 0; k < M; k++ ) modes[k] = 'r';
|
|
440
|
+
modes[M] = '\0';
|
|
441
|
+
c.ca = ca; c.cc = cc; c.cw = cw;
|
|
442
|
+
c.M = M; c.nf = nf; c.weighted = weighted;
|
|
443
|
+
c.edge_ca = edge_ca; c.rincmax = rincmax; c.axes = axes;
|
|
444
|
+
c.ext_stride = ext_stride; c.fiber_stride = fiber_stride;
|
|
445
|
+
ca_attach_window((int32_t) M, edge_ca, modes, histogram_scatter_edges,
|
|
446
|
+
(VALUE) &c);
|
|
351
447
|
}
|
|
352
448
|
|
|
353
|
-
for ( k = 0; k < M; k++ ) ca_detach(edge_ca[k]);
|
|
354
|
-
|
|
355
449
|
return rcounts;
|
|
356
450
|
}
|
|
357
451
|
|
|
@@ -370,7 +464,16 @@ rb_ca_histogram_scatter_ki (VALUE self, VALUE rcounts, VALUE redges,
|
|
|
370
464
|
weights = nil OR float64 [fiber..., A] (second iterator in lockstep).
|
|
371
465
|
=========================================================================== */
|
|
372
466
|
|
|
373
|
-
|
|
467
|
+
/* A label at or above the last bin lands in the overflow cell. An unsigned
|
|
468
|
+
64-bit label above INT64_MAX must be clamped before it becomes an int64,
|
|
469
|
+
or it turns negative and indexes before the counts. */
|
|
470
|
+
static inline int64_t
|
|
471
|
+
bincount_nd_label_u64 (uint64_t x)
|
|
472
|
+
{
|
|
473
|
+
return ( x > (uint64_t) INT64_MAX ) ? INT64_MAX : (int64_t) x;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
#define BINCOUNT_ND_BODY(LABEL_T, TO_INT64) \
|
|
374
477
|
do { \
|
|
375
478
|
while ( ca_iter_state_next_slab_axes(&st, &p, &m) ) { \
|
|
376
479
|
ca_size_t fiber_base = 0, A, a, kk, ss, cs, sms, cms, ws = 0, wms = 0; \
|
|
@@ -383,7 +486,7 @@ rb_ca_histogram_scatter_ki (VALUE self, VALUE rcounts, VALUE redges,
|
|
|
383
486
|
for ( a = 0; a < A; a++ ) { \
|
|
384
487
|
ca_size_t off = fiber_base; int masked = 0; \
|
|
385
488
|
for ( kk = 0; kk < (ca_size_t) M; kk++ ) { \
|
|
386
|
-
int64_t v = (
|
|
489
|
+
int64_t v = TO_INT64(*(const LABEL_T *)(p + a * ss + kk * cs)); \
|
|
387
490
|
if ( m && m[a * sms + kk * cms] ) { masked = 1; break; } \
|
|
388
491
|
if ( v >= ext_dim[kk] - 1 ) v = ext_dim[kk] - 1; \
|
|
389
492
|
off += (ca_size_t) v * ext_stride[kk]; \
|
|
@@ -457,14 +560,14 @@ rb_ca_bincount_nd_count_ki (VALUE self, VALUE rcounts, VALUE rweights)
|
|
|
457
560
|
for ( mm = 0; mm < st.outer_ndim; mm++ ) cur_outer_idx[mm] = 0;
|
|
458
561
|
|
|
459
562
|
switch ( ca->data_type ) {
|
|
460
|
-
case CA_INT8: BINCOUNT_ND_BODY(int8_t); break;
|
|
461
|
-
case CA_UINT8: BINCOUNT_ND_BODY(uint8_t); break;
|
|
462
|
-
case CA_INT16: BINCOUNT_ND_BODY(int16_t); break;
|
|
463
|
-
case CA_UINT16: BINCOUNT_ND_BODY(uint16_t); break;
|
|
464
|
-
case CA_INT32: BINCOUNT_ND_BODY(int32_t); break;
|
|
465
|
-
case CA_UINT32: BINCOUNT_ND_BODY(uint32_t); break;
|
|
466
|
-
case CA_INT64: BINCOUNT_ND_BODY(int64_t); break;
|
|
467
|
-
case CA_UINT64: BINCOUNT_ND_BODY(uint64_t); break;
|
|
563
|
+
case CA_INT8: BINCOUNT_ND_BODY(int8_t, (int64_t)); break;
|
|
564
|
+
case CA_UINT8: BINCOUNT_ND_BODY(uint8_t, (int64_t)); break;
|
|
565
|
+
case CA_INT16: BINCOUNT_ND_BODY(int16_t, (int64_t)); break;
|
|
566
|
+
case CA_UINT16: BINCOUNT_ND_BODY(uint16_t, (int64_t)); break;
|
|
567
|
+
case CA_INT32: BINCOUNT_ND_BODY(int32_t, (int64_t)); break;
|
|
568
|
+
case CA_UINT32: BINCOUNT_ND_BODY(uint32_t, (int64_t)); break;
|
|
569
|
+
case CA_INT64: BINCOUNT_ND_BODY(int64_t, (int64_t)); break;
|
|
570
|
+
case CA_UINT64: BINCOUNT_ND_BODY(uint64_t, bincount_nd_label_u64); break;
|
|
468
571
|
default:
|
|
469
572
|
ca_iter_state_finish(&st);
|
|
470
573
|
if ( weighted ) ca_iter_state_finish(&stw);
|
data/ext/carray_hold.c
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
#include "carray.h"
|
|
21
21
|
#include "ca_kernel_iterator.h"
|
|
22
22
|
#include "ca_obj_face.h"
|
|
23
|
+
#include "carray_internal.h" /* ca_normalize_axis_arg */
|
|
23
24
|
|
|
24
25
|
/* Forward hold along `axis`. Per fiber along the scan axis:
|
|
25
26
|
- present cell -> output = cell value, becomes the held value;
|
|
@@ -47,21 +48,24 @@ rb_ca_hold_forward (VALUE self, int axis)
|
|
|
47
48
|
ca_iter_state st_in, st_out;
|
|
48
49
|
int rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES, slab_axes, 1, 0);
|
|
49
50
|
if ( rc != CA_ITER_OK ) {
|
|
50
|
-
rb_raise(rb_eRuntimeError, "
|
|
51
|
+
rb_raise(rb_eRuntimeError, "hold_forward: input init failed rc=%d", rc);
|
|
51
52
|
}
|
|
52
|
-
rc =
|
|
53
|
+
rc = ca_iter_state_init_l2_paired(&st_out, &st_in, co, CA_SLAB_AXES,
|
|
54
|
+
slab_axes, 1,
|
|
53
55
|
CA_KERNEL_WRITE);
|
|
54
56
|
if ( rc != CA_ITER_OK ) {
|
|
55
57
|
ca_iter_state_finish(&st_in);
|
|
56
|
-
rb_raise(rb_eRuntimeError, "
|
|
58
|
+
rb_raise(rb_eRuntimeError, "hold_forward: output init failed rc=%d", rc);
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
/* Output mask allocated lazily on the first leading-masked (UNDEF) cell:
|
|
60
62
|
a fiber can only go UNDEF on a leading masked run, so a fully filled
|
|
61
|
-
result carries no mask at all.
|
|
62
|
-
|
|
63
|
+
result carries no mask at all. The output is a fresh row-major entity
|
|
64
|
+
and the walk cuts its slabs from a buffer laid out the same way (the
|
|
65
|
+
output's memory, or the walk's scratch when it delivers by transfer),
|
|
66
|
+
so a slab's offset from st_out.alias_ptr is its offset in co, which
|
|
67
|
+
op_mask parallels. */
|
|
63
68
|
boolean8_t *op_mask = NULL;
|
|
64
|
-
char *co_root = (char *) co->ptr;
|
|
65
69
|
|
|
66
70
|
char *pi, *po;
|
|
67
71
|
boolean8_t *mi, *mo;
|
|
@@ -72,7 +76,7 @@ rb_ca_hold_forward (VALUE self, int axis)
|
|
|
72
76
|
ca_size_t oS = st_out.slab_strides[0]; /* output data byte stride */
|
|
73
77
|
ca_size_t iMS = st_in.slab_mask_strides[0]; /* input mask element stride */
|
|
74
78
|
ca_size_t oMStep = oS / K; /* output mask element step */
|
|
75
|
-
ca_size_t oMBase = (ca_size_t)(po -
|
|
79
|
+
ca_size_t oMBase = (ca_size_t)(po - st_out.alias_ptr) / K;
|
|
76
80
|
const char *held = NULL; /* last valid cell (points into input slab) */
|
|
77
81
|
|
|
78
82
|
for ( ca_size_t j = 0; j < N; j++ ) {
|
|
@@ -103,7 +107,7 @@ rb_ca_hold_forward (VALUE self, int axis)
|
|
|
103
107
|
return vout;
|
|
104
108
|
}
|
|
105
109
|
|
|
106
|
-
/*
|
|
110
|
+
/* hold_forward(axis): private forward-hold primitive. axis is a required
|
|
107
111
|
Integer (negative counts from the end). The Ruby wrapper composes
|
|
108
112
|
backward / flatten / linear on top of this. */
|
|
109
113
|
static VALUE
|
|
@@ -111,13 +115,7 @@ rb_ca_hold_method (VALUE self, VALUE raxis)
|
|
|
111
115
|
{
|
|
112
116
|
CArray *ca;
|
|
113
117
|
GetCArray(self, ca);
|
|
114
|
-
|
|
115
|
-
if ( axis < 0 ) axis += ca->ndim;
|
|
116
|
-
if ( axis < 0 || axis >= ca->ndim ) {
|
|
117
|
-
rb_raise(rb_eArgError, "__hold__: axis %d out of range for ndim %d",
|
|
118
|
-
NUM2INT(raxis), ca->ndim);
|
|
119
|
-
}
|
|
120
|
-
return rb_ca_hold_forward(self, axis);
|
|
118
|
+
return rb_ca_hold_forward(self, ca_normalize_axis_arg(raxis, ca->ndim, NULL));
|
|
121
119
|
}
|
|
122
120
|
|
|
123
121
|
/* first / last: the reduction sibling of hold. Reduce each fiber to its
|
|
@@ -222,7 +220,7 @@ rb_ca_last (int argc, VALUE *argv, VALUE self)
|
|
|
222
220
|
void
|
|
223
221
|
Init_carray_hold (void)
|
|
224
222
|
{
|
|
225
|
-
rb_define_private_method(rb_cCArray, "
|
|
223
|
+
rb_define_private_method(rb_cCArray, "hold_forward", rb_ca_hold_method, 1);
|
|
226
224
|
rb_define_method(rb_cCArray, "first", rb_ca_first, -1);
|
|
227
225
|
rb_define_method(rb_cCArray, "last", rb_ca_last, -1);
|
|
228
226
|
}
|