carray 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +5 -25
- data/CHANGELOG.md +16 -0
- data/LICENSE +1 -1
- data/NEWS.md +3 -0
- data/README.md +128 -44
- data/carray.gemspec +22 -24
- data/ext/ca_array_pool.c +91 -0
- data/ext/ca_axis_descriptor.h +186 -0
- data/ext/ca_axis_dispatch.c +924 -0
- data/ext/ca_axis_group.c +1208 -0
- data/ext/ca_bincmp_dispatch.c +76 -0
- data/ext/ca_bincmp_dispatch.h +85 -0
- data/ext/ca_binop_dispatch.c +125 -0
- data/ext/ca_binop_dispatch.h +159 -0
- data/ext/ca_categorical_iterator.c +1375 -0
- data/ext/ca_compare.c +94 -0
- data/ext/ca_compare.h +26 -0
- data/ext/ca_composite_dispatch.c +414 -0
- data/ext/ca_composite_dispatch.h +116 -0
- data/ext/ca_for_buffer.h +96 -0
- data/ext/ca_for_each_element.h +241 -0
- data/ext/ca_group_iter.c +304 -0
- data/ext/ca_iter_substrate.h +325 -0
- data/ext/ca_kernel_iterator.c +4321 -0
- data/ext/ca_kernel_iterator.h +2603 -0
- data/ext/ca_moncmp_dispatch.c +37 -0
- data/ext/ca_moncmp_dispatch.h +62 -0
- data/ext/ca_monop_dispatch.c +200 -0
- data/ext/ca_monop_dispatch.h +235 -0
- data/ext/ca_obj_array.c +355 -359
- data/ext/ca_obj_bincmp.c +809 -0
- data/ext/ca_obj_binop.c +892 -0
- data/ext/ca_obj_bitarray.c +369 -164
- data/ext/ca_obj_bitfield.c +294 -234
- data/ext/ca_obj_block.c +189 -711
- data/ext/ca_obj_byte_swap.c +766 -0
- data/ext/ca_obj_const_string.c +965 -0
- data/ext/ca_obj_face.c +670 -0
- data/ext/ca_obj_face.h +247 -0
- data/ext/ca_obj_fake.c +228 -100
- data/ext/ca_obj_farray.c +54 -441
- data/ext/ca_obj_field.c +82 -529
- data/ext/ca_obj_fixlen_string.c +306 -0
- data/ext/ca_obj_grid.c +858 -440
- data/ext/ca_obj_meld.c +1034 -0
- data/ext/ca_obj_moncmp.c +569 -0
- data/ext/ca_obj_monop.c +1111 -0
- data/ext/ca_obj_object.c +774 -298
- data/ext/ca_obj_record.c +468 -0
- data/ext/ca_obj_reduce.c +97 -82
- data/ext/ca_obj_refer.c +569 -459
- data/ext/ca_obj_remap.c +475 -0
- data/ext/ca_obj_repeat.c +92 -477
- data/ext/ca_obj_roll.c +616 -0
- data/ext/ca_obj_select.c +344 -296
- data/ext/ca_obj_select_axis.c +1296 -0
- data/ext/ca_obj_shift.c +230 -792
- data/ext/ca_obj_source.c +78 -0
- data/ext/ca_obj_stack.c +1173 -0
- data/ext/ca_obj_stride.c +2501 -0
- data/ext/ca_obj_string.c +268 -0
- data/ext/ca_obj_tile.c +614 -0
- data/ext/ca_obj_time.c +546 -0
- data/ext/ca_obj_timedelta.c +435 -0
- data/ext/ca_obj_transpose.c +62 -516
- data/ext/ca_obj_triop.c +746 -0
- data/ext/ca_obj_unbound_repeat.c +208 -241
- data/ext/ca_obj_window.c +1131 -563
- data/ext/ca_op_byte_swap.c +175 -0
- data/ext/ca_op_ipower.c +319 -0
- data/ext/ca_op_powi.h +88 -0
- data/ext/ca_sort_kernels.h +132 -0
- data/ext/ca_sweep_engine.c +430 -0
- data/ext/ca_sweep_engine.h +157 -0
- data/ext/ca_transform_common.c +228 -0
- data/ext/ca_triop_dispatch.c +55 -0
- data/ext/ca_triop_dispatch.h +62 -0
- data/ext/carray.h +795 -402
- data/ext/carray_access.c +831 -711
- data/ext/carray_attribute.c +98 -330
- data/ext/carray_bincount.c +255 -0
- data/ext/carray_broadcast.c +283 -0
- data/ext/carray_call_cfunc.c +1360 -828
- data/ext/carray_call_cfunc.h +160 -0
- data/ext/carray_cast.c +1212 -301
- data/ext/carray_cast_func.rb +81 -40
- data/ext/carray_class.c +53 -63
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +350 -346
- data/ext/carray_copy.c +156 -268
- data/ext/carray_core.c +1342 -199
- data/ext/carray_count.c +312 -0
- data/ext/carray_data_type.c +43 -19
- data/ext/carray_element.c +585 -213
- data/ext/carray_factorize.c +2542 -0
- data/ext/carray_generate.c +230 -559
- data/ext/carray_histogram.c +490 -0
- data/ext/carray_hold.c +228 -0
- data/ext/carray_index_classifier.c +1035 -0
- data/ext/carray_index_classifier.h +27 -0
- data/ext/carray_internal.h +120 -0
- data/ext/carray_kernels_bincmp.c +4445 -0
- data/ext/carray_kernels_binop.c +10979 -0
- data/ext/carray_kernels_init.c +36 -0
- data/ext/carray_kernels_map.c +3466 -0
- data/ext/carray_kernels_moncmp.c +2096 -0
- data/ext/carray_kernels_monop.c +18312 -0
- data/ext/carray_kernels_reduce_aggregate.c +25836 -0
- data/ext/carray_kernels_reduce_boolean.c +329 -0
- data/ext/carray_kernels_reduce_cumulative.c +14592 -0
- data/ext/carray_kernels_reduce_extreme.c +16947 -0
- data/ext/carray_kernels_reduce_variance.c +3909 -0
- data/ext/carray_kernels_scan.c +3692 -0
- data/ext/carray_kernels_search.c +32137 -0
- data/ext/carray_kernels_sort.c +10625 -0
- data/ext/carray_kernels_triop.c +1391 -0
- data/ext/carray_lazy.c +567 -0
- data/ext/carray_loop.c +88 -200
- data/ext/carray_mask.c +848 -154
- data/ext/carray_math_kernel.h +120 -0
- data/ext/carray_mathfunc.c +10 -241
- data/ext/carray_median_percentile.c +1257 -0
- data/ext/carray_memory_view.c +1625 -0
- data/ext/carray_operator.c +1526 -318
- data/ext/carray_order.c +664 -1394
- data/ext/carray_partition.c +416 -0
- data/ext/carray_random.c +518 -0
- data/ext/carray_scatter.c +357 -0
- data/ext/carray_slab.c +1219 -0
- data/ext/carray_slab.h +84 -0
- data/ext/carray_sort.c +829 -0
- data/ext/carray_sort_kernel.c +620 -0
- data/ext/carray_struct.c +695 -0
- data/ext/carray_test.c +343 -229
- data/ext/carray_undef.c +34 -17
- data/ext/carray_utils.c +175 -74
- data/ext/extconf.rb +216 -55
- data/ext/mk_call_cfunc.rb +480 -0
- data/ext/mkkernel.rb +8842 -0
- data/ext/ruby_carray.c +202 -101
- data/ext/version.h +4 -14
- data/ext/version.rb +5 -13
- data/lib/carray/arrow_tensor.rb +401 -0
- data/lib/carray/attribute.rb +166 -0
- data/lib/carray/autoload_carray.rb +220 -0
- data/lib/carray/autoload_method_extension.rb +44 -0
- data/lib/carray/axis_group.rb +711 -0
- data/lib/carray/basics.rb +481 -0
- data/lib/carray/bincount_nd.rb +358 -0
- data/lib/carray/block_iterator.rb +604 -0
- data/lib/carray/boolean_reduce.rb +109 -0
- data/lib/carray/categorical.rb +561 -0
- data/lib/carray/categorical_iterator.rb +1062 -0
- data/lib/carray/complex.rb +150 -0
- data/lib/carray/conditional.rb +216 -0
- data/lib/carray/const_string.rb +228 -0
- data/lib/carray/construct.rb +139 -328
- data/lib/carray/core_extensions.rb +240 -0
- data/lib/carray/data_type_extension.rb +233 -0
- data/lib/carray/fixlen_string.rb +95 -0
- data/lib/carray/frame/concat.rb +132 -0
- data/lib/carray/frame/convert.rb +95 -0
- data/lib/carray/frame/csv_parser.rb +211 -0
- data/lib/carray/frame/frame.rb +649 -0
- data/lib/carray/frame/group.rb +186 -0
- data/lib/carray/frame/io.rb +164 -0
- data/lib/carray/frame/join.rb +248 -0
- data/lib/carray/frame/records.rb +99 -0
- data/lib/carray/frame/sort.rb +113 -0
- data/lib/carray/frame/verbs.rb +299 -0
- data/lib/carray/frame.rb +16 -0
- data/lib/carray/histogram.rb +512 -0
- data/lib/carray/inspect.rb +37 -20
- data/lib/carray/iterator.rb +57 -349
- data/lib/carray/lazy.rb +889 -0
- data/lib/carray/mask_gap_fill.rb +200 -0
- data/lib/carray/math.rb +78 -342
- data/lib/carray/meld_reduce.rb +289 -0
- data/lib/carray/methods/align_addr.rb +116 -0
- data/lib/carray/methods/bin.rb +128 -0
- data/lib/carray/methods/bincount.rb +87 -0
- data/lib/carray/methods/bit_string.rb +92 -0
- data/lib/carray/methods/broadcast.rb +63 -0
- data/lib/carray/methods/choose.rb +39 -0
- data/lib/carray/methods/composition.rb +280 -0
- data/lib/carray/methods/gather_nd.rb +206 -0
- data/lib/carray/methods/index.rb +39 -0
- data/lib/carray/methods/insert_block.rb +99 -0
- data/lib/carray/methods/is_in.rb +141 -0
- data/lib/carray/methods/join.rb +90 -0
- data/lib/carray/methods/locate_addr.rb +47 -0
- data/lib/carray/methods/mask_duplicates.rb +41 -0
- data/lib/carray/methods/meshgrid.rb +91 -0
- data/lib/carray/methods/mode.rb +126 -0
- data/lib/carray/methods/nunique.rb +46 -0
- data/lib/carray/methods/resize.rb +56 -0
- data/lib/carray/methods/snap.rb +156 -0
- data/lib/carray/methods/string_format.rb +57 -0
- data/lib/carray/methods/unique.rb +47 -0
- data/lib/carray/methods/value_counts.rb +71 -0
- data/lib/carray/mkmf.rb +124 -101
- data/lib/carray/runtime.rb +108 -0
- data/lib/carray/serialize.rb +478 -167
- data/lib/carray/slab_iterator.rb +292 -0
- data/lib/carray/stack.rb +291 -0
- data/lib/carray/string.rb +56 -180
- data/lib/carray/string_operation_extension.rb +289 -0
- data/lib/carray/struct.rb +335 -323
- data/lib/carray/struct_builder.rb +697 -0
- data/lib/carray/table.rb +41 -2
- data/lib/carray/time.rb +2255 -38
- data/lib/carray/window_iterator.rb +655 -0
- data/lib/carray.rb +55 -57
- metadata +163 -130
- data/Rakefile +0 -51
- data/TODO.md +0 -18
- data/ext/ca_iter_block.c +0 -257
- data/ext/ca_iter_dimension.c +0 -299
- data/ext/ca_iter_window.c +0 -214
- data/ext/ca_obj_mapping.c +0 -644
- data/ext/carray_iterator.c +0 -641
- data/ext/carray_math.rb +0 -850
- data/ext/carray_numeric.c +0 -259
- data/ext/carray_sort_addr.c +0 -254
- data/ext/carray_stat.c +0 -2100
- data/ext/carray_stat_proc.rb +0 -1999
- data/ext/mkmath.rb +0 -741
- data/ext/ruby_ccomplex.c +0 -509
- data/ext/ruby_float_func.c +0 -86
- data/lib/carray/array.rb +0 -8
- data/lib/carray/autoload/autoload_base.rb +0 -19
- data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
- data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
- data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
- data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
- data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
- data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
- data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
- data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
- data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
- data/lib/carray/autoload/autoload_gem_random.rb +0 -8
- data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
- data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
- data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
- data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
- data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
- data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
- data/lib/carray/autoload/autoload_object_link.rb +0 -1
- data/lib/carray/autoload/autoload_object_pack.rb +0 -2
- data/lib/carray/autoload.rb +0 -141
- data/lib/carray/basic.rb +0 -191
- data/lib/carray/broadcast.rb +0 -101
- data/lib/carray/compose.rb +0 -315
- data/lib/carray/convert.rb +0 -115
- data/lib/carray/info.rb +0 -110
- data/lib/carray/io/imagemagick.rb +0 -235
- data/lib/carray/mask.rb +0 -102
- data/lib/carray/math/histogram.rb +0 -177
- data/lib/carray/math/recurrence.rb +0 -93
- data/lib/carray/object/ca_obj_iterator.rb +0 -50
- data/lib/carray/object/ca_obj_link.rb +0 -50
- data/lib/carray/object/ca_obj_pack.rb +0 -99
- data/lib/carray/obsolete.rb +0 -256
- data/lib/carray/ordering.rb +0 -181
- data/lib/carray/testing.rb +0 -51
- data/lib/carray/transform.rb +0 -109
- data/misc/Methods.ja.md +0 -182
- data/misc/NOTE +0 -51
- data/spec/Classes/CABitfield_spec.rb +0 -58
- data/spec/Classes/CABlockIterator_spec.rb +0 -114
- data/spec/Classes/CABlock_spec.rb +0 -205
- data/spec/Classes/CAField_spec.rb +0 -39
- data/spec/Classes/CAGrid_spec.rb +0 -75
- data/spec/Classes/CAMap_spec.rb +0 -0
- data/spec/Classes/CAMapping_spec.rb +0 -105
- data/spec/Classes/CAObject_attribute_spec.rb +0 -33
- data/spec/Classes/CAObject_spec.rb +0 -33
- data/spec/Classes/CARefer_spec.rb +0 -93
- data/spec/Classes/CARepeat_spec.rb +0 -65
- data/spec/Classes/CASelect_spec.rb +0 -22
- data/spec/Classes/CAShift_spec.rb +0 -16
- data/spec/Classes/CAStruct_spec.rb +0 -71
- data/spec/Classes/CATranspose_spec.rb +0 -60
- data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
- data/spec/Classes/CAWindow_spec.rb +0 -54
- data/spec/Classes/CAWrap_spec.rb +0 -8
- data/spec/Classes/CArray_spec.rb +0 -184
- data/spec/Classes/CScalar_spec.rb +0 -55
- data/spec/Classes/ex1.rb +0 -46
- data/spec/Features/feature_130_spec.rb +0 -19
- data/spec/Features/feature_attributes_spec.rb +0 -280
- data/spec/Features/feature_boolean_spec.rb +0 -98
- data/spec/Features/feature_broadcast.rb +0 -116
- data/spec/Features/feature_cast_function.rb +0 -19
- data/spec/Features/feature_cast_spec.rb +0 -33
- data/spec/Features/feature_class_spec.rb +0 -84
- data/spec/Features/feature_complex_spec.rb +0 -42
- data/spec/Features/feature_composite_spec.rb +0 -124
- data/spec/Features/feature_convert_spec.rb +0 -46
- data/spec/Features/feature_copy_spec.rb +0 -123
- data/spec/Features/feature_creation_spec.rb +0 -84
- data/spec/Features/feature_element_spec.rb +0 -144
- data/spec/Features/feature_extream_spec.rb +0 -54
- data/spec/Features/feature_generate_spec.rb +0 -74
- data/spec/Features/feature_index_spec.rb +0 -69
- data/spec/Features/feature_mask_spec.rb +0 -580
- data/spec/Features/feature_math_spec.rb +0 -97
- data/spec/Features/feature_order_spec.rb +0 -146
- data/spec/Features/feature_ref_store_spec.rb +0 -209
- data/spec/Features/feature_serialization_spec.rb +0 -125
- data/spec/Features/feature_stat_spec.rb +0 -397
- data/spec/Features/feature_virtual_spec.rb +0 -48
- data/spec/Features/method_eq_spec.rb +0 -81
- data/spec/Features/method_is_nan_spec.rb +0 -12
- data/spec/Features/method_map_spec.rb +0 -54
- data/spec/Features/method_max_with.rb +0 -20
- data/spec/Features/method_min_with.rb +0 -19
- data/spec/Features/method_ne_spec.rb +0 -18
- data/spec/Features/method_project_spec.rb +0 -188
- data/spec/Features/method_ref_spec.rb +0 -27
- data/spec/Features/method_round_spec.rb +0 -11
- data/spec/Features/method_s_linspace_spec.rb +0 -48
- data/spec/Features/method_s_span_spec.rb +0 -14
- data/spec/Features/method_seq_spec.rb +0 -47
- data/spec/Features/method_sort_with.rb +0 -43
- data/spec/Features/method_sorted_with.rb +0 -29
- data/spec/Features/method_span_spec.rb +0 -42
- data/spec/Features/method_wrap_readonly_spec.rb +0 -43
- data/spec/UnitTest/test_CAVirtual.rb +0 -214
- data/spec/spec_all.rb +0 -10
- data/utils/ca_ase.rb +0 -21
- data/utils/ca_methods.rb +0 -15
- data/utils/cast_checker.rb +0 -30
- data/utils/convert_test.rb +0 -73
- data/utils/extract_yard.rb +0 -22
- data/utils/guess_shape.rb +0 -76
- data/utils/monkey_patch_methods.rb +0 -62
- data/utils/remove_resource_fork.sh +0 -5
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Mask gap-fill: the `method:` keyword on #unmask / #strip_mask.
|
|
2
|
+
#
|
|
3
|
+
# #unmask and #strip_mask clear a mask by *supplying values*. The value
|
|
4
|
+
# source is either a constant (the existing positional argument) or a
|
|
5
|
+
# scan-method derived from neighbouring valid cells:
|
|
6
|
+
#
|
|
7
|
+
# unmask(v) # in-place, constant fill (C primitive)
|
|
8
|
+
# strip_mask(v) # copy, constant fill (C primitive)
|
|
9
|
+
# unmask(method: :forward) # in-place, carry last valid value (hold)
|
|
10
|
+
# strip_mask(method: :backward)# copy, carry next valid value (hold)
|
|
11
|
+
# unmask(method: :linear) # in-place, linear-by-index interpolation
|
|
12
|
+
#
|
|
13
|
+
# The constant path stays positional; the method path is keyword-only
|
|
14
|
+
# (a positional Symbol is already a valid constant fill, e.g.
|
|
15
|
+
# `strip_mask(:na)`). Passing both raises ArgumentError.
|
|
16
|
+
#
|
|
17
|
+
# Design / rationale: devel/PROPOSAL_UNMASK_FILL_METHOD.md. The forward
|
|
18
|
+
# hold is the C primitive #__hold__; backward = flip -> forward -> flip,
|
|
19
|
+
# flatten = flatten -> hold -> reshape, and :linear composes
|
|
20
|
+
# linear_section / linear_fetch. User-facing YARD docs live in
|
|
21
|
+
# yard-stubs/carray_mask.rb.
|
|
22
|
+
#
|
|
23
|
+
# A Face (CATime, CATimedelta, a categorical) rides both paths through its
|
|
24
|
+
# storage: hold copies bytes, so it never invents a value and needs nothing
|
|
25
|
+
# from the Face; :linear goes through the Face's own linear_fetch, so the
|
|
26
|
+
# filled values land on the array's unit. In place, the write-back goes to
|
|
27
|
+
# the storage -- a bulk store into a Face's surface would try to cast the
|
|
28
|
+
# storage values to it (int64 ticks to fixlen, for a time array).
|
|
29
|
+
|
|
30
|
+
class CArray
|
|
31
|
+
|
|
32
|
+
# Preserve the C constant-fill primitives under private names so the
|
|
33
|
+
# Ruby wrappers can delegate the non-method path unchanged.
|
|
34
|
+
alias __unmask_const__ unmask
|
|
35
|
+
alias __strip_mask_const__ strip_mask
|
|
36
|
+
private :__unmask_const__, :__strip_mask_const__
|
|
37
|
+
|
|
38
|
+
# Sentinel for "no positional fill value given" (distinct from any real
|
|
39
|
+
# fill value, including nil / false / a Symbol).
|
|
40
|
+
MASK_FILL_UNSET = ::Object.new
|
|
41
|
+
private_constant :MASK_FILL_UNSET
|
|
42
|
+
|
|
43
|
+
def unmask (fill = MASK_FILL_UNSET, method: nil, axis: nil)
|
|
44
|
+
if method
|
|
45
|
+
unless fill.equal?(MASK_FILL_UNSET)
|
|
46
|
+
raise ArgumentError,
|
|
47
|
+
"unmask: pass either a constant fill value or method:, not both"
|
|
48
|
+
end
|
|
49
|
+
held = __gap_fill__(method, axis)
|
|
50
|
+
# Copy the filled values in place. A Face writes through its storage: a
|
|
51
|
+
# bulk store into its surface would try to cast the storage values to the
|
|
52
|
+
# surface type (int64 ticks to fixlen, for a time array).
|
|
53
|
+
if face?
|
|
54
|
+
parent.value[] = held.parent.value
|
|
55
|
+
else
|
|
56
|
+
value[] = held.value
|
|
57
|
+
end
|
|
58
|
+
if held.has_mask?
|
|
59
|
+
self.mask = held.mask # residual leading/trailing mask
|
|
60
|
+
else
|
|
61
|
+
__unmask_const__ # fully filled: drop the mask
|
|
62
|
+
end
|
|
63
|
+
return self
|
|
64
|
+
end
|
|
65
|
+
fill.equal?(MASK_FILL_UNSET) ? __unmask_const__ : __unmask_const__(fill)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def strip_mask (fill = MASK_FILL_UNSET, method: nil, axis: nil)
|
|
69
|
+
if method
|
|
70
|
+
unless fill.equal?(MASK_FILL_UNSET)
|
|
71
|
+
raise ArgumentError,
|
|
72
|
+
"strip_mask: pass either a constant fill value or method:, not both"
|
|
73
|
+
end
|
|
74
|
+
return __gap_fill__(method, axis)
|
|
75
|
+
end
|
|
76
|
+
if fill.equal?(MASK_FILL_UNSET)
|
|
77
|
+
raise ArgumentError, "strip_mask: a fill value is required (or method:)"
|
|
78
|
+
end
|
|
79
|
+
__strip_mask_const__(fill)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
# Dispatch a method-fill to a fresh array. Residual (leading/trailing)
|
|
85
|
+
# unfillable cells stay masked; a fully filled result carries no mask
|
|
86
|
+
# (hold allocates the output mask only when a leading run goes UNDEF;
|
|
87
|
+
# :linear masks only the exterior via mask_invalid).
|
|
88
|
+
def __gap_fill__ (method, axis)
|
|
89
|
+
case method
|
|
90
|
+
when :forward, :ffill
|
|
91
|
+
__hold_axis__(axis, false)
|
|
92
|
+
when :backward, :bfill
|
|
93
|
+
__hold_axis__(axis, true)
|
|
94
|
+
when :linear
|
|
95
|
+
__gap_fill_linear__(axis)
|
|
96
|
+
else
|
|
97
|
+
raise ArgumentError,
|
|
98
|
+
"unmask/strip_mask: unknown method: #{method.inspect} " \
|
|
99
|
+
"(:forward | :backward | :linear)"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Forward (backward = false) or backward (true) hold along `axis`
|
|
104
|
+
# (axis nil = flatten). Backward reuses the forward primitive on the
|
|
105
|
+
# reversed view; flatten flattens, holds axis 0, reshapes back.
|
|
106
|
+
def __hold_axis__ (axis, backward)
|
|
107
|
+
if axis.nil?
|
|
108
|
+
flat = flatten
|
|
109
|
+
flat = flat.reverse if backward
|
|
110
|
+
held = flat.send(:__hold__, 0)
|
|
111
|
+
held = held.reverse if backward
|
|
112
|
+
held.reshape(*shape)
|
|
113
|
+
else
|
|
114
|
+
ax = axis < 0 ? axis + ndim : axis
|
|
115
|
+
if backward
|
|
116
|
+
flip(ax).send(:__hold__, ax).flip(ax)
|
|
117
|
+
else
|
|
118
|
+
send(:__hold__, ax)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Linear-by-index gap fill: interpolate each masked cell from the two
|
|
124
|
+
# bracketing valid cells, x = cell index along the axis. Cells outside the
|
|
125
|
+
# valid range (leading/trailing) stay masked. A Face goes through its own
|
|
126
|
+
# linear_fetch, which keeps its unit and rounds to its grid; whether that
|
|
127
|
+
# means anything is the Face's call (an ORDERABLE numeric one answers, the
|
|
128
|
+
# rest raise from there), so this gate only asks that it be one.
|
|
129
|
+
def __gap_fill_linear__ (axis)
|
|
130
|
+
unless numeric? || face?
|
|
131
|
+
raise ArgumentError,
|
|
132
|
+
"unmask/strip_mask(method: :linear): numeric or time data_type " \
|
|
133
|
+
"required (got #{data_type_name})"
|
|
134
|
+
end
|
|
135
|
+
if axis.nil?
|
|
136
|
+
return __linear_fiber__(flatten).reshape(*shape)
|
|
137
|
+
end
|
|
138
|
+
ax = axis < 0 ? axis + ndim : axis
|
|
139
|
+
if ax < 0 || ax >= ndim
|
|
140
|
+
raise ArgumentError, "axis #{axis} out of range for ndim #{ndim}"
|
|
141
|
+
end
|
|
142
|
+
# A Face assembles in storage space -- its linear_fetch has already rounded
|
|
143
|
+
# to the grid, so there is nothing left to hold in float64. A numeric
|
|
144
|
+
# array assembles in float64 and casts back once at the end.
|
|
145
|
+
out = face? ? template : float64.copy
|
|
146
|
+
sink = face? ? out.parent : out
|
|
147
|
+
__each_fiber_key__(ax) do |key|
|
|
148
|
+
fiber = __linear_fiber__(self[*key])
|
|
149
|
+
sink[*key] = face? ? fiber.parent : fiber
|
|
150
|
+
end
|
|
151
|
+
face? ? out : out.to_type(data_type)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# 1-D linear-by-index fill of a single (possibly masked) fiber. Present
|
|
155
|
+
# cells reproduce exactly; interior masked cells interpolate; exterior
|
|
156
|
+
# masked cells become UNDEF (linear_section returns NaN out of range,
|
|
157
|
+
# mask_invalid marks it). Returns the same kind as `vec`: a Face fiber
|
|
158
|
+
# comes back as that Face, on its own unit.
|
|
159
|
+
def __linear_fiber__ (vec)
|
|
160
|
+
n = vec.elements
|
|
161
|
+
present = vec.is_not_masked
|
|
162
|
+
# Fewer than two valid points -> nothing to interpolate between; leave
|
|
163
|
+
# every masked cell masked (the copy carries vec's mask).
|
|
164
|
+
if present.count(true) < 2
|
|
165
|
+
return vec.face? ? vec.copy : vec.float64.copy
|
|
166
|
+
end
|
|
167
|
+
pos = CArray.float64(n) { |i| i.to_f }
|
|
168
|
+
addr = pos[present].linear_section(pos) # valid positions -> monotonic grid
|
|
169
|
+
if vec.face?
|
|
170
|
+
# The Face's linear_fetch already masks the exterior (out of range) and
|
|
171
|
+
# lands on its own grid, so it needs no cast and no mask_invalid.
|
|
172
|
+
return vec[present].linear_fetch(addr)
|
|
173
|
+
end
|
|
174
|
+
vval = vec.value.float64[present] # valid values
|
|
175
|
+
vval.linear_fetch(addr).to_type(vec.data_type).mask_invalid
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Yield an index key (Array with `nil` at `axis`, integers elsewhere)
|
|
179
|
+
# for every fiber along `axis`. `self[*key]` is that fiber as a masked
|
|
180
|
+
# 1-D view.
|
|
181
|
+
def __each_fiber_key__ (axis)
|
|
182
|
+
outer = shape
|
|
183
|
+
outer_dims = outer.each_index.reject { |k| k == axis }.map { |k| outer[k] }
|
|
184
|
+
idx = Array.new(outer_dims.size, 0)
|
|
185
|
+
total = outer_dims.inject(1, :*)
|
|
186
|
+
total.times do
|
|
187
|
+
key = idx.dup
|
|
188
|
+
key.insert(axis, nil)
|
|
189
|
+
yield key
|
|
190
|
+
(outer_dims.size - 1).downto(0) do |k|
|
|
191
|
+
idx[k] += 1
|
|
192
|
+
break if idx[k] < outer_dims[k]
|
|
193
|
+
idx[k] = 0
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
private :__hold_axis__, :__gap_fill_linear__, :__linear_fiber__,
|
|
198
|
+
:__each_fiber_key__
|
|
199
|
+
|
|
200
|
+
end
|
data/lib/carray/math.rb
CHANGED
|
@@ -1,169 +1,80 @@
|
|
|
1
|
-
# ----------------------------------------------------------------------------
|
|
2
|
-
#
|
|
3
|
-
# carray/math.rb
|
|
4
|
-
#
|
|
5
|
-
# This file is part of Ruby/CArray extension library.
|
|
6
|
-
#
|
|
7
|
-
# Copyright (C) 2005-2020 Hiroki Motoyoshi
|
|
8
|
-
#
|
|
9
|
-
# ----------------------------------------------------------------------------
|
|
10
|
-
|
|
11
|
-
class CArray
|
|
12
|
-
|
|
13
|
-
# complex number
|
|
14
|
-
|
|
15
|
-
# Return the real part of +self+.
|
|
16
|
-
# If +self+ is a complex array, the resulted array is CAMember object
|
|
17
|
-
# refers the appropriate part of +self+.
|
|
18
|
-
# Otherwise, the resulted array is CARefer object refers +self+.
|
|
19
|
-
# If you change the resulted array, the original array is also changed.
|
|
20
|
-
#
|
|
21
|
-
def real
|
|
22
|
-
if not @__real__
|
|
23
|
-
if complex?
|
|
24
|
-
@__real__ = case data_type
|
|
25
|
-
when CA_CMPLX64
|
|
26
|
-
field(0, CA_FLOAT32)
|
|
27
|
-
when CA_CMPLX128
|
|
28
|
-
field(0, CA_FLOAT64)
|
|
29
|
-
when CA_CMPLX128
|
|
30
|
-
field(0, CA_FLOAT128)
|
|
31
|
-
end
|
|
32
|
-
else
|
|
33
|
-
@__real__ = self[]
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
@__real__
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def real= (val)
|
|
40
|
-
real[] = val
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Return the imaginary part of +self+.
|
|
44
|
-
# If +self+ is a complex array, the resulted array is CAMember object
|
|
45
|
-
# refers the appropriate part of +self+. In this case,
|
|
46
|
-
# you change the resulted array, the original array is also changed.
|
|
47
|
-
#
|
|
48
|
-
# Otherwise, the resulted array is a dummy CArray object filled with 0.
|
|
49
|
-
# In this case, the change in the resulted array does not affect
|
|
50
|
-
# the original array. For this purpose, you should explicitly convert
|
|
51
|
-
# the array to complex array.
|
|
52
|
-
#
|
|
53
|
-
def imag
|
|
54
|
-
if not @__imag__
|
|
55
|
-
if complex?
|
|
56
|
-
@__imag__ = case data_type
|
|
57
|
-
when CA_CMPLX64
|
|
58
|
-
field(4, CA_FLOAT32)
|
|
59
|
-
when CA_CMPLX128
|
|
60
|
-
field(8, CA_FLOAT64)
|
|
61
|
-
when CA_CMPLX128
|
|
62
|
-
field(16, CA_FLOAT128)
|
|
63
|
-
end
|
|
64
|
-
else
|
|
65
|
-
@__imag__ = self.template { 0 }
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
return @__imag__
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def imag= (val)
|
|
72
|
-
if complex?
|
|
73
|
-
imag[] = val
|
|
74
|
-
else
|
|
75
|
-
raise "not a complex array"
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# comparison operators
|
|
80
|
-
|
|
81
|
-
def <=> (other)
|
|
82
|
-
lower = self < other
|
|
83
|
-
upper = self > other
|
|
84
|
-
out = CArray.new(CA_INT8, lower.dim)
|
|
85
|
-
out[lower] = -1
|
|
86
|
-
out[upper] = 1
|
|
87
|
-
return out
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
alias cmp <=>
|
|
91
|
-
|
|
92
|
-
def is_equiv (other, rtol)
|
|
93
|
-
exact_eq = self.eq(other)
|
|
94
|
-
relative_eq = ((self - other).abs/CAMath.max(self.abs, other.abs) <= rtol)
|
|
95
|
-
return (exact_eq).or(relative_eq)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def is_close (other, atol)
|
|
99
|
-
return ((self - other).abs <= atol)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def is_divisible (n)
|
|
103
|
-
unless integer?
|
|
104
|
-
raise "data type of reciever of CArray#divisible? should be integer."
|
|
105
|
-
end
|
|
106
|
-
return (self % n).eq(0)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def is_not_divisible (n)
|
|
110
|
-
unless integer?
|
|
111
|
-
raise "data type of reciever of CArray#divisible? should be integer."
|
|
112
|
-
end
|
|
113
|
-
return (self % n).ne(0)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def real?
|
|
117
|
-
if complex?
|
|
118
|
-
imag.all_equal?(0)
|
|
119
|
-
elsif numeric?
|
|
120
|
-
true
|
|
121
|
-
else
|
|
122
|
-
nil
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def is_real
|
|
127
|
-
if complex?
|
|
128
|
-
imag.eq(0)
|
|
129
|
-
elsif numeric?
|
|
130
|
-
self.true
|
|
131
|
-
else
|
|
132
|
-
nil
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def sign
|
|
137
|
-
out = self.zero
|
|
138
|
-
out[self.lt(0)] = -1
|
|
139
|
-
out[self.gt(0)] = 1
|
|
140
|
-
if float?
|
|
141
|
-
out[self.is_nan] = 0.0/0.0
|
|
142
|
-
end
|
|
143
|
-
return out
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def quo (other)
|
|
147
|
-
case
|
|
148
|
-
when integer?
|
|
149
|
-
return object.quo_i(other)
|
|
150
|
-
when object?
|
|
151
|
-
return quo_i(other)
|
|
152
|
-
else
|
|
153
|
-
return self/other
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
|
|
160
1
|
module CAMath
|
|
161
2
|
|
|
162
3
|
module_function
|
|
163
4
|
|
|
5
|
+
# Module-function front-ends for binop math methods registered on
|
|
6
|
+
# CArray by mkkernel. The first argument is auto-wrapped to CArray
|
|
7
|
+
# via `CArray.wrap_readonly`, so `CAMath.hypot(3, arr)` continues to
|
|
8
|
+
# work. Integer input is unsupported at the kernel layer -- the
|
|
9
|
+
# caller must cast to float64 explicitly (e.g.
|
|
10
|
+
# `arr.as_float64.hypot(...)`).
|
|
11
|
+
|
|
12
|
+
# @overload expm1(x)
|
|
13
|
+
# Returns `exp(x) - 1` element-wise as float64.
|
|
14
|
+
# @param x [CArray, Numeric] input value.
|
|
15
|
+
# @return [CArray]
|
|
16
|
+
def expm1(x); CArray.wrap_readonly(x, :float64).expm1; end
|
|
17
|
+
|
|
18
|
+
# @overload log1p(x)
|
|
19
|
+
# Returns `log(1 + x)` element-wise as float64.
|
|
20
|
+
# @param x [CArray, Numeric] input value.
|
|
21
|
+
# @return [CArray]
|
|
22
|
+
def log1p(x); CArray.wrap_readonly(x, :float64).log1p; end
|
|
23
|
+
|
|
24
|
+
# @overload atan2(y, x)
|
|
25
|
+
# Returns the element-wise arc tangent of `y / x` with quadrant
|
|
26
|
+
# selection.
|
|
27
|
+
# @param y [CArray, Numeric] numerator.
|
|
28
|
+
# @param x [CArray, Numeric] denominator.
|
|
29
|
+
# @return [CArray]
|
|
30
|
+
def atan2(y, x); CArray.wrap_readonly(y, :float64).atan2(x); end
|
|
31
|
+
|
|
32
|
+
# @overload hypot(x, y)
|
|
33
|
+
# Returns the element-wise Euclidean distance `sqrt(x^2 + y^2)`.
|
|
34
|
+
# @param x [CArray, Numeric] first leg.
|
|
35
|
+
# @param y [CArray, Numeric] second leg.
|
|
36
|
+
# @return [CArray]
|
|
37
|
+
def hypot(x, y); CArray.wrap_readonly(x, :float64).hypot(y); end
|
|
38
|
+
|
|
39
|
+
# @overload copysign(x, y)
|
|
40
|
+
# Returns `|x|` with the sign of `y`, element-wise.
|
|
41
|
+
# @param x [CArray, Numeric] magnitude source.
|
|
42
|
+
# @param y [CArray, Numeric] sign source.
|
|
43
|
+
# @return [CArray]
|
|
44
|
+
def copysign(x, y); CArray.wrap_readonly(x, :float64).copysign(y); end
|
|
45
|
+
|
|
46
|
+
# @overload logaddexp(x, y)
|
|
47
|
+
# Returns `log(exp(x) + exp(y))` computed to avoid overflow,
|
|
48
|
+
# element-wise.
|
|
49
|
+
# @param x [CArray, Numeric] first log-space value.
|
|
50
|
+
# @param y [CArray, Numeric] second log-space value.
|
|
51
|
+
# @return [CArray]
|
|
52
|
+
def logaddexp(x, y); CArray.wrap_readonly(x, :float64).logaddexp(y); end
|
|
53
|
+
|
|
54
|
+
# @overload nextafter(x, y)
|
|
55
|
+
# Returns the next representable float from `x` toward `y`,
|
|
56
|
+
# element-wise.
|
|
57
|
+
# @param x [CArray, Numeric] starting value.
|
|
58
|
+
# @param y [CArray, Numeric] direction target.
|
|
59
|
+
# @return [CArray]
|
|
60
|
+
def nextafter(x, y); CArray.wrap_readonly(x, :float64).nextafter(y); end
|
|
61
|
+
|
|
62
|
+
# @overload fmod(x, y)
|
|
63
|
+
# Returns the C-style `fmod(x, y)` element-wise (sign follows `x`).
|
|
64
|
+
# @param x [CArray, Numeric] dividend.
|
|
65
|
+
# @param y [CArray, Numeric] divisor.
|
|
66
|
+
# @return [CArray]
|
|
67
|
+
def fmod(x, y); CArray.wrap_readonly(x, :float64).fmod(y); end
|
|
68
|
+
|
|
69
|
+
# @overload min(*argv)
|
|
70
|
+
# Returns the element-wise minimum of the given CArray and other
|
|
71
|
+
# arguments. At least one argument must be a CArray.
|
|
72
|
+
# @param argv [Array<CArray, Numeric>] operands.
|
|
73
|
+
# @return [CArray] fresh CArray holding the running min.
|
|
74
|
+
# @raise [RuntimeError] when no CArray argument is present.
|
|
164
75
|
def min (*argv)
|
|
165
76
|
if ary = argv.find{|x| x.is_a?(CArray) }
|
|
166
|
-
out = ary.
|
|
77
|
+
out = ary.copy
|
|
167
78
|
argv.delete(ary)
|
|
168
79
|
argv.each do |x|
|
|
169
80
|
out.pmin!(x)
|
|
@@ -174,9 +85,15 @@ module CAMath
|
|
|
174
85
|
return out
|
|
175
86
|
end
|
|
176
87
|
|
|
88
|
+
# @overload max(*argv)
|
|
89
|
+
# Returns the element-wise maximum of the given CArray and other
|
|
90
|
+
# arguments. At least one argument must be a CArray.
|
|
91
|
+
# @param argv [Array<CArray, Numeric>] operands.
|
|
92
|
+
# @return [CArray] fresh CArray holding the running max.
|
|
93
|
+
# @raise [RuntimeError] when no CArray argument is present.
|
|
177
94
|
def max (*argv)
|
|
178
95
|
if ary = argv.find{|x| x.is_a?(CArray) }
|
|
179
|
-
out = ary.
|
|
96
|
+
out = ary.copy
|
|
180
97
|
argv.delete(ary)
|
|
181
98
|
argv.each do |x|
|
|
182
99
|
out.pmax!(x)
|
|
@@ -188,184 +105,3 @@ module CAMath
|
|
|
188
105
|
end
|
|
189
106
|
|
|
190
107
|
end
|
|
191
|
-
|
|
192
|
-
class CArray
|
|
193
|
-
|
|
194
|
-
#
|
|
195
|
-
# statistics
|
|
196
|
-
#
|
|
197
|
-
|
|
198
|
-
def random (*argv)
|
|
199
|
-
return template.random!(*argv)
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
def randomn!
|
|
203
|
-
if elements == 1
|
|
204
|
-
self[0] = CArray.new(data_type,[2]).randomn![0]
|
|
205
|
-
return self
|
|
206
|
-
end
|
|
207
|
-
x1 = CArray.new(data_type, [elements/2])
|
|
208
|
-
x2 = CArray.new(data_type, [elements/2])
|
|
209
|
-
fac = x1.random!.log!.mul!(-2.0).sqrt! ### fac = sqrt(-2*log(rnd()))
|
|
210
|
-
x2.random!.mul!(2.0*Math::PI) ### x2 = 2*PI*rnd()
|
|
211
|
-
x3 = x2.to_ca
|
|
212
|
-
self2 = reshape(2,elements/2)
|
|
213
|
-
self2[0,nil] = x2.cos!.mul!(fac) ### self[even] = fac*cos(x2)
|
|
214
|
-
self2[1,nil] = x3.sin!.mul!(fac) ### self[odd] = fac*sin(x2)
|
|
215
|
-
if elements % 2 == 1
|
|
216
|
-
self[[-1]].randomn!
|
|
217
|
-
end
|
|
218
|
-
return self
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def randomn
|
|
222
|
-
return template.randomn!
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def anomaly (*argv)
|
|
226
|
-
opt = argv.last.is_a?(Hash) ? argv.pop : {}
|
|
227
|
-
idxs = Array.new(self.ndim) { |i| argv.include?(i) ? :* : nil }
|
|
228
|
-
if mn = opt[:mean]
|
|
229
|
-
return self - mn[*idxs]
|
|
230
|
-
else
|
|
231
|
-
return self - self.mean(*argv)[*idxs]
|
|
232
|
-
end
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
alias anom anomaly
|
|
236
|
-
|
|
237
|
-
def median (*argv)
|
|
238
|
-
opt = argv.last.is_a?(Hash) ? argv.pop : {}
|
|
239
|
-
min_count = opt[:mask_limit]
|
|
240
|
-
if min_count and min_count < 0
|
|
241
|
-
min_count += elements
|
|
242
|
-
end
|
|
243
|
-
fill_value = opt[:fill_value]
|
|
244
|
-
if argv.empty?
|
|
245
|
-
if has_mask?
|
|
246
|
-
if min_count and count_masked() > min_count
|
|
247
|
-
return fill_value || UNDEF
|
|
248
|
-
end
|
|
249
|
-
c = self[:is_not_masked].sort
|
|
250
|
-
n = self.count_not_masked
|
|
251
|
-
else
|
|
252
|
-
c = self.sort
|
|
253
|
-
n = c.elements
|
|
254
|
-
end
|
|
255
|
-
if n == 0
|
|
256
|
-
return fill_value || UNDEF
|
|
257
|
-
else
|
|
258
|
-
return (c[(n-1)/2] + c[n/2])/2.0
|
|
259
|
-
end
|
|
260
|
-
else
|
|
261
|
-
raise "CArray#median is not implemented for multiple ndims"
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
def percentile (*argv)
|
|
267
|
-
opt = argv.last.is_a?(Hash) ? argv.pop : {}
|
|
268
|
-
pers = argv
|
|
269
|
-
min_count = opt[:mask_limit]
|
|
270
|
-
if min_count and min_count < 0
|
|
271
|
-
min_count += elements
|
|
272
|
-
end
|
|
273
|
-
fill_value = opt[:fill_value]
|
|
274
|
-
if has_mask?
|
|
275
|
-
if min_count and count_masked() > min_count
|
|
276
|
-
return argv.map { fill_value || UNDEF }
|
|
277
|
-
end
|
|
278
|
-
ca = self[:is_not_masked].sort
|
|
279
|
-
n = self.count_not_masked
|
|
280
|
-
else
|
|
281
|
-
ca = self.sort
|
|
282
|
-
n = ca.elements
|
|
283
|
-
end
|
|
284
|
-
out = []
|
|
285
|
-
begin
|
|
286
|
-
pers.each do |per|
|
|
287
|
-
if per == 100
|
|
288
|
-
out << ca[n-1]
|
|
289
|
-
elsif per >= 0 and per < 100
|
|
290
|
-
if n > 1
|
|
291
|
-
f = (n-1)*per/100.0
|
|
292
|
-
k = f.floor
|
|
293
|
-
r = f - k
|
|
294
|
-
out << (1-r)*ca[k] + r*ca[k+1]
|
|
295
|
-
else
|
|
296
|
-
out << ca[0]
|
|
297
|
-
end
|
|
298
|
-
else
|
|
299
|
-
out << CA_NAN
|
|
300
|
-
end
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
return out
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
def quantile
|
|
307
|
-
return percentile(0, 25, 50, 75, 100)
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
def covariancep (y, min_count = nil, fill_value = nil)
|
|
311
|
-
x = self.double
|
|
312
|
-
y = y.double
|
|
313
|
-
if x.has_mask? or y.has_mask?
|
|
314
|
-
x.inherit_mask(y)
|
|
315
|
-
y.inherit_mask(x)
|
|
316
|
-
count = x.count_not_masked
|
|
317
|
-
xm = x.mean(:min_count => min_count)
|
|
318
|
-
ym = y.mean(:min_count => min_count)
|
|
319
|
-
if ( xm == UNDEF or ym == UNDEF )
|
|
320
|
-
return fill_value || UNDEF
|
|
321
|
-
else
|
|
322
|
-
return (x-xm).wsum(y-ym)/count
|
|
323
|
-
end
|
|
324
|
-
else
|
|
325
|
-
return (x-x.mean).wsum(y-y.mean)/elements
|
|
326
|
-
end
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
def covariance (y, min_count = nil, fill_value = nil)
|
|
330
|
-
x = self.double
|
|
331
|
-
y = y.double
|
|
332
|
-
if x.has_mask? or y.has_mask?
|
|
333
|
-
x.inherit_mask(y)
|
|
334
|
-
y.inherit_mask(x)
|
|
335
|
-
count = x.count_not_masked
|
|
336
|
-
xm = x.mean(:min_count=>min_count)
|
|
337
|
-
ym = y.mean(:min_count=>min_count)
|
|
338
|
-
if ( xm == UNDEF or ym == UNDEF )
|
|
339
|
-
return fill_value || UNDEF
|
|
340
|
-
else
|
|
341
|
-
return (x-xm).wsum(y-ym)/(count-1)
|
|
342
|
-
end
|
|
343
|
-
else
|
|
344
|
-
return (x-x.mean).wsum(y-y.mean)/(elements-1)
|
|
345
|
-
end
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
def correlation (y, min_count = nil, fill_value = nil)
|
|
349
|
-
x = self.double
|
|
350
|
-
y = y.double
|
|
351
|
-
if x.has_mask? or y.has_mask?
|
|
352
|
-
x.inherit_mask(y)
|
|
353
|
-
y.inherit_mask(x)
|
|
354
|
-
xm = x.mean(:min_count=>min_count)
|
|
355
|
-
ym = y.mean(:min_count=>min_count)
|
|
356
|
-
if ( xm == UNDEF or ym == UNDEF )
|
|
357
|
-
return fill_value || UNDEF
|
|
358
|
-
else
|
|
359
|
-
xd, yd = x-xm, y-ym
|
|
360
|
-
return xd.wsum(yd)/(xd.wsum(xd)*yd.wsum(yd)).sqrt
|
|
361
|
-
end
|
|
362
|
-
else
|
|
363
|
-
xd, yd = x-x.mean, y-y.mean
|
|
364
|
-
return xd.wsum(yd)/(xd.wsum(xd)*yd.wsum(yd)).sqrt
|
|
365
|
-
end
|
|
366
|
-
end
|
|
367
|
-
|
|
368
|
-
end
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|