carray 3.0.4 → 3.0.6

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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +438 -0
  3. data/README.md +1 -1
  4. data/carray.gemspec +3 -2
  5. data/ext/ca_array_pool.c +25 -1
  6. data/ext/ca_axis_dispatch.c +19 -20
  7. data/ext/ca_axis_group.c +1 -1
  8. data/ext/ca_categorical_iterator.c +34 -27
  9. data/ext/ca_compare.c +4 -4
  10. data/ext/ca_composite_dispatch.c +9 -9
  11. data/ext/ca_kernel_iterator.c +122 -237
  12. data/ext/ca_kernel_iterator.h +522 -337
  13. data/ext/ca_obj_array.c +69 -19
  14. data/ext/ca_obj_bincmp.c +10 -1
  15. data/ext/ca_obj_binop.c +11 -1
  16. data/ext/ca_obj_bitarray.c +5 -1
  17. data/ext/ca_obj_bitfield.c +60 -43
  18. data/ext/ca_obj_byte_swap.c +4 -1
  19. data/ext/ca_obj_const_string.c +15 -3
  20. data/ext/ca_obj_face.c +44 -1
  21. data/ext/ca_obj_fake.c +3 -1
  22. data/ext/ca_obj_field.c +13 -3
  23. data/ext/ca_obj_grid.c +219 -17
  24. data/ext/ca_obj_meld.c +69 -113
  25. data/ext/ca_obj_moncmp.c +9 -1
  26. data/ext/ca_obj_monop.c +86 -12
  27. data/ext/ca_obj_object.c +118 -32
  28. data/ext/ca_obj_record.c +3 -0
  29. data/ext/ca_obj_reduce.c +19 -1
  30. data/ext/ca_obj_refer.c +80 -26
  31. data/ext/ca_obj_remap.c +69 -10
  32. data/ext/ca_obj_roll.c +27 -6
  33. data/ext/ca_obj_select.c +38 -6
  34. data/ext/ca_obj_select_axis.c +1 -0
  35. data/ext/ca_obj_shift.c +32 -7
  36. data/ext/ca_obj_stack.c +311 -111
  37. data/ext/ca_obj_stride.c +159 -64
  38. data/ext/ca_obj_string.c +27 -2
  39. data/ext/ca_obj_tile.c +28 -7
  40. data/ext/ca_obj_transpose.c +8 -4
  41. data/ext/ca_obj_triop.c +12 -1
  42. data/ext/ca_obj_window.c +80 -50
  43. data/ext/ca_op_ipower.c +12 -12
  44. data/ext/ca_sort_kernels.h +6 -3
  45. data/ext/caframe_csv_reader.c +1 -1
  46. data/ext/carray.h +35 -1
  47. data/ext/carray_access.c +43 -67
  48. data/ext/carray_address_basis.c +134 -0
  49. data/ext/carray_attribute.c +32 -0
  50. data/ext/carray_broadcast.c +3 -4
  51. data/ext/carray_build_flags.h +1 -1
  52. data/ext/carray_cast.c +251 -93
  53. data/ext/carray_cast_func.rb +56 -26
  54. data/ext/carray_conversion.c +11 -7
  55. data/ext/carray_core.c +814 -72
  56. data/ext/carray_count.c +6 -0
  57. data/ext/carray_element.c +22 -13
  58. data/ext/carray_factorize.c +20 -20
  59. data/ext/carray_generate.c +8 -2
  60. data/ext/carray_histogram.c +26 -4
  61. data/ext/carray_index_classifier.c +4 -4
  62. data/ext/carray_internal.h +159 -12
  63. data/ext/carray_kernels_bincmp.c +2174 -170
  64. data/ext/carray_kernels_binop.c +25653 -5487
  65. data/ext/carray_kernels_init.c +8 -8
  66. data/ext/carray_kernels_moncmp.c +96 -96
  67. data/ext/carray_kernels_monop.c +12253 -5235
  68. data/ext/carray_kernels_reduce_aggregate.c +6150 -2423
  69. data/ext/carray_kernels_reduce_boolean.c +1533 -15
  70. data/ext/carray_kernels_reduce_cumulative.c +2442 -882
  71. data/ext/carray_kernels_reduce_extreme.c +5658 -1661
  72. data/ext/carray_kernels_reduce_variance.c +2534 -402
  73. data/ext/carray_kernels_scan.c +368 -368
  74. data/ext/carray_kernels_search.c +4551 -604
  75. data/ext/carray_kernels_sort.c +659 -751
  76. data/ext/carray_kernels_triop.c +114 -114
  77. data/ext/carray_key_windows.c +4 -0
  78. data/ext/carray_lazy.c +47 -0
  79. data/ext/carray_loop.c +1 -1
  80. data/ext/carray_mask.c +175 -161
  81. data/ext/carray_median_percentile.c +4 -4
  82. data/ext/carray_memory_view.c +15 -9
  83. data/ext/carray_operator.c +152 -49
  84. data/ext/carray_order.c +230 -10
  85. data/ext/carray_random.c +22 -19
  86. data/ext/carray_scatter.c +24 -7
  87. data/ext/carray_slab.c +128 -29
  88. data/ext/carray_sort.c +224 -16
  89. data/ext/carray_sort_kernel.c +5 -7
  90. data/ext/carray_struct.c +35 -43
  91. data/ext/carray_test.c +74 -19
  92. data/ext/carray_time_text.c +6 -4
  93. data/ext/carray_utils.c +63 -21
  94. data/ext/extconf.rb +11 -0
  95. data/ext/mkkernel.rb +546 -199
  96. data/ext/ruby_carray.c +4 -1
  97. data/ext/version.h +4 -4
  98. data/lib/carray/attribute.rb +42 -5
  99. data/lib/carray/autoload_carray.rb +3 -3
  100. data/lib/carray/autoload_method_extension.rb +5 -3
  101. data/lib/carray/axis_group.rb +13 -7
  102. data/lib/carray/basics.rb +28 -8
  103. data/lib/carray/block_iterator.rb +17 -3
  104. data/lib/carray/categorical.rb +35 -23
  105. data/lib/carray/categorical_iterator.rb +8 -8
  106. data/lib/carray/complex.rb +2 -2
  107. data/lib/carray/conditional.rb +3 -2
  108. data/lib/carray/const_string.rb +10 -0
  109. data/lib/carray/data_type_extension.rb +8 -1
  110. data/lib/carray/fixlen_string.rb +41 -2
  111. data/lib/carray/frame/column_verbs.rb +48 -16
  112. data/lib/carray/frame/concat.rb +17 -3
  113. data/lib/carray/frame/convert.rb +19 -0
  114. data/lib/carray/frame/csv_parser.rb +32 -32
  115. data/lib/carray/frame/describe.rb +4 -2
  116. data/lib/carray/frame/frame.rb +405 -85
  117. data/lib/carray/frame/group.rb +777 -64
  118. data/lib/carray/frame/io.rb +212 -72
  119. data/lib/carray/frame/join.rb +146 -37
  120. data/lib/carray/frame/records.rb +3 -3
  121. data/lib/carray/frame/reshape.rb +89 -11
  122. data/lib/carray/frame/sort.rb +57 -9
  123. data/lib/carray/frame/verbs.rb +384 -49
  124. data/lib/carray/frame/windows.rb +44 -6
  125. data/lib/carray/fuse_source.rb +31 -2
  126. data/lib/carray/inspect.rb +7 -2
  127. data/lib/carray/iterator.rb +32 -0
  128. data/lib/carray/lazy.rb +52 -8
  129. data/lib/carray/mask_gap_fill.rb +37 -17
  130. data/lib/carray/meld_reduce.rb +1 -1
  131. data/lib/carray/methods/choose.rb +3 -2
  132. data/lib/carray/methods/is_in.rb +8 -1
  133. data/lib/carray/methods/meshgrid.rb +3 -1
  134. data/lib/carray/runtime.rb +47 -8
  135. data/lib/carray/segment_iterator.rb +35 -16
  136. data/lib/carray/serialize.rb +53 -19
  137. data/lib/carray/stack.rb +33 -18
  138. data/lib/carray/string.rb +8 -0
  139. data/lib/carray/string_operation_extension.rb +13 -5
  140. data/lib/carray/struct_builder.rb +5 -3
  141. data/lib/carray/time.rb +112 -68
  142. data/lib/carray/window_iterator.rb +16 -4
  143. data/yard-stubs/ca_obj_array.rb +26 -1
  144. data/yard-stubs/ca_obj_transpose.rb +5 -4
  145. data/yard-stubs/carray_attribute.rb +3 -1
  146. data/yard-stubs/carray_cast.rb +10 -5
  147. data/yard-stubs/carray_conversion.rb +13 -3
  148. data/yard-stubs/carray_element.rb +7 -6
  149. data/yard-stubs/carray_mask.rb +28 -4
  150. data/yard-stubs/carray_math.rb +45 -20
  151. data/yard-stubs/carray_memory_view.rb +7 -0
  152. data/yard-stubs/carray_order.rb +100 -4
  153. data/yard-stubs/carray_scatter.rb +7 -5
  154. data/yard-stubs/carray_test.rb +7 -4
  155. metadata +18 -4
@@ -202,10 +202,13 @@ class CArray
202
202
  # -- as_type: reinterpreting view (no copy) ---------------------------
203
203
 
204
204
  # @overload as_type(data_type, bytes: nil)
205
- # Returns a {CAFake} view of `self` reinterpreted as `data_type`
206
- # (with `bytes:` for `:fixlen`). Reads and writes cast on the fly
207
- # through the shared parent storage; no copy is made. For an eager
208
- # copy use `arr.as_type(...).to_ca` or {#to_type}.
205
+ # Returns a view of `self` reinterpreted as `data_type` (with
206
+ # `bytes:` for `:fixlen`): a {CAMonOp} for a numeric type, a {CAFake}
207
+ # otherwise. Reads and writes cast on the fly through the shared
208
+ # parent storage; no copy is made. The view is a new array also when
209
+ # `data_type` is `self`'s own, so an attribute set on it or a freeze
210
+ # of it does not reach `self`. For an eager copy use
211
+ # `arr.as_type(...).copy` or {#to_type}.
209
212
  #
210
213
  # Note: for an `:object` source the on-the-fly cast to a numeric type
211
214
  # uses the lenient path and does NOT mask parse failures — a
@@ -225,7 +228,7 @@ class CArray
225
228
  # @param data_type [Symbol, Integer, Class, String] target element type.
226
229
  # @param bytes [Integer, nil] element width in bytes, required for
227
230
  # `:fixlen`.
228
- # @return [CAFake]
231
+ # @return [CAMonOp, CAFake]
229
232
  # @raise [TypeError] when `self` is a Face and the request would read its
230
233
  # storage under another type.
231
234
  # @raise [FloatDomainError] when a NaN cell that is not masked is read
@@ -472,6 +475,8 @@ class CArray
472
475
  #
473
476
  # - CArray instance -> its `data_type`
474
477
  # - Symbol / String / Class -> data_type representation (name lookup)
478
+ # - MemoryView producer -> the data_type its format names; one whose
479
+ # format carray cannot read is refused, as an operator refuses it
475
480
  # - Integer / Float / Complex / true / false / nil / Object -> *value*,
476
481
  # data_type inferred (3 -> `:int64`, 3.14 -> `:float64`,
477
482
  # 1+2i -> `:cmplx128`, ...)
@@ -63,7 +63,11 @@ class CArray
63
63
 
64
64
  # @overload to_s
65
65
  # Equivalent to `dump_binary` with no arguments. Returns the raw
66
- # element bytes of `self` as a binary String.
66
+ # element bytes of `self` as a binary String. Ruby uses `to_s` where
67
+ # it puts an object into text, so such text holds the bytes: a
68
+ # `Ractor.make_shareable` refusal of a view, for one, raises
69
+ # `ArgumentError: string contains null byte` in place of its own
70
+ # message. Use `inspect` for a readable form.
67
71
  # @return [String]
68
72
  def to_s; end
69
73
 
@@ -77,10 +81,16 @@ class CArray
77
81
  # `String` of the exact size, or any object responding to
78
82
  # `read(n, buf = nil)`. Into a boolean array, a non-zero byte is
79
83
  # read as 1 (true).
84
+ # From an IO into an array that owns its memory, the bytes are written
85
+ # as they are read, so that no second copy of the data is held; when the
86
+ # IO runs out before the array is full, what the array holds afterwards
87
+ # is not defined (the part read so far may already be in it). Into a
88
+ # view the whole data is read first and nothing is written on a short
89
+ # read.
80
90
  # @param io [String, IO, #read]
81
91
  # @return [self]
82
- # @raise [RuntimeError] on a short read.
83
- # @raise [ArgumentError] when a String source is not the array's size.
92
+ # @raise [ArgumentError] on a short read, and when a String source is
93
+ # not the array's size.
84
94
  # @raise [CArray::DataTypeError] if `self.data_type` is
85
95
  # `:object`.
86
96
  def load_binary(io); end
@@ -5,12 +5,13 @@
5
5
  class CArray
6
6
  # @!group Element access
7
7
  #
8
- # `elem_*` methods are low-level single-cell operations. They
9
- # accept `idx` as either an Integer (flat address into the
10
- # row-major element sequence) or an `Array<Integer>` (one index
11
- # per axis). They bypass the broadcasting and view-construction
12
- # paths used by `[]` / `[]=`, and are the right tool for
13
- # tight per-cell loops where allocation matters.
8
+ # `elem_*` methods are the fastest way to reach one cell when you
9
+ # hold its per-axis index. They accept `idx` as an `Array<Integer>`
10
+ # (one index per axis) or an Integer (flat address into the
11
+ # row-major element sequence). An index is read as `[]` reads one:
12
+ # an Integer, or a Float with no fraction. The result is the same as `[]` /
13
+ # `[]=` for that cell; the key parsing and view construction of
14
+ # the general indexer are skipped.
14
15
 
15
16
  # @overload elem_swap(idx1, idx2)
16
17
  # Exchanges the values (and mask states, if any) at positions
@@ -26,10 +26,27 @@ class CArray
26
26
  # bypassing the mask. The returned view itself cannot carry a
27
27
  # mask (`value_array? == true`).
28
28
  #
29
- # Use this to read or write the data slot of masked elements.
29
+ # This is a method for peeking at the internal state of an array, and
30
+ # nothing more. What a masked cell holds is not defined: a computation
31
+ # leaves there whatever it happens to. Use it on the spot, as in
32
+ # `a.value.copy`, `a.value[nil, 1].copy` or `a.value[nil, 1] = 2`; do
33
+ # not keep the view to carry around (`b = a.value`,
34
+ # `b = a.value[nil, 1]`), do not compute with it, and do not mix it
35
+ # with other arrays (as an operand, or as a part of {CArray.stack} or
36
+ # {CArray.meld}). To take the mask off, use {#unmask} or
37
+ # {#strip_mask} and give the masked cells a value.
38
+ #
39
+ # A library that handles the mask itself may use `value` on the spot
40
+ # to hand the stored cells on together with {#mask}, as long as it
41
+ # reads nothing from the masked ones.
42
+ #
30
43
  # Nothing in a value array is masked, so `unmask` on it does nothing,
31
44
  # while a write that would mask a cell (`UNDEF`, `mask=`,
32
45
  # `invert_mask`) raises TypeError.
46
+ #
47
+ # On a Face the data slot is read through the Face. A {CACategorical}
48
+ # cell excluded by the sentinel code has no label, so its value reads
49
+ # as `nil` (the codes are in `codes`).
33
50
  # @return [CArray]
34
51
  def value; end
35
52
 
@@ -80,6 +97,12 @@ class CArray
80
97
  # that derives values from neighbouring valid cells (mask gap-fill).
81
98
  # The two are mutually exclusive: passing both raises `ArgumentError`.
82
99
  #
100
+ # On a view, the values are written through to the cells it views. A
101
+ # position with no cell behind it -- the place of a masked cell of an
102
+ # index array (`a[i]`), as a join with `view: :full` gives for an
103
+ # unmatched row -- takes no write and stays masked, without an error.
104
+ # `strip_mask` gives a new array, where every masked cell takes a value.
105
+ #
83
106
  # @overload unmask
84
107
  # Clears the mask state of every element of `self`, leaving the
85
108
  # stored data values untouched. Mutates `self`.
@@ -180,10 +203,11 @@ class CArray
180
203
  # of `self` and the masks of each array in `others`. Mutates
181
204
  # `self`.
182
205
  # @param others [Array<CArray>] arrays whose mask states are
183
- # OR-ed into `self`. Non-CArray arguments are ignored.
206
+ # OR-ed into `self`.
184
207
  # @return [self]
185
208
  # @raise [ArgumentError] if an array in `others` other than a scalar
186
- # has fewer elements than `self`.
209
+ # has a different number of elements from `self`.
210
+ # @raise [TypeError] if an argument is not a CArray.
187
211
  def inherit_mask(*others); end
188
212
 
189
213
  # @overload inherit_mask_replace(*others)
@@ -194,7 +218,7 @@ class CArray
194
218
  # new mask of `self`.
195
219
  # @return [self]
196
220
  # @raise [ArgumentError] if an array in `others` other than a scalar
197
- # has fewer elements than `self`.
221
+ # has a different number of elements from `self`.
198
222
  def inherit_mask_replace(*others); end
199
223
 
200
224
  # @overload count_masked
@@ -11,6 +11,11 @@
11
11
  # builds a node in the expression tree instead of evaluating, and the
12
12
  # eager and lazy paths are required to agree element for element.
13
13
  #
14
+ # The transcendental functions call the platform's C math library, so
15
+ # their last bits, and the complex functions' answers at special values
16
+ # (signed zeros, infinities, NaN), follow that library and can differ
17
+ # between operating systems.
18
+ #
14
19
  # See yard-stubs/README.md and yard-stubs/STYLE.md.
15
20
 
16
21
  class CArray
@@ -226,6 +231,13 @@ class CArray
226
231
  # integer base with a negative integer exponent truncates toward
227
232
  # zero rather than producing a fraction (`2 ** -1` is `0`). Cast to
228
233
  # a float `data_type` first when a fractional power is wanted.
234
+ # A float or complex array raised to an Integer is computed by
235
+ # repeated multiplication rather than by `pow`. Its rounding error
236
+ # grows roughly in proportion to the exponent (tens of ulps at 100,
237
+ # hundreds of thousands at a million), where `Float#**` and the same
238
+ # exponent given as a Float are within an ulp or so; give the exponent
239
+ # as a Float when a large one needs full precision. The exponent can
240
+ # be any Integer that fits 64 bits.
229
241
  # Masked elements stay masked.
230
242
  # @param other [CArray, Numeric] exponent, broadcast to `self.shape`.
231
243
  # @return [CArray] result of the promoted `data_type` of the two
@@ -598,6 +610,8 @@ class CArray
598
610
  # Returns each element of `self` with the magnitude it already has
599
611
  # and the sign of the matching element of `other`. The sign of a
600
612
  # zero is respected, so `copysign` distinguishes `-0.0` from `0.0`.
613
+ # The sign of a NaN that a computation produced (`sqrt(-1)`,
614
+ # `Inf * 0`) depends on the CPU: x86 sets it, ARM does not.
601
615
  # Accepts float and `:object` arrays only, as {#atan2}.
602
616
  # @param other [CArray, Numeric] sign source, broadcast to
603
617
  # `self.shape`.
@@ -683,8 +697,8 @@ class CArray
683
697
  # @overload pmax(other)
684
698
  # Returns the element-wise larger of `self` and `other`, ignoring
685
699
  # `NaN`: where one element is `NaN` the other is returned, and only
686
- # two `NaN`s give `NaN`. This is C's `fmax`. For the form that lets
687
- # a `NaN` win see {#maximum}.
700
+ # two `NaN`s give `NaN`. Of `-0.0` and `0.0` the result is `0.0`,
701
+ # in either order. For the form that lets a `NaN` win see {#maximum}.
688
702
  # @param other [CArray, Numeric] the other operand, broadcast to
689
703
  # `self.shape`.
690
704
  # @return [CArray] result of the promoted `data_type` of the two
@@ -697,7 +711,8 @@ class CArray
697
711
 
698
712
  # @overload pmin(other)
699
713
  # Returns the element-wise smaller of `self` and `other`, ignoring
700
- # `NaN`. The counterpart of {#pmax}.
714
+ # `NaN`. Of `-0.0` and `0.0` the result is `-0.0`, in either order.
715
+ # The counterpart of {#pmax}.
701
716
  # @param other [CArray, Numeric] the other operand.
702
717
  # @return [CArray]
703
718
  # @raise [CArray::DataTypeError] for a complex array.
@@ -929,7 +944,9 @@ class CArray
929
944
  # @overload signbit
930
945
  # Returns a boolean array that is true where an element carries a
931
946
  # negative sign bit. A negative zero is true, which distinguishes
932
- # `-0.0` from `0.0` where a `< 0` comparison cannot.
947
+ # `-0.0` from `0.0` where a `< 0` comparison cannot. On a NaN that a
948
+ # computation produced (`sqrt(-1)`, `Inf * 0`) the answer depends on
949
+ # the CPU: x86 sets the sign bit, ARM does not.
933
950
  # @return [CArray] `:boolean`.
934
951
  # @raise [CArray::DataTypeError] for a complex array.
935
952
  # @example
@@ -939,13 +956,15 @@ class CArray
939
956
  # @overload &(other)
940
957
  # Returns the element-wise conjunction of `self` and `other`: a
941
958
  # bitwise `AND` on integer arrays, a logical `AND` on boolean ones.
959
+ # **On boolean arrays it is three-valued (Kleene); {#and} is the
960
+ # two-valued form.** The two give different answers where one side
961
+ # is masked.
942
962
  #
943
- # On boolean arrays the masked elements follow three-valued
944
- # (Kleene) logic rather than propagating blindly: an unknown
945
- # element `AND` `false` is `false`, because the answer does not
946
- # depend on the unknown. Only where the result genuinely depends on
947
- # a masked element is the result masked. {#and} is the two-valued
948
- # form that always propagates.
963
+ # An unknown (masked) element `AND` `false` is `false`, because the
964
+ # answer does not depend on the unknown; only where the result
965
+ # genuinely depends on a masked element is the result masked. So
966
+ # `(a & b).not` is `true` where `a` is `false`, whatever `b` is,
967
+ # while `a.and(b).not` stays masked where `b` is.
949
968
  # @param other [CArray, Integer, true, false] the other operand,
950
969
  # broadcast to `self.shape`.
951
970
  # @return [CArray] `:boolean` for boolean operands, otherwise the
@@ -962,8 +981,9 @@ class CArray
962
981
  # @overload |(other)
963
982
  # Returns the element-wise disjunction of `self` and `other`: a
964
983
  # bitwise `OR` on integer arrays, a logical `OR` on boolean ones.
965
- # Boolean operands follow Kleene logic as in {#&}, so an unknown
966
- # element `OR` `true` is `true`.
984
+ # **On boolean arrays it is three-valued (Kleene) as {#&} is; {#or}
985
+ # is the two-valued form.** An unknown element `OR` `true` is
986
+ # `true`.
967
987
  # @param other [CArray, Integer, true, false] the other operand,
968
988
  # broadcast to `self.shape`.
969
989
  # @return [CArray] `:boolean` for boolean operands, otherwise the
@@ -1045,13 +1065,16 @@ class CArray
1045
1065
  def not; end
1046
1066
 
1047
1067
  # @overload and(other)
1048
- # Returns the two-valued logical `AND` of two boolean arrays.
1068
+ # Returns the logical `AND` of two boolean arrays, **two-valued: a
1069
+ # masked element on either side makes the result masked**, even
1070
+ # where the other side alone would settle the answer. {#&} is the
1071
+ # three-valued form, and the two differ exactly there: `false & U`
1072
+ # is `false`, `false.and(U)` is `U`.
1049
1073
  #
1050
- # Where {#&} applies Kleene logic, this form propagates the mask
1051
- # unconditionally: if either element is masked the result is
1052
- # masked, even when the unmasked element alone would settle the
1053
- # answer. Use it when an unknown operand should make the result
1054
- # unknown regardless.
1074
+ # Use it when the answer should be given only where both inputs are
1075
+ # known -- the element-wise counterpart of keeping only complete
1076
+ # records -- and {#&} when an answer the known side settles should
1077
+ # stand.
1055
1078
  # @param other [CArray, true, false] the other operand, broadcast
1056
1079
  # to `self.shape`.
1057
1080
  # @return [CArray] `:boolean`.
@@ -1060,8 +1083,10 @@ class CArray
1060
1083
  def and(other); end
1061
1084
 
1062
1085
  # @overload or(other)
1063
- # Returns the two-valued logical `OR` of two boolean arrays,
1064
- # propagating the mask unconditionally as {#and} does.
1086
+ # Returns the logical `OR` of two boolean arrays, **two-valued: a
1087
+ # masked element on either side makes the result masked**, as
1088
+ # {#and} does. {#|} is the three-valued form: `true | U` is `true`,
1089
+ # `true.or(U)` is `U`.
1065
1090
  # @param other [CArray, true, false] the other operand.
1066
1091
  # @return [CArray] `:boolean`.
1067
1092
  # @raise [CArray::DataTypeError] for any `data_type` other than
@@ -102,6 +102,13 @@ class CArray
102
102
  # returned object via internal ivars; the source is released
103
103
  # when the wrap is garbage-collected.
104
104
  #
105
+ # Views made from the wrap keep it reachable too, so the view is
106
+ # given back only once all of them are collected. A producer that
107
+ # locks while it is borrowed (`IO::Buffer` refuses `resize` and
108
+ # `free`) stays locked until then; import with
109
+ # {.from_memory_view} to hold no view at all. See
110
+ # {file:docs/interop/MemoryView.md MemoryView} §9.
111
+ #
105
112
  # Contiguous typed producers return a `CAWrap`. Strided typed
106
113
  # producers return a `CAStride` over a byte `CAWrap` of the
107
114
  # bytes its elements reach, preserving the full stride pattern
@@ -128,7 +128,8 @@ class CArray
128
128
 
129
129
  # @overload bsearch(val)
130
130
  # Returns the flat address of `val` in `self` via binary search.
131
- # `self` must be sorted along its single (flat) axis. Returns
131
+ # `self` must be sorted along its single (flat) axis. Of several
132
+ # equal cells, the first one's address is returned. Returns
132
133
  # `nil` if `val` is not present. When `val` is a CArray, returns
133
134
  # a CArray of `:int64` addresses (one per element of `val`),
134
135
  # with `UNDEF` at positions where the value is not present.
@@ -159,7 +160,8 @@ class CArray
159
160
  # @overload search(val, eps = nil)
160
161
  # Returns the flat address of the first element of `self` equal
161
162
  # to `val`. For float types, `eps` (default machine epsilon)
162
- # sets the tolerance. Returns `nil` if no match.
163
+ # sets the tolerance; a negative or NaN `eps` raises
164
+ # `ArgumentError`. Returns `nil` if no match.
163
165
  #
164
166
  # `val` is compared in the type both share, as `self.eq(val)`
165
167
  # compares: an integer array searched with a Float is compared in
@@ -201,7 +203,10 @@ class CArray
201
203
 
202
204
  # @overload search_nearest(val)
203
205
  # Returns the flat address of the element of `self` whose value
204
- # is closest to `val`.
206
+ # is closest to `val`. Of several equally close elements, the one
207
+ # at the lowest address wins, as {#search} answers the first match
208
+ # (`[0, 2, 4].search_nearest(1)` is 0). {#locate_nearest_addr}
209
+ # rounds a position instead, and answers the larger value on a tie.
205
210
  #
206
211
  # In an `:object` array the distance is `val.distance(other)` when
207
212
  # `val` answers `#distance`, and `(val - other).abs` when it is a
@@ -268,7 +273,9 @@ class CArray
268
273
  # `self` is coerced to `:float64` if it is not already. When
269
274
  # `axis: nil`, `self` is flattened to 1-D first.
270
275
  #
271
- # Out-of-range `addr` returns NaN.
276
+ # A position with no answer -- out of range, or between samples one
277
+ # of which is NaN -- gives `nil` for a scalar `addr` and NaN in the
278
+ # cell of an array result.
272
279
  #
273
280
  # Because this half of the pair returns a *value* rather than a
274
281
  # position, a Face axis gets its Face back: `CATime#linear_fetch` /
@@ -280,5 +287,94 @@ class CArray
280
287
  # @see file:docs/topics/LinearInterpolation.md
281
288
  def linear_fetch(addr, axis: nil); end
282
289
 
290
+ # @overload nlargest(n, axis: nil)
291
+ # Returns the `n` largest values, largest first. Without `axis:` the
292
+ # array is read flat; with it, each fiber along `axis` gives its own
293
+ # `n` and the axis keeps length `n`. A NaN and a masked cell lose to
294
+ # every value; when fewer cells remain than `n`, the result is
295
+ # shorter (or, per fiber, ends in UNDEF).
296
+ # @param n [Integer] how many values, 0 or more.
297
+ # @param axis [Integer, nil]
298
+ # @return [CArray]
299
+ # @raise [ArgumentError] when `n` is negative.
300
+ def nlargest(n, axis: nil); end
301
+
302
+ # @overload nsmallest(n, axis: nil)
303
+ # Returns the `n` smallest values, smallest first. As {#nlargest}
304
+ # otherwise.
305
+ # @param n [Integer]
306
+ # @param axis [Integer, nil]
307
+ # @return [CArray]
308
+ # @raise [ArgumentError] when `n` is negative.
309
+ def nsmallest(n, axis: nil); end
310
+
311
+ # @overload nlargest_index(n, axis:)
312
+ # Returns, along `axis`, the axis-local positions of each fiber's `n`
313
+ # largest values, largest first (`take_along_axis` reads the values
314
+ # back). `axis:` is required.
315
+ # @param n [Integer]
316
+ # @param axis [Integer]
317
+ # @return [CArray] `:int64` positions.
318
+ # @raise [ArgumentError] when `axis:` is missing or `n` is negative.
319
+ def nlargest_index(n, axis:); end
320
+
321
+ # @overload nsmallest_index(n, axis:)
322
+ # As {#nlargest_index}, for the `n` smallest values.
323
+ # @param n [Integer]
324
+ # @param axis [Integer]
325
+ # @return [CArray] `:int64` positions.
326
+ # @raise [ArgumentError] when `axis:` is missing or `n` is negative.
327
+ def nsmallest_index(n, axis:); end
328
+
329
+ # @overload sort_by_key(key, axis: 0)
330
+ # Returns `self` reordered along `axis` by the order of `key` (an
331
+ # array of `self`'s shape): `self[key.sort_addr(axis:)]`.
332
+ # @param key [CArray] the values to order by.
333
+ # @param axis [Integer]
334
+ # @return [CArray]
335
+ # @raise [ArgumentError] when `key`'s shape differs from `self`'s.
336
+ def sort_by_key(key, axis: 0); end
337
+
338
+ # @overload max_by_key(key, axis: nil)
339
+ # Returns the value of `self` where `key` is largest: one value, or
340
+ # one per fiber along `axis`. UNDEF where there is no cell to compare.
341
+ # @param key [CArray] the values to compare, of `self`'s shape.
342
+ # @param axis [Integer, nil]
343
+ # @return [Object, CArray]
344
+ # @raise [ArgumentError] when `key`'s shape differs from `self`'s.
345
+ def max_by_key(key, axis: nil); end
346
+
347
+ # @overload min_by_key(key, axis: nil)
348
+ # As {#max_by_key}, where `key` is smallest.
349
+ # @param key [CArray]
350
+ # @param axis [Integer, nil]
351
+ # @return [Object, CArray]
352
+ # @raise [ArgumentError] when `key`'s shape differs from `self`'s.
353
+ def min_by_key(key, axis: nil); end
354
+
355
+ # @overload take_along_axis(indices, axis: 0)
356
+ # Returns the values of `self` at axis-local `indices` along `axis`
357
+ # (`indices` has `self`'s shape except along `axis`), as the
358
+ # `*_index(axis:)` methods answer them. A masked index reads UNDEF.
359
+ # @param indices [CArray] integer positions along `axis`.
360
+ # @param axis [Integer]
361
+ # @return [CArray]
362
+ def take_along_axis(indices, axis: 0); end
363
+
364
+ # @overload put_along_axis(indices, values, axis: 0)
365
+ # Writes `values` into `self` at axis-local `indices` along `axis`,
366
+ # the inverse of {#take_along_axis}. A masked index writes nothing.
367
+ # @param indices [CArray] integer positions along `axis`.
368
+ # @param values [CArray, Object]
369
+ # @param axis [Integer]
370
+ # @return [self]
371
+ def put_along_axis(indices, values, axis: 0); end
372
+
373
+ # @overload range
374
+ # Returns `min..max` of `self` from one pass (`UNDEF..UNDEF` when no
375
+ # cell takes part).
376
+ # @return [Range]
377
+ def range; end
378
+
283
379
  # @!endgroup
284
380
  end
@@ -104,13 +104,15 @@ class CArray
104
104
  # allocates view state); useful in hot loops where a scatter
105
105
  # result is written back many times.
106
106
  #
107
- # Unlike the arithmetic `scatter_*!` family, `self` may be
108
- # **boolean** (assignment does not widen); `true` / `false` (or
109
- # `1` / `0`) are its scalar values. A scalar `UNDEF` masks every
110
- # addressed cell.
107
+ # Unlike the arithmetic `scatter_*!` family, `self` may be of any
108
+ # type (assignment does not widen): **boolean**, with `true` /
109
+ # `false` (or `1` / `0`) as its scalar values, and **object** or
110
+ # **fixlen**, written as `self.flatten[addrs] = vals` writes them
111
+ # (as `put_nd` and `put_along_axis` take them). A scalar `UNDEF`
112
+ # masks every addressed cell.
111
113
  #
112
114
  # @param addrs [CArray, Array<Integer>]
113
- # @param vals [CArray, Numeric, true, false, UNDEF]
115
+ # @param vals [CArray, Object, UNDEF]
114
116
  # @return [self]
115
117
  def scatter_replace!(addrs, vals); end
116
118
 
@@ -36,8 +36,11 @@ class CArray
36
36
  # @overload ==(other)
37
37
  # Returns `true` if `other` is a CArray with the same shape,
38
38
  # `data_class`, `data_type`, mask state, and elementwise values as
39
- # `self`. NaN values compare unequal (IEEE semantics), so two
40
- # arrays with NaN at the same position are not `==`.
39
+ # `self`. It asks whether the contents are the same, so a NaN equals
40
+ # a NaN at the same position (whatever its payload, in a float, a
41
+ # complex part or an object cell) and -0.0 equals 0.0: an array with
42
+ # NaN is `==` to its copy. The IEEE comparison, where NaN equals
43
+ # nothing, is {#eq}, cell by cell.
41
44
  #
42
45
  # A Face (a time, string or categorical array) equals only a Face of
43
46
  # its own class, and is compared by its values: two time arrays of
@@ -53,8 +56,8 @@ class CArray
53
56
  # Returns `true` under Hash-invariant semantics: `data_class`,
54
57
  # `data_type`, shape, and mask state must all match, and elements
55
58
  # are compared bitwise (for numeric types) or via `Object#eql?`
56
- # (for `:object` arrays). Unlike `==`, `NaN.eql?(NaN)` holds, so
57
- # two mask-free arrays with NaN at the same positions are `eql?`.
59
+ # (for `:object` arrays), so -0.0 and 0.0 differ and two NaNs are
60
+ # `eql?` only with the same bits.
58
61
  # Two Faces are `eql?` only when they are of the same class, share
59
62
  # their state (a time array's unit, a categorical's labels) and hold
60
63
  # the same storage.
metadata CHANGED
@@ -1,14 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carray
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.4
4
+ version: 3.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - himotoyoshi
8
8
  bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
- dependencies: []
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: prism
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '1.0'
12
26
  description: |2
13
27
  Ruby/CArray adds multi-dimensional numerical arrays to Ruby. Elements are held
14
28
  in a single flat memory block, so whole-array work -- element-wise arithmetic,
@@ -318,14 +332,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
318
332
  requirements:
319
333
  - - ">="
320
334
  - !ruby/object:Gem::Version
321
- version: '3.0'
335
+ version: '3.2'
322
336
  required_rubygems_version: !ruby/object:Gem::Requirement
323
337
  requirements:
324
338
  - - ">="
325
339
  - !ruby/object:Gem::Version
326
340
  version: '0'
327
341
  requirements: []
328
- rubygems_version: 4.0.17
342
+ rubygems_version: 4.0.8
329
343
  specification_version: 4
330
344
  summary: Multi-dimensional numerical array class for Ruby
331
345
  test_files: []