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
|
@@ -83,10 +83,10 @@ class CAWindowIterator < CAIterator
|
|
|
83
83
|
def initialize (source, *ranges, bounds: :skip, fill_value: nil)
|
|
84
84
|
if source.is_a?(CArray) && source.obj_type == CA_OBJ_WINDOW
|
|
85
85
|
# Backward-compat: read geometry from a CAWindow view built by #window.
|
|
86
|
-
# start[i] = lo,
|
|
86
|
+
# start[i] = lo, shape[i] (window width) = w, so hi = lo + w - 1.
|
|
87
87
|
win = source
|
|
88
88
|
@source = win.parent
|
|
89
|
-
widths = win.
|
|
89
|
+
widths = win.shape
|
|
90
90
|
@ranges = win.start.each_with_index.map { |lo, i| lo..(lo + widths[i] - 1) }
|
|
91
91
|
# The legacy #window default is FILL (constant), whose value is the
|
|
92
92
|
# view's fill_value; map that to a :constant margin.
|
|
@@ -104,6 +104,7 @@ class CAWindowIterator < CAIterator
|
|
|
104
104
|
"windows: expected #{@source.ndim} ranges (one per axis), " \
|
|
105
105
|
"got #{@ranges.size}"
|
|
106
106
|
end
|
|
107
|
+
@ranges = @ranges.each_with_index.map { |r, k| window_offsets(r, k) }
|
|
107
108
|
|
|
108
109
|
@sndim = @source.ndim
|
|
109
110
|
@widths = @ranges.map { |r| r.end - r.begin + 1 }
|
|
@@ -158,11 +159,38 @@ class CAWindowIterator < CAIterator
|
|
|
158
159
|
# the padded entity.
|
|
159
160
|
# @return [CArray]
|
|
160
161
|
def sliding_view
|
|
161
|
-
@sliding_view ||= anchored_buffer.sliding_windows(*@widths)
|
|
162
|
+
@sliding_view ||= @shape.include?(0) ? no_windows : anchored_buffer.sliding_windows(*@widths)
|
|
162
163
|
end
|
|
163
164
|
|
|
164
165
|
private
|
|
165
166
|
|
|
167
|
+
# An axis's offsets as an inclusive Integer range, as Ruby reads the range
|
|
168
|
+
# given (`-1...1` is the offsets -1 and 0).
|
|
169
|
+
def window_offsets (r, k)
|
|
170
|
+
unless r.is_a?(Range) && r.begin.is_a?(Integer) && r.end.is_a?(Integer)
|
|
171
|
+
raise TypeError,
|
|
172
|
+
"windows: axis #{k} takes a Range of Integer offsets, got #{r.inspect}"
|
|
173
|
+
end
|
|
174
|
+
last = r.exclude_end? ? r.end - 1 : r.end
|
|
175
|
+
if last < r.begin
|
|
176
|
+
raise ArgumentError, "windows: axis #{k} offsets #{r.inspect} are empty"
|
|
177
|
+
end
|
|
178
|
+
r.begin..last
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# With no anchors (an empty source, or a :truncate window wider than the
|
|
182
|
+
# source) there is nothing to slide over, and sliding_windows refuses a
|
|
183
|
+
# window wider than its buffer. The view is then an empty one of the same
|
|
184
|
+
# shape: the source's unit tiles cut to the output and stretched along the
|
|
185
|
+
# window axes, so every reduction answers with an empty array of its type.
|
|
186
|
+
def no_windows
|
|
187
|
+
unit = @source.block_view(*[1] * @sndim)
|
|
188
|
+
cut = @shape.each_with_index.map { |n, k| n == unit.shape[k] ? nil : 0...n }
|
|
189
|
+
unit = unit[*cut, *[nil] * @sndim] unless cut.all?(&:nil?)
|
|
190
|
+
view = unit.broadcast_to(*(@shape + @widths))
|
|
191
|
+
@source.face? ? view.face_lift(@source) : view
|
|
192
|
+
end
|
|
193
|
+
|
|
166
194
|
# The stretch of the padded buffer the windows are taken from: it begins at
|
|
167
195
|
# the first window and holds one window per anchor. For a window that covers
|
|
168
196
|
# its own anchor and a boundary policy that pads, that is the whole buffer.
|
|
@@ -210,10 +238,11 @@ class CAWindowIterator < CAIterator
|
|
|
210
238
|
# One allocation, the source copied into the interior region, then the
|
|
211
239
|
# margins filled per mode.
|
|
212
240
|
def pad_source (src, lefts, rights, mode, value)
|
|
241
|
+
return pad_face(src, lefts, rights, mode, value) if src.face?
|
|
213
242
|
nd = src.ndim
|
|
214
243
|
shape = src.shape
|
|
215
244
|
pshape = nd.times.map { |i| shape[i] + lefts[i] + rights[i] }
|
|
216
|
-
pad = CArray.new(src.data_type, pshape)
|
|
245
|
+
pad = CArray.new(src.data_type, pshape, bytes: src.bytes)
|
|
217
246
|
|
|
218
247
|
# Fill the whole buffer first, then overwrite the interior with the source.
|
|
219
248
|
case mode
|
|
@@ -222,8 +251,8 @@ class CAWindowIterator < CAIterator
|
|
|
222
251
|
when :masked
|
|
223
252
|
pad[] = UNDEF
|
|
224
253
|
when :edge
|
|
225
|
-
#
|
|
226
|
-
|
|
254
|
+
# Nothing to fill: every margin cell is written from the source below
|
|
255
|
+
# (a provisional 0 cannot be stored in a fixlen buffer).
|
|
227
256
|
end
|
|
228
257
|
|
|
229
258
|
interior = nd.times.map { |i| lefts[i]...(lefts[i] + shape[i]) }
|
|
@@ -234,6 +263,23 @@ class CAWindowIterator < CAIterator
|
|
|
234
263
|
pad
|
|
235
264
|
end
|
|
236
265
|
|
|
266
|
+
# A Face is padded on its storage and put back on at the end, so the margins
|
|
267
|
+
# hold storage -- UNDEF, a copy of an edge cell, or a `:constant` value the
|
|
268
|
+
# Face has turned into storage -- and the reductions over the windows are
|
|
269
|
+
# the Face's own. A buffer of the Face's surface type could not take the
|
|
270
|
+
# margin values at all.
|
|
271
|
+
def pad_face (src, lefts, rights, mode, value)
|
|
272
|
+
storage = src.__send__(:__face_storage__)
|
|
273
|
+
if mode == :constant && !value.nil?
|
|
274
|
+
cell = src.__send__(:__blank_like__, [1])
|
|
275
|
+
cell[0] = value
|
|
276
|
+
padded = pad_source(storage, lefts, rights, :constant, cell.parent[0])
|
|
277
|
+
else
|
|
278
|
+
padded = pad_source(storage, lefts, rights, mode, value)
|
|
279
|
+
end
|
|
280
|
+
padded.face_lift(src)
|
|
281
|
+
end
|
|
282
|
+
|
|
237
283
|
# Edge-replicate the margins of a padded buffer whose interior already holds
|
|
238
284
|
# the source. Per axis, the left margin rows copy the first interior row and
|
|
239
285
|
# the right margin rows copy the last; done axis by axis over the whole
|
|
@@ -298,24 +344,112 @@ class CAWindowIterator < CAIterator
|
|
|
298
344
|
# unchanged. `min_count:` / `fill_value:` pass straight to the core (the
|
|
299
345
|
# boundary strictness + result fill knobs).
|
|
300
346
|
|
|
301
|
-
#
|
|
302
|
-
# Rolling sum
|
|
347
|
+
# @!method sum(min_count: nil, fill_value: nil)
|
|
348
|
+
# Rolling sum.
|
|
349
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
350
|
+
# for a result; a piece with fewer comes back masked.
|
|
351
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
352
|
+
# result instead of leaving it masked.
|
|
353
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
354
|
+
# @!method accumulate(min_count: nil, fill_value: nil)
|
|
355
|
+
# Rolling sum kept in the source's own data type, wrapping at its
|
|
356
|
+
# width, as the core `accumulate` does -- `sum` answers in the type
|
|
357
|
+
# the core promotes to (float64 for integers).
|
|
358
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
359
|
+
# for a result; a piece with fewer comes back masked.
|
|
360
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
361
|
+
# result instead of leaving it masked.
|
|
362
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
363
|
+
# @!method prod(min_count: nil, fill_value: nil)
|
|
364
|
+
# Rolling product.
|
|
365
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
366
|
+
# for a result; a piece with fewer comes back masked.
|
|
367
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
368
|
+
# result instead of leaving it masked.
|
|
369
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
370
|
+
# @!method mean(min_count: nil, fill_value: nil)
|
|
371
|
+
# Rolling arithmetic mean.
|
|
372
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
373
|
+
# for a result; a piece with fewer comes back masked.
|
|
374
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
375
|
+
# result instead of leaving it masked.
|
|
376
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
377
|
+
# @!method min(min_count: nil, fill_value: nil)
|
|
378
|
+
# Rolling minimum.
|
|
379
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
380
|
+
# for a result; a piece with fewer comes back masked.
|
|
381
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
382
|
+
# result instead of leaving it masked.
|
|
303
383
|
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
304
|
-
#
|
|
305
|
-
# Rolling
|
|
306
|
-
#
|
|
307
|
-
#
|
|
308
|
-
#
|
|
309
|
-
#
|
|
384
|
+
# @!method max(min_count: nil, fill_value: nil)
|
|
385
|
+
# Rolling maximum.
|
|
386
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
387
|
+
# for a result; a piece with fewer comes back masked.
|
|
388
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
389
|
+
# result instead of leaving it masked.
|
|
310
390
|
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
311
|
-
#
|
|
312
|
-
# variance
|
|
313
|
-
#
|
|
314
|
-
|
|
391
|
+
# @!method variance(min_count: nil, fill_value: nil)
|
|
392
|
+
# Rolling sample variance (divisor `n - 1`).
|
|
393
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
394
|
+
# for a result; a piece with fewer comes back masked.
|
|
395
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
396
|
+
# result instead of leaving it masked.
|
|
397
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
398
|
+
# @!method stddev(min_count: nil, fill_value: nil)
|
|
399
|
+
# Rolling sample standard deviation (divisor `n - 1`).
|
|
400
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
401
|
+
# for a result; a piece with fewer comes back masked.
|
|
402
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
403
|
+
# result instead of leaving it masked.
|
|
404
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
405
|
+
# @!method all
|
|
406
|
+
# Whether every cell of each rolling is true.
|
|
407
|
+
# Takes no `min_count:` or `fill_value:`, as the core `all` does not.
|
|
408
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
409
|
+
# @!method any
|
|
410
|
+
# Whether any cell of each rolling is true.
|
|
411
|
+
# Takes no `min_count:` or `fill_value:`, as the core `any` does not.
|
|
412
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
413
|
+
# @!method variancep(min_count: nil, fill_value: nil)
|
|
414
|
+
# Rolling population variance (divisor `n`).
|
|
415
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
416
|
+
# for a result; a piece with fewer comes back masked.
|
|
417
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
418
|
+
# result instead of leaving it masked.
|
|
419
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
420
|
+
# @!method stddevp(min_count: nil, fill_value: nil)
|
|
421
|
+
# Rolling population standard deviation (divisor `n`).
|
|
422
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
423
|
+
# for a result; a piece with fewer comes back masked.
|
|
424
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
425
|
+
# result instead of leaving it masked.
|
|
426
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
427
|
+
# @!method minmax(min_count: nil, fill_value: nil)
|
|
428
|
+
# Rolling minimum and maximum, found in one pass.
|
|
429
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
430
|
+
# for a result; a piece with fewer comes back masked.
|
|
431
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
432
|
+
# result instead of leaving it masked.
|
|
433
|
+
# @return [Array<CArray>] the pair `[min, max]`, reference-shaped (or shrunk, for :truncate)
|
|
434
|
+
# @!method min_index(min_count: nil, fill_value: nil)
|
|
435
|
+
# Rolling position of the minimum, local to the window axes.
|
|
436
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
437
|
+
# for a result; a piece with fewer comes back masked.
|
|
438
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
439
|
+
# result instead of leaving it masked.
|
|
440
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
441
|
+
# @!method max_index(min_count: nil, fill_value: nil)
|
|
442
|
+
# Rolling position of the maximum, local to the window axes.
|
|
443
|
+
# @param min_count [Integer, nil] fewest cells that must be present
|
|
444
|
+
# for a result; a piece with fewer comes back masked.
|
|
445
|
+
# @param fill_value [Object, nil] value to put in place of a masked
|
|
446
|
+
# result instead of leaving it masked.
|
|
447
|
+
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
448
|
+
[:sum, :accumulate, :prod, :mean, :min, :max, :variance, :stddev,
|
|
315
449
|
:variancep, :stddevp, :minmax, :min_index, :max_index].each do |op|
|
|
316
450
|
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
317
451
|
def #{op} (min_count: nil, fill_value: nil)
|
|
318
|
-
folded = fold_by_offset(:#{op}, min_count, fill_value)
|
|
452
|
+
folded = @shape.include?(0) ? nil : fold_by_offset(:#{op}, min_count, fill_value)
|
|
319
453
|
return folded unless folded.nil?
|
|
320
454
|
kw = {}
|
|
321
455
|
kw[:min_count] = min_count unless min_count.nil?
|
|
@@ -325,6 +459,19 @@ class CAWindowIterator < CAIterator
|
|
|
325
459
|
RUBY
|
|
326
460
|
end
|
|
327
461
|
|
|
462
|
+
# all / any take no min_count: or fill_value:, as the core ones do not.
|
|
463
|
+
[:all, :any].each do |op|
|
|
464
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
465
|
+
def #{op} (**kw)
|
|
466
|
+
if kw.empty?
|
|
467
|
+
folded = @shape.include?(0) ? nil : fold_by_offset(:#{op}, nil)
|
|
468
|
+
return folded unless folded.nil?
|
|
469
|
+
end
|
|
470
|
+
sliding_view.#{op}(axis: @window_axes, **CAIterator.reduce_keywords(:#{op}, kw))
|
|
471
|
+
end
|
|
472
|
+
RUBY
|
|
473
|
+
end
|
|
474
|
+
|
|
328
475
|
# @overload min_addr
|
|
329
476
|
# Rolling flat SOURCE address of the window minimum — which source cell holds
|
|
330
477
|
# it, so `source.reshape(source.elements)[sw.min_addr]` are the window minima.
|
|
@@ -334,12 +481,12 @@ class CAWindowIterator < CAIterator
|
|
|
334
481
|
# source cell it replicates, and with `bounds: :constant` (or `fill_value:`)
|
|
335
482
|
# a winning margin cell has no source address and is a masked result.
|
|
336
483
|
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
337
|
-
def min_addr; window_winner_addr(:min_index); end
|
|
484
|
+
def min_addr (**kw); window_winner_addr(:min_index, kw); end
|
|
338
485
|
|
|
339
486
|
# @overload max_addr
|
|
340
487
|
# Rolling flat source address of the window maximum. See {#min_addr}.
|
|
341
488
|
# @return [CArray] reference-shaped (or shrunk, for :truncate)
|
|
342
|
-
def max_addr; window_winner_addr(:max_index); end
|
|
489
|
+
def max_addr (**kw); window_winner_addr(:max_index, kw); end
|
|
343
490
|
|
|
344
491
|
private
|
|
345
492
|
|
|
@@ -376,16 +523,22 @@ class CAWindowIterator < CAIterator
|
|
|
376
523
|
# Runs the fold by offset, or returns nil when this window is not one it can
|
|
377
524
|
# answer for -- in which case the caller delegates as before.
|
|
378
525
|
def fold_by_offset (op, min_count, fill_value = nil)
|
|
526
|
+
return nil unless CArray.__fast_paths_enabled__
|
|
527
|
+
need = CArray.__min_count_need__(op, min_count, 0)
|
|
379
528
|
return nil unless op == :mean || OFFSET_FOLD.key?(op)
|
|
529
|
+
# The elementwise kernels act on a Face's storage; its reductions are its own.
|
|
530
|
+
return nil if @source.face?
|
|
380
531
|
return nil if @widths.any? { |width| width > OFFSET_FOLD_MAX_WIDTH }
|
|
381
532
|
return nil if neutral_value(op).nil?
|
|
533
|
+
# pmin / pmax let NaN lose, so a window holding only NaN would fold to the
|
|
534
|
+
# neutral value; the core answers NaN there.
|
|
535
|
+
return nil if (op == :min || op == :max) && source_has_nan?
|
|
382
536
|
|
|
383
537
|
folded = op == :mean ? fold_mean : accumulate_offsets(op)
|
|
384
538
|
folded = mask_empty_windows(folded) if EMPTY_WINDOW_IS_UNDEFINED.include?(op)
|
|
385
|
-
folded = apply_min_count(folded,
|
|
539
|
+
folded = apply_min_count(folded, need)
|
|
386
540
|
# A `fill_value:` on the call replaces a result that came out undefined.
|
|
387
|
-
folded
|
|
388
|
-
folded
|
|
541
|
+
CArray.__reduce_fill__(folded, fill_value)
|
|
389
542
|
end
|
|
390
543
|
|
|
391
544
|
# The mean is the sum over the same offsets, divided by the number of cells
|
|
@@ -446,14 +599,19 @@ class CAWindowIterator < CAIterator
|
|
|
446
599
|
end
|
|
447
600
|
end
|
|
448
601
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
602
|
+
def source_has_nan?
|
|
603
|
+
return false unless @source.float? || @source.data_type == CA_OBJECT
|
|
604
|
+
@source.is_nan.any
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
# A result only where the window held `need` cells (CArray.__min_count_need__).
|
|
608
|
+
def apply_min_count (folded, need)
|
|
609
|
+
return folded if need == 0
|
|
452
610
|
counts = window_cell_counts
|
|
453
611
|
if counts.is_a?(Integer)
|
|
454
|
-
folded[] = UNDEF if counts <
|
|
612
|
+
folded[] = UNDEF if counts < need
|
|
455
613
|
else
|
|
456
|
-
folded[counts.lt(
|
|
614
|
+
folded[counts.lt(need)] = UNDEF
|
|
457
615
|
end
|
|
458
616
|
folded
|
|
459
617
|
end
|
|
@@ -550,7 +708,7 @@ class CAWindowIterator < CAIterator
|
|
|
550
708
|
def offset_fold_data_type (op)
|
|
551
709
|
@offset_fold_data_type ||= {}
|
|
552
710
|
@offset_fold_data_type[op] ||=
|
|
553
|
-
CArray.new(@source.data_type, [1, 1]).send(op, axis: [1]).data_type
|
|
711
|
+
CArray.new(@source.data_type, [1, 1], bytes: @source.bytes).send(op, axis: [1]).data_type
|
|
554
712
|
end
|
|
555
713
|
|
|
556
714
|
# Every offset within the window, as a list of per-axis positions into the
|
|
@@ -568,8 +726,9 @@ class CAWindowIterator < CAIterator
|
|
|
568
726
|
# offset is the range's begin for a padded margin, 0 for :truncate). A margin
|
|
569
727
|
# winner (coordinate out of bounds) resolves per the boundary policy:
|
|
570
728
|
# :nearest clamps to the edge source cell, :constant / :skip mask the result.
|
|
571
|
-
def window_winner_addr (idx_op)
|
|
572
|
-
|
|
729
|
+
def window_winner_addr (idx_op, kw = {})
|
|
730
|
+
kw = CAIterator.reduce_keywords(idx_op, kw)
|
|
731
|
+
mi = send(idx_op, **kw.slice(:min_count)) # window-local flat index
|
|
573
732
|
n = @source.shape
|
|
574
733
|
wstride = Array.new(@sndim); acc = 1
|
|
575
734
|
(@sndim - 1).downto(0) { |i| wstride[i] = acc; acc *= @widths[i] }
|
|
@@ -593,7 +752,7 @@ class CAWindowIterator < CAIterator
|
|
|
593
752
|
end
|
|
594
753
|
addr[oob] = UNDEF unless @bounds == :nearest
|
|
595
754
|
addr[mi.is_masked.eq(1)] = UNDEF if mi.has_mask?
|
|
596
|
-
addr
|
|
755
|
+
CArray.__reduce_fill__(addr, kw[:fill_value])
|
|
597
756
|
end
|
|
598
757
|
|
|
599
758
|
public
|
|
@@ -603,26 +762,29 @@ class CAWindowIterator < CAIterator
|
|
|
603
762
|
# cells (the effective tap count, which drops near a :skip edge);
|
|
604
763
|
# `count(UNDEF)` counts masked cells; `count(v)` counts cells equal to `v`.
|
|
605
764
|
# @return [CArray]
|
|
606
|
-
def count (*args)
|
|
607
|
-
return count_not_masked if args.empty?
|
|
765
|
+
def count (*args, **kw)
|
|
766
|
+
return count_not_masked(**kw) if args.empty?
|
|
608
767
|
# The sliding_windows view is a CAStride, so its #count is not shadowed;
|
|
609
768
|
# dispatch CArray#count explicitly anyway, matching the family regularity.
|
|
610
|
-
CArray.instance_method(:count).bind_call(sliding_view, *args, axis: @window_axes
|
|
769
|
+
CArray.instance_method(:count).bind_call(sliding_view, *args, axis: @window_axes,
|
|
770
|
+
**CAIterator.reduce_keywords(:count, kw))
|
|
611
771
|
end
|
|
612
772
|
|
|
613
773
|
# @overload count_not_masked
|
|
614
774
|
# Rolling count of present (non-masked) cells -- the denominator of a
|
|
615
775
|
# renormalizing convolution.
|
|
616
776
|
# @return [CArray]
|
|
617
|
-
def count_not_masked
|
|
618
|
-
sliding_view.count_not_masked(axis: @window_axes
|
|
777
|
+
def count_not_masked (**kw)
|
|
778
|
+
sliding_view.count_not_masked(axis: @window_axes,
|
|
779
|
+
**CAIterator.reduce_keywords(:count_not_masked, kw))
|
|
619
780
|
end
|
|
620
781
|
|
|
621
782
|
# @overload count_masked
|
|
622
783
|
# Rolling count of masked cells.
|
|
623
784
|
# @return [CArray]
|
|
624
|
-
def count_masked
|
|
625
|
-
sliding_view.count_masked(axis: @window_axes
|
|
785
|
+
def count_masked (**kw)
|
|
786
|
+
sliding_view.count_masked(axis: @window_axes,
|
|
787
|
+
**CAIterator.reduce_keywords(:count_masked, kw))
|
|
626
788
|
end
|
|
627
789
|
|
|
628
790
|
# @overload elements
|
|
@@ -694,40 +856,31 @@ class CAWindowIterator < CAIterator
|
|
|
694
856
|
|
|
695
857
|
# ---- order statistics (median / percentile / quantile) ----------------
|
|
696
858
|
#
|
|
697
|
-
# Core per-axis order statistics take a single axis
|
|
698
|
-
#
|
|
699
|
-
#
|
|
700
|
-
#
|
|
701
|
-
# multi window axes + unmasked margin -> materialize the windows, flatten
|
|
702
|
-
# the window axes into one, single-
|
|
703
|
-
# axis core order-stat
|
|
704
|
-
# :skip (UNDEF margin) -> raise (core has no masked per-axis
|
|
705
|
-
# order-stat); guide to :nearest /
|
|
706
|
-
# :truncate
|
|
707
|
-
#
|
|
708
|
-
# When core gains masked per-axis order statistics (a tracked refactor), the
|
|
709
|
-
# :skip guard can be dropped and :skip served directly.
|
|
859
|
+
# Core per-axis order statistics take a single axis, so a single window
|
|
860
|
+
# axis goes straight to `sliding_view.op(axis: window_axis)`, and several
|
|
861
|
+
# are materialized with the window axes flattened into one. The UNDEF
|
|
862
|
+
# margin of :skip is left out of each window as any masked cell is.
|
|
710
863
|
|
|
711
|
-
# @overload median
|
|
712
|
-
# Rolling median.
|
|
713
|
-
# `:truncate`); with the default `:skip` it raises.
|
|
864
|
+
# @overload median(min_count: nil, fill_value: nil)
|
|
865
|
+
# Rolling median.
|
|
714
866
|
# @return [CArray]
|
|
715
|
-
def median
|
|
716
|
-
|
|
867
|
+
def median (**kw)
|
|
868
|
+
kw = CAIterator.reduce_keywords(:median, kw)
|
|
869
|
+
order_stat { |view, axis| view.median(axis: axis, **kw) }
|
|
717
870
|
end
|
|
718
871
|
|
|
719
|
-
# @overload percentile(*pers)
|
|
872
|
+
# @overload percentile(*pers, min_count: nil, fill_value: nil)
|
|
720
873
|
# Rolling percentile(s). One argument returns one CArray, several return
|
|
721
|
-
# an array of CArrays (as `CArray#percentile`).
|
|
722
|
-
# margin.
|
|
874
|
+
# an array of CArrays (as `CArray#percentile`).
|
|
723
875
|
# @return [CArray, Array<CArray>]
|
|
724
|
-
def percentile (*pers)
|
|
725
|
-
|
|
876
|
+
def percentile (*pers, **kw)
|
|
877
|
+
kw = CAIterator.reduce_keywords(:percentile, kw)
|
|
878
|
+
order_stat { |view, axis| view.percentile(*pers, axis: axis, **kw) }
|
|
726
879
|
end
|
|
727
880
|
|
|
728
881
|
# @overload quantile
|
|
729
882
|
# Rolling five-number summary `[min, Q1, median, Q3, max]` (five CArrays),
|
|
730
|
-
# as `CArray#quantile`.
|
|
883
|
+
# as `CArray#quantile`.
|
|
731
884
|
# @return [Array<CArray>]
|
|
732
885
|
def quantile
|
|
733
886
|
order_stat { |view, axis| view.quantile(axis: axis) }
|
|
@@ -736,14 +889,8 @@ class CAWindowIterator < CAIterator
|
|
|
736
889
|
private
|
|
737
890
|
|
|
738
891
|
# Drive an order statistic (yielded as `block.call(view, axis)`) through the
|
|
739
|
-
# single-axis / multi-axis
|
|
892
|
+
# single-axis / multi-axis dispatch above.
|
|
740
893
|
def order_stat
|
|
741
|
-
if @bounds == :skip
|
|
742
|
-
raise ArgumentError,
|
|
743
|
-
"windowed order statistics need an unmasked margin; " \
|
|
744
|
-
"use bounds: :nearest (edge-extend) or bounds: :truncate (valid). " \
|
|
745
|
-
"For an UNDEF-margin median use reduce { |w| w.median } (slower)."
|
|
746
|
-
end
|
|
747
894
|
sv = sliding_view
|
|
748
895
|
if @window_axes.size == 1
|
|
749
896
|
yield sv, @window_axes[0]
|
|
@@ -764,15 +911,17 @@ class CAWindowIterator < CAIterator
|
|
|
764
911
|
# @overload wsum(weights)
|
|
765
912
|
# Rolling weighted sum, `weights` shaped like a single window.
|
|
766
913
|
# @return [CArray]
|
|
767
|
-
def wsum (weights)
|
|
768
|
-
|
|
914
|
+
def wsum (weights, **kw)
|
|
915
|
+
kw = CAIterator.reduce_keywords(:wsum, kw)
|
|
916
|
+
weighted(weights) { |sv, w, axis| sv.wsum(w, axis: axis, **kw) }
|
|
769
917
|
end
|
|
770
918
|
|
|
771
919
|
# @overload wmean(weights)
|
|
772
920
|
# Rolling weighted mean, `weights` shaped like a single window.
|
|
773
921
|
# @return [CArray]
|
|
774
|
-
def wmean (weights)
|
|
775
|
-
|
|
922
|
+
def wmean (weights, **kw)
|
|
923
|
+
kw = CAIterator.reduce_keywords(:wmean, kw)
|
|
924
|
+
weighted(weights) { |sv, w, axis| sv.wmean(w, axis: axis, **kw) }
|
|
776
925
|
end
|
|
777
926
|
|
|
778
927
|
private
|
|
@@ -873,13 +1022,41 @@ class CAWindowIterator < CAIterator
|
|
|
873
1022
|
"sort of source addresses is ill-defined."
|
|
874
1023
|
end
|
|
875
1024
|
|
|
876
|
-
#
|
|
877
|
-
#
|
|
878
|
-
#
|
|
879
|
-
#
|
|
880
|
-
#
|
|
881
|
-
#
|
|
882
|
-
#
|
|
1025
|
+
# @!method cumsum
|
|
1026
|
+
# Not supported for a window iterator. A segment scan writes a per-cell
|
|
1027
|
+
# running sum, which is single-valued only when each cell belongs to
|
|
1028
|
+
# exactly one piece. Overlapping windows put a cell in many windows, so
|
|
1029
|
+
# there is no single running value. Raises NotImplementedError, exactly as
|
|
1030
|
+
# {#map} / {#sort_addr} do (min / max reductions stay available: a single
|
|
1031
|
+
# winner is well-defined).
|
|
1032
|
+
# @raise [NotImplementedError]
|
|
1033
|
+
# @!method cumprod
|
|
1034
|
+
# Not supported for a window iterator. A segment scan writes a per-cell
|
|
1035
|
+
# running product, which is single-valued only when each cell belongs to
|
|
1036
|
+
# exactly one piece. Overlapping windows put a cell in many windows, so
|
|
1037
|
+
# there is no single running value. Raises NotImplementedError, exactly as
|
|
1038
|
+
# {#map} / {#sort_addr} do (min / max reductions stay available: a single
|
|
1039
|
+
# winner is well-defined).
|
|
1040
|
+
# @raise [NotImplementedError]
|
|
1041
|
+
# @!method cummax
|
|
1042
|
+
# Not supported for a window iterator. A segment scan writes a per-cell
|
|
1043
|
+
# running maximum, which is single-valued only when each cell belongs to
|
|
1044
|
+
# exactly one piece. Overlapping windows put a cell in many windows, so
|
|
1045
|
+
# there is no single running value. Raises NotImplementedError, exactly as
|
|
1046
|
+
# {#map} / {#sort_addr} do (min / max reductions stay available: a single
|
|
1047
|
+
# winner is well-defined).
|
|
1048
|
+
# @raise [NotImplementedError]
|
|
1049
|
+
# @!method cummin
|
|
1050
|
+
# Not supported for a window iterator. A segment scan writes a per-cell
|
|
1051
|
+
# running minimum, which is single-valued only when each cell belongs to
|
|
1052
|
+
# exactly one piece. Overlapping windows put a cell in many windows, so
|
|
1053
|
+
# there is no single running value. Raises NotImplementedError, exactly as
|
|
1054
|
+
# {#map} / {#sort_addr} do (min / max reductions stay available: a single
|
|
1055
|
+
# winner is well-defined).
|
|
1056
|
+
# @raise [NotImplementedError]
|
|
1057
|
+
# @!method cumcount
|
|
1058
|
+
# Not supported for a window iterator. A segment scan writes a per-cell
|
|
1059
|
+
# running count of present cells, which is single-valued only when each cell belongs to
|
|
883
1060
|
# exactly one piece. Overlapping windows put a cell in many windows, so
|
|
884
1061
|
# there is no single running value. Raises NotImplementedError, exactly as
|
|
885
1062
|
# {#map} / {#sort_addr} do (min / max reductions stay available: a single
|
data/lib/carray.rb
CHANGED
|
@@ -16,6 +16,7 @@ end
|
|
|
16
16
|
# interpolation, so compute programs that never print a CArray skip it.
|
|
17
17
|
require 'carray/construct'
|
|
18
18
|
require 'carray/data_type_extension'
|
|
19
|
+
require 'carray/data_type_limits' # MIN / MAX / TINY / EPSILON on the typed classes
|
|
19
20
|
# carray/stack is loaded lazily via autoload_carray (entry-method stubs).
|
|
20
21
|
# CAStack is C-defined so its constant is always present; only the Ruby
|
|
21
22
|
# composition surface (stack/meld/montage/split/append) needs the file.
|
|
@@ -23,19 +24,20 @@ require 'carray/runtime' # load-bearing Ruby support the core depends on
|
|
|
23
24
|
require 'carray/basics' # frequently-used convenience methods kept eager
|
|
24
25
|
require 'carray/conditional' # then_else / replace_where / conditional
|
|
25
26
|
require 'carray/mask_gap_fill' # unmask/strip_mask method: keyword (hold / linear gap-fill)
|
|
26
|
-
require 'carray/attribute' # per-instance metadata Hash (#
|
|
27
|
+
require 'carray/attribute' # per-instance metadata Hash (#attr / #set_attr / #attrs / #has_attr?)
|
|
27
28
|
require 'carray/boolean_reduce' # all/any/none skip_masked: keyword (Kleene fold)
|
|
28
29
|
require 'carray/meld_reduce' # CAMeld per-parent reduce fast path (sum/mean/min/max along meld_axis)
|
|
29
30
|
# carray/ordering CIFY (2026-06-21): translated to ext/carray_order.c
|
|
30
31
|
|
|
31
32
|
require 'carray/math'
|
|
33
|
+
require 'carray/rng' # CArray::Rng: the generator its C is shared from
|
|
32
34
|
# carray/clip_cast CIFY (2026-06-23): translated to ext/carray_cast.c
|
|
33
35
|
require 'carray/complex' # real / imag accessors; MUST precede carray/lazy
|
|
34
36
|
# (lazy aliases real/imag at load time)
|
|
35
37
|
require 'carray/lazy' # the lazy elementwise view layer
|
|
36
38
|
# carray/face.rb was deleted (the Phase 1 skeleton CArray::Face module
|
|
37
39
|
# became dead weight, replaced by C-layer macro deploy +
|
|
38
|
-
# copy_state/
|
|
40
|
+
# copy_state/storage_to_element convention).
|
|
39
41
|
require 'carray/time' # CATime / CATimedelta
|
|
40
42
|
# carray/methods/* (bincount / broadcast / gather_nd+put_nd) are small
|
|
41
43
|
# single-feature method files, loaded lazily via autoload_carray.
|
data/yard-stubs/ca_obj_array.rb
CHANGED
|
@@ -43,9 +43,9 @@ class CArray
|
|
|
43
43
|
# `data_type`, shape, mask, and element data into `self`. Result
|
|
44
44
|
# is an independent entity.
|
|
45
45
|
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
46
|
+
# For views, `dup` / `clone` produce a new view sharing the parent
|
|
47
|
+
# (Ruby shallow-copy semantics), so they do not copy. Don't use
|
|
48
|
+
# them to copy a CArray; use {#copy}.
|
|
49
49
|
# @param other [CArray]
|
|
50
50
|
# @return [self]
|
|
51
51
|
# @api private
|
|
@@ -66,7 +66,7 @@ class CArray
|
|
|
66
66
|
# @return [Class]
|
|
67
67
|
# @overload fixlen(*shape, bytes:) { ... }
|
|
68
68
|
# Equivalent to `CArray.new(:fixlen, shape, bytes: bytes) { ... }`.
|
|
69
|
-
# The `bytes:` keyword is required for `:fixlen
|
|
69
|
+
# The `bytes:` keyword is required for `:fixlen`, and is 1 or more.
|
|
70
70
|
# @param shape [Array<Integer>]
|
|
71
71
|
# @param bytes [Integer]
|
|
72
72
|
# @return [CArray]
|
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
# On big-endian hosts the bit axis of a non-fixlen parent reflects
|
|
12
12
|
# network byte order (parent bytes are walked in reverse within each
|
|
13
13
|
# element); single-byte parents are linear on either endian.
|
|
14
|
+
#
|
|
15
|
+
# A bit view has no mask. The bits of one byte would share that byte's
|
|
16
|
+
# one mask cell, so the view refuses a masked parent and refuses to be
|
|
17
|
+
# masked (`mask=`, storing `UNDEF`, storing a masked array). Read the
|
|
18
|
+
# bits of a masked array through `value.bitarray`.
|
|
14
19
|
class CABitarray < CAView
|
|
15
20
|
end
|
|
16
21
|
|
|
@@ -27,6 +32,8 @@ class CArray
|
|
|
27
32
|
# @return [CABitarray]
|
|
28
33
|
# @raise [CADataTypeError] when `self.data_type` is a complex or
|
|
29
34
|
# object type (bit-level access is not defined for those).
|
|
35
|
+
# @raise [ArgumentError] when `self` has a mask; use
|
|
36
|
+
# `value.bitarray` to read the bits without it.
|
|
30
37
|
def bitarray; end
|
|
31
38
|
|
|
32
39
|
# Alias for {#bitarray}.
|
|
@@ -19,24 +19,35 @@ class CArray
|
|
|
19
19
|
# of the returned array.
|
|
20
20
|
#
|
|
21
21
|
# `range` may be an integer (a single bit — the resulting view has
|
|
22
|
-
# `data_type :boolean`) or a `Range` covering the bit positions.
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
# `
|
|
28
|
-
# is
|
|
22
|
+
# `data_type :boolean`) or a `Range` covering the bit positions. A
|
|
23
|
+
# negative bit or range end counts from the last bit of the cell.
|
|
24
|
+
# A field is read with one 8-byte load from the byte it starts in, so
|
|
25
|
+
# it may not reach more than 64 bits past the start of that byte.
|
|
26
|
+
# `type` is the integer type the field is read as. A signed type
|
|
27
|
+
# (`:int8` .. `:int64`) reads the field's top bit as its sign: the
|
|
28
|
+
# 3-bit field `0b101` is 5 as `:uint8` and -3 as `:int8`. A type
|
|
29
|
+
# wider than the field only widens the value. Without `type`, the
|
|
30
|
+
# narrowest unsigned type that holds the field is used: 1 bit →
|
|
31
|
+
# `:boolean`, 2..8 → `:uint8`, 9..16 → `:uint16`, 17..32 → `:uint32`,
|
|
32
|
+
# 33..64 → `:uint64`. A write keeps the low bits of the value that
|
|
33
|
+
# fit the field, signed or not (-3 into a 3-bit field is `0b101`).
|
|
29
34
|
#
|
|
30
35
|
# @overload bitfield(range, type = nil)
|
|
31
36
|
# @param range [Integer, Range] bit position (single bit) or bit
|
|
32
37
|
# range within one parent cell.
|
|
33
|
-
# @param type [Symbol, nil]
|
|
38
|
+
# @param type [Symbol, Integer, nil] the integer type the field is
|
|
39
|
+
# read as, or `nil` for the narrowest unsigned type.
|
|
34
40
|
# @return [CABitfield]
|
|
35
41
|
# @raise [IndexError] when `range` extends past the parent's bit
|
|
36
|
-
# width, when the range has a step != 1,
|
|
37
|
-
# is outside `1..64
|
|
38
|
-
#
|
|
39
|
-
#
|
|
42
|
+
# width, when the range has a step != 1, when the bit length
|
|
43
|
+
# is outside `1..64`, or when the field reaches more than 64 bits
|
|
44
|
+
# past the start of its first byte.
|
|
45
|
+
# @raise [CArray::DataTypeError] when `self` is an object or complex
|
|
46
|
+
# array.
|
|
47
|
+
# @raise [ArgumentError] when `type` is narrower than the field
|
|
48
|
+
# (or `:boolean` for a field of more than one bit).
|
|
49
|
+
# @raise [CArray::DataTypeError] when `type` is not an integer type
|
|
50
|
+
# or `:boolean`.
|
|
40
51
|
def bitfield(range, type = nil); end
|
|
41
52
|
|
|
42
53
|
# @!endgroup
|