carray 3.0.6 → 3.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +110 -0
- data/README.md +24 -3
- data/carray.gemspec +1 -1
- data/ext/ca_axis_group.c +6 -6
- data/ext/ca_binop_dispatch.c +8 -0
- data/ext/ca_binop_dispatch.h +1 -0
- data/ext/ca_categorical_iterator.c +7 -7
- data/ext/ca_kernel_iterator.h +6 -4
- data/ext/ca_obj_array.c +4 -4
- data/ext/ca_obj_bincmp.c +19 -3
- data/ext/ca_obj_binop.c +36 -11
- data/ext/ca_obj_bitarray.c +2 -4
- data/ext/ca_obj_bitfield.c +86 -4
- data/ext/ca_obj_byte_swap.c +2 -4
- data/ext/ca_obj_const_string.c +422 -257
- data/ext/ca_obj_face.c +71 -33
- data/ext/ca_obj_fake.c +112 -13
- data/ext/ca_obj_farray.c +7 -1
- data/ext/ca_obj_fixlen_string.c +51 -17
- data/ext/ca_obj_grid.c +12 -7
- data/ext/ca_obj_meld.c +5 -5
- data/ext/ca_obj_monop.c +65 -39
- data/ext/ca_obj_object.c +9 -9
- data/ext/ca_obj_reduce.c +2 -4
- data/ext/ca_obj_refer.c +104 -10
- data/ext/ca_obj_repeat.c +1 -1
- data/ext/ca_obj_roll.c +2 -4
- data/ext/ca_obj_select.c +8 -6
- data/ext/ca_obj_select_axis.c +8 -6
- data/ext/ca_obj_stack.c +5 -5
- data/ext/ca_obj_stride.c +46 -8
- data/ext/ca_obj_string.c +2 -2
- data/ext/ca_obj_tile.c +2 -4
- data/ext/ca_obj_triop.c +15 -12
- data/ext/ca_obj_window.c +22 -15
- data/ext/ca_op_ipower.c +63 -15
- data/ext/ca_op_powi.h +6 -29
- data/ext/ca_sort_kernels.h +3 -0
- data/ext/ca_sweep_engine.c +90 -23
- data/ext/ca_sweep_engine.h +5 -6
- data/ext/caframe_csv_reader.c +1 -1
- data/ext/carray.h +3 -1
- data/ext/carray_access.c +98 -39
- data/ext/carray_address_basis.c +98 -24
- data/ext/carray_broadcast.c +2 -2
- data/ext/carray_call_cfunc.c +5 -8
- data/ext/carray_cast.c +311 -37
- data/ext/carray_cast_func.rb +37 -5
- data/ext/carray_conversion.c +56 -2
- data/ext/carray_copy.c +24 -0
- data/ext/carray_core.c +69 -6
- data/ext/carray_count.c +28 -9
- data/ext/carray_element.c +9 -3
- data/ext/carray_factorize.c +11 -11
- data/ext/carray_histogram.c +2 -2
- data/ext/carray_index_classifier.c +7 -5
- data/ext/carray_internal.h +94 -0
- data/ext/carray_kernels_binop.c +55 -55
- data/ext/carray_kernels_init.c +14 -14
- data/ext/carray_kernels_monop.c +90 -140
- data/ext/carray_lazy.c +16 -1
- data/ext/carray_loop.c +9 -2
- data/ext/carray_mask.c +118 -11
- data/ext/carray_median_percentile.c +13 -8
- data/ext/carray_memory_view.c +41 -22
- data/ext/carray_operator.c +72 -11
- data/ext/carray_order.c +52 -9
- data/ext/carray_partition.c +1 -1
- data/ext/carray_random.c +1 -1
- data/ext/carray_round.c +24 -1
- data/ext/carray_scatter.c +4 -0
- data/ext/carray_segment.c +1 -1
- data/ext/carray_slab.c +13 -4
- data/ext/carray_sort.c +6 -3
- data/ext/carray_sort_kernel.c +24 -0
- data/ext/carray_struct.c +21 -6
- data/ext/carray_test.c +85 -39
- data/ext/carray_time_text.c +6 -0
- data/ext/carray_utils.c +124 -54
- data/ext/mk_call_cfunc.rb +6 -11
- data/ext/mkkernel.rb +37 -27
- data/ext/version.h +4 -4
- data/lib/carray/axis_group.rb +9 -6
- data/lib/carray/basics.rb +26 -8
- data/lib/carray/bincount_nd.rb +8 -2
- data/lib/carray/block_iterator.rb +48 -21
- data/lib/carray/categorical.rb +21 -8
- data/lib/carray/categorical_iterator.rb +2 -1
- data/lib/carray/conditional.rb +52 -4
- data/lib/carray/const_string.rb +74 -0
- data/lib/carray/construct.rb +2 -2
- data/lib/carray/core_extensions.rb +19 -68
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/fixlen_string.rb +83 -1
- data/lib/carray/frame/column_verbs.rb +61 -6
- data/lib/carray/frame/concat.rb +50 -6
- data/lib/carray/frame/csv_parser.rb +13 -4
- data/lib/carray/frame/frame.rb +38 -6
- data/lib/carray/frame/group.rb +67 -40
- data/lib/carray/frame/io.rb +10 -5
- data/lib/carray/frame/join.rb +20 -6
- data/lib/carray/frame/records.rb +6 -4
- data/lib/carray/frame/reshape.rb +25 -5
- data/lib/carray/frame/verbs.rb +78 -25
- data/lib/carray/frame/windows.rb +30 -6
- data/lib/carray/fuse_source.rb +4 -2
- data/lib/carray/iterator.rb +8 -0
- data/lib/carray/key_windows.rb +10 -4
- data/lib/carray/lazy.rb +12 -17
- data/lib/carray/methods/bin.rb +3 -0
- data/lib/carray/methods/composition.rb +1 -1
- data/lib/carray/methods/factorize.rb +2 -0
- data/lib/carray/methods/gather_nd.rb +4 -1
- data/lib/carray/methods/is_in.rb +23 -3
- data/lib/carray/methods/locate_addr.rb +63 -12
- data/lib/carray/methods/repeat.rb +11 -1
- data/lib/carray/record_order.rb +35 -6
- data/lib/carray/runtime.rb +10 -0
- data/lib/carray/segment_iterator.rb +19 -16
- data/lib/carray/serialize.rb +22 -0
- data/lib/carray/slab_iterator.rb +1 -1
- data/lib/carray/stack.rb +3 -3
- data/lib/carray/string.rb +6 -6
- data/lib/carray/string_operation_extension.rb +25 -4
- data/lib/carray/struct_builder.rb +4 -1
- data/lib/carray/time.rb +190 -46
- data/lib/carray/window_iterator.rb +48 -12
- data/yard-stubs/ca_obj_bitfield.rb +4 -1
- data/yard-stubs/ca_obj_refer.rb +3 -0
- data/yard-stubs/ca_obj_window.rb +2 -1
- data/yard-stubs/carray_access.rb +4 -2
- data/yard-stubs/carray_cast.rb +6 -0
- data/yard-stubs/carray_count.rb +6 -3
- data/yard-stubs/carray_math.rb +5 -0
- data/yard-stubs/carray_order.rb +6 -0
- data/yard-stubs/carray_scatter.rb +2 -1
- data/yard-stubs/carray_test.rb +18 -5
- metadata +2 -2
data/lib/carray/time.rb
CHANGED
|
@@ -623,8 +623,57 @@ module CATimeOperandValues
|
|
|
623
623
|
in_common_unit_with(lifted)
|
|
624
624
|
end
|
|
625
625
|
|
|
626
|
+
# @overload pmax(other)
|
|
627
|
+
# The later time, or the longer duration, of each cell and `other`, cell
|
|
628
|
+
# by cell: `other` is an array of the same kind and shape, or one value
|
|
629
|
+
# (for a time a {CATime::Element}, a `Time`, a `Date`, `"2024-01-02"`; for
|
|
630
|
+
# a duration a {CATimedelta::Element}, `"3 days"`) for every cell. The
|
|
631
|
+
# two meet as a comparison does, so the result is in `self`'s unit when
|
|
632
|
+
# `other` sits on its grid and in the finer unit the two share otherwise.
|
|
633
|
+
# A masked cell on either side gives a masked cell.
|
|
634
|
+
# @param other [CATime, CATimedelta, CATime::Element, CATimedelta::Element, Time, Date, String]
|
|
635
|
+
# @return [CATime, CATimedelta]
|
|
636
|
+
# @raise [TypeError] when `other` is not of this kind.
|
|
637
|
+
def pmax (other)
|
|
638
|
+
pick_by_order(other) { |a, b| a < b }
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
# @overload pmin(other)
|
|
642
|
+
# The earlier time, or the shorter duration; see {#pmax}.
|
|
643
|
+
# @param other [CATime, CATimedelta, CATime::Element, CATimedelta::Element, Time, Date, String]
|
|
644
|
+
# @return [CATime, CATimedelta]
|
|
645
|
+
# @raise [TypeError] when `other` is not of this kind.
|
|
646
|
+
def pmin (other)
|
|
647
|
+
pick_by_order(other) { |a, b| a > b }
|
|
648
|
+
end
|
|
649
|
+
|
|
650
|
+
# A time or a duration has no NaN, so maximum / minimum (which let a NaN
|
|
651
|
+
# win) are pmax / pmin, and fmax / fmin are their other names.
|
|
652
|
+
alias_method :maximum, :pmax
|
|
653
|
+
alias_method :minimum, :pmin
|
|
654
|
+
alias_method :fmax, :pmax
|
|
655
|
+
alias_method :fmin, :pmin
|
|
656
|
+
|
|
626
657
|
private
|
|
627
658
|
|
|
659
|
+
# `other` where the block says self's cell loses to it, else self's cell.
|
|
660
|
+
def pick_by_order (other)
|
|
661
|
+
return copy.tap { |out| out[] = UNDEF } if UNDEF.equal?(other)
|
|
662
|
+
a, b = comparable_pair(other)
|
|
663
|
+
b = b[0] unless other.is_a?(CArray) || other.is_a?(Array)
|
|
664
|
+
yield(a, b).then_else(b, a)
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
# Both branches of a selection in the unit a comparison meets them in, so
|
|
668
|
+
# the finer unit wins whichever branch it is.
|
|
669
|
+
def branches_in_common (x, y)
|
|
670
|
+
other, base = y.is_a?(CArray) && !y.scalar? ? [x, y] : [y, x]
|
|
671
|
+
return [x, y] if other.nil? || UNDEF.equal?(other)
|
|
672
|
+
a, b = base.comparable_pair(other)
|
|
673
|
+
b = b[0] unless other.is_a?(CArray) && !other.scalar?
|
|
674
|
+
base.equal?(y) ? [b, a] : [a, b]
|
|
675
|
+
end
|
|
676
|
+
|
|
628
677
|
# The operand as an array of this kind in its own unit: one value read as
|
|
629
678
|
# it is written, an Array or an array of another kind read value by value
|
|
630
679
|
# in the unit they share, an UNDEF or a masked cell kept masked.
|
|
@@ -739,13 +788,19 @@ class CATime
|
|
|
739
788
|
# @return [String]
|
|
740
789
|
def to_s
|
|
741
790
|
case unit.base
|
|
742
|
-
when :Y then to_date.strftime("%Y")
|
|
743
|
-
when :M then to_date.strftime("%Y-%m")
|
|
744
|
-
when :W, :D then to_date.strftime("%Y-%m-%d")
|
|
745
|
-
else to_time.iso8601(fractional_second_digits) # :h .. :as (time shown)
|
|
791
|
+
when :Y then signed_past_four_digits(to_date.strftime("%Y"))
|
|
792
|
+
when :M then signed_past_four_digits(to_date.strftime("%Y-%m"))
|
|
793
|
+
when :W, :D then signed_past_four_digits(to_date.strftime("%Y-%m-%d"))
|
|
794
|
+
else signed_past_four_digits(to_time.iso8601(fractional_second_digits)) # :h .. :as (time shown)
|
|
746
795
|
end
|
|
747
796
|
end
|
|
748
797
|
|
|
798
|
+
# A year past four digits carries its sign, which is what tells it from a
|
|
799
|
+
# date written without separators when the text is read back.
|
|
800
|
+
private def signed_past_four_digits (text)
|
|
801
|
+
text.start_with?("-") || to_date.year < 10000 ? text : "+#{text}"
|
|
802
|
+
end
|
|
803
|
+
|
|
749
804
|
# @return [String] the instant plus its storage unit.
|
|
750
805
|
def inspect
|
|
751
806
|
tag = unit.count == 1 ? "#{value}#{unit.base}" : "#{value} @ #{unit}"
|
|
@@ -810,7 +865,7 @@ class CATime
|
|
|
810
865
|
# @raise [TypeError, ArgumentError] on a non-timedelta operand, or a
|
|
811
866
|
# pair that has no answer on self's grid.
|
|
812
867
|
def +(td)
|
|
813
|
-
shifted_by_duration(td, 1)
|
|
868
|
+
shifted_by_duration(one_step_of(td), 1)
|
|
814
869
|
end
|
|
815
870
|
|
|
816
871
|
# @overload -(other)
|
|
@@ -831,6 +886,10 @@ class CATime
|
|
|
831
886
|
shifted_by_duration(other, -1)
|
|
832
887
|
when CATime
|
|
833
888
|
-(other - self)
|
|
889
|
+
when String, Time, Date
|
|
890
|
+
step = other.is_a?(String) ? one_step_of(other) : other
|
|
891
|
+
return shifted_by_duration(step, -1) unless step.equal?(other)
|
|
892
|
+
(CATime.wrap(CA_INT64([value]), unit: unit) - other)[0]
|
|
834
893
|
else
|
|
835
894
|
raise TypeError, "CATime::Element - #{other.class} is not allowed"
|
|
836
895
|
end
|
|
@@ -851,6 +910,18 @@ class CATime
|
|
|
851
910
|
# the duration is converted into it (truncated toward zero when finer; a
|
|
852
911
|
# month or year duration on a fixed grid moves the date by months).
|
|
853
912
|
# Mirrors the array CATime +/-.
|
|
913
|
+
# A String naming a duration ("3 days") as one step of it; anything else
|
|
914
|
+
# as it is.
|
|
915
|
+
def one_step_of(x)
|
|
916
|
+
return x unless x.is_a?(String)
|
|
917
|
+
res = begin
|
|
918
|
+
CATime::Resolution.parse(x)
|
|
919
|
+
rescue ArgumentError
|
|
920
|
+
return x
|
|
921
|
+
end
|
|
922
|
+
CATimedelta::Element.new(1, res)
|
|
923
|
+
end
|
|
924
|
+
|
|
854
925
|
def shifted_by_duration(td, sign)
|
|
855
926
|
# An array of durations gives an array of instants, anchored here.
|
|
856
927
|
return sign > 0 ? td + self : (-td) + self if td.is_a?(CATimedelta)
|
|
@@ -1005,6 +1076,20 @@ class CATimedelta
|
|
|
1005
1076
|
# @return [CATimedelta::Element]
|
|
1006
1077
|
def -(other) = combined_with_duration(other, -1)
|
|
1007
1078
|
|
|
1079
|
+
# @return [CATimedelta::Element] this duration with its sign reversed.
|
|
1080
|
+
def -@ = Element.new(-value, unit)
|
|
1081
|
+
|
|
1082
|
+
# @return [CATimedelta::Element] the magnitude of this duration.
|
|
1083
|
+
def abs = Element.new(value.abs, unit)
|
|
1084
|
+
|
|
1085
|
+
# @overload coerce(number)
|
|
1086
|
+
# Lets a duration stand on the right of a number, so `2 * d` is `d * 2`.
|
|
1087
|
+
# @param number [Numeric]
|
|
1088
|
+
# @return [Array]
|
|
1089
|
+
def coerce (number)
|
|
1090
|
+
[LeftFactor.new(number), self]
|
|
1091
|
+
end
|
|
1092
|
+
|
|
1008
1093
|
# @overload *(n)
|
|
1009
1094
|
# Returns this duration scaled by an Integer.
|
|
1010
1095
|
# @param n [Integer]
|
|
@@ -1203,6 +1288,13 @@ class CATime
|
|
|
1203
1288
|
end
|
|
1204
1289
|
end
|
|
1205
1290
|
|
|
1291
|
+
# The word form of {#+}.
|
|
1292
|
+
# @return [CATime]
|
|
1293
|
+
alias_method :add, :+
|
|
1294
|
+
# The word form of {#-}.
|
|
1295
|
+
# @return [CATime, CATimedelta]
|
|
1296
|
+
alias_method :sub, :-
|
|
1297
|
+
|
|
1206
1298
|
# Whether a duration moves this time by calendar months: a month or year
|
|
1207
1299
|
# duration on a time whose grid is fixed-length. A time on a month or year
|
|
1208
1300
|
# grid adds it as months already, and a fixed duration on a calendar grid
|
|
@@ -1220,44 +1312,6 @@ class CATime
|
|
|
1220
1312
|
CATimeUnitAlgebra.shift_months(face_storage, unit, months).time(unit: unit)
|
|
1221
1313
|
end
|
|
1222
1314
|
|
|
1223
|
-
# @overload pmax(other)
|
|
1224
|
-
# The later of each cell and `other`, cell by cell: `other` is a time
|
|
1225
|
-
# array of the same shape, or one time (a {CATime::Element}, a `Time`, a
|
|
1226
|
-
# `Date`, `"2024-01-02"`) for every cell. The two meet as a comparison
|
|
1227
|
-
# does, so the result is in `self`'s unit when `other` sits on its grid
|
|
1228
|
-
# and in the finer unit the two share otherwise. A masked cell on either
|
|
1229
|
-
# side gives a masked cell.
|
|
1230
|
-
# @param other [CATime, CATime::Element, Time, Date, String]
|
|
1231
|
-
# @return [CATime]
|
|
1232
|
-
# @raise [TypeError] when `other` is not a time.
|
|
1233
|
-
def pmax (other)
|
|
1234
|
-
pick_by_order(other) { |a, b| a < b }
|
|
1235
|
-
end
|
|
1236
|
-
|
|
1237
|
-
# @overload pmin(other)
|
|
1238
|
-
# The earlier of each cell and `other`; see {#pmax}.
|
|
1239
|
-
# @param other [CATime, CATime::Element, Time, Date, String]
|
|
1240
|
-
# @return [CATime]
|
|
1241
|
-
# @raise [TypeError] when `other` is not a time.
|
|
1242
|
-
def pmin (other)
|
|
1243
|
-
pick_by_order(other) { |a, b| a > b }
|
|
1244
|
-
end
|
|
1245
|
-
|
|
1246
|
-
# A time has no NaN, so maximum / minimum (which let a NaN win) are pmax /
|
|
1247
|
-
# pmin, and fmax / fmin are their other names.
|
|
1248
|
-
alias_method :maximum, :pmax
|
|
1249
|
-
alias_method :minimum, :pmin
|
|
1250
|
-
alias_method :fmax, :pmax
|
|
1251
|
-
alias_method :fmin, :pmin
|
|
1252
|
-
|
|
1253
|
-
# `other` where the block says self's cell loses to it, else self's cell.
|
|
1254
|
-
private def pick_by_order (other)
|
|
1255
|
-
return copy.tap { |out| out[] = UNDEF } if UNDEF.equal?(other)
|
|
1256
|
-
a, b = comparable_pair(other)
|
|
1257
|
-
b = b[0] unless other.is_a?(CArray) || other.is_a?(Array)
|
|
1258
|
-
yield(a, b).then_else(b, a)
|
|
1259
|
-
end
|
|
1260
|
-
|
|
1261
1315
|
# Element-wise comparison (< <= > >= <=>) rides the core comparison Face
|
|
1262
1316
|
# gate (ca_face_reconcile_comparison in ext/ca_obj_face.c): the inherited
|
|
1263
1317
|
# CArray operators descend to storage and reconcile a CATime RHS in a
|
|
@@ -1928,6 +1982,7 @@ class CATimedelta
|
|
|
1928
1982
|
# @raise [TypeError] on incompatible operands.
|
|
1929
1983
|
def /(other)
|
|
1930
1984
|
given, other = other, CATimeUnitAlgebra.operand(other)
|
|
1985
|
+
other = CATimeUnitAlgebra.scalar_operand(other, unit) || other
|
|
1931
1986
|
case other
|
|
1932
1987
|
when Integer
|
|
1933
1988
|
CATimeUnitAlgebra.trunc_divide(face_storage, other).timedelta(unit: unit)
|
|
@@ -1942,6 +1997,68 @@ class CATimedelta
|
|
|
1942
1997
|
end
|
|
1943
1998
|
end
|
|
1944
1999
|
|
|
2000
|
+
# A number on the left of a duration: only `n * duration` has an answer.
|
|
2001
|
+
class LeftFactor
|
|
2002
|
+
def initialize (factor)
|
|
2003
|
+
@factor = factor
|
|
2004
|
+
end
|
|
2005
|
+
|
|
2006
|
+
def * (duration) = duration * @factor
|
|
2007
|
+
|
|
2008
|
+
def method_missing (op, duration, *)
|
|
2009
|
+
raise TypeError, "#{@factor.class} #{op} #{duration.class} is not allowed"
|
|
2010
|
+
end
|
|
2011
|
+
|
|
2012
|
+
def respond_to_missing? (*) = true
|
|
2013
|
+
end
|
|
2014
|
+
private_constant :LeftFactor
|
|
2015
|
+
|
|
2016
|
+
# @overload coerce(number)
|
|
2017
|
+
# Lets a duration stand on the right of a number, so `2 * td` is `td * 2`.
|
|
2018
|
+
# @param number [Numeric]
|
|
2019
|
+
# @return [Array]
|
|
2020
|
+
def coerce (number)
|
|
2021
|
+
number.is_a?(Numeric) ? [LeftFactor.new(number), self] : super
|
|
2022
|
+
end
|
|
2023
|
+
|
|
2024
|
+
# @overload to_seconds
|
|
2025
|
+
# Each duration in seconds, exactly, as {Element#to_seconds} answers.
|
|
2026
|
+
# @return [CArray] an object array of Rational.
|
|
2027
|
+
# @raise [ArgumentError] for a :Y / :M unit, which has no exact seconds.
|
|
2028
|
+
def to_seconds
|
|
2029
|
+
unless CATimeUnitAlgebra::FIXED.key?(unit.base)
|
|
2030
|
+
raise ArgumentError,
|
|
2031
|
+
"CATimedelta #{unit} has no exact seconds (a :#{unit.base} is " \
|
|
2032
|
+
"calendar-variable); use to_seconds_approx for an estimate"
|
|
2033
|
+
end
|
|
2034
|
+
ratio = unit.tick_ratio
|
|
2035
|
+
face_storage.convert(:object) { |v| Rational(v) * ratio }
|
|
2036
|
+
end
|
|
2037
|
+
|
|
2038
|
+
# @overload to_seconds_approx
|
|
2039
|
+
# Each duration in seconds by nominal lengths, as
|
|
2040
|
+
# {Element#to_seconds_approx} answers.
|
|
2041
|
+
# @return [CArray] float64.
|
|
2042
|
+
def to_seconds_approx
|
|
2043
|
+
face_storage.to_type(:float64) * (unit.count * (Element::UNIT_TO_SECONDS[unit.base] || 1))
|
|
2044
|
+
end
|
|
2045
|
+
|
|
2046
|
+
# The word form of {#+}.
|
|
2047
|
+
# @return [CATimedelta, CATime]
|
|
2048
|
+
alias_method :add, :+
|
|
2049
|
+
# The word form of {#-}.
|
|
2050
|
+
# @return [CATimedelta]
|
|
2051
|
+
alias_method :sub, :-
|
|
2052
|
+
# The word form of {#*}.
|
|
2053
|
+
# @return [CATimedelta]
|
|
2054
|
+
alias_method :mul, :*
|
|
2055
|
+
# The word form of {#/}.
|
|
2056
|
+
# @return [CATimedelta, CArray]
|
|
2057
|
+
alias_method :div, :/
|
|
2058
|
+
# The word form of {#-@}.
|
|
2059
|
+
# @return [CATimedelta]
|
|
2060
|
+
alias_method :neg, :-@
|
|
2061
|
+
|
|
1945
2062
|
# Element-wise comparison (< <= > >= <=>) rides the core comparison Face
|
|
1946
2063
|
# gate (ca_face_reconcile_comparison): the inherited CArray operators
|
|
1947
2064
|
# descend to storage and reconcile a CATimedelta RHS in a different unit
|
|
@@ -2138,8 +2255,12 @@ class CATimedelta
|
|
|
2138
2255
|
|
|
2139
2256
|
# One duration as a length-1 duration array in its own unit, or nil.
|
|
2140
2257
|
private def lift_value (operand)
|
|
2141
|
-
|
|
2258
|
+
case operand
|
|
2259
|
+
when CATimedelta::Element
|
|
2142
2260
|
CATimedelta.wrap(CA_INT64([operand.value]), unit: operand.unit)
|
|
2261
|
+
when String
|
|
2262
|
+
res = CATime::Resolution.parse(operand)
|
|
2263
|
+
CATimedelta.wrap(CA_INT64([res.count]), unit: res.base)
|
|
2143
2264
|
end
|
|
2144
2265
|
end
|
|
2145
2266
|
|
|
@@ -2152,6 +2273,8 @@ class CATimedelta
|
|
|
2152
2273
|
when CATimedelta::Element
|
|
2153
2274
|
lifted = CATimedelta.wrap(CA_INT64([operand.value]), unit: operand.unit)
|
|
2154
2275
|
to_comparable(lifted)
|
|
2276
|
+
when String
|
|
2277
|
+
to_comparable(lift_value(operand))
|
|
2155
2278
|
when Array, CArray
|
|
2156
2279
|
# Durations written one by one, or an array that is not a duration
|
|
2157
2280
|
# array (an object column of elements), read value by value.
|
|
@@ -2169,7 +2292,8 @@ class CATimedelta
|
|
|
2169
2292
|
# scalar store round-trips with a fetch. A {Element} is reconciled to
|
|
2170
2293
|
# self's unit via {#to_comparable} (lossless discipline; a `Time` /
|
|
2171
2294
|
# `DateTime` is an absolute instant, not a duration, so it raises there).
|
|
2172
|
-
# A
|
|
2295
|
+
# A String that names a duration (`"3 days"`) is read as one. A bare
|
|
2296
|
+
# Integer (the `.parent` raw-storage escape) and any other String pass
|
|
2173
2297
|
# through unchanged.
|
|
2174
2298
|
# @param surface [Element, Integer, String]
|
|
2175
2299
|
# @return [Integer, Object] the storage-domain value, or `surface`
|
|
@@ -2177,8 +2301,15 @@ class CATimedelta
|
|
|
2177
2301
|
# @raise [TypeError, ArgumentError] on an unreconcilable surface / unit.
|
|
2178
2302
|
def element_to_storage (surface)
|
|
2179
2303
|
case surface
|
|
2180
|
-
when Integer
|
|
2304
|
+
when Integer
|
|
2181
2305
|
surface
|
|
2306
|
+
when String
|
|
2307
|
+
begin
|
|
2308
|
+
to_comparable(surface).parent[0]
|
|
2309
|
+
rescue ArgumentError => e
|
|
2310
|
+
raise unless e.message.start_with?("invalid unit spec")
|
|
2311
|
+
surface
|
|
2312
|
+
end
|
|
2182
2313
|
else
|
|
2183
2314
|
to_comparable(surface).parent[0]
|
|
2184
2315
|
end
|
|
@@ -2266,11 +2397,24 @@ module CATimeLiteral
|
|
|
2266
2397
|
sec: t.sec, sec_fraction: frac.zero? ? nil : Rational(frac), leftover: h[:leftover] }.compact
|
|
2267
2398
|
end
|
|
2268
2399
|
|
|
2400
|
+
# Date._parse drops the sign of a year on its own or before a month, a day
|
|
2401
|
+
# of the year or a week, and reads a year below 100 as this century's, so
|
|
2402
|
+
# those are read here.
|
|
2403
|
+
def year_first_fields(spec)
|
|
2404
|
+
case spec
|
|
2405
|
+
when /\A([-+]\d{4,})\z/ then { year: $1.to_i }
|
|
2406
|
+
when /\A([-+]\d{4,})-(\d{1,2})\z/ then { year: $1.to_i, mon: $2.to_i }
|
|
2407
|
+
when /\A([-+]?\d{4,})-(\d{3})\z/ then { year: $1.to_i, yday: $2.to_i }
|
|
2408
|
+
when /\A([-+]?\d{4,})-W(\d{2})-(\d)\z/ then { cwyear: $1.to_i, cweek: $2.to_i, cwday: $3.to_i }
|
|
2409
|
+
end
|
|
2410
|
+
end
|
|
2411
|
+
|
|
2269
2412
|
def parse_date_fields(spec, format)
|
|
2270
2413
|
h =
|
|
2271
2414
|
if format then epoch_fields(Date._strptime(spec, format))
|
|
2272
2415
|
elsif spec =~ /\A(\d{4})-(\d{1,2})\z/ then { year: $1.to_i, mon: $2.to_i }
|
|
2273
2416
|
elsif spec =~ /\A(\d{4})\z/ then { year: $1.to_i }
|
|
2417
|
+
elsif (year_first = year_first_fields(spec)) then year_first
|
|
2274
2418
|
elsif (hour = hour_only_fields(spec)) then hour
|
|
2275
2419
|
else Date._parse(spec)
|
|
2276
2420
|
end
|
|
@@ -70,6 +70,8 @@ class CAWindowIterator < CAIterator
|
|
|
70
70
|
# forward-looking). `bounds:` selects the margin policy (`:skip` /
|
|
71
71
|
# `:nearest` / `:truncate`). `fill_value:` is a constant margin value
|
|
72
72
|
# (an escape for `:constant` padding); when given it overrides `:skip`.
|
|
73
|
+
# Over a categorical or a const string, which hold no new value, it has
|
|
74
|
+
# to be a value some cell already holds.
|
|
73
75
|
#
|
|
74
76
|
# For backward compatibility `initialize(window_view)` with no ranges
|
|
75
77
|
# accepts a CAWindow view (the old `CAWindowIterator.new(a.window(...))`
|
|
@@ -82,6 +84,8 @@ class CAWindowIterator < CAIterator
|
|
|
82
84
|
# @param ranges [Array<Range>] per-axis offset ranges.
|
|
83
85
|
# @param bounds [Symbol] `:skip` / `:nearest` / `:truncate`.
|
|
84
86
|
# @param fill_value [Object, nil] constant margin value, overriding :skip.
|
|
87
|
+
# @raise [ArgumentError] when a categorical or const string source holds
|
|
88
|
+
# no cell with `fill_value` (raised when the windows are first read).
|
|
85
89
|
def initialize (source, *ranges, bounds: :skip, fill_value: nil)
|
|
86
90
|
if ranges.empty? && source.is_a?(CArray) && source.obj_type == CA_OBJ_WINDOW
|
|
87
91
|
# Backward-compat: read geometry from a CAWindow view built by #window.
|
|
@@ -282,15 +286,32 @@ class CAWindowIterator < CAIterator
|
|
|
282
286
|
def pad_face (src, lefts, rights, mode, value)
|
|
283
287
|
storage = src.__send__(:face_storage)
|
|
284
288
|
if mode == :constant && !value.nil?
|
|
285
|
-
|
|
286
|
-
cell[0] = value
|
|
287
|
-
padded = pad_source(storage, lefts, rights, :constant, cell.parent[0])
|
|
289
|
+
padded = pad_source(storage, lefts, rights, :constant, margin_storage(src, storage, value))
|
|
288
290
|
else
|
|
289
291
|
padded = pad_source(storage, lefts, rights, mode, value)
|
|
290
292
|
end
|
|
291
293
|
padded.face_lift(src)
|
|
292
294
|
end
|
|
293
295
|
|
|
296
|
+
# The storage of a `:constant` margin value. A Face that holds new values
|
|
297
|
+
# turns the value into storage; one that holds none (a const string's
|
|
298
|
+
# records index a shared pool, a categorical's codes index its labels) can
|
|
299
|
+
# only repeat the storage of a cell that already holds the value.
|
|
300
|
+
def margin_storage (src, storage, value)
|
|
301
|
+
if src.__send__(:holds_new_values?)
|
|
302
|
+
cell = src.__send__(:blank_like, [1])
|
|
303
|
+
cell[0] = value
|
|
304
|
+
return cell.parent[0]
|
|
305
|
+
end
|
|
306
|
+
hit = src.eq(value).where
|
|
307
|
+
if hit.elements == 0
|
|
308
|
+
raise ArgumentError,
|
|
309
|
+
"windows: fill_value #{value.inspect} is not a value of this " \
|
|
310
|
+
"#{src.class}, which can only repeat a value it already holds"
|
|
311
|
+
end
|
|
312
|
+
storage.flatten[hit[0]]
|
|
313
|
+
end
|
|
314
|
+
|
|
294
315
|
# Edge-replicate the margins of a padded buffer whose interior already holds
|
|
295
316
|
# the source. Per axis, the left margin rows copy the first interior row and
|
|
296
317
|
# the right margin rows copy the last; done axis by axis over the whole
|
|
@@ -567,11 +588,15 @@ class CAWindowIterator < CAIterator
|
|
|
567
588
|
return nil unless op == :mean || OFFSET_FOLD.key?(op)
|
|
568
589
|
# The elementwise kernels act on a Face's storage; its reductions are its own.
|
|
569
590
|
return nil if @source.face?
|
|
591
|
+
# Fixed-length cells have no elementwise kernels and no neutral value.
|
|
592
|
+
return nil if @source.data_type == CA_FIXLEN
|
|
593
|
+
# An undefined constant margin is a masked one, which a fold must skip.
|
|
594
|
+
return nil if @fill_value.equal?(UNDEF)
|
|
570
595
|
return nil if @widths.any? { |width| width > OFFSET_FOLD_MAX_WIDTH }
|
|
571
|
-
return nil if neutral_value(op).nil?
|
|
572
596
|
# pmin / pmax let NaN lose, so a window holding only NaN would fold to the
|
|
573
597
|
# neutral value; the core answers NaN there.
|
|
574
598
|
return nil if (op == :min || op == :max) && source_has_nan?
|
|
599
|
+
return nil if neutral_value(op).nil?
|
|
575
600
|
|
|
576
601
|
folded = op == :mean ? fold_mean : accumulate_offsets(op)
|
|
577
602
|
folded = mask_empty_windows(folded) if EMPTY_WINDOW_IS_UNDEFINED.include?(op)
|
|
@@ -640,6 +665,7 @@ class CAWindowIterator < CAIterator
|
|
|
640
665
|
end
|
|
641
666
|
|
|
642
667
|
def source_has_nan?
|
|
668
|
+
return true if @bounds == :constant && @fill_value.is_a?(Float) && @fill_value.nan?
|
|
643
669
|
return false unless @source.float? || @source.data_type == CA_OBJECT
|
|
644
670
|
@source.is_nan.any
|
|
645
671
|
end
|
|
@@ -659,9 +685,9 @@ class CAWindowIterator < CAIterator
|
|
|
659
685
|
# What stands in for a cell the fold must not see: a margin the boundary
|
|
660
686
|
# policy does not fill, or a masked cell of the source. For sum, prod, all
|
|
661
687
|
# and any that is the operation's identity. For min and max it is any value
|
|
662
|
-
# that cannot win, and the
|
|
663
|
-
# per-type limits is needed. Nil means there is none
|
|
664
|
-
# masked everywhere), and the caller delegates instead.
|
|
688
|
+
# that cannot win, and the extreme of the array and its constant margin is
|
|
689
|
+
# one -- so no table of per-type limits is needed. Nil means there is none
|
|
690
|
+
# to be had (a source masked everywhere), and the caller delegates instead.
|
|
665
691
|
def neutral_value (op)
|
|
666
692
|
@neutral_value ||= {}
|
|
667
693
|
return @neutral_value[op] if @neutral_value.key?(op)
|
|
@@ -678,7 +704,11 @@ class CAWindowIterator < CAIterator
|
|
|
678
704
|
|
|
679
705
|
def source_extreme (op)
|
|
680
706
|
value = @source.send(op)
|
|
681
|
-
value.equal?(UNDEF)
|
|
707
|
+
return nil if value.equal?(UNDEF)
|
|
708
|
+
return value unless @bounds == :constant
|
|
709
|
+
margin = @fill_value || 0
|
|
710
|
+
margin = margin ? 1 : 0 if @source.boolean? # the core answers 0 or 1
|
|
711
|
+
[value, margin].public_send(op)
|
|
682
712
|
end
|
|
683
713
|
|
|
684
714
|
# The buffer the offsets are read from: the source with its margins filled
|
|
@@ -722,13 +752,19 @@ class CAWindowIterator < CAIterator
|
|
|
722
752
|
# real values, so the count is the whole window and one Integer says it;
|
|
723
753
|
# `:skip` counts the in-bounds offsets, which is separable -- the count on
|
|
724
754
|
# one axis depends on that axis alone. A masked source has to be counted for
|
|
725
|
-
# real, by accumulating over the same offsets
|
|
755
|
+
# real, by accumulating over the same offsets; a cell of a constant margin
|
|
756
|
+
# counts once, whatever its value.
|
|
726
757
|
def window_cell_counts
|
|
727
758
|
return @window_cell_counts unless @window_cell_counts.nil?
|
|
728
759
|
@window_cell_counts =
|
|
729
760
|
if @source.has_mask?
|
|
730
|
-
|
|
731
|
-
|
|
761
|
+
present = @source.is_not_masked.int64
|
|
762
|
+
present = if @bounds == :constant
|
|
763
|
+
pad_source(present, @lefts, @rights, :constant, 1)
|
|
764
|
+
else
|
|
765
|
+
pad_for(present, 0)
|
|
766
|
+
end
|
|
767
|
+
accumulate_offsets(:sum, present, :add!, CA_INT64)
|
|
732
768
|
elsif @bounds != :skip
|
|
733
769
|
@widths.inject(:*)
|
|
734
770
|
else
|
|
@@ -806,7 +842,7 @@ class CAWindowIterator < CAIterator
|
|
|
806
842
|
return count_not_masked(**kw) if args.empty?
|
|
807
843
|
# The sliding_windows view is a CAStride, so its #count is not shadowed;
|
|
808
844
|
# dispatch CArray#count explicitly anyway, matching the family regularity.
|
|
809
|
-
|
|
845
|
+
count_cells(sliding_view, *args, axis: @window_axes,
|
|
810
846
|
**CAIterator.reduce_keywords(:count, kw))
|
|
811
847
|
end
|
|
812
848
|
|
|
@@ -30,7 +30,10 @@ class CArray
|
|
|
30
30
|
# narrowest unsigned type that holds the field is used: 1 bit →
|
|
31
31
|
# `:boolean`, 2..8 → `:uint8`, 9..16 → `:uint16`, 17..32 → `:uint32`,
|
|
32
32
|
# 33..64 → `:uint64`. A write keeps the low bits of the value that
|
|
33
|
-
# fit the field, signed or not (-3 into a
|
|
33
|
+
# fit the field, signed or not, for an Integer of any size (-3 into a
|
|
34
|
+
# 3-bit field is `0b101`, 300 is `0b100`). The same holds for a view
|
|
35
|
+
# taken of the field (a slice, an index, a mask selection). A String
|
|
36
|
+
# is read as a decimal integer, a Float through `Integer()`.
|
|
34
37
|
#
|
|
35
38
|
# @overload bitfield(range, type = nil)
|
|
36
39
|
# @param range [Integer, Range] bit position (single bit) or bit
|
data/yard-stubs/ca_obj_refer.rb
CHANGED
|
@@ -35,6 +35,9 @@ class CArray
|
|
|
35
35
|
# @raise [ArgumentError] when the byte widths do not divide
|
|
36
36
|
# evenly, when `offset` is negative, or when the requested
|
|
37
37
|
# view extends past the parent's data.
|
|
38
|
+
# @raise [TypeError] on a Face, for a data type that is neither its
|
|
39
|
+
# surface type nor its storage type: `to_type` gives the values,
|
|
40
|
+
# `parent.refer` the raw storage.
|
|
38
41
|
# @raise [CArray::DataTypeError] when reinterpreting a CA_OBJECT parent
|
|
39
42
|
# with a non-object `data_type`, or a parent of another data type as
|
|
40
43
|
# `:boolean` (a boolean cell holds 0 or 1; compare instead, `ne(0)`).
|
data/yard-stubs/ca_obj_window.rb
CHANGED
|
@@ -54,7 +54,8 @@ class CArray
|
|
|
54
54
|
# or when `bounds` is not a recognised value.
|
|
55
55
|
# @raise [IndexError] when `bounds` is `"strict"` and a range reaches
|
|
56
56
|
# outside `self`, or `"ruby"` and a range reaches past the end or
|
|
57
|
-
# before the first cell counted from the end
|
|
57
|
+
# before the first cell counted from the end, or `"nearest"` and a
|
|
58
|
+
# range takes cells of an axis of length 0.
|
|
58
59
|
def window(*ranges, fill_value: 0, bounds: "fill"); end
|
|
59
60
|
|
|
60
61
|
# @!endgroup
|
data/yard-stubs/carray_access.rb
CHANGED
|
@@ -90,7 +90,8 @@ class CArray
|
|
|
90
90
|
# or a CArray of such addresses (arbitrary shape). A negative
|
|
91
91
|
# address counts from the end.
|
|
92
92
|
# @return [Array<Integer>, Array<CArray>] one entry per axis.
|
|
93
|
-
# @raise [IndexError] when any `addr` is out of range
|
|
93
|
+
# @raise [IndexError] when any `addr` is out of range, or when `addr` is
|
|
94
|
+
# float, complex, object or boolean.
|
|
94
95
|
def addr2index(addr); end
|
|
95
96
|
|
|
96
97
|
# @overload index2addr(*index)
|
|
@@ -101,7 +102,8 @@ class CArray
|
|
|
101
102
|
# must match that shape). Mask propagates from the inputs.
|
|
102
103
|
# @param index [Array<Integer, CArray>] one entry per axis.
|
|
103
104
|
# @return [Integer, CArray] the flat address(es).
|
|
104
|
-
# @raise [IndexError] on an out-of-range index
|
|
105
|
+
# @raise [IndexError] on an out-of-range index, or an index array that
|
|
106
|
+
# is float, complex, object or boolean.
|
|
105
107
|
# @raise [ArgumentError] on shape mismatch between non-scalar inputs.
|
|
106
108
|
def index2addr(*index); end
|
|
107
109
|
|
data/yard-stubs/carray_cast.rb
CHANGED
|
@@ -490,6 +490,12 @@ class CArray
|
|
|
490
490
|
# that does not fit an integer type takes `:int64`. With no array or
|
|
491
491
|
# data_type representation, every argument promotes by its own type.
|
|
492
492
|
#
|
|
493
|
+
# This is the type an operator computes in: `int32_array + float32_array`
|
|
494
|
+
# is `:float32`. Arrays joined value for value ({CArray.stack},
|
|
495
|
+
# {CArray.meld}, {CArray.concatenate}) take the type {.promote_list}
|
|
496
|
+
# gives, which is `:float64` for that pair, since `float32` does not
|
|
497
|
+
# hold every `int32` exactly.
|
|
498
|
+
#
|
|
493
499
|
# Integer args are interpreted as *values*, not as data_type codes:
|
|
494
500
|
# `result_type(8)` returns `:int64` because the value 8 is an Integer,
|
|
495
501
|
# not because a data_type code equals 8. Use `result_type(:int64)` or
|
data/yard-stubs/carray_count.rb
CHANGED
|
@@ -36,6 +36,9 @@ class CArray
|
|
|
36
36
|
# count).
|
|
37
37
|
# - `v == UNDEF`: forwards to {#count_masked} (UNDEF is mask-state
|
|
38
38
|
# vocabulary, not a value).
|
|
39
|
+
# - `v` is `nil`, a String, a Symbol or another value that is not a
|
|
40
|
+
# number, on an array that is not `:object` or `:fixlen`: `0`. It
|
|
41
|
+
# is no value of such an array, so no cell equals it.
|
|
39
42
|
# - `v` is a CArray: broadcasts; each `v[k]` is counted
|
|
40
43
|
# independently and stacked into a result whose trailing axes
|
|
41
44
|
# have shape `v.shape`. Not supported when `self.data_type` is
|
|
@@ -43,9 +46,9 @@ class CArray
|
|
|
43
46
|
# - `self.data_type == :boolean`: `v` must be `true` / `false`, or
|
|
44
47
|
# the integer literal `1` (= true) / `0` (= false) — boolean
|
|
45
48
|
# stores 0/1, so `count(1)` == `count(true)`. Any other value
|
|
46
|
-
# (`2`, `1.0`,
|
|
47
|
-
# - `self` is numeric, `v` is scalar: `
|
|
48
|
-
#
|
|
49
|
+
# (`2`, `1.0`, …) raises `TypeError`.
|
|
50
|
+
# - `self` is numeric, `v` is scalar: `true` and `false` are the
|
|
51
|
+
# numbers `1` and `0`, as they are to {#eq}.
|
|
49
52
|
# `v` (a scalar or an array) is compared in the type it and the
|
|
50
53
|
# array match in, as {#eq} compares: `CA_INT32([1, 2]).count(1.5)`
|
|
51
54
|
# is `0`, `CA_UINT8([255]).count(-1)` is `0` (-1 is not 255), and an
|
data/yard-stubs/carray_math.rb
CHANGED
|
@@ -784,6 +784,11 @@ class CArray
|
|
|
784
784
|
# point equality is exact here; for a tolerant comparison see
|
|
785
785
|
# {#is_close} (absolute) or {#is_equiv} (relative). Integers compare
|
|
786
786
|
# by value, as for {#<}.
|
|
787
|
+
#
|
|
788
|
+
# `eq(UNDEF)` asks the mask, as {#is_masked} does. `nil`, a String, a
|
|
789
|
+
# Symbol or another value that is not a number is no value of a numeric
|
|
790
|
+
# or boolean array, so `eq` is false in every cell there; an `:object`
|
|
791
|
+
# or `:fixlen` array compares it like any other value.
|
|
787
792
|
# @param other [CArray, Numeric, Object] comparand, broadcast to
|
|
788
793
|
# `self.shape`.
|
|
789
794
|
# @return [CArray] `:boolean`, same shape as `self`.
|
data/yard-stubs/carray_order.rb
CHANGED
|
@@ -24,6 +24,7 @@ class CArray
|
|
|
24
24
|
# @return [CArray] a fresh array shaped like `idx`; a Face of the same
|
|
25
25
|
# type when `self` is a Face.
|
|
26
26
|
# @raise [ArgumentError] if `lval` / `uval` is given and `self` is a Face.
|
|
27
|
+
# @raise [IndexError] when `idx` is float, complex, object or boolean.
|
|
27
28
|
def project(idx, lval = nil, uval = nil); end
|
|
28
29
|
|
|
29
30
|
# sort / sort_copy stubs live in yard-stubs/carray_sort.rb (same
|
|
@@ -176,6 +177,11 @@ class CArray
|
|
|
176
177
|
# nothing: `nil`, or `UNDEF` in that cell of the result. The same
|
|
177
178
|
# holds for {#bsearch} and {#search_nearest}.
|
|
178
179
|
#
|
|
180
|
+
# `nil` is no value of an array that is not `:object`, so it finds
|
|
181
|
+
# nothing there; an `:object` array looks for it like any other value.
|
|
182
|
+
# {#bsearch} and {#search_nearest} need an order or a distance, which
|
|
183
|
+
# `nil` does not have, and raise.
|
|
184
|
+
#
|
|
179
185
|
# A time array (`CATime`, `CATimedelta`) takes a value of another
|
|
180
186
|
# unit, a `Time` or a String: when it is off the array's grid the
|
|
181
187
|
# two are compared in the finer unit, so it matches nothing (and
|
|
@@ -45,7 +45,8 @@ class CArray
|
|
|
45
45
|
# @param addrs [CArray, Array<Integer>]
|
|
46
46
|
# @param vals [CArray, Numeric]
|
|
47
47
|
# @return [self]
|
|
48
|
-
# @raise [IndexError] for out-of-range addresses
|
|
48
|
+
# @raise [IndexError] for out-of-range addresses, or when `addrs` is
|
|
49
|
+
# float, complex, object or boolean.
|
|
49
50
|
# @raise [CArray::DataTypeError] for non-numeric `data_type`.
|
|
50
51
|
def scatter_add!(addrs, vals); end
|
|
51
52
|
|
data/yard-stubs/carray_test.rb
CHANGED
|
@@ -13,6 +13,7 @@ class CArray
|
|
|
13
13
|
# @return [Boolean]
|
|
14
14
|
# @raise [ArgumentError] if the number of indices does not match
|
|
15
15
|
# `ndim`.
|
|
16
|
+
# @raise [TypeError] if an index is not an Integer.
|
|
16
17
|
def valid_index?(*idx); end
|
|
17
18
|
|
|
18
19
|
# @overload valid_addr?(addr)
|
|
@@ -21,11 +22,16 @@ class CArray
|
|
|
21
22
|
# @param addr [Integer] flat address into the contiguous element
|
|
22
23
|
# sequence.
|
|
23
24
|
# @return [Boolean]
|
|
25
|
+
# @raise [TypeError] if `addr` is not an Integer.
|
|
24
26
|
def valid_addr?(addr); end
|
|
25
27
|
|
|
26
28
|
# @overload same_shape?(other)
|
|
27
|
-
# Returns `true` if `other` has the same shape as `self`.
|
|
28
|
-
#
|
|
29
|
+
# Returns `true` if `other` has the same shape as `self`. Only the
|
|
30
|
+
# shape is compared, whatever the data types of the two. A scalar has
|
|
31
|
+
# the same shape as any array. An `other` that is not a CArray is read
|
|
32
|
+
# as an object array: a nested Array by its nesting, anything else as
|
|
33
|
+
# a scalar.
|
|
34
|
+
# @param other [CArray, Object]
|
|
29
35
|
# @return [Boolean]
|
|
30
36
|
def same_shape?(other); end
|
|
31
37
|
|
|
@@ -55,9 +61,10 @@ class CArray
|
|
|
55
61
|
# @overload eql?(other)
|
|
56
62
|
# Returns `true` under Hash-invariant semantics: `data_class`,
|
|
57
63
|
# `data_type`, shape, and mask state must all match, and elements
|
|
58
|
-
# are compared bitwise (for numeric types) or
|
|
59
|
-
#
|
|
60
|
-
# `eql
|
|
64
|
+
# are compared bitwise (for numeric types) or, for `:object` arrays, via
|
|
65
|
+
# `Object#eql?` with an object equal to itself first, as in
|
|
66
|
+
# `Array#eql?`. In a numeric array -0.0 and 0.0 differ and two NaNs
|
|
67
|
+
# are `eql?` only with the same bits.
|
|
61
68
|
# Two Faces are `eql?` only when they are of the same class, share
|
|
62
69
|
# their state (a time array's unit, a categorical's labels) and hold
|
|
63
70
|
# the same storage.
|
|
@@ -72,7 +79,13 @@ class CArray
|
|
|
72
79
|
# `ndim`, `bytes`, `elements`, shape, scalar-ness, and mask
|
|
73
80
|
# presence; for unmasked arrays, samples the leading 64 bytes of
|
|
74
81
|
# data. Masked arrays skip the data sample.
|
|
82
|
+
#
|
|
83
|
+
# An `:object` array samples the `#hash` of its cells, so an array in
|
|
84
|
+
# a cell is hashed in turn. {#==}, {#eql?} and `Marshal.dump` walk into
|
|
85
|
+
# cells the same way, and all of them refuse arrays nested more than
|
|
86
|
+
# 256 levels deep.
|
|
75
87
|
# @return [Integer]
|
|
88
|
+
# @raise [ArgumentError] when object cells nest more than 256 levels.
|
|
76
89
|
def hash; end
|
|
77
90
|
|
|
78
91
|
# @!endgroup
|