carray 3.0.0 → 3.0.2
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/.yardopts +2 -1
- data/CHANGELOG.md +845 -3
- data/{NEWS.md → CHANGELOG.v1.md} +1 -1
- data/README.md +33 -33
- data/carray.gemspec +12 -8
- data/ext/ca_axis_dispatch.c +33 -4
- data/ext/ca_axis_group.c +256 -114
- data/ext/ca_binop_dispatch.c +5 -6
- data/ext/ca_binop_dispatch.h +0 -7
- data/ext/ca_categorical_iterator.c +121 -67
- data/ext/ca_for_each_element.h +6 -8
- data/ext/ca_group_iter.c +1 -1
- data/ext/ca_kernel_iterator.c +386 -74
- data/ext/ca_kernel_iterator.h +145 -45
- data/ext/ca_obj_array.c +62 -20
- data/ext/ca_obj_bincmp.c +57 -27
- data/ext/ca_obj_binop.c +86 -30
- data/ext/ca_obj_block.c +4 -4
- data/ext/ca_obj_const_string.c +88 -27
- data/ext/ca_obj_face.c +104 -0
- data/ext/ca_obj_face.h +48 -1
- data/ext/ca_obj_fake.c +11 -0
- data/ext/ca_obj_fixlen_string.c +21 -6
- data/ext/ca_obj_grid.c +11 -3
- data/ext/ca_obj_meld.c +125 -22
- data/ext/ca_obj_moncmp.c +33 -14
- data/ext/ca_obj_monop.c +19 -7
- data/ext/ca_obj_object.c +107 -4
- data/ext/ca_obj_record.c +3 -1
- data/ext/ca_obj_refer.c +30 -6
- data/ext/ca_obj_roll.c +13 -5
- data/ext/ca_obj_select.c +49 -34
- data/ext/ca_obj_select_axis.c +16 -6
- data/ext/ca_obj_shift.c +3 -3
- data/ext/ca_obj_stack.c +3 -8
- data/ext/ca_obj_stride.c +178 -24
- data/ext/ca_obj_string.c +11 -5
- data/ext/ca_obj_tile.c +13 -5
- data/ext/ca_obj_time.c +3 -1
- data/ext/ca_obj_timedelta.c +3 -1
- data/ext/ca_obj_transpose.c +1 -1
- data/ext/ca_obj_triop.c +62 -23
- data/ext/ca_obj_window.c +94 -19
- data/ext/ca_op_cmplx64.h +123 -0
- data/ext/ca_op_ipower.c +1 -5
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sort_kernels.h +5 -5
- data/ext/ca_sweep_engine.c +362 -155
- data/ext/ca_sweep_engine.h +39 -9
- data/ext/ca_transform_common.c +7 -0
- data/ext/carray.h +148 -132
- data/ext/carray_access.c +83 -49
- data/ext/carray_address_basis.c +590 -0
- data/ext/carray_bincount.c +8 -8
- data/ext/carray_broadcast.c +102 -9
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +2010 -335
- data/ext/carray_call_cfunc.h +153 -0
- data/ext/carray_cast.c +184 -72
- data/ext/carray_conversion.c +22 -22
- data/ext/carray_copy.c +67 -32
- data/ext/carray_core.c +140 -13
- data/ext/carray_count.c +10 -11
- data/ext/carray_element.c +7 -7
- data/ext/carray_factorize.c +72 -51
- data/ext/carray_hold.c +1 -1
- data/ext/carray_index_classifier.c +7 -21
- data/ext/carray_internal.h +36 -3
- data/ext/carray_kernels_bincmp.c +1 -0
- data/ext/carray_kernels_binop.c +320 -298
- data/ext/carray_kernels_init.c +1095 -0
- data/ext/carray_kernels_map.c +1 -0
- data/ext/carray_kernels_moncmp.c +1 -0
- data/ext/carray_kernels_monop.c +412 -411
- data/ext/carray_kernels_reduce_aggregate.c +256 -87
- data/ext/carray_kernels_reduce_boolean.c +1 -0
- data/ext/carray_kernels_reduce_cumulative.c +324 -54
- data/ext/carray_kernels_reduce_extreme.c +605 -58
- data/ext/carray_kernels_reduce_variance.c +1 -0
- data/ext/carray_kernels_scan.c +5 -4
- data/ext/carray_kernels_search.c +187 -106
- data/ext/carray_kernels_sort.c +1 -0
- data/ext/carray_kernels_triop.c +1 -0
- data/ext/carray_lazy.c +175 -5
- data/ext/carray_loop.c +7 -1
- data/ext/carray_mask.c +29 -13
- data/ext/carray_median_percentile.c +56 -1
- data/ext/carray_memory_view.c +46 -21
- data/ext/carray_operator.c +50 -53
- data/ext/carray_order.c +1 -1
- data/ext/carray_partition.c +4 -4
- data/ext/carray_random.c +391 -47
- data/ext/carray_scatter.c +1 -1
- data/ext/carray_slab.c +13 -0
- data/ext/carray_sort.c +22 -24
- data/ext/carray_sort_kernel.c +10 -10
- data/ext/carray_test.c +1 -1
- data/ext/extconf.rb +18 -0
- data/ext/mk_call_cfunc.rb +323 -145
- data/ext/mkkernel.rb +651 -129
- data/ext/ruby_carray.c +28 -17
- data/ext/version.h +4 -4
- data/lib/carray/autoload_carray.rb +24 -3
- data/lib/carray/autoload_method_extension.rb +14 -1
- data/lib/carray/axis_group.rb +84 -7
- data/lib/carray/basics.rb +63 -59
- data/lib/carray/bincount_nd.rb +12 -12
- data/lib/carray/block_iterator.rb +111 -25
- data/lib/carray/categorical.rb +154 -37
- data/lib/carray/categorical_iterator.rb +300 -151
- data/lib/carray/conditional.rb +14 -14
- data/lib/carray/const_string.rb +131 -27
- data/lib/carray/construct.rb +61 -0
- data/lib/carray/core_extensions.rb +62 -5
- data/lib/carray/data_type_extension.rb +21 -1
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/concat.rb +3 -3
- data/lib/carray/frame/convert.rb +1 -1
- data/lib/carray/frame/csv_parser.rb +11 -4
- data/lib/carray/frame/frame.rb +85 -21
- data/lib/carray/frame/group.rb +36 -3
- data/lib/carray/frame/io.rb +224 -15
- data/lib/carray/frame/records.rb +18 -4
- data/lib/carray/frame/sort.rb +1 -1
- data/lib/carray/frame/verbs.rb +32 -12
- data/lib/carray/fuse_source.rb +123 -0
- data/lib/carray/fusion.rb +218 -0
- data/lib/carray/histogram.rb +16 -16
- data/lib/carray/inspect.rb +43 -16
- data/lib/carray/iterator.rb +147 -3
- data/lib/carray/lazy.rb +88 -73
- data/lib/carray/mask_gap_fill.rb +3 -1
- data/lib/carray/meld_reduce.rb +2 -2
- data/lib/carray/methods/align_addr.rb +1 -1
- data/lib/carray/methods/composition.rb +1 -1
- data/lib/carray/methods/discovery_along.rb +74 -0
- data/lib/carray/methods/factorize.rb +50 -0
- data/lib/carray/methods/is_in.rb +25 -14
- data/lib/carray/methods/locate_addr.rb +81 -3
- data/lib/carray/methods/mask_duplicates.rb +36 -2
- data/lib/carray/methods/meshgrid.rb +4 -5
- data/lib/carray/methods/mode.rb +2 -2
- data/lib/carray/methods/nunique.rb +23 -2
- data/lib/carray/methods/repeat.rb +110 -0
- data/lib/carray/methods/snap.rb +7 -2
- data/lib/carray/methods/unique.rb +44 -4
- data/lib/carray/methods/value_counts.rb +2 -2
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/runtime.rb +0 -19
- data/lib/carray/slab_iterator.rb +77 -19
- data/lib/carray/string_operation_extension.rb +10 -6
- data/lib/carray/time.rb +906 -491
- data/lib/carray/window_iterator.rb +421 -27
- data/lib/carray.rb +7 -5
- data/yard-stubs/ca_obj_array.rb +385 -0
- data/yard-stubs/ca_obj_bitarray.rb +38 -0
- data/yard-stubs/ca_obj_bitfield.rb +43 -0
- data/yard-stubs/ca_obj_block.rb +68 -0
- data/yard-stubs/ca_obj_byte_swap.rb +56 -0
- data/yard-stubs/ca_obj_fake.rb +31 -0
- data/yard-stubs/ca_obj_farray.rb +32 -0
- data/yard-stubs/ca_obj_field.rb +45 -0
- data/yard-stubs/ca_obj_grid.rb +35 -0
- data/yard-stubs/ca_obj_refer.rb +72 -0
- data/yard-stubs/ca_obj_roll.rb +45 -0
- data/yard-stubs/ca_obj_shift.rb +43 -0
- data/yard-stubs/ca_obj_stride.rb +181 -0
- data/yard-stubs/ca_obj_tile.rb +29 -0
- data/yard-stubs/ca_obj_transpose.rb +40 -0
- data/yard-stubs/ca_obj_window.rb +57 -0
- data/yard-stubs/carray_access.rb +131 -0
- data/yard-stubs/carray_attribute.rb +246 -0
- data/yard-stubs/carray_broadcast.rb +37 -0
- data/yard-stubs/carray_cast.rb +489 -0
- data/yard-stubs/carray_class.rb +65 -0
- data/yard-stubs/carray_conversion.rb +76 -0
- data/yard-stubs/carray_copy.rb +79 -0
- data/yard-stubs/carray_core.rb +34 -0
- data/yard-stubs/carray_count.rb +84 -0
- data/yard-stubs/carray_element.rb +108 -0
- data/yard-stubs/carray_generate.rb +66 -0
- data/yard-stubs/carray_lazy.rb +228 -0
- data/yard-stubs/carray_loop.rb +140 -0
- data/yard-stubs/carray_mask.rb +259 -0
- data/yard-stubs/carray_math.rb +1615 -0
- data/yard-stubs/carray_mathfunc.rb +45 -0
- data/yard-stubs/carray_median_percentile.rb +103 -0
- data/yard-stubs/carray_memory_view.rb +163 -0
- data/yard-stubs/carray_order.rb +252 -0
- data/yard-stubs/carray_random.rb +89 -0
- data/yard-stubs/carray_scatter.rb +106 -0
- data/yard-stubs/carray_slab.rb +59 -0
- data/yard-stubs/carray_sort.rb +165 -0
- data/yard-stubs/carray_test.rb +85 -0
- data/yard-stubs/carray_undef.rb +64 -0
- data/yard-stubs/carray_utils.rb +97 -0
- data/yard-stubs/ruby_carray.rb +193 -0
- metadata +67 -10
- data/ext/ca_obj_unbound_repeat.c +0 -496
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# DOCUMENTATION ONLY — DO NOT REQUIRE.
|
|
2
|
+
# Stubs for methods defined in ext/carray_scatter.c.
|
|
3
|
+
# See yard-stubs/README.md and yard-stubs/STYLE.md.
|
|
4
|
+
|
|
5
|
+
class CArray
|
|
6
|
+
# @!group Scatter and generation
|
|
7
|
+
#
|
|
8
|
+
# The `scatter_*!` family applies an in-place reduction at each
|
|
9
|
+
# `addrs[i]` position from a paired `vals[i]` (or scalar). The
|
|
10
|
+
# accumulate variants (`scatter_add!` / `scatter_sub!` /
|
|
11
|
+
# `scatter_mul!` / `scatter_min!` / `scatter_max!`) apply duplicate
|
|
12
|
+
# addresses in sequence (unbuffered). {#scatter_replace!} is the
|
|
13
|
+
# last-write variant, equivalent to `self[addrs] = vals` but
|
|
14
|
+
# bypasses the CAGrid view chain.
|
|
15
|
+
#
|
|
16
|
+
# Shared contract:
|
|
17
|
+
#
|
|
18
|
+
# - `addrs` is a CArray of any integer type (coerced to
|
|
19
|
+
# `CA_SIZE`) or a Ruby Array.
|
|
20
|
+
# - `vals` is a CArray of length matching `addrs` (coerced to
|
|
21
|
+
# `self.data_type`), or a Numeric scalar broadcast to all
|
|
22
|
+
# addresses.
|
|
23
|
+
# - Out-of-range `addrs[i]` (`< 0` or `>= self.elements`) raises
|
|
24
|
+
# `IndexError`.
|
|
25
|
+
# - `self.data_type` must be numeric.
|
|
26
|
+
#
|
|
27
|
+
# Mask policy differs between the accumulate family and
|
|
28
|
+
# {#scatter_replace!}: the accumulate variants skip the pair when
|
|
29
|
+
# any of `addrs[i]`, `vals[i]`, or `self[addrs[i]]` is masked (an
|
|
30
|
+
# unknown source can't accumulate). {#scatter_replace!} instead
|
|
31
|
+
# overwrites the target (masked `vals[i]` flips the target to
|
|
32
|
+
# masked, valid `vals[i]` clears the target's mask), matching the
|
|
33
|
+
# `self[addrs] = vals` indexer.
|
|
34
|
+
|
|
35
|
+
# @overload scatter_add!(addrs, vals)
|
|
36
|
+
# For each `i`, applies `self[addrs[i]] += vals[i]`
|
|
37
|
+
# (or `+= vals` if `vals` is scalar). Mutates `self`.
|
|
38
|
+
# @param addrs [CArray, Array<Integer>]
|
|
39
|
+
# @param vals [CArray, Numeric]
|
|
40
|
+
# @return [self]
|
|
41
|
+
# @raise [IndexError] for out-of-range addresses.
|
|
42
|
+
# @raise [CArray::DataTypeError] for non-numeric `data_type`.
|
|
43
|
+
def scatter_add!(addrs, vals); end
|
|
44
|
+
|
|
45
|
+
# @overload scatter_sub!(addrs, vals)
|
|
46
|
+
# For each `i`, applies `self[addrs[i]] -= vals[i]`. Same
|
|
47
|
+
# contract as {#scatter_add!}.
|
|
48
|
+
# @param addrs [CArray, Array<Integer>]
|
|
49
|
+
# @param vals [CArray, Numeric]
|
|
50
|
+
# @return [self]
|
|
51
|
+
def scatter_sub!(addrs, vals); end
|
|
52
|
+
|
|
53
|
+
# @overload scatter_mul!(addrs, vals)
|
|
54
|
+
# For each `i`, applies `self[addrs[i]] *= vals[i]`. Duplicate
|
|
55
|
+
# addresses multiply.
|
|
56
|
+
#
|
|
57
|
+
# NaN/inf follow standard C arithmetic propagation (no
|
|
58
|
+
# `fmin`-style missing-value rule). Integer overflow wraps.
|
|
59
|
+
#
|
|
60
|
+
# Typical uses: Bayesian likelihood patch update, scatter blend,
|
|
61
|
+
# log-domain → linear product, weight composition.
|
|
62
|
+
# @param addrs [CArray, Array<Integer>]
|
|
63
|
+
# @param vals [CArray, Numeric]
|
|
64
|
+
# @return [self]
|
|
65
|
+
def scatter_mul!(addrs, vals); end
|
|
66
|
+
|
|
67
|
+
# @overload scatter_min!(addrs, vals)
|
|
68
|
+
# For each `i`, applies
|
|
69
|
+
# `self[addrs[i]] = min(self[addrs[i]], vals[i])`.
|
|
70
|
+
#
|
|
71
|
+
# For float `data_type`, NaN follows the `fmin` rule (NaN is
|
|
72
|
+
# treated as missing: `min(NaN, v) → v`, `min(x, NaN) → x`).
|
|
73
|
+
# @param addrs [CArray, Array<Integer>]
|
|
74
|
+
# @param vals [CArray, Numeric]
|
|
75
|
+
# @return [self]
|
|
76
|
+
def scatter_min!(addrs, vals); end
|
|
77
|
+
|
|
78
|
+
# @overload scatter_max!(addrs, vals)
|
|
79
|
+
# For each `i`, applies
|
|
80
|
+
# `self[addrs[i]] = max(self[addrs[i]], vals[i])`. For float
|
|
81
|
+
# `data_type`, NaN follows the `fmax` rule.
|
|
82
|
+
# @param addrs [CArray, Array<Integer>]
|
|
83
|
+
# @param vals [CArray, Numeric]
|
|
84
|
+
# @return [self]
|
|
85
|
+
def scatter_max!(addrs, vals); end
|
|
86
|
+
|
|
87
|
+
# @overload scatter_replace!(addrs, vals)
|
|
88
|
+
# For each `i`, applies `self[addrs[i]] = vals[i]` (or `= vals`
|
|
89
|
+
# if scalar). Duplicate addresses resolve to last-write-wins.
|
|
90
|
+
#
|
|
91
|
+
# Semantically equivalent to `self[addrs] = vals` but bypasses
|
|
92
|
+
# the CAGrid view chain (which snapshot-copies `addrs` and
|
|
93
|
+
# allocates view state); useful in hot loops where a scatter
|
|
94
|
+
# result is written back many times.
|
|
95
|
+
#
|
|
96
|
+
# Unlike the arithmetic `scatter_*!` family, `self` may be
|
|
97
|
+
# **boolean** (assignment does not widen), and `true` / `false`
|
|
98
|
+
# are accepted as scalar `vals` alongside numeric scalars.
|
|
99
|
+
#
|
|
100
|
+
# @param addrs [CArray, Array<Integer>]
|
|
101
|
+
# @param vals [CArray, Numeric, true, false]
|
|
102
|
+
# @return [self]
|
|
103
|
+
def scatter_replace!(addrs, vals); end
|
|
104
|
+
|
|
105
|
+
# @!endgroup
|
|
106
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# DOCUMENTATION ONLY — DO NOT REQUIRE.
|
|
2
|
+
# Stubs for methods defined in ext/carray_slab.c.
|
|
3
|
+
# See yard-stubs/README.md and yard-stubs/STYLE.md.
|
|
4
|
+
#
|
|
5
|
+
# The slab-iteration family walks `self` in slabs (sub-arrays) taken along
|
|
6
|
+
# a chosen set of axes. See the @see links for the full walkthrough.
|
|
7
|
+
|
|
8
|
+
class CArray
|
|
9
|
+
# @!group Iteration
|
|
10
|
+
|
|
11
|
+
# @overload each_slab(axis:)
|
|
12
|
+
# Yields each slab of `self` (a view along the axes NOT in `axis`) to
|
|
13
|
+
# the block and returns `self`. The slab is valid only for the
|
|
14
|
+
# duration of the block — capturing it across iterations sees the last
|
|
15
|
+
# slab's data — and it is read-only: writing through it raises. To
|
|
16
|
+
# produce values per slab use `map_slab` or `reduce_slab`; to write in
|
|
17
|
+
# place, assign through the array itself.
|
|
18
|
+
# @overload each_slab(axis:)
|
|
19
|
+
# Returns an Enumerator when no block is given.
|
|
20
|
+
# @param axis [Integer, Array<Integer>, nil] the slab axis or axes
|
|
21
|
+
# (`nil` = the whole view as a single slab).
|
|
22
|
+
# @return [self, Enumerator]
|
|
23
|
+
# @see file:docs/topics/SlabIterator.md SlabIterator
|
|
24
|
+
# @see file:guides/users/11_slab_iteration.md Slab iteration
|
|
25
|
+
def each_slab(axis:); end
|
|
26
|
+
|
|
27
|
+
# @overload map_slab(axis:, data_type: nil)
|
|
28
|
+
# Returns a new CArray built by replacing each slab of `self` with the
|
|
29
|
+
# block's result. The block receives the slab view and must return a
|
|
30
|
+
# value of the same shape as the slab (a CArray or scalar); the results
|
|
31
|
+
# are written into the output at the same positions.
|
|
32
|
+
# @param axis [Integer, Array<Integer>, nil] the slab axis or axes.
|
|
33
|
+
# @param data_type [Symbol, Integer, Class, nil] output data type
|
|
34
|
+
# (defaults to `self`'s data type).
|
|
35
|
+
# @return [CArray]
|
|
36
|
+
# @raise [ArgumentError] when the block result's shape does not match
|
|
37
|
+
# the slab.
|
|
38
|
+
# @see file:docs/topics/SlabIterator.md SlabIterator
|
|
39
|
+
def map_slab(axis:, data_type: nil); end
|
|
40
|
+
|
|
41
|
+
# @overload reduce_slab(axis:, data_type: nil)
|
|
42
|
+
# Per-slab form (no `init:`): the block receives each slab view and
|
|
43
|
+
# returns a scalar; the scalars fill an output CArray with the slab
|
|
44
|
+
# axes collapsed. Returning a CArray from the block is an error (use
|
|
45
|
+
# `slab[0]`, `slab.sum`, etc. to extract a scalar).
|
|
46
|
+
# @overload reduce_slab(axis:, init:, data_type: nil)
|
|
47
|
+
# Per-element form (`init:` given): the block receives `(acc, x)` for
|
|
48
|
+
# each element of the slab and returns the new accumulator; the final
|
|
49
|
+
# accumulator per slab fills the output.
|
|
50
|
+
# @param axis [Integer, Array<Integer>, nil] the slab axis or axes.
|
|
51
|
+
# @param init [Object] the initial accumulator (selects the
|
|
52
|
+
# per-element form).
|
|
53
|
+
# @param data_type [Symbol, Integer, Class, nil] output data type.
|
|
54
|
+
# @return [CArray] the reduced array (slab axes collapsed).
|
|
55
|
+
# @see file:docs/topics/SlabIterator.md SlabIterator
|
|
56
|
+
def reduce_slab(axis:, init: nil, data_type: nil); end
|
|
57
|
+
|
|
58
|
+
# @!endgroup
|
|
59
|
+
end
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# DOCUMENTATION ONLY — DO NOT REQUIRE.
|
|
2
|
+
# Stubs for methods defined in ext/carray_sort.c.
|
|
3
|
+
# See yard-stubs/README.md and yard-stubs/STYLE.md.
|
|
4
|
+
|
|
5
|
+
class CArray
|
|
6
|
+
# @!group Sorting and searching
|
|
7
|
+
|
|
8
|
+
# @overload sort_addr(*keys, masked_position: :last)
|
|
9
|
+
# Returns a 1-D CArray of `:int64` indices that lex-sort `keys`
|
|
10
|
+
# in priority order (`keys[0]` is highest priority,
|
|
11
|
+
# `keys[1]` breaks ties, etc.). All `keys` must share the same
|
|
12
|
+
# element count.
|
|
13
|
+
#
|
|
14
|
+
# Masked cells are an incomparable sentinel clustered at
|
|
15
|
+
# `masked_position:` (`:last`, default, or `:first`), applied
|
|
16
|
+
# uniformly across all `keys`. Ties are broken by original index
|
|
17
|
+
# (stable).
|
|
18
|
+
#
|
|
19
|
+
# @example
|
|
20
|
+
# idx = CArray.sort_addr(a, b, c) # priority: a > b > c
|
|
21
|
+
# a[idx]; b[idx]; c[idx]
|
|
22
|
+
#
|
|
23
|
+
# @param keys [Array<CArray>] one or more CArrays, all of the
|
|
24
|
+
# same element count.
|
|
25
|
+
# @param masked_position [Symbol] `:last` (default) or `:first`.
|
|
26
|
+
# @return [CArray] flat `:int64` indices, shape `[a.elements]`.
|
|
27
|
+
# @raise [ArgumentError] when no key is given or element counts
|
|
28
|
+
# differ.
|
|
29
|
+
def self.sort_addr(*keys, masked_position: :last); end
|
|
30
|
+
|
|
31
|
+
# @overload sort(axis: nil, kind: :quick, masked_position: :last)
|
|
32
|
+
# Returns a `CARemap` view of `self` whose elements are sorted
|
|
33
|
+
# along `axis`. When `axis` is omitted, `self` is first
|
|
34
|
+
# flattened to 1-D and the entire array is sorted (so the
|
|
35
|
+
# result is a 1-D view regardless of `self.ndim`).
|
|
36
|
+
#
|
|
37
|
+
# `kind:` selects the sorting algorithm. Both kinds are stable
|
|
38
|
+
# (tie-broken by fiber-local index); the choice is a
|
|
39
|
+
# performance characteristic only:
|
|
40
|
+
#
|
|
41
|
+
# - `:quick` (default) — portable textbook introsort with
|
|
42
|
+
# mergesort escape. Faster on random data.
|
|
43
|
+
# - `:stable` — portable bottom-up mergesort with insertion
|
|
44
|
+
# pre-pass. Predictable worst case.
|
|
45
|
+
#
|
|
46
|
+
# Masked cells are an incomparable sentinel (the same role NaN
|
|
47
|
+
# plays for float data types): they are excluded from the value
|
|
48
|
+
# comparison and clustered at one end of each fiber.
|
|
49
|
+
# `masked_position:` picks which end (`:last`, default, or
|
|
50
|
+
# `:first`); relative order within the masked cluster is
|
|
51
|
+
# unspecified. Masked cells keep their masked-ness at the
|
|
52
|
+
# clustered position (the `CARemap` gather carries the mask bit
|
|
53
|
+
# through, no separate output-mask step needed).
|
|
54
|
+
#
|
|
55
|
+
# Supports numeric (`i8`..`f64`), `CA_FIXLEN` (via memcmp
|
|
56
|
+
# lexicographic order), and `CA_OBJECT` (via `<=>` per pair) --
|
|
57
|
+
# all through the same view path, `masked_position:` included.
|
|
58
|
+
# @param axis [Integer, nil]
|
|
59
|
+
# @param kind [Symbol] `:quick` or `:stable`.
|
|
60
|
+
# @param masked_position [Symbol] `:last` (default) or `:first`.
|
|
61
|
+
# @return [CArray] sorted view.
|
|
62
|
+
def sort(axis: nil, kind: :quick, masked_position: :last); end
|
|
63
|
+
|
|
64
|
+
# @overload sort_copy(axis: nil, kind: :quick, masked_position: :last)
|
|
65
|
+
# Eager-copy counterpart of {#sort}: returns a fresh entity
|
|
66
|
+
# CArray with the same shape and `data_type` as `self`, sorted
|
|
67
|
+
# along `axis`. Use this when you want an independent array
|
|
68
|
+
# rather than a view.
|
|
69
|
+
#
|
|
70
|
+
# It takes whatever {#sort} takes: numeric (`i8`..`f64`),
|
|
71
|
+
# `CA_BOOLEAN`, `CA_FIXLEN` and `CA_OBJECT`, masked or not.
|
|
72
|
+
#
|
|
73
|
+
# Unmasked `i8`..`f64` uses a per-fiber gather + sort + scatter,
|
|
74
|
+
# bypassing the `CARemap` scatter layer that `sort` uses.
|
|
75
|
+
# Everything else materializes the `sort` view instead (same
|
|
76
|
+
# shape, ordering, and `masked_position:` semantics as {#sort}).
|
|
77
|
+
# @param axis [Integer, nil]
|
|
78
|
+
# @param kind [Symbol] `:quick` or `:stable`.
|
|
79
|
+
# @param masked_position [Symbol] `:last` (default) or `:first`.
|
|
80
|
+
# @return [CArray]
|
|
81
|
+
def sort_copy(axis: nil, kind: :quick, masked_position: :last); end
|
|
82
|
+
|
|
83
|
+
# @overload sort_addr(axis: nil, kind: :quick, masked_position: :last)
|
|
84
|
+
# Returns view-flat addresses that index a sort.
|
|
85
|
+
#
|
|
86
|
+
# - With no kwarg (`a.sort_addr`): returns a CArray of `:int64`
|
|
87
|
+
# flat addresses shaped like `self` (NOT flattened -- the
|
|
88
|
+
# legacy 1-key case of `CArray.sort_addr`'s multi-key lex
|
|
89
|
+
# sort). `kind:` has no effect on this form.
|
|
90
|
+
# - With `axis:` (e.g. `a.sort_addr(axis: 0)`): returns
|
|
91
|
+
# per-fiber view-flat addresses along the given axis, output
|
|
92
|
+
# shape == `self.shape`.
|
|
93
|
+
#
|
|
94
|
+
# `kind:` selects the sort algorithm for the `axis:` path:
|
|
95
|
+
#
|
|
96
|
+
# - `:quick` (default) — introsort with mergesort escape.
|
|
97
|
+
# - `:stable` — bottom-up mergesort.
|
|
98
|
+
#
|
|
99
|
+
# Both kinds are algorithmically stable (pair sort with index
|
|
100
|
+
# tie-break); `kind:` chooses the performance characteristic.
|
|
101
|
+
#
|
|
102
|
+
# `masked_position:` (`:last` default, or `:first`) picks which
|
|
103
|
+
# end masked cells cluster to. Effective on both forms: the
|
|
104
|
+
# `axis:` path forwards to the `sort`/`sort_index` kernel family;
|
|
105
|
+
# the no-`axis:` path forwards to `CArray.sort_addr`'s own
|
|
106
|
+
# masked-position-aware comparator.
|
|
107
|
+
#
|
|
108
|
+
# Companion of {#axis2addr} (axis-local indices to view-flat
|
|
109
|
+
# addresses) and {#sort} (the view counterpart).
|
|
110
|
+
# @param axis [Integer, nil]
|
|
111
|
+
# @param kind [Symbol] `:quick` or `:stable`.
|
|
112
|
+
# @param masked_position [Symbol] `:last` (default) or `:first`.
|
|
113
|
+
# @return [CArray] `:int64` addresses.
|
|
114
|
+
# @raise [ArgumentError] when `kind:` is neither `:quick` nor
|
|
115
|
+
# `:stable`.
|
|
116
|
+
def sort_addr(axis: nil, kind: :quick, masked_position: :last); end
|
|
117
|
+
|
|
118
|
+
# @!group Index and address conversion
|
|
119
|
+
|
|
120
|
+
# @overload axis2addr(indices, axis: 0)
|
|
121
|
+
# Converts per-fiber axis-local indices into row-major
|
|
122
|
+
# view-flat addresses into `self`. For each cell at coord
|
|
123
|
+
# `c = (c_0, ..., c_(n-1))` in `indices`:
|
|
124
|
+
#
|
|
125
|
+
# addr[c] = sum over `j != axis` of c_j * stride_j +
|
|
126
|
+
# indices[c] * stride_axis
|
|
127
|
+
#
|
|
128
|
+
# where strides are row-major over `self.shape`.
|
|
129
|
+
#
|
|
130
|
+
# Canonical converter between the two axis-position
|
|
131
|
+
# representations the `*_index` / `*_addr` kernel families
|
|
132
|
+
# produce:
|
|
133
|
+
#
|
|
134
|
+
# @example
|
|
135
|
+
# a.min_index(axis: k) # axis-local scalar per fiber
|
|
136
|
+
# a.min_addr(axis: k) # view-flat address per fiber
|
|
137
|
+
# flat = key.axis2addr(key.min_index(axis: k), axis: k)
|
|
138
|
+
# # flat == key.min_addr(axis: k)
|
|
139
|
+
#
|
|
140
|
+
# Sits underneath `#take_along_axis`: the heavy "axis-local
|
|
141
|
+
# -> view-flat" arithmetic lives here, and `take_along_axis`
|
|
142
|
+
# is a one-liner on top of `flatten[axis2addr(...)]`.
|
|
143
|
+
#
|
|
144
|
+
# Shape rule: `indices.ndim == self.ndim`, and
|
|
145
|
+
# `indices.dim[j] == self.dim[j]` for all `j != axis`;
|
|
146
|
+
# `indices.dim[axis]` is free.
|
|
147
|
+
#
|
|
148
|
+
# `indices` data_type: any integer kind (zero-copy when
|
|
149
|
+
# already `:int64`). Negative indices: Python-style
|
|
150
|
+
# (`-1` == last). Out-of-range indices raise `RangeError`.
|
|
151
|
+
# Negative `axis:` is Python-style.
|
|
152
|
+
#
|
|
153
|
+
# @param indices [CArray] integer-typed axis-local positions.
|
|
154
|
+
# @param axis [Integer] axis along which `indices` are
|
|
155
|
+
# interpreted.
|
|
156
|
+
# @return [CArray] `:int64` view-flat addresses, same shape as
|
|
157
|
+
# `indices`.
|
|
158
|
+
# @raise [RangeError] when an index is out of range after
|
|
159
|
+
# negative normalization.
|
|
160
|
+
# @raise [ArgumentError] for shape / ndim / data_type
|
|
161
|
+
# violations.
|
|
162
|
+
def axis2addr(indices, axis: 0); end
|
|
163
|
+
|
|
164
|
+
# @!endgroup
|
|
165
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# DOCUMENTATION ONLY — DO NOT REQUIRE.
|
|
2
|
+
# Stubs for methods defined in ext/carray_test.c.
|
|
3
|
+
# See yard-stubs/README.md and yard-stubs/STYLE.md.
|
|
4
|
+
|
|
5
|
+
class CArray
|
|
6
|
+
# @!group Index and address conversion
|
|
7
|
+
|
|
8
|
+
# @overload valid_index?(*idx)
|
|
9
|
+
# Returns `true` if the given index tuple is in range for `self`.
|
|
10
|
+
# The number of indices must equal `ndim`.
|
|
11
|
+
# @param idx [Array<Integer>] one index per axis.
|
|
12
|
+
# @return [Boolean]
|
|
13
|
+
# @raise [ArgumentError] if the number of indices does not match
|
|
14
|
+
# `ndim`.
|
|
15
|
+
def valid_index?(*idx); end
|
|
16
|
+
|
|
17
|
+
# @overload valid_addr?(addr)
|
|
18
|
+
# Returns `true` if `addr` is in range `0...elements` for `self`.
|
|
19
|
+
# @param addr [Integer] flat address into the contiguous element
|
|
20
|
+
# sequence.
|
|
21
|
+
# @return [Boolean]
|
|
22
|
+
def valid_addr?(addr); end
|
|
23
|
+
|
|
24
|
+
# @overload same_shape?(other)
|
|
25
|
+
# Returns `true` if `other` has the same shape as `self`.
|
|
26
|
+
# @param other [CArray]
|
|
27
|
+
# @return [Boolean]
|
|
28
|
+
def same_shape?(other); end
|
|
29
|
+
|
|
30
|
+
# @!endgroup
|
|
31
|
+
|
|
32
|
+
# @!group Equality and hashing
|
|
33
|
+
|
|
34
|
+
# @overload ==(other)
|
|
35
|
+
# Returns `true` if `other` is a CArray with the same shape,
|
|
36
|
+
# `data_class`, `data_type`, mask state, and elementwise values as
|
|
37
|
+
# `self`. NaN values compare unequal (IEEE semantics), so two
|
|
38
|
+
# arrays with NaN at the same position are not `==`.
|
|
39
|
+
# @param other [Object]
|
|
40
|
+
# @return [Boolean]
|
|
41
|
+
def ==(other); end
|
|
42
|
+
|
|
43
|
+
# @overload eql?(other)
|
|
44
|
+
# Returns `true` under Hash-invariant semantics: `data_class`,
|
|
45
|
+
# `data_type`, shape, and mask state must all match, and elements
|
|
46
|
+
# are compared bitwise (for numeric types) or via `Object#eql?`
|
|
47
|
+
# (for `:object` arrays). Unlike `==`, `NaN.eql?(NaN)` holds, so
|
|
48
|
+
# two mask-free arrays with NaN at the same positions are `eql?`.
|
|
49
|
+
#
|
|
50
|
+
# Guarantees `a.eql?(b)` ⇒ `a.hash == b.hash`.
|
|
51
|
+
# @param other [Object]
|
|
52
|
+
# @return [Boolean]
|
|
53
|
+
def eql?(other); end
|
|
54
|
+
|
|
55
|
+
# @overload hash
|
|
56
|
+
# Returns the Hash key value for `self`. Mixes `data_type`,
|
|
57
|
+
# `ndim`, `bytes`, `elements`, shape, scalar-ness, and mask
|
|
58
|
+
# presence; for unmasked arrays, samples the leading 64 bytes of
|
|
59
|
+
# data. Masked arrays skip the data sample.
|
|
60
|
+
# @return [Integer]
|
|
61
|
+
def hash; end
|
|
62
|
+
|
|
63
|
+
# @!endgroup
|
|
64
|
+
|
|
65
|
+
# @!group Equality and hashing
|
|
66
|
+
|
|
67
|
+
# @overload freeze
|
|
68
|
+
# Freezes `self` and marks it read-only. Subsequent mutations
|
|
69
|
+
# raise `FrozenError`.
|
|
70
|
+
# @return [self]
|
|
71
|
+
def freeze; end
|
|
72
|
+
|
|
73
|
+
# @overload set_read_only_flag
|
|
74
|
+
# Marks `self` read-only (sets `CA_FLAG_READ_ONLY`) without
|
|
75
|
+
# freezing the Ruby object, so subsequent mutations raise
|
|
76
|
+
# `RuntimeError` while `frozen?` stays false and views / Faces
|
|
77
|
+
# derived from `self` can still memoise. One-way: there is no
|
|
78
|
+
# method to clear the flag. Use `#copy` for a writable copy (a
|
|
79
|
+
# copy does not inherit the flag). Contrast `#freeze`, which also
|
|
80
|
+
# freezes the Ruby object.
|
|
81
|
+
# @return [self]
|
|
82
|
+
def set_read_only_flag; end
|
|
83
|
+
|
|
84
|
+
# @!endgroup
|
|
85
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# DOCUMENTATION ONLY — DO NOT REQUIRE.
|
|
2
|
+
# Stubs for the UNDEF sentinel and UndefClass defined in
|
|
3
|
+
# ext/carray_undef.c. See yard-stubs/README.md and yard-stubs/STYLE.md.
|
|
4
|
+
|
|
5
|
+
# Singleton class of the {UNDEF} sentinel value. Not instantiable
|
|
6
|
+
# (`UndefClass.new` is undef'd after the single instance is created
|
|
7
|
+
# in `Init_carray_undef`).
|
|
8
|
+
#
|
|
9
|
+
# The class is private API in practice: read and write the sentinel
|
|
10
|
+
# through the top-level `UNDEF` constant rather than touching the
|
|
11
|
+
# class directly.
|
|
12
|
+
class UndefClass
|
|
13
|
+
# @overload inspect
|
|
14
|
+
# Returns the literal string `"UNDEF"`.
|
|
15
|
+
# @return [String]
|
|
16
|
+
def inspect; end
|
|
17
|
+
|
|
18
|
+
# @overload to_s
|
|
19
|
+
# Returns the literal string `"UNDEF"`. Display works (so
|
|
20
|
+
# `puts UNDEF` shows `"UNDEF"`); numeric coercion via {#to_f}
|
|
21
|
+
# / {#to_i} raises.
|
|
22
|
+
# @return [String]
|
|
23
|
+
def to_s; end
|
|
24
|
+
|
|
25
|
+
# @overload to_f
|
|
26
|
+
# Raises `TypeError`. Numeric coercion of UNDEF is rejected so
|
|
27
|
+
# that accidental arithmetic on a masked sentinel surfaces as an
|
|
28
|
+
# error rather than silently producing `0.0` / `NaN`.
|
|
29
|
+
# @raise [TypeError]
|
|
30
|
+
def to_f; end
|
|
31
|
+
|
|
32
|
+
# @overload to_i
|
|
33
|
+
# Raises `TypeError`. Same rationale as {#to_f}.
|
|
34
|
+
# @raise [TypeError]
|
|
35
|
+
def to_i; end
|
|
36
|
+
|
|
37
|
+
# @overload to_int
|
|
38
|
+
# Alias of {#to_i}. Raises `TypeError`.
|
|
39
|
+
# @raise [TypeError]
|
|
40
|
+
def to_int; end
|
|
41
|
+
|
|
42
|
+
# @overload ==(other)
|
|
43
|
+
# Returns `true` only when `other` is the same UNDEF singleton
|
|
44
|
+
# (identity comparison). No coercion or value equality.
|
|
45
|
+
# @param other [Object]
|
|
46
|
+
# @return [Boolean]
|
|
47
|
+
def ==(other); end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Top-level sentinel used by mask-bearing CArray APIs to mean
|
|
51
|
+
# "masked / no value here" without choosing a numeric sentinel
|
|
52
|
+
# (NaN, `-1`, etc.) that might collide with valid data.
|
|
53
|
+
#
|
|
54
|
+
# Identity semantics: every reference to `UNDEF` is the same Ruby
|
|
55
|
+
# object, pinned against the compacting GC so the C extension can
|
|
56
|
+
# safely use raw pointer comparison to detect it.
|
|
57
|
+
#
|
|
58
|
+
# @example mask a cell during construction
|
|
59
|
+
# a = CArray.int32(3) { |i| (i == 1) ? UNDEF : i * 10 }
|
|
60
|
+
# a.to_a # => [0, nil, 20] # UNDEF surfaces as nil after to_a
|
|
61
|
+
#
|
|
62
|
+
# @example check whether an element is masked
|
|
63
|
+
# a[1] == UNDEF # => true
|
|
64
|
+
UNDEF = UndefClass.new
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# DOCUMENTATION ONLY — DO NOT REQUIRE.
|
|
2
|
+
# Stubs for methods defined in ext/carray_utils.c.
|
|
3
|
+
# See yard-stubs/README.md and yard-stubs/STYLE.md.
|
|
4
|
+
|
|
5
|
+
class CArray
|
|
6
|
+
# @!group Index and address conversion
|
|
7
|
+
|
|
8
|
+
# @overload normalize_axis(axis, name = nil)
|
|
9
|
+
# Returns the canonical non-negative integer axis index in
|
|
10
|
+
# `[0, ndim)` for `self`. Accepts Python-style negative indices
|
|
11
|
+
# (`-1` ⇒ `ndim-1`).
|
|
12
|
+
# @param axis [Integer] axis index, possibly negative.
|
|
13
|
+
# @param name [String, nil] argument name to embed in error
|
|
14
|
+
# messages (e.g. `"axis"`, `"at"`).
|
|
15
|
+
# @return [Integer]
|
|
16
|
+
# @raise [ArgumentError] if `axis` is outside `[-ndim, ndim)`.
|
|
17
|
+
def normalize_axis(axis, name = nil); end
|
|
18
|
+
|
|
19
|
+
# @overload normalize_axes(axes, name = nil)
|
|
20
|
+
# Returns an Array of canonical non-negative axis indices in
|
|
21
|
+
# input order. Accepts:
|
|
22
|
+
#
|
|
23
|
+
# - `nil` ⇒ all axes `[0, 1, ..., ndim-1]`
|
|
24
|
+
# - `Integer` ⇒ `[normalize_axis(axis)]`
|
|
25
|
+
# - `Array<Integer>` ⇒ each normalized, preserving input order
|
|
26
|
+
#
|
|
27
|
+
# @param axes [Integer, Array<Integer>, nil]
|
|
28
|
+
# @param name [String, nil] argument name for error messages.
|
|
29
|
+
# @return [Array<Integer>]
|
|
30
|
+
# @raise [ArgumentError] on out-of-range or duplicate axes.
|
|
31
|
+
def normalize_axes(axes, name = nil); end
|
|
32
|
+
|
|
33
|
+
# @!endgroup
|
|
34
|
+
|
|
35
|
+
class << self
|
|
36
|
+
# @!group Index and address conversion
|
|
37
|
+
|
|
38
|
+
# @overload normalize_axis(axis, ndim, name = nil)
|
|
39
|
+
# Class-method form of {CArray#normalize_axis} that operates on
|
|
40
|
+
# an explicit `ndim` rather than a CArray instance. Range is
|
|
41
|
+
# `[0, ndim)`.
|
|
42
|
+
#
|
|
43
|
+
# For an insertion position (valid range `[0, old_ndim]`
|
|
44
|
+
# inclusive), pass `old_ndim + 1` as `ndim`. Used by class-level
|
|
45
|
+
# callers such as `CArray.stack(list, axis:)` that must
|
|
46
|
+
# normalize before any instance is available, and by
|
|
47
|
+
# composition helpers in `lib/carray/compose.rb`.
|
|
48
|
+
# @param axis [Integer]
|
|
49
|
+
# @param ndim [Integer]
|
|
50
|
+
# @param name [String, nil]
|
|
51
|
+
# @return [Integer]
|
|
52
|
+
def normalize_axis(axis, ndim, name = nil); end
|
|
53
|
+
|
|
54
|
+
# @!endgroup
|
|
55
|
+
|
|
56
|
+
# @!group Type guessing
|
|
57
|
+
|
|
58
|
+
# @overload guess_type_and_bytes(type_spec, bytes = nil)
|
|
59
|
+
# Resolves a user-supplied type spec into the pair
|
|
60
|
+
# `[data_type_code, bytes]`. `data_type_code` is the internal
|
|
61
|
+
# `int8_t` numeric code (see {CArray.data_type_code}); `bytes`
|
|
62
|
+
# is the per-element byte size (`0` for non-`:fixlen`).
|
|
63
|
+
# @param type_spec [Symbol, Integer, Class, String]
|
|
64
|
+
# @param bytes [Integer, nil] element byte size, used only for
|
|
65
|
+
# `:fixlen`.
|
|
66
|
+
# @return [Array(Integer, Integer)]
|
|
67
|
+
def guess_type_and_bytes(type_spec, bytes = nil); end
|
|
68
|
+
|
|
69
|
+
# @!endgroup
|
|
70
|
+
|
|
71
|
+
# @!group String scanning (internal)
|
|
72
|
+
|
|
73
|
+
# @overload _scan_float(str, fill_value = nil)
|
|
74
|
+
# Parses `str` as a single double-precision float. Returns
|
|
75
|
+
# `fill_value` (or `NaN` if `fill_value` is nil) when `str` is
|
|
76
|
+
# `nil` or unparseable. Internal helper used by text-format I/O
|
|
77
|
+
# readers; end users should prefer Ruby's `Float()` /
|
|
78
|
+
# `String#to_f`.
|
|
79
|
+
# @param str [String, nil]
|
|
80
|
+
# @param fill_value [Float, nil]
|
|
81
|
+
# @return [Float]
|
|
82
|
+
# @api private
|
|
83
|
+
def _scan_float(str, fill_value = nil); end
|
|
84
|
+
|
|
85
|
+
# @overload _scan_int(str, fill_value = nil)
|
|
86
|
+
# Parses `str` as a single integer. Returns `fill_value`
|
|
87
|
+
# (or `0` if `fill_value` is nil) when `str` is `nil` or
|
|
88
|
+
# unparseable. Internal helper used by text-format I/O readers.
|
|
89
|
+
# @param str [String, nil]
|
|
90
|
+
# @param fill_value [Integer, nil]
|
|
91
|
+
# @return [Integer]
|
|
92
|
+
# @api private
|
|
93
|
+
def _scan_int(str, fill_value = nil); end
|
|
94
|
+
|
|
95
|
+
# @!endgroup
|
|
96
|
+
end
|
|
97
|
+
end
|