carray 2.0.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -25
  3. data/CHANGELOG.md +338 -0
  4. data/{NEWS.md → CHANGELOG.v1.md} +3 -0
  5. data/LICENSE +1 -1
  6. data/README.md +120 -36
  7. data/carray.gemspec +32 -30
  8. data/ext/ca_array_pool.c +91 -0
  9. data/ext/ca_axis_descriptor.h +186 -0
  10. data/ext/ca_axis_dispatch.c +924 -0
  11. data/ext/ca_axis_group.c +1244 -0
  12. data/ext/ca_bincmp_dispatch.c +76 -0
  13. data/ext/ca_bincmp_dispatch.h +85 -0
  14. data/ext/ca_binop_dispatch.c +124 -0
  15. data/ext/ca_binop_dispatch.h +152 -0
  16. data/ext/ca_categorical_iterator.c +1375 -0
  17. data/ext/ca_compare.c +94 -0
  18. data/ext/ca_compare.h +26 -0
  19. data/ext/ca_composite_dispatch.c +414 -0
  20. data/ext/ca_composite_dispatch.h +116 -0
  21. data/ext/ca_for_buffer.h +96 -0
  22. data/ext/ca_for_each_element.h +239 -0
  23. data/ext/ca_group_iter.c +304 -0
  24. data/ext/ca_iter_substrate.h +325 -0
  25. data/ext/ca_kernel_iterator.c +4367 -0
  26. data/ext/ca_kernel_iterator.h +2596 -0
  27. data/ext/ca_moncmp_dispatch.c +37 -0
  28. data/ext/ca_moncmp_dispatch.h +62 -0
  29. data/ext/ca_monop_dispatch.c +200 -0
  30. data/ext/ca_monop_dispatch.h +235 -0
  31. data/ext/ca_obj_array.c +355 -359
  32. data/ext/ca_obj_bincmp.c +839 -0
  33. data/ext/ca_obj_binop.c +948 -0
  34. data/ext/ca_obj_bitarray.c +369 -164
  35. data/ext/ca_obj_bitfield.c +294 -234
  36. data/ext/ca_obj_block.c +189 -711
  37. data/ext/ca_obj_byte_swap.c +766 -0
  38. data/ext/ca_obj_const_string.c +967 -0
  39. data/ext/ca_obj_face.c +750 -0
  40. data/ext/ca_obj_face.h +279 -0
  41. data/ext/ca_obj_fake.c +239 -100
  42. data/ext/ca_obj_farray.c +54 -441
  43. data/ext/ca_obj_field.c +82 -529
  44. data/ext/ca_obj_fixlen_string.c +308 -0
  45. data/ext/ca_obj_grid.c +866 -440
  46. data/ext/ca_obj_meld.c +1039 -0
  47. data/ext/ca_obj_moncmp.c +588 -0
  48. data/ext/ca_obj_monop.c +1123 -0
  49. data/ext/ca_obj_object.c +866 -296
  50. data/ext/ca_obj_record.c +470 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +593 -459
  53. data/ext/ca_obj_remap.c +475 -0
  54. data/ext/ca_obj_repeat.c +92 -477
  55. data/ext/ca_obj_roll.c +624 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1306 -0
  58. data/ext/ca_obj_shift.c +231 -793
  59. data/ext/ca_obj_source.c +78 -0
  60. data/ext/ca_obj_stack.c +1173 -0
  61. data/ext/ca_obj_stride.c +2584 -0
  62. data/ext/ca_obj_string.c +270 -0
  63. data/ext/ca_obj_tile.c +622 -0
  64. data/ext/ca_obj_time.c +548 -0
  65. data/ext/ca_obj_timedelta.c +437 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +785 -0
  68. data/ext/ca_obj_window.c +1202 -565
  69. data/ext/ca_op_byte_swap.c +175 -0
  70. data/ext/ca_op_cmplx64.h +123 -0
  71. data/ext/ca_op_ipower.c +316 -0
  72. data/ext/ca_op_powi.h +88 -0
  73. data/ext/ca_sort_kernels.h +132 -0
  74. data/ext/ca_sweep_engine.c +473 -0
  75. data/ext/ca_sweep_engine.h +166 -0
  76. data/ext/ca_transform_common.c +235 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +810 -420
  80. data/ext/carray_access.c +873 -731
  81. data/ext/carray_attribute.c +98 -329
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +376 -0
  84. data/ext/carray_build_flags.h +3 -0
  85. data/ext/carray_call_cfunc.c +2897 -874
  86. data/ext/carray_call_cfunc.h +313 -0
  87. data/ext/carray_cast.c +1264 -315
  88. data/ext/carray_cast_func.rb +81 -40
  89. data/ext/carray_class.c +53 -63
  90. data/ext/carray_config.h +28 -0
  91. data/ext/carray_conversion.c +350 -346
  92. data/ext/carray_copy.c +168 -270
  93. data/ext/carray_core.c +1396 -206
  94. data/ext/carray_count.c +312 -0
  95. data/ext/carray_data_type.c +43 -19
  96. data/ext/carray_element.c +585 -213
  97. data/ext/carray_factorize.c +2542 -0
  98. data/ext/carray_generate.c +230 -559
  99. data/ext/carray_histogram.c +490 -0
  100. data/ext/carray_hold.c +228 -0
  101. data/ext/carray_index_classifier.c +1021 -0
  102. data/ext/carray_index_classifier.h +27 -0
  103. data/ext/carray_internal.h +136 -0
  104. data/ext/carray_kernels_bincmp.c +4446 -0
  105. data/ext/carray_kernels_binop.c +11001 -0
  106. data/ext/carray_kernels_init.c +1131 -0
  107. data/ext/carray_kernels_map.c +3467 -0
  108. data/ext/carray_kernels_moncmp.c +2097 -0
  109. data/ext/carray_kernels_monop.c +18313 -0
  110. data/ext/carray_kernels_reduce_aggregate.c +25837 -0
  111. data/ext/carray_kernels_reduce_boolean.c +330 -0
  112. data/ext/carray_kernels_reduce_cumulative.c +14593 -0
  113. data/ext/carray_kernels_reduce_extreme.c +16948 -0
  114. data/ext/carray_kernels_reduce_variance.c +3910 -0
  115. data/ext/carray_kernels_scan.c +3693 -0
  116. data/ext/carray_kernels_search.c +32138 -0
  117. data/ext/carray_kernels_sort.c +10626 -0
  118. data/ext/carray_kernels_triop.c +1392 -0
  119. data/ext/carray_lazy.c +737 -0
  120. data/ext/carray_loop.c +88 -200
  121. data/ext/carray_mask.c +853 -158
  122. data/ext/carray_math_kernel.h +120 -0
  123. data/ext/carray_mathfunc.c +10 -241
  124. data/ext/carray_median_percentile.c +1257 -0
  125. data/ext/carray_memory_view.c +1650 -0
  126. data/ext/carray_operator.c +1525 -320
  127. data/ext/carray_order.c +664 -1394
  128. data/ext/carray_partition.c +416 -0
  129. data/ext/carray_random.c +518 -0
  130. data/ext/carray_scatter.c +357 -0
  131. data/ext/carray_slab.c +1219 -0
  132. data/ext/carray_slab.h +84 -0
  133. data/ext/carray_sort.c +829 -0
  134. data/ext/carray_sort_kernel.c +620 -0
  135. data/ext/carray_struct.c +695 -0
  136. data/ext/carray_test.c +343 -229
  137. data/ext/carray_undef.c +34 -17
  138. data/ext/carray_utils.c +175 -74
  139. data/ext/extconf.rb +234 -55
  140. data/ext/mk_call_cfunc.rb +671 -0
  141. data/ext/mkkernel.rb +9096 -0
  142. data/ext/ruby_carray.c +211 -108
  143. data/ext/version.h +4 -14
  144. data/ext/version.rb +5 -13
  145. data/lib/carray/arrow_tensor.rb +401 -0
  146. data/lib/carray/attribute.rb +166 -0
  147. data/lib/carray/autoload_carray.rb +239 -0
  148. data/lib/carray/autoload_method_extension.rb +45 -0
  149. data/lib/carray/axis_group.rb +711 -0
  150. data/lib/carray/basics.rb +481 -0
  151. data/lib/carray/bincount_nd.rb +358 -0
  152. data/lib/carray/block_iterator.rb +614 -0
  153. data/lib/carray/boolean_reduce.rb +109 -0
  154. data/lib/carray/categorical.rb +561 -0
  155. data/lib/carray/categorical_iterator.rb +1084 -0
  156. data/lib/carray/complex.rb +150 -0
  157. data/lib/carray/conditional.rb +216 -0
  158. data/lib/carray/const_string.rb +228 -0
  159. data/lib/carray/construct.rb +160 -328
  160. data/lib/carray/core_extensions.rb +297 -0
  161. data/lib/carray/data_type_extension.rb +250 -0
  162. data/lib/carray/fixlen_string.rb +95 -0
  163. data/lib/carray/frame/concat.rb +132 -0
  164. data/lib/carray/frame/convert.rb +95 -0
  165. data/lib/carray/frame/csv_parser.rb +211 -0
  166. data/lib/carray/frame/frame.rb +642 -0
  167. data/lib/carray/frame/group.rb +186 -0
  168. data/lib/carray/frame/io.rb +321 -0
  169. data/lib/carray/frame/join.rb +248 -0
  170. data/lib/carray/frame/records.rb +99 -0
  171. data/lib/carray/frame/sort.rb +113 -0
  172. data/lib/carray/frame/verbs.rb +316 -0
  173. data/lib/carray/frame.rb +16 -0
  174. data/lib/carray/fuse_source.rb +123 -0
  175. data/lib/carray/fusion.rb +218 -0
  176. data/lib/carray/histogram.rb +512 -0
  177. data/lib/carray/inspect.rb +37 -26
  178. data/lib/carray/iterator.rb +58 -349
  179. data/lib/carray/lazy.rb +941 -0
  180. data/lib/carray/mask_gap_fill.rb +200 -0
  181. data/lib/carray/math.rb +78 -342
  182. data/lib/carray/meld_reduce.rb +289 -0
  183. data/lib/carray/methods/align_addr.rb +116 -0
  184. data/lib/carray/methods/bin.rb +128 -0
  185. data/lib/carray/methods/bincount.rb +87 -0
  186. data/lib/carray/methods/bit_string.rb +92 -0
  187. data/lib/carray/methods/broadcast.rb +63 -0
  188. data/lib/carray/methods/choose.rb +39 -0
  189. data/lib/carray/methods/composition.rb +280 -0
  190. data/lib/carray/methods/gather_nd.rb +206 -0
  191. data/lib/carray/methods/index.rb +39 -0
  192. data/lib/carray/methods/insert_block.rb +99 -0
  193. data/lib/carray/methods/is_in.rb +141 -0
  194. data/lib/carray/methods/join.rb +90 -0
  195. data/lib/carray/methods/locate_addr.rb +52 -0
  196. data/lib/carray/methods/mask_duplicates.rb +41 -0
  197. data/lib/carray/methods/meshgrid.rb +90 -0
  198. data/lib/carray/methods/mode.rb +126 -0
  199. data/lib/carray/methods/nunique.rb +46 -0
  200. data/lib/carray/methods/resize.rb +56 -0
  201. data/lib/carray/methods/snap.rb +161 -0
  202. data/lib/carray/methods/string_format.rb +57 -0
  203. data/lib/carray/methods/unique.rb +47 -0
  204. data/lib/carray/methods/value_counts.rb +71 -0
  205. data/lib/carray/mkmf.rb +124 -101
  206. data/lib/carray/runtime.rb +89 -0
  207. data/lib/carray/serialize.rb +478 -167
  208. data/lib/carray/slab_iterator.rb +305 -0
  209. data/lib/carray/stack.rb +291 -0
  210. data/lib/carray/string.rb +56 -180
  211. data/lib/carray/string_operation_extension.rb +289 -0
  212. data/lib/carray/struct.rb +335 -323
  213. data/lib/carray/struct_builder.rb +697 -0
  214. data/lib/carray/table.rb +41 -2
  215. data/lib/carray/time.rb +2654 -38
  216. data/lib/carray/window_iterator.rb +927 -0
  217. data/lib/carray.rb +55 -57
  218. data/yard-stubs/ca_obj_array.rb +385 -0
  219. data/yard-stubs/ca_obj_bitarray.rb +38 -0
  220. data/yard-stubs/ca_obj_bitfield.rb +43 -0
  221. data/yard-stubs/ca_obj_block.rb +73 -0
  222. data/yard-stubs/ca_obj_byte_swap.rb +56 -0
  223. data/yard-stubs/ca_obj_fake.rb +31 -0
  224. data/yard-stubs/ca_obj_farray.rb +32 -0
  225. data/yard-stubs/ca_obj_field.rb +45 -0
  226. data/yard-stubs/ca_obj_grid.rb +35 -0
  227. data/yard-stubs/ca_obj_refer.rb +72 -0
  228. data/yard-stubs/ca_obj_roll.rb +45 -0
  229. data/yard-stubs/ca_obj_shift.rb +43 -0
  230. data/yard-stubs/ca_obj_stride.rb +181 -0
  231. data/yard-stubs/ca_obj_tile.rb +29 -0
  232. data/yard-stubs/ca_obj_transpose.rb +40 -0
  233. data/yard-stubs/ca_obj_window.rb +49 -0
  234. data/yard-stubs/carray_access.rb +131 -0
  235. data/yard-stubs/carray_attribute.rb +246 -0
  236. data/yard-stubs/carray_broadcast.rb +37 -0
  237. data/yard-stubs/carray_cast.rb +489 -0
  238. data/yard-stubs/carray_class.rb +65 -0
  239. data/yard-stubs/carray_conversion.rb +76 -0
  240. data/yard-stubs/carray_copy.rb +79 -0
  241. data/yard-stubs/carray_core.rb +114 -0
  242. data/yard-stubs/carray_count.rb +79 -0
  243. data/yard-stubs/carray_element.rb +108 -0
  244. data/yard-stubs/carray_generate.rb +66 -0
  245. data/yard-stubs/carray_lazy.rb +23 -0
  246. data/yard-stubs/carray_loop.rb +140 -0
  247. data/yard-stubs/carray_mask.rb +259 -0
  248. data/yard-stubs/carray_math.rb +132 -0
  249. data/yard-stubs/carray_mathfunc.rb +45 -0
  250. data/yard-stubs/carray_median_percentile.rb +89 -0
  251. data/yard-stubs/carray_memory_view.rb +163 -0
  252. data/yard-stubs/carray_order.rb +312 -0
  253. data/yard-stubs/carray_random.rb +89 -0
  254. data/yard-stubs/carray_scatter.rb +106 -0
  255. data/yard-stubs/carray_slab.rb +57 -0
  256. data/yard-stubs/carray_sort.rb +163 -0
  257. data/yard-stubs/carray_test.rb +85 -0
  258. data/yard-stubs/carray_undef.rb +64 -0
  259. data/yard-stubs/carray_utils.rb +97 -0
  260. data/yard-stubs/ruby_carray.rb +193 -0
  261. metadata +220 -138
  262. data/Rakefile +0 -51
  263. data/TODO.md +0 -18
  264. data/ext/ca_iter_block.c +0 -257
  265. data/ext/ca_iter_dimension.c +0 -299
  266. data/ext/ca_iter_window.c +0 -214
  267. data/ext/ca_obj_mapping.c +0 -644
  268. data/ext/ca_obj_unbound_repeat.c +0 -529
  269. data/ext/carray_iterator.c +0 -641
  270. data/ext/carray_math.rb +0 -850
  271. data/ext/carray_numeric.c +0 -259
  272. data/ext/carray_sort_addr.c +0 -254
  273. data/ext/carray_stat.c +0 -2100
  274. data/ext/carray_stat_proc.rb +0 -1999
  275. data/ext/mkmath.rb +0 -741
  276. data/ext/ruby_ccomplex.c +0 -509
  277. data/ext/ruby_float_func.c +0 -86
  278. data/lib/carray/array.rb +0 -8
  279. data/lib/carray/autoload/autoload_base.rb +0 -19
  280. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  281. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  282. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  283. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  284. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  285. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  286. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  287. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  288. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  289. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  290. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  291. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  292. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  293. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  294. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  295. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  296. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  297. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  298. data/lib/carray/autoload.rb +0 -141
  299. data/lib/carray/basic.rb +0 -191
  300. data/lib/carray/broadcast.rb +0 -101
  301. data/lib/carray/compose.rb +0 -315
  302. data/lib/carray/convert.rb +0 -115
  303. data/lib/carray/info.rb +0 -110
  304. data/lib/carray/io/imagemagick.rb +0 -235
  305. data/lib/carray/mask.rb +0 -102
  306. data/lib/carray/math/histogram.rb +0 -177
  307. data/lib/carray/math/recurrence.rb +0 -93
  308. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  309. data/lib/carray/object/ca_obj_link.rb +0 -50
  310. data/lib/carray/object/ca_obj_pack.rb +0 -99
  311. data/lib/carray/obsolete.rb +0 -256
  312. data/lib/carray/ordering.rb +0 -181
  313. data/lib/carray/testing.rb +0 -51
  314. data/lib/carray/transform.rb +0 -109
  315. data/mailmap +0 -1
  316. data/misc/Methods.ja.md +0 -182
  317. data/misc/NOTE +0 -51
  318. data/spec/Classes/CABitfield_spec.rb +0 -58
  319. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  320. data/spec/Classes/CABlock_spec.rb +0 -205
  321. data/spec/Classes/CAField_spec.rb +0 -39
  322. data/spec/Classes/CAGrid_spec.rb +0 -75
  323. data/spec/Classes/CAMap_spec.rb +0 -0
  324. data/spec/Classes/CAMapping_spec.rb +0 -105
  325. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  326. data/spec/Classes/CAObject_spec.rb +0 -33
  327. data/spec/Classes/CARefer_spec.rb +0 -93
  328. data/spec/Classes/CARepeat_spec.rb +0 -65
  329. data/spec/Classes/CASelect_spec.rb +0 -22
  330. data/spec/Classes/CAShift_spec.rb +0 -16
  331. data/spec/Classes/CAStruct_spec.rb +0 -71
  332. data/spec/Classes/CATranspose_spec.rb +0 -60
  333. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  334. data/spec/Classes/CAWindow_spec.rb +0 -54
  335. data/spec/Classes/CAWrap_spec.rb +0 -8
  336. data/spec/Classes/CArray_spec.rb +0 -184
  337. data/spec/Classes/CScalar_spec.rb +0 -55
  338. data/spec/Features/feature_130_spec.rb +0 -19
  339. data/spec/Features/feature_attributes_spec.rb +0 -280
  340. data/spec/Features/feature_boolean_spec.rb +0 -98
  341. data/spec/Features/feature_broadcast.rb +0 -116
  342. data/spec/Features/feature_cast_function.rb +0 -19
  343. data/spec/Features/feature_cast_spec.rb +0 -33
  344. data/spec/Features/feature_class_spec.rb +0 -84
  345. data/spec/Features/feature_complex_spec.rb +0 -42
  346. data/spec/Features/feature_composite_spec.rb +0 -124
  347. data/spec/Features/feature_convert_spec.rb +0 -46
  348. data/spec/Features/feature_copy_spec.rb +0 -123
  349. data/spec/Features/feature_creation_spec.rb +0 -84
  350. data/spec/Features/feature_element_spec.rb +0 -144
  351. data/spec/Features/feature_extream_spec.rb +0 -54
  352. data/spec/Features/feature_generate_spec.rb +0 -74
  353. data/spec/Features/feature_index_spec.rb +0 -69
  354. data/spec/Features/feature_mask_spec.rb +0 -580
  355. data/spec/Features/feature_math_spec.rb +0 -97
  356. data/spec/Features/feature_order_spec.rb +0 -146
  357. data/spec/Features/feature_ref_store_spec.rb +0 -209
  358. data/spec/Features/feature_serialization_spec.rb +0 -125
  359. data/spec/Features/feature_stat_spec.rb +0 -397
  360. data/spec/Features/feature_virtual_spec.rb +0 -48
  361. data/spec/Features/method_eq_spec.rb +0 -81
  362. data/spec/Features/method_is_nan_spec.rb +0 -12
  363. data/spec/Features/method_map_spec.rb +0 -54
  364. data/spec/Features/method_max_with.rb +0 -20
  365. data/spec/Features/method_min_with.rb +0 -19
  366. data/spec/Features/method_ne_spec.rb +0 -18
  367. data/spec/Features/method_project_spec.rb +0 -188
  368. data/spec/Features/method_ref_spec.rb +0 -27
  369. data/spec/Features/method_round_spec.rb +0 -11
  370. data/spec/Features/method_s_linspace_spec.rb +0 -48
  371. data/spec/Features/method_s_span_spec.rb +0 -14
  372. data/spec/Features/method_seq_spec.rb +0 -47
  373. data/spec/Features/method_sort_with.rb +0 -43
  374. data/spec/Features/method_sorted_with.rb +0 -29
  375. data/spec/Features/method_span_spec.rb +0 -42
  376. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  377. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  378. data/spec/spec_all.rb +0 -10
  379. data/utils/ca_ase.rb +0 -21
  380. data/utils/ca_methods.rb +0 -15
  381. data/utils/cast_checker.rb +0 -30
  382. data/utils/convert_test.rb +0 -73
  383. data/utils/extract_yard.rb +0 -22
  384. data/utils/guess_shape.rb +0 -76
  385. data/utils/monkey_patch_methods.rb +0 -62
  386. data/utils/remove_resource_fork.sh +0 -5
@@ -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-type 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 data types, `..` closed adds 1 to high (turns into half-open
113
+ * for the sampler); for float data types, closed and half-open are
114
+ * equivalent so no adjustment. */
115
+ if (!is_default) {
116
+ int is_integer_type = (ca->data_type >= CA_INT8
117
+ && ca->data_type <= CA_UINT64);
118
+ if (is_integer_type) {
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 data types. 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 data type 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
+ }