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.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -1
  3. data/CHANGELOG.md +845 -3
  4. data/{NEWS.md → CHANGELOG.v1.md} +1 -1
  5. data/README.md +33 -33
  6. data/carray.gemspec +12 -8
  7. data/ext/ca_axis_dispatch.c +33 -4
  8. data/ext/ca_axis_group.c +256 -114
  9. data/ext/ca_binop_dispatch.c +5 -6
  10. data/ext/ca_binop_dispatch.h +0 -7
  11. data/ext/ca_categorical_iterator.c +121 -67
  12. data/ext/ca_for_each_element.h +6 -8
  13. data/ext/ca_group_iter.c +1 -1
  14. data/ext/ca_kernel_iterator.c +386 -74
  15. data/ext/ca_kernel_iterator.h +145 -45
  16. data/ext/ca_obj_array.c +62 -20
  17. data/ext/ca_obj_bincmp.c +57 -27
  18. data/ext/ca_obj_binop.c +86 -30
  19. data/ext/ca_obj_block.c +4 -4
  20. data/ext/ca_obj_const_string.c +88 -27
  21. data/ext/ca_obj_face.c +104 -0
  22. data/ext/ca_obj_face.h +48 -1
  23. data/ext/ca_obj_fake.c +11 -0
  24. data/ext/ca_obj_fixlen_string.c +21 -6
  25. data/ext/ca_obj_grid.c +11 -3
  26. data/ext/ca_obj_meld.c +125 -22
  27. data/ext/ca_obj_moncmp.c +33 -14
  28. data/ext/ca_obj_monop.c +19 -7
  29. data/ext/ca_obj_object.c +107 -4
  30. data/ext/ca_obj_record.c +3 -1
  31. data/ext/ca_obj_refer.c +30 -6
  32. data/ext/ca_obj_roll.c +13 -5
  33. data/ext/ca_obj_select.c +49 -34
  34. data/ext/ca_obj_select_axis.c +16 -6
  35. data/ext/ca_obj_shift.c +3 -3
  36. data/ext/ca_obj_stack.c +3 -8
  37. data/ext/ca_obj_stride.c +178 -24
  38. data/ext/ca_obj_string.c +11 -5
  39. data/ext/ca_obj_tile.c +13 -5
  40. data/ext/ca_obj_time.c +3 -1
  41. data/ext/ca_obj_timedelta.c +3 -1
  42. data/ext/ca_obj_transpose.c +1 -1
  43. data/ext/ca_obj_triop.c +62 -23
  44. data/ext/ca_obj_window.c +94 -19
  45. data/ext/ca_op_cmplx64.h +123 -0
  46. data/ext/ca_op_ipower.c +1 -5
  47. data/ext/ca_rng_normal.h +42 -0
  48. data/ext/ca_rng_xoshiro256pp.h +105 -0
  49. data/ext/ca_sort_kernels.h +5 -5
  50. data/ext/ca_sweep_engine.c +362 -155
  51. data/ext/ca_sweep_engine.h +39 -9
  52. data/ext/ca_transform_common.c +7 -0
  53. data/ext/carray.h +148 -132
  54. data/ext/carray_access.c +83 -49
  55. data/ext/carray_address_basis.c +590 -0
  56. data/ext/carray_bincount.c +8 -8
  57. data/ext/carray_broadcast.c +102 -9
  58. data/ext/carray_build_flags.h +3 -0
  59. data/ext/carray_call_cfunc.c +2010 -335
  60. data/ext/carray_call_cfunc.h +153 -0
  61. data/ext/carray_cast.c +184 -72
  62. data/ext/carray_conversion.c +22 -22
  63. data/ext/carray_copy.c +67 -32
  64. data/ext/carray_core.c +140 -13
  65. data/ext/carray_count.c +10 -11
  66. data/ext/carray_element.c +7 -7
  67. data/ext/carray_factorize.c +72 -51
  68. data/ext/carray_hold.c +1 -1
  69. data/ext/carray_index_classifier.c +7 -21
  70. data/ext/carray_internal.h +36 -3
  71. data/ext/carray_kernels_bincmp.c +1 -0
  72. data/ext/carray_kernels_binop.c +320 -298
  73. data/ext/carray_kernels_init.c +1095 -0
  74. data/ext/carray_kernels_map.c +1 -0
  75. data/ext/carray_kernels_moncmp.c +1 -0
  76. data/ext/carray_kernels_monop.c +412 -411
  77. data/ext/carray_kernels_reduce_aggregate.c +256 -87
  78. data/ext/carray_kernels_reduce_boolean.c +1 -0
  79. data/ext/carray_kernels_reduce_cumulative.c +324 -54
  80. data/ext/carray_kernels_reduce_extreme.c +605 -58
  81. data/ext/carray_kernels_reduce_variance.c +1 -0
  82. data/ext/carray_kernels_scan.c +5 -4
  83. data/ext/carray_kernels_search.c +187 -106
  84. data/ext/carray_kernels_sort.c +1 -0
  85. data/ext/carray_kernels_triop.c +1 -0
  86. data/ext/carray_lazy.c +175 -5
  87. data/ext/carray_loop.c +7 -1
  88. data/ext/carray_mask.c +29 -13
  89. data/ext/carray_median_percentile.c +56 -1
  90. data/ext/carray_memory_view.c +46 -21
  91. data/ext/carray_operator.c +50 -53
  92. data/ext/carray_order.c +1 -1
  93. data/ext/carray_partition.c +4 -4
  94. data/ext/carray_random.c +391 -47
  95. data/ext/carray_scatter.c +1 -1
  96. data/ext/carray_slab.c +13 -0
  97. data/ext/carray_sort.c +22 -24
  98. data/ext/carray_sort_kernel.c +10 -10
  99. data/ext/carray_test.c +1 -1
  100. data/ext/extconf.rb +18 -0
  101. data/ext/mk_call_cfunc.rb +323 -145
  102. data/ext/mkkernel.rb +651 -129
  103. data/ext/ruby_carray.c +28 -17
  104. data/ext/version.h +4 -4
  105. data/lib/carray/autoload_carray.rb +24 -3
  106. data/lib/carray/autoload_method_extension.rb +14 -1
  107. data/lib/carray/axis_group.rb +84 -7
  108. data/lib/carray/basics.rb +63 -59
  109. data/lib/carray/bincount_nd.rb +12 -12
  110. data/lib/carray/block_iterator.rb +111 -25
  111. data/lib/carray/categorical.rb +154 -37
  112. data/lib/carray/categorical_iterator.rb +300 -151
  113. data/lib/carray/conditional.rb +14 -14
  114. data/lib/carray/const_string.rb +131 -27
  115. data/lib/carray/construct.rb +61 -0
  116. data/lib/carray/core_extensions.rb +62 -5
  117. data/lib/carray/data_type_extension.rb +21 -1
  118. data/lib/carray/data_type_limits.rb +91 -0
  119. data/lib/carray/fixlen_string.rb +1 -1
  120. data/lib/carray/frame/concat.rb +3 -3
  121. data/lib/carray/frame/convert.rb +1 -1
  122. data/lib/carray/frame/csv_parser.rb +11 -4
  123. data/lib/carray/frame/frame.rb +85 -21
  124. data/lib/carray/frame/group.rb +36 -3
  125. data/lib/carray/frame/io.rb +224 -15
  126. data/lib/carray/frame/records.rb +18 -4
  127. data/lib/carray/frame/sort.rb +1 -1
  128. data/lib/carray/frame/verbs.rb +32 -12
  129. data/lib/carray/fuse_source.rb +123 -0
  130. data/lib/carray/fusion.rb +218 -0
  131. data/lib/carray/histogram.rb +16 -16
  132. data/lib/carray/inspect.rb +43 -16
  133. data/lib/carray/iterator.rb +147 -3
  134. data/lib/carray/lazy.rb +88 -73
  135. data/lib/carray/mask_gap_fill.rb +3 -1
  136. data/lib/carray/meld_reduce.rb +2 -2
  137. data/lib/carray/methods/align_addr.rb +1 -1
  138. data/lib/carray/methods/composition.rb +1 -1
  139. data/lib/carray/methods/discovery_along.rb +74 -0
  140. data/lib/carray/methods/factorize.rb +50 -0
  141. data/lib/carray/methods/is_in.rb +25 -14
  142. data/lib/carray/methods/locate_addr.rb +81 -3
  143. data/lib/carray/methods/mask_duplicates.rb +36 -2
  144. data/lib/carray/methods/meshgrid.rb +4 -5
  145. data/lib/carray/methods/mode.rb +2 -2
  146. data/lib/carray/methods/nunique.rb +23 -2
  147. data/lib/carray/methods/repeat.rb +110 -0
  148. data/lib/carray/methods/snap.rb +7 -2
  149. data/lib/carray/methods/unique.rb +44 -4
  150. data/lib/carray/methods/value_counts.rb +2 -2
  151. data/lib/carray/rng.rb +86 -0
  152. data/lib/carray/runtime.rb +0 -19
  153. data/lib/carray/slab_iterator.rb +77 -19
  154. data/lib/carray/string_operation_extension.rb +10 -6
  155. data/lib/carray/time.rb +906 -491
  156. data/lib/carray/window_iterator.rb +421 -27
  157. data/lib/carray.rb +7 -5
  158. data/yard-stubs/ca_obj_array.rb +385 -0
  159. data/yard-stubs/ca_obj_bitarray.rb +38 -0
  160. data/yard-stubs/ca_obj_bitfield.rb +43 -0
  161. data/yard-stubs/ca_obj_block.rb +68 -0
  162. data/yard-stubs/ca_obj_byte_swap.rb +56 -0
  163. data/yard-stubs/ca_obj_fake.rb +31 -0
  164. data/yard-stubs/ca_obj_farray.rb +32 -0
  165. data/yard-stubs/ca_obj_field.rb +45 -0
  166. data/yard-stubs/ca_obj_grid.rb +35 -0
  167. data/yard-stubs/ca_obj_refer.rb +72 -0
  168. data/yard-stubs/ca_obj_roll.rb +45 -0
  169. data/yard-stubs/ca_obj_shift.rb +43 -0
  170. data/yard-stubs/ca_obj_stride.rb +181 -0
  171. data/yard-stubs/ca_obj_tile.rb +29 -0
  172. data/yard-stubs/ca_obj_transpose.rb +40 -0
  173. data/yard-stubs/ca_obj_window.rb +57 -0
  174. data/yard-stubs/carray_access.rb +131 -0
  175. data/yard-stubs/carray_attribute.rb +246 -0
  176. data/yard-stubs/carray_broadcast.rb +37 -0
  177. data/yard-stubs/carray_cast.rb +489 -0
  178. data/yard-stubs/carray_class.rb +65 -0
  179. data/yard-stubs/carray_conversion.rb +76 -0
  180. data/yard-stubs/carray_copy.rb +79 -0
  181. data/yard-stubs/carray_core.rb +34 -0
  182. data/yard-stubs/carray_count.rb +84 -0
  183. data/yard-stubs/carray_element.rb +108 -0
  184. data/yard-stubs/carray_generate.rb +66 -0
  185. data/yard-stubs/carray_lazy.rb +228 -0
  186. data/yard-stubs/carray_loop.rb +140 -0
  187. data/yard-stubs/carray_mask.rb +259 -0
  188. data/yard-stubs/carray_math.rb +1615 -0
  189. data/yard-stubs/carray_mathfunc.rb +45 -0
  190. data/yard-stubs/carray_median_percentile.rb +103 -0
  191. data/yard-stubs/carray_memory_view.rb +163 -0
  192. data/yard-stubs/carray_order.rb +252 -0
  193. data/yard-stubs/carray_random.rb +89 -0
  194. data/yard-stubs/carray_scatter.rb +106 -0
  195. data/yard-stubs/carray_slab.rb +59 -0
  196. data/yard-stubs/carray_sort.rb +165 -0
  197. data/yard-stubs/carray_test.rb +85 -0
  198. data/yard-stubs/carray_undef.rb +64 -0
  199. data/yard-stubs/carray_utils.rb +97 -0
  200. data/yard-stubs/ruby_carray.rb +193 -0
  201. metadata +67 -10
  202. data/ext/ca_obj_unbound_repeat.c +0 -496
@@ -0,0 +1,45 @@
1
+ # DOCUMENTATION ONLY — DO NOT REQUIRE.
2
+ # Stubs for the CAMath module functions defined in
3
+ # ext/carray_mathfunc.c. Most CAMath entries (atan2 / hypot / expm1
4
+ # / log1p / copysign / logaddexp / nextafter / fmod / min / max) live
5
+ # in lib/carray/math.rb and are documented at the source. This file
6
+ # covers only the C-defined module functions.
7
+ # See yard-stubs/README.md and yard-stubs/STYLE.md.
8
+
9
+ # Namespace for math module functions that operate on CArray (and
10
+ # auto-wrappable scalar) inputs.
11
+ module CAMath
12
+ module_function
13
+
14
+ # @overload spherical_to_xyz(r, theta, phi)
15
+ # Returns three CArrays `[x, y, z]` of cartesian coordinates
16
+ # converted from spherical coordinates. All inputs are coerced
17
+ # to `:float64`; outputs are `:float64`.
18
+ #
19
+ # `theta` is the polar angle from the `+z` axis in radians;
20
+ # `phi` is the azimuthal angle in the `xy` plane in radians.
21
+ # @param r [CArray, Numeric] radial distance.
22
+ # @param theta [CArray, Numeric] polar angle (radians).
23
+ # @param phi [CArray, Numeric] azimuthal angle (radians).
24
+ # @return [Array<CArray>] `[x, y, z]`.
25
+ def spherical_to_xyz(r, theta, phi); end
26
+
27
+ # @overload xyz_to_spherical(x, y, z)
28
+ # Returns three CArrays `[r, theta, phi]` of spherical
29
+ # coordinates converted from cartesian coordinates. All inputs
30
+ # are coerced to `:float64`; outputs are `:float64`.
31
+ # @param x [CArray, Numeric]
32
+ # @param y [CArray, Numeric]
33
+ # @param z [CArray, Numeric]
34
+ # @return [Array<CArray>] `[r, theta, phi]`.
35
+ # @raise [RuntimeError] when the build lacks `atan2`.
36
+ def xyz_to_spherical(x, y, z); end
37
+
38
+ # @overload lgamma(x)
39
+ # Returns a `:float64` CArray of `log(|Γ(x)|)` for each element of
40
+ # `x`. `x` is coerced to `:float64`.
41
+ # @param x [CArray, Numeric]
42
+ # @return [CArray]
43
+ # @raise [RuntimeError] when the build lacks `lgamma`.
44
+ def lgamma(x); end
45
+ end
@@ -0,0 +1,103 @@
1
+ # DOCUMENTATION ONLY — DO NOT REQUIRE.
2
+ # Stubs for methods defined in ext/carray_median_percentile.c.
3
+ # See yard-stubs/README.md and yard-stubs/STYLE.md.
4
+
5
+ class CArray
6
+ # @!group Statistics
7
+
8
+ # @overload median(axis: nil, min_count: 0, fill_value: nil, keep_axis: false)
9
+ # Returns the median of `self` along `axis` (or over all elements
10
+ # when `axis` is `nil`).
11
+ #
12
+ # Numeric arrays return a `Float`; `CA_OBJECT` arrays return the
13
+ # result of Ruby `+` / `/` on the stored objects. Fixlen arrays
14
+ # raise, since no numeric midpoint is defined.
15
+ #
16
+ # An even number of elements has no middle one, only the average of
17
+ # two -- so an object array whose elements cannot be averaged (a
18
+ # column of Strings) has a median at odd length and raises at even.
19
+ # `percentile(50, method: :lower)` names an element either way.
20
+ #
21
+ # Masked cells are excluded. Per-axis, each fiber uses only its own
22
+ # present values; a fully masked fiber reduces to `UNDEF`. If the
23
+ # count of not-masked cells (per fiber, or over all elements in the
24
+ # flat form) is below `min_count`, that cell is `fill_value` (or
25
+ # `UNDEF` when `fill_value` is `nil`).
26
+ #
27
+ # With `keep_axis: true`, the reduced axis is retained with
28
+ # length 1 rather than dropped.
29
+ # @param axis [Integer, nil]
30
+ # @param min_count [Integer] minimum not-masked count required.
31
+ # @param fill_value [Object, nil] replacement when the not-masked
32
+ # count is below `min_count`.
33
+ # @param keep_axis [Boolean]
34
+ # @return [Float, CArray, Object]
35
+ # @raise [CArray::DataTypeError] for fixlen data_type, or for an even
36
+ # number of elements whose objects cannot be averaged.
37
+ # @raise [ArgumentError] on negative `min_count`.
38
+ def median(*); end
39
+
40
+ # @overload percentile(*p, axis: nil, min_count: 0, fill_value: nil,
41
+ # method: :linear, keep_axis: false)
42
+ # Returns percentile values at each `p` (each in `[0, 100]`)
43
+ # along `axis` or over all elements.
44
+ #
45
+ # `p` may be given as individual positional arguments, a single
46
+ # `Array<Numeric>`, or a single 1-D `CArray`. When the effective
47
+ # `p` count (after flattening) is 1, the result is unwrapped:
48
+ # flat form returns a `Float`, per-axis form returns a `CArray`.
49
+ # With 2 or more `p` values the result is an `Array` whose length
50
+ # matches the number of requested `p` values.
51
+ #
52
+ # `method` picks the interpolation rule between adjacent order
53
+ # statistics:
54
+ #
55
+ # - `:linear` (default) — linear interpolation.
56
+ # - `:lower` — floor to the smaller neighbor.
57
+ # - `:higher` — ceil to the larger neighbor.
58
+ # - `:nearest` — round-half-to-even to the nearer neighbor.
59
+ # - `:midpoint` — arithmetic mean of the two neighbors.
60
+ #
61
+ # The first three pick an element and the last two compute one, so
62
+ # only the first three apply to a `CA_OBJECT` array whose elements
63
+ # have no arithmetic: `:linear` and `:midpoint` raise there, and do
64
+ # so only when the requested `p` actually falls between two
65
+ # elements (`percentile(50)` of five Strings still answers).
66
+ #
67
+ # Numeric arrays produce `Float` results; `CA_OBJECT` arrays
68
+ # apply Ruby `+` / `/` / `*` on the stored objects. Fixlen
69
+ # arrays raise.
70
+ #
71
+ # Masking, `min_count`, `fill_value`, and `keep_axis` follow the
72
+ # same rules as {#median}.
73
+ # @param p [Numeric, Array<Numeric>, CArray] percentile targets in
74
+ # `[0, 100]`.
75
+ # @param axis [Integer, nil]
76
+ # @param min_count [Integer]
77
+ # @param fill_value [Object, nil]
78
+ # @param method [Symbol] one of `:linear`, `:lower`, `:higher`,
79
+ # `:nearest`, `:midpoint`.
80
+ # @param keep_axis [Boolean]
81
+ # @return [Float, CArray, Object, Array<Float>, Array<CArray>, Array<Object>]
82
+ # @raise [CArray::DataTypeError] for fixlen data_type, or when an
83
+ # interpolating `method` is asked to interpolate between objects
84
+ # that have no arithmetic.
85
+ # @raise [ArgumentError] on empty `p` list, `p` outside `[0, 100]`,
86
+ # empty axis, unknown `method`, or invalid option combinations.
87
+ def percentile(*); end
88
+
89
+ # @overload quantile(axis: nil, keep_axis: false)
90
+ # Returns the five quartile percentiles
91
+ # `[p0, p25, p50, p75, p100]` — shorthand for
92
+ # `percentile(0, 25, 50, 75, 100, axis: axis, keep_axis: keep_axis)`.
93
+ # Accepts no positional arguments. Flat form returns
94
+ # `Array<Float>` of length 5; per-axis form returns `Array<CArray>`
95
+ # of length 5, each CArray reduced along `axis`.
96
+ # @param axis [Integer, nil]
97
+ # @param keep_axis [Boolean]
98
+ # @return [Array<Float>, Array<CArray>]
99
+ # @raise [ArgumentError] on any positional argument.
100
+ def quantile(*); end
101
+
102
+ # @!endgroup
103
+ end
@@ -0,0 +1,163 @@
1
+ # DOCUMENTATION ONLY — DO NOT REQUIRE.
2
+ # Stubs for singleton methods defined in ext/carray_memory_view.c.
3
+ # See yard-stubs/README.md and yard-stubs/STYLE.md.
4
+
5
+ class CArray
6
+ class << self
7
+ # @!group MemoryView interop
8
+
9
+ # @overload memory_view_available?(obj)
10
+ # Returns `true` if `obj` exposes the Ruby `rb_memory_view`
11
+ # protocol and a view can be acquired from it. Lightweight probe
12
+ # used to gate {.from_memory_view} / {.wrap_memory_view} calls.
13
+ #
14
+ # Returning `true` does not guarantee acquisition will succeed —
15
+ # a producer may still refuse a particular flag combination at
16
+ # acquisition time.
17
+ # @param obj [Object] any object (typically a foreign array such
18
+ # as `Numo::NArray`, `Arrow::Array`, a `bytearray`, or a
19
+ # CArray).
20
+ # @return [Boolean]
21
+ # @example
22
+ # CArray.memory_view_available?(CArray.int32(3)) # => true
23
+ # CArray.memory_view_available?("plain string") # => false
24
+ def memory_view_available?(obj); end
25
+
26
+ # @overload memory_view_reject_reason(obj)
27
+ # Returns a String explaining why CArray's MemoryView producer
28
+ # refuses to export `obj`, or `nil` if no problem is detected.
29
+ #
30
+ # Diagnostic only; useful when {.memory_view_available?} returns
31
+ # `false` on a CArray and the generic "memory view not available"
32
+ # error does not say which link in the parent chain caused the
33
+ # reject. Consumers that need to debug an alias-chain reject
34
+ # (mask propagation, non-contiguous strided view, etc.) call this
35
+ # to print a human-readable reason.
36
+ # @param obj [Object]
37
+ # @return [String, nil] reason text, or `nil` when acquisition
38
+ # would succeed.
39
+ def memory_view_reject_reason(obj); end
40
+
41
+ # @overload from_memory_view(src, data_type: nil, mask: nil)
42
+ # Returns a new `CArray` that owns an independent copy of `src`'s
43
+ # buffer. Accepts both contiguous and strided producers; strided
44
+ # sources are gathered into a freshly allocated row-major
45
+ # buffer.
46
+ #
47
+ # For typeless producers (format `nil`, e.g. byte blobs from
48
+ # `IO#read`), `data_type:` is required and the byte buffer is
49
+ # reinterpreted as that data type with `ndim = 1`. For typed
50
+ # producers `data_type:` is optional; when given it must match
51
+ # the producer's format.
52
+ #
53
+ # `mask:` accepts a paired buffer-protocol source whose shape
54
+ # matches `src` and whose item size is 1 (PEP 3118 `?` / `B` /
55
+ # `b`). The mask bytes are copied into the canonical
56
+ # `CA_BOOLEAN` mask slot with non-zero coerced to `1`. The copy
57
+ # is independent of both buffers after the call.
58
+ # @param src [Object] any MemoryView producer.
59
+ # @param data_type [Symbol, Integer, Class, nil] target data
60
+ # type. Required for typeless producers; optional (must match
61
+ # producer format) for typed ones.
62
+ # @param mask [Object, nil] optional paired mask MemoryView
63
+ # source. Must match `src.shape` and use a 1-byte/element
64
+ # format.
65
+ # @return [CArray] independent copy; not a `CAWrap`.
66
+ # @raise [ArgumentError] if `src` is not a MemoryView producer,
67
+ # if `data_type:` is missing for a typeless source, if
68
+ # `data_type:` conflicts with the producer's format, or if
69
+ # the supplied `mask:` fails shape / data type / contiguity
70
+ # validation.
71
+ # @example Copy from a strided source
72
+ # a = CArray.int32(4, 3).seq
73
+ # b = CArray.from_memory_view(a.transpose)
74
+ # b.shape # => [3, 4]
75
+ # b.equal?(a) # => false
76
+ # @example Copy paired (data, mask) — independent of source
77
+ # data = CArray.uint8(3) { |i| i }
78
+ # mask = CArray.boolean(3) { |i| i.zero? ? 1 : 0 }
79
+ # c = CArray.from_memory_view(data, mask: mask)
80
+ # c.has_mask? # => true
81
+ # data[0] = 99 # source change does not reach c
82
+ def from_memory_view(src, data_type: nil, mask: nil); end
83
+
84
+ # @overload wrap_memory_view(src, data_type: nil, mask: nil)
85
+ # Returns a `CAWrap` (or `CAStride` for strided producers) that
86
+ # borrows `src`'s buffer zero-copy. Writes through the wrap
87
+ # reach the source buffer; external changes to the source are
88
+ # visible through the wrap.
89
+ #
90
+ # The borrowed view is kept alive for the lifetime of the
91
+ # returned object via internal ivars; the source is released
92
+ # when the wrap is garbage-collected.
93
+ #
94
+ # Contiguous typed producers return a `CAWrap`. Strided typed
95
+ # producers return a `CAStride` layered on an inner `CAWrap` of
96
+ # the producer's first byte, preserving the full stride pattern
97
+ # (including negative strides where the producer offers them).
98
+ # Typeless producers (format `nil`) require `data_type:` and are
99
+ # reinterpreted with `ndim = 1`.
100
+ #
101
+ # `mask:` accepts a paired buffer-protocol source whose shape
102
+ # matches `src` and whose item size is 1 (PEP 3118 `?` / `B` /
103
+ # `b`). The mask buffer is borrowed; writes to either side
104
+ # propagate, and the mask MemoryView is released when the wrap
105
+ # is collected. In this release, `mask:` requires a row-major
106
+ # contiguous data source and a row-major contiguous mask
107
+ # buffer.
108
+ #
109
+ # The receiver picks the class of the result. Called on `CArray`
110
+ # it builds a `CAWrap`; called on a subclass of `CAWrap` it
111
+ # builds that subclass, so a gem bridging a foreign buffer can
112
+ # name where the array came from without writing a C extension.
113
+ # Any other receiver raises `TypeError`, and a strided producer
114
+ # raises `ArgumentError` when a subclass was asked for, since the
115
+ # result would be a `CAStride` rather than the named class.
116
+ #
117
+ # The class marks the provenance of the returned object only. A
118
+ # view derived from it is a `CABlock` or a `CAStride` like any
119
+ # other — a slice of a borrowed image is no longer that image —
120
+ # so do not build an API that expects the class to survive view
121
+ # algebra. For semantic identity that does survive it, see
122
+ # {file:docs/topics/CAFace.md CAFace}.
123
+ # @param src [Object] any MemoryView producer.
124
+ # @param data_type [Symbol, Integer, Class, nil] target data
125
+ # type, same rules as {.from_memory_view}.
126
+ # @param mask [Object, nil] optional paired mask MemoryView
127
+ # source.
128
+ # @return [CAWrap, CAStride] zero-copy borrowed view of `src`.
129
+ # A `CAStride` is returned when `src` is strided (and `mask:`
130
+ # is not given); otherwise a `CAWrap`, or the subclass of
131
+ # `CAWrap` the method was called on.
132
+ # @raise [TypeError] if the receiver is neither `CArray` nor a
133
+ # subclass of `CAWrap`.
134
+ # @raise [ArgumentError] if `src` is not a MemoryView producer,
135
+ # if `data_type:` is missing for a typeless source, if
136
+ # `data_type:` conflicts with the producer's format, or if
137
+ # the supplied `mask:` fails validation (shape / ndim /
138
+ # data type / item_size / contiguity). Also raises when `mask:`
139
+ # is combined with a strided data source — that combination
140
+ # is not supported in this release.
141
+ # @example Zero-copy write propagation
142
+ # a = CArray.int32(4).seq
143
+ # w = CArray.wrap_memory_view(a)
144
+ # w[0] = 999
145
+ # a[0] # => 999
146
+ # @example Paired masked wrap
147
+ # data = CArray.uint8(3) { |i| i + 10 }
148
+ # mask = CArray.boolean(3) { 0 }
149
+ # w = CArray.wrap_memory_view(data, mask: mask)
150
+ # w[1] = UNDEF # writes the source mask buffer
151
+ # mask[1] # => 1
152
+ # @example Naming where a borrowed buffer came from
153
+ # class VipsPixels < CAWrap
154
+ # def image ; instance_variable_get(:@vips_image) ; end
155
+ # end
156
+ # v = VipsPixels.wrap_memory_view(bmv)
157
+ # v.class # => VipsPixels
158
+ # v[0..1, nil].class # => CABlock (the class does not descend)
159
+ def wrap_memory_view(src, data_type: nil, mask: nil); end
160
+
161
+ # @!endgroup
162
+ end
163
+ end
@@ -0,0 +1,252 @@
1
+ # DOCUMENTATION ONLY — DO NOT REQUIRE.
2
+ # Stubs for methods defined in ext/carray_order.c.
3
+ # See yard-stubs/README.md and yard-stubs/STYLE.md.
4
+
5
+ class CArray
6
+ # @!group Sorting and searching
7
+
8
+ # @overload project(idx, lval = nil, uval = nil)
9
+ # Returns a new array whose elements are taken from `self` at
10
+ # the positions named by `idx`. `idx` is a CArray of flat
11
+ # addresses into `self`; the result has the shape of `idx`.
12
+ #
13
+ # Out-of-range positions are filled with `lval` (below-range) and
14
+ # `uval` (above-range); when `lval` is given alone, it fills
15
+ # both. Without either, out-of-range positions are masked.
16
+ #
17
+ # When `self` is a Face (CATime / CATimedelta / CACategorical),
18
+ # the result is the same Face type, carrying the unit / labels; the
19
+ # gather runs on the underlying storage and misses become UNDEF. Fill
20
+ # (`lval` / `uval`) is not supported for a Face and raises ArgumentError
21
+ # — omit the fill args to get UNDEF at misses.
22
+ # @param idx [CArray] flat addresses, of any shape.
23
+ # @param lval [Object, nil] fill for indices `< 0` (non-Face only).
24
+ # @param uval [Object, nil] fill for indices `>= self.elements` (non-Face only).
25
+ # @return [CArray] a fresh array shaped like `idx`; a Face of the same
26
+ # type when `self` is a Face.
27
+ # @raise [ArgumentError] if `lval` / `uval` is given and `self` is a Face.
28
+ def project(idx, lval = nil, uval = nil); end
29
+
30
+ # sort / sort_copy stubs live in yard-stubs/carray_sort.rb (same
31
+ # file split as ext/carray_sort.c <-> ext/carray_order.c).
32
+
33
+ # @overload partition(kth, axis: 0, masked_position: :last)
34
+ # Returns a `CARemap` view of `self` permuted along `axis` so that
35
+ # the element at fiber-local position `kth` is in its final sorted
36
+ # place, every element before it is `<=` it, and every element
37
+ # after it is `>=` it. Order within the two regions is unspecified.
38
+ # Average `O(n)` per fiber via quickselect.
39
+ #
40
+ # Negative `kth` counts from the end of the fiber
41
+ # (`-self.shape[axis] <= kth < self.shape[axis]`).
42
+ #
43
+ # Supports numeric (`i8`..`f64`), boolean (as its `0`/`1` value,
44
+ # `false` < `true`), `CA_FIXLEN` (memcmp lexicographic order), and
45
+ # `CA_OBJECT` (via `<=>` per pair).
46
+ #
47
+ # Mask handling matches {#sort}: masked cells are an incomparable
48
+ # sentinel, excluded from the kth-selection and clustered at
49
+ # `masked_position:`. A `kth` landing in the masked cluster needs
50
+ # no selection (unspecified order, same contract as the `<` / `>`
51
+ # regions); a `kth` landing in the unmasked range selects properly
52
+ # among unmasked values.
53
+ #
54
+ # @param kth [Integer] target fiber-local position along `axis`.
55
+ # @param axis [Integer]
56
+ # @param masked_position [Symbol] `:last` (default) or `:first`.
57
+ # @return [CArray] `CARemap` view of `self`.
58
+ # @raise [ArgumentError] when `kth` is out of range.
59
+ def partition(kth, axis: 0, masked_position: :last); end
60
+
61
+ # @overload partition_copy(kth, axis: 0, masked_position: :last)
62
+ # Returns a fresh entity `CArray` with the same shape as `self`,
63
+ # partitioned along `axis` by the same rule as {#partition}.
64
+ # Bypasses the `CARemap` scatter layer for cases where an entity
65
+ # is wanted directly. Same dispatch (numeric / boolean / `CA_FIXLEN` /
66
+ # `CA_OBJECT`), same `kth` and `masked_position:` semantics.
67
+ # Masked input delegates to {#partition} + copy.
68
+ #
69
+ # Float NaN policy: NaN cells are pre-partitioned to the tail. If
70
+ # `kth` falls within the finite slice, quickselect runs over the
71
+ # finite cells; otherwise the kth cell is already NaN.
72
+ #
73
+ # @param kth [Integer]
74
+ # @param axis [Integer]
75
+ # @param masked_position [Symbol] `:last` (default) or `:first`.
76
+ # @return [CArray] fresh entity.
77
+ # @raise [ArgumentError] same conditions as {#partition}.
78
+ def partition_copy(kth, axis: 0, masked_position: :last); end
79
+
80
+ # @overload order(axis: nil, descending: false, method: :ordinal)
81
+ # Returns each cell's rank among the other cells along `axis`
82
+ # (`0` = smallest). When `axis` is omitted, `self` is flattened
83
+ # first (global rank). Sugar over `rank_index` (built on the
84
+ # same sort machinery as `sort_index`); the inverse relationship
85
+ # is `self.order == self.sort_index.sort_index`.
86
+ #
87
+ # `method:` selects how ties are ranked:
88
+ #
89
+ # - `:ordinal` (default) — every cell gets a distinct rank; ties
90
+ # are broken by original position (stable). This is a total
91
+ # order: no two cells ever compare equal.
92
+ # - `:dense` — tied values share one rank (no gaps). Useful as a
93
+ # `sort_addr` priority key: an `:ordinal` key never ties, so a
94
+ # lower-priority key after it is never consulted; a `:dense` key
95
+ # preserves the tie so it is.
96
+ #
97
+ # `descending:` negates the rank order (`(n-1) - rank`, `n` =
98
+ # fiber element count minus masked cells). This composes correctly
99
+ # with `method: :dense`: ties stay tied after the transform, and
100
+ # group-to-group order still reverses.
101
+ #
102
+ # Masked cells are excluded from ranking (own cell becomes UNDEF,
103
+ # like `rank_index`); `descending:`/`method:` apply to the
104
+ # remaining unmasked cells.
105
+ # @param axis [Integer, nil]
106
+ # @param descending [Boolean]
107
+ # @param method [Symbol] `:ordinal` (default) or `:dense`.
108
+ # @return [CArray] `:int64` ranks, shape == `self.shape`.
109
+ # @raise [ArgumentError] when `method:` is neither `:ordinal` nor `:dense`.
110
+ def order(axis: nil, descending: false, method: :ordinal); end
111
+
112
+ # @!endgroup
113
+
114
+ # @!group Sorting and searching
115
+
116
+ # @overload bsearch(val)
117
+ # Returns the flat address of `val` in `self` via binary search.
118
+ # `self` must be sorted along its single (flat) axis. Returns
119
+ # `nil` if `val` is not present. When `val` is a CArray, returns
120
+ # a CArray of `:int64` addresses (one per element of `val`),
121
+ # with `UNDEF` at positions where the value is not present.
122
+ # @param val [Numeric, CArray]
123
+ # @return [Integer, CArray, nil]
124
+ # @raise [RuntimeError] if `self` has any masked element.
125
+ # @overload bsearch(val, axis:)
126
+ # Per-fiber binary search along `axis`. Returns a CArray of
127
+ # axis-local positions, one per fiber.
128
+ # @param val [Numeric, CArray]
129
+ # @param axis [Integer]
130
+ # @return [CArray]
131
+ def bsearch(val, axis: nil); end
132
+
133
+ # @overload bsearch_addr(val)
134
+ # Equivalent to {#bsearch} when `axis:` is omitted (the flat
135
+ # case already returns a flat address).
136
+ # @param val [Numeric, CArray]
137
+ # @return [Integer, CArray, nil]
138
+ # @overload bsearch_addr(val, axis:)
139
+ # Per-fiber binary search along `axis`, returning flat addresses
140
+ # rather than axis-local positions.
141
+ # @param val [Numeric, CArray]
142
+ # @param axis [Integer]
143
+ # @return [CArray]
144
+ def bsearch_addr(val, axis: nil); end
145
+
146
+ # @overload search(val, eps = nil)
147
+ # Returns the flat address of the first element of `self` equal
148
+ # to `val`. For float types, `eps` (default machine epsilon)
149
+ # sets the tolerance. Returns `nil` if no match.
150
+ #
151
+ # `self` need not be sorted; this is a linear scan. For sorted
152
+ # data prefer {#bsearch}.
153
+ # @param val [Object]
154
+ # @param eps [Float, nil]
155
+ # @return [Integer, nil]
156
+ # @overload search(val, eps = nil, axis:)
157
+ # Per-fiber linear search along `axis`. Returns axis-local
158
+ # positions.
159
+ # @return [CArray]
160
+ def search(val, eps = nil, axis: nil); end
161
+
162
+ # @overload search_addr(val, eps = nil)
163
+ # Equivalent to {#search} when `axis:` is omitted.
164
+ # @return [Integer, nil]
165
+ # @overload search_addr(val, eps = nil, axis:)
166
+ # Per-fiber linear search along `axis`, returning flat
167
+ # addresses rather than axis-local positions.
168
+ # @return [CArray]
169
+ def search_addr(val, eps = nil, axis: nil); end
170
+
171
+ # @overload search_nearest(val)
172
+ # Returns the flat address of the element of `self` whose value
173
+ # is closest to `val`.
174
+ #
175
+ # In an `:object` array the distance is `val.distance(other)` when
176
+ # `val` answers `#distance`, and `(val - other).abs` when it is a
177
+ # number. Anything else -- a String, say -- has no distance and
178
+ # raises `CArray::DataTypeError`; use {#search} or {#bsearch} for an
179
+ # exact match.
180
+ # @param val [Object]
181
+ # @return [Integer, nil]
182
+ # @raise [CArray::DataTypeError] when `val` is neither a number nor
183
+ # answers `#distance`.
184
+ # @overload search_nearest(val, axis:)
185
+ # Per-fiber nearest-value search along `axis`. Returns
186
+ # axis-local positions.
187
+ # @return [CArray]
188
+ def search_nearest(val, axis: nil); end
189
+
190
+ # @overload search_nearest_addr(val)
191
+ # Equivalent to {#search_nearest} when `axis:` is omitted.
192
+ # @return [Integer, nil]
193
+ # @overload search_nearest_addr(val, axis:)
194
+ # Per-fiber nearest-value search along `axis`, returning flat
195
+ # addresses rather than axis-local positions.
196
+ # @return [CArray]
197
+ def search_nearest_addr(val, axis: nil); end
198
+
199
+ # @!endgroup
200
+
201
+ # @!group Sorting and searching
202
+
203
+ # @overload linear_section(val, axis: nil, method: :binary)
204
+ # Returns the fractional position of `val` within `self` (treated
205
+ # as a coordinate axis), interpolating linearly between the two
206
+ # bracketing samples. The integer part of the returned address is
207
+ # the index of the lower bracket, the fractional part is the
208
+ # interpolation weight toward the next sample. Out-of-range `val`
209
+ # returns NaN.
210
+ #
211
+ # `self` is coerced to `:float64` if it is not already. When
212
+ # `axis: nil`, `self` is flattened to 1-D first.
213
+ #
214
+ # `method:` selects the search backend:
215
+ # - `:binary` (default) — bisection. `O(log N)` per query.
216
+ # Assumes an ascending (sorted) axis; returns NaN on
217
+ # descending data.
218
+ # - `:linear` — sign-product scan. `O(N)` per query but handles
219
+ # both ascending and descending monotone axes correctly.
220
+ #
221
+ # See {#linear_fetch} for the inverse operation (fractional
222
+ # address to interpolated value).
223
+ # @param val [Numeric, CArray]
224
+ # @param axis [Integer, nil]
225
+ # @param method [Symbol] `:binary` or `:linear`.
226
+ # @return [Float, CArray]
227
+ # @raise [ArgumentError] when `method:` is neither `:binary` nor
228
+ # `:linear`.
229
+ def linear_section(val, axis: nil, method: :binary); end
230
+
231
+ # @overload linear_fetch(addr, axis: nil)
232
+ # Returns the value of `self` (treated as a coordinate axis) at
233
+ # the fractional position `addr`, interpolating linearly between
234
+ # the two bracketing samples. The inverse of {#linear_section}.
235
+ #
236
+ # `self` is coerced to `:float64` if it is not already. When
237
+ # `axis: nil`, `self` is flattened to 1-D first.
238
+ #
239
+ # Out-of-range `addr` returns NaN.
240
+ #
241
+ # Because this half of the pair returns a *value* rather than a
242
+ # position, a Face axis gets its Face back: `CATime#linear_fetch` /
243
+ # `CATimedelta#linear_fetch` return a time on the axis's own unit
244
+ # (rounded to that grid, UNDEF out of range) instead of raw ticks.
245
+ # @param addr [Float, CArray] fractional position(s) into `self`.
246
+ # @param axis [Integer, nil]
247
+ # @return [Float, CArray]
248
+ # @see file:docs/topics/LinearInterpolation.md
249
+ def linear_fetch(addr, axis: nil); end
250
+
251
+ # @!endgroup
252
+ end
@@ -0,0 +1,89 @@
1
+ # DOCUMENTATION ONLY — DO NOT REQUIRE.
2
+ # Stubs for methods defined in ext/carray_random.c.
3
+ # See yard-stubs/README.md and yard-stubs/STYLE.md.
4
+
5
+ class CArray
6
+ # @!group Random
7
+
8
+ # @overload random!(rng: nil)
9
+ # A float array: samples `[0.0, 1.0)`. An integer array: raises
10
+ # (a range is required).
11
+ # @overload random!(high, rng: nil)
12
+ # Samples `[0, high)` (Ruby `rand` / Numo `.rand` shorthand).
13
+ # @overload random!(low, high, rng: nil)
14
+ # Samples `[low, high)` (Numo positional convention).
15
+ # @overload random!(range, rng: nil)
16
+ # Samples from a Ruby Range: `a..b` closed, `a...b` half-open.
17
+ # An integer array honors the endpoint distinction (dice: `1..6`
18
+ # yields values in `1..6` including 6; `1...6` yields `1..5`).
19
+ # For a float array, closed and half-open are equivalent at the
20
+ # sampler level (endpoint probability ≈ 2^-53), matching
21
+ # NumPy/SciPy convention — `..` is accepted for syntax but the
22
+ # endpoint is not enforced at the mantissa.
23
+ #
24
+ # Fills `self` with uniform random numbers in-place and returns
25
+ # `self`. Boolean arrays fill 0/1 at 50% probability, ignoring
26
+ # any range argument. Complex arrays sample real and imaginary
27
+ # parts independently from the same range.
28
+ #
29
+ # @param low [Numeric] lower bound (inclusive).
30
+ # @param high [Numeric] upper bound (exclusive).
31
+ # @param range [Range] closed (`a..b`) or half-open (`a...b`).
32
+ # @param rng [Random, nil] RNG instance; nil uses the per-ractor
33
+ # default RNG.
34
+ # @return [self]
35
+ # @raise [CArray::DataTypeError] for `:object` / `:fixlen` arrays.
36
+ # @raise [ArgumentError] when an integer array is called with no
37
+ # range, when `low >= high`, when a Range is combined with a
38
+ # second positional argument, or when a Range endpoint is nil.
39
+ def random!(*args, rng: nil); end
40
+
41
+ # @overload random(rng: nil)
42
+ # @overload random(high, rng: nil)
43
+ # @overload random(low, high, rng: nil)
44
+ # @overload random(range, rng: nil)
45
+ # Non-bang variant: returns a newly templated array filled by
46
+ # `random!`. Accepts the same argument forms.
47
+ # @return [CArray]
48
+ def random(*args, rng: nil); end
49
+
50
+ # @overload randomn!(rng: nil)
51
+ # Fills `self` with standard normal `N(0, 1)` samples via
52
+ # Box-Muller and returns `self`. Restricted to float / complex
53
+ # data types; complex fills real and imaginary parts as two
54
+ # independent normals per cell.
55
+ # @param rng [Random, nil] RNG instance; nil uses the per-ractor
56
+ # default RNG.
57
+ # @return [self]
58
+ # @raise [CArray::DataTypeError] for non-float / non-complex arrays.
59
+ def randomn!(rng: nil); end
60
+
61
+ # @overload randomn(rng: nil)
62
+ # Non-bang variant: returns a newly templated array filled by
63
+ # `randomn!`.
64
+ # @return [CArray]
65
+ def randomn(rng: nil); end
66
+
67
+ # @!endgroup
68
+
69
+ # @!group Random
70
+
71
+ # @overload shuffle!(axis: nil, rng: nil)
72
+ # Fisher-Yates permutes `self` in-place and returns `self`.
73
+ # Without `axis:`, shuffles all cells as if flattened. With
74
+ # `axis:`, permutes slices along that axis (the trailing
75
+ # sub-slab is treated as a byte chunk and swapped whole).
76
+ # @param axis [Integer, nil] axis to permute along; nil = flat.
77
+ # @param rng [Random, nil] RNG instance; nil uses the per-ractor
78
+ # default RNG.
79
+ # @return [self]
80
+ # @raise [ArgumentError] if `axis` is out of range.
81
+ def shuffle!(axis: nil, rng: nil); end
82
+
83
+ # @overload shuffle(axis: nil, rng: nil)
84
+ # Non-bang variant: returns a shuffled copy of `self`.
85
+ # @return [CArray]
86
+ def shuffle(axis: nil, rng: nil); end
87
+
88
+ # @!endgroup
89
+ end