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
data/ext/carray_random.c
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
Random-number fill and shuffle: random / randomn / shuffle (+ bang
|
|
4
|
+
variants). Ruby-facing docs live in yard-stubs/carray_random.rb.
|
|
5
|
+
|
|
6
|
+
Backend: Ruby's built-in Random (MT19937) via public C API. When
|
|
7
|
+
the `rng:` kwarg is nil, uses the per-ractor default RNG
|
|
8
|
+
(rb_genrand_*); otherwise uses the given Random instance
|
|
9
|
+
(rb_random_*).
|
|
10
|
+
|
|
11
|
+
Dispatch:
|
|
12
|
+
random! -> uniform fill (per-dtype branch below)
|
|
13
|
+
randomn! -> standard normal via Box-Muller (float / complex only)
|
|
14
|
+
shuffle! -> Fisher-Yates over the flat buffer, or per-slice
|
|
15
|
+
when axis: is given (byte-chunk swap)
|
|
16
|
+
non-bang -> template / copy then delegate to the bang form
|
|
17
|
+
|
|
18
|
+
---------------------------------------------------------------------------- */
|
|
19
|
+
|
|
20
|
+
#include "carray.h"
|
|
21
|
+
#include <math.h>
|
|
22
|
+
#include <string.h>
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
static inline double
|
|
26
|
+
ca_random_real(VALUE rng)
|
|
27
|
+
{
|
|
28
|
+
if (NIL_P(rng))
|
|
29
|
+
return rb_genrand_real();
|
|
30
|
+
else
|
|
31
|
+
return rb_random_real(rng);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static inline unsigned long
|
|
35
|
+
ca_random_ulong_limited(VALUE rng, unsigned long limit)
|
|
36
|
+
{
|
|
37
|
+
if (NIL_P(rng))
|
|
38
|
+
return rb_genrand_ulong_limited(limit);
|
|
39
|
+
else
|
|
40
|
+
return rb_random_ulong_limited(rng, limit);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* ---- random! ----------------------------------------------------------- */
|
|
44
|
+
|
|
45
|
+
/* CArray#random!([low,] [high], rng:) — fill self with uniform random
|
|
46
|
+
* numbers in-place, returning self. Range surface mirrors Numo/NumPy
|
|
47
|
+
* (half-open [low, high) as the default) plus Ruby idiom (`..` closed,
|
|
48
|
+
* `...` half-open):
|
|
49
|
+
*
|
|
50
|
+
* random! float [0.0, 1.0); integer -> ArgumentError
|
|
51
|
+
* random!(high) [0, high) (Ruby rand shorthand)
|
|
52
|
+
* random!(low, high) [low, high) (Numo positional)
|
|
53
|
+
* random!(a..b) [a, b] closed (integer: b included)
|
|
54
|
+
* random!(a...b) [a, b) half-open
|
|
55
|
+
* random!(..., rng: r) any of the above with a custom Random source
|
|
56
|
+
*
|
|
57
|
+
* For float, `..` and `...` return the same distribution (endpoint
|
|
58
|
+
* probability ~2^-53); the closed form is honored syntactically but not
|
|
59
|
+
* enforced at the mantissa level, matching NumPy/SciPy convention.
|
|
60
|
+
* Boolean fills 0/1 with 50% probability each and ignores the range
|
|
61
|
+
* argument. Rejects CA_OBJECT / CA_FIXLEN. */
|
|
62
|
+
static VALUE
|
|
63
|
+
rb_ca_random_bang(int argc, VALUE *argv, VALUE self)
|
|
64
|
+
{
|
|
65
|
+
CArray *ca;
|
|
66
|
+
VALUE arg1 = Qnil, arg2 = Qnil, opts = Qnil;
|
|
67
|
+
VALUE low_val = Qnil, high_val = Qnil;
|
|
68
|
+
int is_default = 1;
|
|
69
|
+
int high_is_closed = 0;
|
|
70
|
+
double low_dbl = 0.0, high_dbl = 0.0;
|
|
71
|
+
long low_long = 0, high_long = 0;
|
|
72
|
+
unsigned long limit = 0;
|
|
73
|
+
ca_size_t i, n;
|
|
74
|
+
VALUE rng = Qnil;
|
|
75
|
+
|
|
76
|
+
rb_scan_args(argc, argv, "02:", &arg1, &arg2, &opts);
|
|
77
|
+
rb_scan_options(opts, "rng", &rng);
|
|
78
|
+
|
|
79
|
+
/* Parse positional args into (low_val, high_val) + high_is_closed. */
|
|
80
|
+
if (rb_obj_is_kind_of(arg1, rb_cRange)) {
|
|
81
|
+
if (!NIL_P(arg2)) {
|
|
82
|
+
rb_raise(rb_eArgError,
|
|
83
|
+
"random: cannot combine a Range with a second positional arg");
|
|
84
|
+
}
|
|
85
|
+
low_val = rb_funcall(arg1, rb_intern("begin"), 0);
|
|
86
|
+
high_val = rb_funcall(arg1, rb_intern("end"), 0);
|
|
87
|
+
if (NIL_P(low_val) || NIL_P(high_val)) {
|
|
88
|
+
rb_raise(rb_eArgError,
|
|
89
|
+
"random: Range must have finite begin and end");
|
|
90
|
+
}
|
|
91
|
+
high_is_closed = ! RTEST(rb_funcall(arg1, rb_intern("exclude_end?"), 0));
|
|
92
|
+
is_default = 0;
|
|
93
|
+
} else if (!NIL_P(arg1) && !NIL_P(arg2)) {
|
|
94
|
+
low_val = arg1;
|
|
95
|
+
high_val = arg2;
|
|
96
|
+
is_default = 0;
|
|
97
|
+
} else if (!NIL_P(arg1)) {
|
|
98
|
+
low_val = INT2FIX(0);
|
|
99
|
+
high_val = arg1;
|
|
100
|
+
is_default = 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
rb_ca_modify(self);
|
|
104
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
105
|
+
|
|
106
|
+
if (ca->data_type == CA_OBJECT || ca->data_type == CA_FIXLEN) {
|
|
107
|
+
rb_raise(rb_eCADataTypeError,
|
|
108
|
+
"random! is not supported for object/fixlen arrays");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* Materialize (low, high) as the correct scalar type and validate.
|
|
112
|
+
* For integer dtypes, `..` closed adds 1 to high (turns into half-open
|
|
113
|
+
* for the sampler); for float dtypes, closed and half-open are
|
|
114
|
+
* equivalent so no adjustment. */
|
|
115
|
+
if (!is_default) {
|
|
116
|
+
int is_integer_dtype = (ca->data_type >= CA_INT8
|
|
117
|
+
&& ca->data_type <= CA_UINT64);
|
|
118
|
+
if (is_integer_dtype) {
|
|
119
|
+
low_long = NUM2LONG(low_val);
|
|
120
|
+
high_long = NUM2LONG(high_val);
|
|
121
|
+
if (high_is_closed) high_long += 1;
|
|
122
|
+
if (low_long >= high_long) {
|
|
123
|
+
rb_raise(rb_eArgError,
|
|
124
|
+
"random: low must be less than high "
|
|
125
|
+
"(got low=%ld, high=%ld)",
|
|
126
|
+
low_long, high_long);
|
|
127
|
+
}
|
|
128
|
+
limit = (unsigned long)(high_long - low_long) - 1;
|
|
129
|
+
} else {
|
|
130
|
+
low_dbl = NUM2DBL(low_val);
|
|
131
|
+
high_dbl = NUM2DBL(high_val);
|
|
132
|
+
if (low_dbl >= high_dbl) {
|
|
133
|
+
rb_raise(rb_eArgError,
|
|
134
|
+
"random: low must be less than high "
|
|
135
|
+
"(got low=%g, high=%g)",
|
|
136
|
+
low_dbl, high_dbl);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
n = ca->elements;
|
|
142
|
+
ca_attach(ca);
|
|
143
|
+
|
|
144
|
+
switch (ca->data_type) {
|
|
145
|
+
case CA_FLOAT64: {
|
|
146
|
+
double *p = (double *)ca->ptr;
|
|
147
|
+
if (is_default) {
|
|
148
|
+
for (i = 0; i < n; i++)
|
|
149
|
+
p[i] = ca_random_real(rng);
|
|
150
|
+
} else {
|
|
151
|
+
double range = high_dbl - low_dbl;
|
|
152
|
+
for (i = 0; i < n; i++)
|
|
153
|
+
p[i] = low_dbl + ca_random_real(rng) * range;
|
|
154
|
+
}
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
case CA_FLOAT32: {
|
|
158
|
+
float *p = (float *)ca->ptr;
|
|
159
|
+
if (is_default) {
|
|
160
|
+
for (i = 0; i < n; i++)
|
|
161
|
+
p[i] = (float)ca_random_real(rng);
|
|
162
|
+
} else {
|
|
163
|
+
double range = high_dbl - low_dbl;
|
|
164
|
+
for (i = 0; i < n; i++)
|
|
165
|
+
p[i] = (float)(low_dbl + ca_random_real(rng) * range);
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
case CA_CMPLX128: {
|
|
170
|
+
double complex *p = (double complex *)ca->ptr;
|
|
171
|
+
if (is_default) {
|
|
172
|
+
for (i = 0; i < n; i++)
|
|
173
|
+
p[i] = ca_random_real(rng) + ca_random_real(rng) * I;
|
|
174
|
+
} else {
|
|
175
|
+
double range = high_dbl - low_dbl;
|
|
176
|
+
for (i = 0; i < n; i++)
|
|
177
|
+
p[i] = (low_dbl + ca_random_real(rng) * range)
|
|
178
|
+
+ (low_dbl + ca_random_real(rng) * range) * I;
|
|
179
|
+
}
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
case CA_CMPLX64: {
|
|
183
|
+
float complex *p = (float complex *)ca->ptr;
|
|
184
|
+
if (is_default) {
|
|
185
|
+
for (i = 0; i < n; i++)
|
|
186
|
+
p[i] = (float)ca_random_real(rng) + (float)ca_random_real(rng) * I;
|
|
187
|
+
} else {
|
|
188
|
+
double range = high_dbl - low_dbl;
|
|
189
|
+
for (i = 0; i < n; i++)
|
|
190
|
+
p[i] = (float)(low_dbl + ca_random_real(rng) * range)
|
|
191
|
+
+ (float)(low_dbl + ca_random_real(rng) * range) * I;
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
case CA_BOOLEAN: {
|
|
196
|
+
boolean8_t *p = (boolean8_t *)ca->ptr;
|
|
197
|
+
for (i = 0; i < n; i++)
|
|
198
|
+
p[i] = (ca_random_real(rng) < 0.5) ? 1 : 0;
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
default: {
|
|
202
|
+
/* integer types: CA_INT8..CA_UINT64 */
|
|
203
|
+
if (is_default) {
|
|
204
|
+
ca_sync(ca);
|
|
205
|
+
ca_detach(ca);
|
|
206
|
+
rb_raise(rb_eArgError,
|
|
207
|
+
"random! on an integer array requires a range: "
|
|
208
|
+
"a.random!(high), a.random!(low, high), or "
|
|
209
|
+
"a.random!(low..high) / a.random!(low...high)");
|
|
210
|
+
}
|
|
211
|
+
switch (ca->data_type) {
|
|
212
|
+
case CA_INT8: {
|
|
213
|
+
int8_t *p = (int8_t *)ca->ptr;
|
|
214
|
+
for (i = 0; i < n; i++)
|
|
215
|
+
p[i] = (int8_t)(low_long + ca_random_ulong_limited(rng, limit));
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case CA_UINT8: {
|
|
219
|
+
uint8_t *p = (uint8_t *)ca->ptr;
|
|
220
|
+
for (i = 0; i < n; i++)
|
|
221
|
+
p[i] = (uint8_t)(low_long + ca_random_ulong_limited(rng, limit));
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
case CA_INT16: {
|
|
225
|
+
int16_t *p = (int16_t *)ca->ptr;
|
|
226
|
+
for (i = 0; i < n; i++)
|
|
227
|
+
p[i] = (int16_t)(low_long + ca_random_ulong_limited(rng, limit));
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
case CA_UINT16: {
|
|
231
|
+
uint16_t *p = (uint16_t *)ca->ptr;
|
|
232
|
+
for (i = 0; i < n; i++)
|
|
233
|
+
p[i] = (uint16_t)(low_long + ca_random_ulong_limited(rng, limit));
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
case CA_INT32: {
|
|
237
|
+
int32_t *p = (int32_t *)ca->ptr;
|
|
238
|
+
for (i = 0; i < n; i++)
|
|
239
|
+
p[i] = (int32_t)(low_long + ca_random_ulong_limited(rng, limit));
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
case CA_UINT32: {
|
|
243
|
+
uint32_t *p = (uint32_t *)ca->ptr;
|
|
244
|
+
for (i = 0; i < n; i++)
|
|
245
|
+
p[i] = (uint32_t)(low_long + ca_random_ulong_limited(rng, limit));
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
case CA_INT64: {
|
|
249
|
+
int64_t *p = (int64_t *)ca->ptr;
|
|
250
|
+
for (i = 0; i < n; i++)
|
|
251
|
+
p[i] = (int64_t)(low_long + ca_random_ulong_limited(rng, limit));
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
case CA_UINT64: {
|
|
255
|
+
uint64_t *p = (uint64_t *)ca->ptr;
|
|
256
|
+
for (i = 0; i < n; i++)
|
|
257
|
+
p[i] = (uint64_t)(low_long + ca_random_ulong_limited(rng, limit));
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
default:
|
|
261
|
+
ca_sync(ca);
|
|
262
|
+
ca_detach(ca);
|
|
263
|
+
rb_raise(rb_eCADataTypeError,
|
|
264
|
+
"random! is not supported for this data type");
|
|
265
|
+
}
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
ca_sync(ca);
|
|
271
|
+
ca_detach(ca);
|
|
272
|
+
return self;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* ---- randomn! ---------------------------------------------------------- */
|
|
276
|
+
|
|
277
|
+
static inline void
|
|
278
|
+
box_muller_pair(VALUE rng, double *r1, double *r2)
|
|
279
|
+
{
|
|
280
|
+
double u1 = ca_random_real(rng);
|
|
281
|
+
double u2 = ca_random_real(rng);
|
|
282
|
+
while (u1 == 0.0)
|
|
283
|
+
u1 = ca_random_real(rng);
|
|
284
|
+
double r = sqrt(-2.0 * log(u1));
|
|
285
|
+
double theta = 2.0 * M_PI * u2;
|
|
286
|
+
*r1 = r * cos(theta);
|
|
287
|
+
*r2 = r * sin(theta);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* CArray#randomn!(rng:) — fill self with standard normal N(0, 1)
|
|
291
|
+
* samples in-place via Box-Muller, returning self.
|
|
292
|
+
*
|
|
293
|
+
* Restricted to float / complex dtypes. Complex fills real + imag as
|
|
294
|
+
* two independent normals per cell. */
|
|
295
|
+
static VALUE
|
|
296
|
+
rb_ca_randomn_bang(int argc, VALUE *argv, VALUE self)
|
|
297
|
+
{
|
|
298
|
+
CArray *ca;
|
|
299
|
+
VALUE opts = Qnil;
|
|
300
|
+
ca_size_t i, n;
|
|
301
|
+
|
|
302
|
+
rb_scan_args(argc, argv, "0:", &opts);
|
|
303
|
+
VALUE rng = Qnil;
|
|
304
|
+
rb_scan_options(opts, "rng", &rng);
|
|
305
|
+
|
|
306
|
+
rb_ca_modify(self);
|
|
307
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
308
|
+
|
|
309
|
+
if (ca->data_type != CA_FLOAT64 && ca->data_type != CA_FLOAT32 &&
|
|
310
|
+
ca->data_type != CA_CMPLX128 && ca->data_type != CA_CMPLX64) {
|
|
311
|
+
rb_raise(rb_eCADataTypeError,
|
|
312
|
+
"randomn! requires float or complex array");
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
n = ca->elements;
|
|
316
|
+
ca_attach(ca);
|
|
317
|
+
|
|
318
|
+
switch (ca->data_type) {
|
|
319
|
+
case CA_FLOAT64: {
|
|
320
|
+
double *p = (double *)ca->ptr;
|
|
321
|
+
ca_size_t pairs = n / 2;
|
|
322
|
+
for (i = 0; i < pairs; i++) {
|
|
323
|
+
box_muller_pair(rng, &p[2*i], &p[2*i+1]);
|
|
324
|
+
}
|
|
325
|
+
if (n % 2 == 1) {
|
|
326
|
+
double r1, r2;
|
|
327
|
+
box_muller_pair(rng, &r1, &r2);
|
|
328
|
+
p[n-1] = r1;
|
|
329
|
+
}
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
case CA_FLOAT32: {
|
|
333
|
+
float *p = (float *)ca->ptr;
|
|
334
|
+
ca_size_t pairs = n / 2;
|
|
335
|
+
for (i = 0; i < pairs; i++) {
|
|
336
|
+
double r1, r2;
|
|
337
|
+
box_muller_pair(rng, &r1, &r2);
|
|
338
|
+
p[2*i] = (float)r1;
|
|
339
|
+
p[2*i+1] = (float)r2;
|
|
340
|
+
}
|
|
341
|
+
if (n % 2 == 1) {
|
|
342
|
+
double r1, r2;
|
|
343
|
+
box_muller_pair(rng, &r1, &r2);
|
|
344
|
+
p[n-1] = (float)r1;
|
|
345
|
+
}
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
case CA_CMPLX128: {
|
|
349
|
+
double complex *p = (double complex *)ca->ptr;
|
|
350
|
+
for (i = 0; i < n; i++) {
|
|
351
|
+
double r1, r2;
|
|
352
|
+
box_muller_pair(rng, &r1, &r2);
|
|
353
|
+
p[i] = r1 + r2 * I;
|
|
354
|
+
}
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
case CA_CMPLX64: {
|
|
358
|
+
float complex *p = (float complex *)ca->ptr;
|
|
359
|
+
for (i = 0; i < n; i++) {
|
|
360
|
+
double r1, r2;
|
|
361
|
+
box_muller_pair(rng, &r1, &r2);
|
|
362
|
+
p[i] = (float)r1 + (float)r2 * I;
|
|
363
|
+
}
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
default:
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
ca_sync(ca);
|
|
371
|
+
ca_detach(ca);
|
|
372
|
+
return self;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/* ---- shuffle! ---------------------------------------------------------- */
|
|
376
|
+
|
|
377
|
+
static void
|
|
378
|
+
swap_chunks(char *a, char *b, ca_size_t chunk_bytes, char *tmp)
|
|
379
|
+
{
|
|
380
|
+
memcpy(tmp, a, chunk_bytes);
|
|
381
|
+
memcpy(a, b, chunk_bytes);
|
|
382
|
+
memcpy(b, tmp, chunk_bytes);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/* CArray#shuffle!(axis:, rng:) — Fisher-Yates permute self in-place,
|
|
386
|
+
* returning self.
|
|
387
|
+
*
|
|
388
|
+
* Without axis:, shuffles all cells as if flattened. With axis:,
|
|
389
|
+
* permutes slices along that axis (the trailing sub-slab is treated
|
|
390
|
+
* as a byte chunk and swapped whole, so multi-dim slices move
|
|
391
|
+
* together). */
|
|
392
|
+
static VALUE
|
|
393
|
+
rb_ca_shuffle_bang(int argc, VALUE *argv, VALUE self)
|
|
394
|
+
{
|
|
395
|
+
CArray *ca;
|
|
396
|
+
VALUE opts = Qnil, v_axis = Qnil;
|
|
397
|
+
ca_size_t n;
|
|
398
|
+
int axis = -1;
|
|
399
|
+
|
|
400
|
+
rb_scan_args(argc, argv, "0:", &opts);
|
|
401
|
+
VALUE rng = Qnil;
|
|
402
|
+
rb_scan_options(opts, "rng,axis", &rng, &v_axis);
|
|
403
|
+
|
|
404
|
+
rb_ca_modify(self);
|
|
405
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
406
|
+
|
|
407
|
+
if (ca->elements <= 1) return self;
|
|
408
|
+
|
|
409
|
+
ca_attach(ca);
|
|
410
|
+
|
|
411
|
+
if (NIL_P(v_axis)) {
|
|
412
|
+
/* shuffle all elements */
|
|
413
|
+
n = ca->elements;
|
|
414
|
+
ca_size_t elem_bytes = ca->bytes;
|
|
415
|
+
char *tmp = (char *)xmalloc(elem_bytes);
|
|
416
|
+
char *p = ca->ptr;
|
|
417
|
+
|
|
418
|
+
for (ca_size_t i = n - 1; i > 0; i--) {
|
|
419
|
+
unsigned long j = ca_random_ulong_limited(rng, (unsigned long)i);
|
|
420
|
+
if ((ca_size_t)j != i) {
|
|
421
|
+
swap_chunks(p + i * elem_bytes, p + j * elem_bytes, elem_bytes, tmp);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
xfree(tmp);
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
axis = NUM2INT(v_axis);
|
|
428
|
+
if (axis < 0) axis += ca->ndim;
|
|
429
|
+
if (axis < 0 || axis >= ca->ndim) {
|
|
430
|
+
ca_sync(ca);
|
|
431
|
+
ca_detach(ca);
|
|
432
|
+
rb_raise(rb_eArgError,
|
|
433
|
+
"axis %d is out of range for ndim %d", axis, ca->ndim);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
n = ca->dim[axis];
|
|
437
|
+
if (n <= 1) {
|
|
438
|
+
ca_sync(ca);
|
|
439
|
+
ca_detach(ca);
|
|
440
|
+
return self;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
ca_size_t outer = 1;
|
|
444
|
+
for (int d = 0; d < axis; d++)
|
|
445
|
+
outer *= ca->dim[d];
|
|
446
|
+
|
|
447
|
+
ca_size_t inner = 1;
|
|
448
|
+
for (int d = axis + 1; d < ca->ndim; d++)
|
|
449
|
+
inner *= ca->dim[d];
|
|
450
|
+
|
|
451
|
+
ca_size_t chunk_bytes = inner * ca->bytes;
|
|
452
|
+
ca_size_t stride = n * chunk_bytes;
|
|
453
|
+
char *tmp = (char *)xmalloc(chunk_bytes);
|
|
454
|
+
|
|
455
|
+
for (ca_size_t o = 0; o < outer; o++) {
|
|
456
|
+
char *base = ca->ptr + o * stride;
|
|
457
|
+
for (ca_size_t i = n - 1; i > 0; i--) {
|
|
458
|
+
unsigned long j = ca_random_ulong_limited(rng, (unsigned long)i);
|
|
459
|
+
if ((ca_size_t)j != i) {
|
|
460
|
+
swap_chunks(base + i * chunk_bytes,
|
|
461
|
+
base + j * chunk_bytes,
|
|
462
|
+
chunk_bytes, tmp);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
xfree(tmp);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
ca_sync(ca);
|
|
470
|
+
ca_detach(ca);
|
|
471
|
+
return self;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/* ---- shuffle (copy) ---------------------------------------------------- */
|
|
475
|
+
|
|
476
|
+
/* CArray#shuffle(axis:, rng:) — non-bang variant: shuffle a copy of self. */
|
|
477
|
+
static VALUE
|
|
478
|
+
rb_ca_shuffle(int argc, VALUE *argv, VALUE self)
|
|
479
|
+
{
|
|
480
|
+
volatile VALUE copy = rb_funcall(self, rb_intern("copy"), 0);
|
|
481
|
+
return rb_ca_shuffle_bang(argc, argv, copy);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/* ---- random (copy) ----------------------------------------------------- */
|
|
485
|
+
|
|
486
|
+
/* CArray#random([low,] [high], rng:) — non-bang variant: return a
|
|
487
|
+
* newly templated array filled uniformly. Shape and dtype come from
|
|
488
|
+
* CArray#template, so the receiver is only consulted for those.
|
|
489
|
+
* Accepts the same argument forms as {rb_ca_random_bang}. */
|
|
490
|
+
static VALUE
|
|
491
|
+
rb_ca_random(int argc, VALUE *argv, VALUE self)
|
|
492
|
+
{
|
|
493
|
+
volatile VALUE copy = rb_funcall(self, rb_intern("template"), 0);
|
|
494
|
+
return rb_ca_random_bang(argc, argv, copy);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/* CArray#randomn(rng:) — non-bang variant: return a newly templated
|
|
498
|
+
* array filled with standard normal samples. */
|
|
499
|
+
static VALUE
|
|
500
|
+
rb_ca_randomn(int argc, VALUE *argv, VALUE self)
|
|
501
|
+
{
|
|
502
|
+
volatile VALUE copy = rb_funcall(self, rb_intern("template"), 0);
|
|
503
|
+
return rb_ca_randomn_bang(argc, argv, copy);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/* ---- Init -------------------------------------------------------------- */
|
|
507
|
+
|
|
508
|
+
void
|
|
509
|
+
Init_carray_random (void)
|
|
510
|
+
{
|
|
511
|
+
rb_define_method(rb_cCArray, "random!", rb_ca_random_bang, -1);
|
|
512
|
+
rb_define_method(rb_cCArray, "randomn!", rb_ca_randomn_bang, -1);
|
|
513
|
+
rb_define_method(rb_cCArray, "shuffle!", rb_ca_shuffle_bang, -1);
|
|
514
|
+
|
|
515
|
+
rb_define_method(rb_cCArray, "random", rb_ca_random, -1);
|
|
516
|
+
rb_define_method(rb_cCArray, "randomn", rb_ca_randomn, -1);
|
|
517
|
+
rb_define_method(rb_cCArray, "shuffle", rb_ca_shuffle, -1);
|
|
518
|
+
}
|