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.
Files changed (339) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +5 -25
  3. data/CHANGELOG.md +16 -0
  4. data/LICENSE +1 -1
  5. data/NEWS.md +3 -0
  6. data/README.md +128 -44
  7. data/carray.gemspec +22 -24
  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 +1208 -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 +125 -0
  15. data/ext/ca_binop_dispatch.h +159 -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 +241 -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 +4321 -0
  26. data/ext/ca_kernel_iterator.h +2603 -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 +809 -0
  33. data/ext/ca_obj_binop.c +892 -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 +965 -0
  39. data/ext/ca_obj_face.c +670 -0
  40. data/ext/ca_obj_face.h +247 -0
  41. data/ext/ca_obj_fake.c +228 -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 +306 -0
  45. data/ext/ca_obj_grid.c +858 -440
  46. data/ext/ca_obj_meld.c +1034 -0
  47. data/ext/ca_obj_moncmp.c +569 -0
  48. data/ext/ca_obj_monop.c +1111 -0
  49. data/ext/ca_obj_object.c +774 -298
  50. data/ext/ca_obj_record.c +468 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +569 -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 +616 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1296 -0
  58. data/ext/ca_obj_shift.c +230 -792
  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 +2501 -0
  62. data/ext/ca_obj_string.c +268 -0
  63. data/ext/ca_obj_tile.c +614 -0
  64. data/ext/ca_obj_time.c +546 -0
  65. data/ext/ca_obj_timedelta.c +435 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +746 -0
  68. data/ext/ca_obj_unbound_repeat.c +208 -241
  69. data/ext/ca_obj_window.c +1131 -563
  70. data/ext/ca_op_byte_swap.c +175 -0
  71. data/ext/ca_op_ipower.c +319 -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 +430 -0
  75. data/ext/ca_sweep_engine.h +157 -0
  76. data/ext/ca_transform_common.c +228 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +795 -402
  80. data/ext/carray_access.c +831 -711
  81. data/ext/carray_attribute.c +98 -330
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +283 -0
  84. data/ext/carray_call_cfunc.c +1360 -828
  85. data/ext/carray_call_cfunc.h +160 -0
  86. data/ext/carray_cast.c +1212 -301
  87. data/ext/carray_cast_func.rb +81 -40
  88. data/ext/carray_class.c +53 -63
  89. data/ext/carray_config.h +28 -0
  90. data/ext/carray_conversion.c +350 -346
  91. data/ext/carray_copy.c +156 -268
  92. data/ext/carray_core.c +1342 -199
  93. data/ext/carray_count.c +312 -0
  94. data/ext/carray_data_type.c +43 -19
  95. data/ext/carray_element.c +585 -213
  96. data/ext/carray_factorize.c +2542 -0
  97. data/ext/carray_generate.c +230 -559
  98. data/ext/carray_histogram.c +490 -0
  99. data/ext/carray_hold.c +228 -0
  100. data/ext/carray_index_classifier.c +1035 -0
  101. data/ext/carray_index_classifier.h +27 -0
  102. data/ext/carray_internal.h +120 -0
  103. data/ext/carray_kernels_bincmp.c +4445 -0
  104. data/ext/carray_kernels_binop.c +10979 -0
  105. data/ext/carray_kernels_init.c +36 -0
  106. data/ext/carray_kernels_map.c +3466 -0
  107. data/ext/carray_kernels_moncmp.c +2096 -0
  108. data/ext/carray_kernels_monop.c +18312 -0
  109. data/ext/carray_kernels_reduce_aggregate.c +25836 -0
  110. data/ext/carray_kernels_reduce_boolean.c +329 -0
  111. data/ext/carray_kernels_reduce_cumulative.c +14592 -0
  112. data/ext/carray_kernels_reduce_extreme.c +16947 -0
  113. data/ext/carray_kernels_reduce_variance.c +3909 -0
  114. data/ext/carray_kernels_scan.c +3692 -0
  115. data/ext/carray_kernels_search.c +32137 -0
  116. data/ext/carray_kernels_sort.c +10625 -0
  117. data/ext/carray_kernels_triop.c +1391 -0
  118. data/ext/carray_lazy.c +567 -0
  119. data/ext/carray_loop.c +88 -200
  120. data/ext/carray_mask.c +848 -154
  121. data/ext/carray_math_kernel.h +120 -0
  122. data/ext/carray_mathfunc.c +10 -241
  123. data/ext/carray_median_percentile.c +1257 -0
  124. data/ext/carray_memory_view.c +1625 -0
  125. data/ext/carray_operator.c +1526 -318
  126. data/ext/carray_order.c +664 -1394
  127. data/ext/carray_partition.c +416 -0
  128. data/ext/carray_random.c +518 -0
  129. data/ext/carray_scatter.c +357 -0
  130. data/ext/carray_slab.c +1219 -0
  131. data/ext/carray_slab.h +84 -0
  132. data/ext/carray_sort.c +829 -0
  133. data/ext/carray_sort_kernel.c +620 -0
  134. data/ext/carray_struct.c +695 -0
  135. data/ext/carray_test.c +343 -229
  136. data/ext/carray_undef.c +34 -17
  137. data/ext/carray_utils.c +175 -74
  138. data/ext/extconf.rb +216 -55
  139. data/ext/mk_call_cfunc.rb +480 -0
  140. data/ext/mkkernel.rb +8842 -0
  141. data/ext/ruby_carray.c +202 -101
  142. data/ext/version.h +4 -14
  143. data/ext/version.rb +5 -13
  144. data/lib/carray/arrow_tensor.rb +401 -0
  145. data/lib/carray/attribute.rb +166 -0
  146. data/lib/carray/autoload_carray.rb +220 -0
  147. data/lib/carray/autoload_method_extension.rb +44 -0
  148. data/lib/carray/axis_group.rb +711 -0
  149. data/lib/carray/basics.rb +481 -0
  150. data/lib/carray/bincount_nd.rb +358 -0
  151. data/lib/carray/block_iterator.rb +604 -0
  152. data/lib/carray/boolean_reduce.rb +109 -0
  153. data/lib/carray/categorical.rb +561 -0
  154. data/lib/carray/categorical_iterator.rb +1062 -0
  155. data/lib/carray/complex.rb +150 -0
  156. data/lib/carray/conditional.rb +216 -0
  157. data/lib/carray/const_string.rb +228 -0
  158. data/lib/carray/construct.rb +139 -328
  159. data/lib/carray/core_extensions.rb +240 -0
  160. data/lib/carray/data_type_extension.rb +233 -0
  161. data/lib/carray/fixlen_string.rb +95 -0
  162. data/lib/carray/frame/concat.rb +132 -0
  163. data/lib/carray/frame/convert.rb +95 -0
  164. data/lib/carray/frame/csv_parser.rb +211 -0
  165. data/lib/carray/frame/frame.rb +649 -0
  166. data/lib/carray/frame/group.rb +186 -0
  167. data/lib/carray/frame/io.rb +164 -0
  168. data/lib/carray/frame/join.rb +248 -0
  169. data/lib/carray/frame/records.rb +99 -0
  170. data/lib/carray/frame/sort.rb +113 -0
  171. data/lib/carray/frame/verbs.rb +299 -0
  172. data/lib/carray/frame.rb +16 -0
  173. data/lib/carray/histogram.rb +512 -0
  174. data/lib/carray/inspect.rb +37 -20
  175. data/lib/carray/iterator.rb +57 -349
  176. data/lib/carray/lazy.rb +889 -0
  177. data/lib/carray/mask_gap_fill.rb +200 -0
  178. data/lib/carray/math.rb +78 -342
  179. data/lib/carray/meld_reduce.rb +289 -0
  180. data/lib/carray/methods/align_addr.rb +116 -0
  181. data/lib/carray/methods/bin.rb +128 -0
  182. data/lib/carray/methods/bincount.rb +87 -0
  183. data/lib/carray/methods/bit_string.rb +92 -0
  184. data/lib/carray/methods/broadcast.rb +63 -0
  185. data/lib/carray/methods/choose.rb +39 -0
  186. data/lib/carray/methods/composition.rb +280 -0
  187. data/lib/carray/methods/gather_nd.rb +206 -0
  188. data/lib/carray/methods/index.rb +39 -0
  189. data/lib/carray/methods/insert_block.rb +99 -0
  190. data/lib/carray/methods/is_in.rb +141 -0
  191. data/lib/carray/methods/join.rb +90 -0
  192. data/lib/carray/methods/locate_addr.rb +47 -0
  193. data/lib/carray/methods/mask_duplicates.rb +41 -0
  194. data/lib/carray/methods/meshgrid.rb +91 -0
  195. data/lib/carray/methods/mode.rb +126 -0
  196. data/lib/carray/methods/nunique.rb +46 -0
  197. data/lib/carray/methods/resize.rb +56 -0
  198. data/lib/carray/methods/snap.rb +156 -0
  199. data/lib/carray/methods/string_format.rb +57 -0
  200. data/lib/carray/methods/unique.rb +47 -0
  201. data/lib/carray/methods/value_counts.rb +71 -0
  202. data/lib/carray/mkmf.rb +124 -101
  203. data/lib/carray/runtime.rb +108 -0
  204. data/lib/carray/serialize.rb +478 -167
  205. data/lib/carray/slab_iterator.rb +292 -0
  206. data/lib/carray/stack.rb +291 -0
  207. data/lib/carray/string.rb +56 -180
  208. data/lib/carray/string_operation_extension.rb +289 -0
  209. data/lib/carray/struct.rb +335 -323
  210. data/lib/carray/struct_builder.rb +697 -0
  211. data/lib/carray/table.rb +41 -2
  212. data/lib/carray/time.rb +2255 -38
  213. data/lib/carray/window_iterator.rb +655 -0
  214. data/lib/carray.rb +55 -57
  215. metadata +163 -130
  216. data/Rakefile +0 -51
  217. data/TODO.md +0 -18
  218. data/ext/ca_iter_block.c +0 -257
  219. data/ext/ca_iter_dimension.c +0 -299
  220. data/ext/ca_iter_window.c +0 -214
  221. data/ext/ca_obj_mapping.c +0 -644
  222. data/ext/carray_iterator.c +0 -641
  223. data/ext/carray_math.rb +0 -850
  224. data/ext/carray_numeric.c +0 -259
  225. data/ext/carray_sort_addr.c +0 -254
  226. data/ext/carray_stat.c +0 -2100
  227. data/ext/carray_stat_proc.rb +0 -1999
  228. data/ext/mkmath.rb +0 -741
  229. data/ext/ruby_ccomplex.c +0 -509
  230. data/ext/ruby_float_func.c +0 -86
  231. data/lib/carray/array.rb +0 -8
  232. data/lib/carray/autoload/autoload_base.rb +0 -19
  233. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  234. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  235. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  236. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  237. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  238. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  239. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  240. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  241. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  242. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  243. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  244. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  245. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  246. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  247. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  248. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  249. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  250. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  251. data/lib/carray/autoload.rb +0 -141
  252. data/lib/carray/basic.rb +0 -191
  253. data/lib/carray/broadcast.rb +0 -101
  254. data/lib/carray/compose.rb +0 -315
  255. data/lib/carray/convert.rb +0 -115
  256. data/lib/carray/info.rb +0 -110
  257. data/lib/carray/io/imagemagick.rb +0 -235
  258. data/lib/carray/mask.rb +0 -102
  259. data/lib/carray/math/histogram.rb +0 -177
  260. data/lib/carray/math/recurrence.rb +0 -93
  261. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  262. data/lib/carray/object/ca_obj_link.rb +0 -50
  263. data/lib/carray/object/ca_obj_pack.rb +0 -99
  264. data/lib/carray/obsolete.rb +0 -256
  265. data/lib/carray/ordering.rb +0 -181
  266. data/lib/carray/testing.rb +0 -51
  267. data/lib/carray/transform.rb +0 -109
  268. data/misc/Methods.ja.md +0 -182
  269. data/misc/NOTE +0 -51
  270. data/spec/Classes/CABitfield_spec.rb +0 -58
  271. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  272. data/spec/Classes/CABlock_spec.rb +0 -205
  273. data/spec/Classes/CAField_spec.rb +0 -39
  274. data/spec/Classes/CAGrid_spec.rb +0 -75
  275. data/spec/Classes/CAMap_spec.rb +0 -0
  276. data/spec/Classes/CAMapping_spec.rb +0 -105
  277. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  278. data/spec/Classes/CAObject_spec.rb +0 -33
  279. data/spec/Classes/CARefer_spec.rb +0 -93
  280. data/spec/Classes/CARepeat_spec.rb +0 -65
  281. data/spec/Classes/CASelect_spec.rb +0 -22
  282. data/spec/Classes/CAShift_spec.rb +0 -16
  283. data/spec/Classes/CAStruct_spec.rb +0 -71
  284. data/spec/Classes/CATranspose_spec.rb +0 -60
  285. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  286. data/spec/Classes/CAWindow_spec.rb +0 -54
  287. data/spec/Classes/CAWrap_spec.rb +0 -8
  288. data/spec/Classes/CArray_spec.rb +0 -184
  289. data/spec/Classes/CScalar_spec.rb +0 -55
  290. data/spec/Classes/ex1.rb +0 -46
  291. data/spec/Features/feature_130_spec.rb +0 -19
  292. data/spec/Features/feature_attributes_spec.rb +0 -280
  293. data/spec/Features/feature_boolean_spec.rb +0 -98
  294. data/spec/Features/feature_broadcast.rb +0 -116
  295. data/spec/Features/feature_cast_function.rb +0 -19
  296. data/spec/Features/feature_cast_spec.rb +0 -33
  297. data/spec/Features/feature_class_spec.rb +0 -84
  298. data/spec/Features/feature_complex_spec.rb +0 -42
  299. data/spec/Features/feature_composite_spec.rb +0 -124
  300. data/spec/Features/feature_convert_spec.rb +0 -46
  301. data/spec/Features/feature_copy_spec.rb +0 -123
  302. data/spec/Features/feature_creation_spec.rb +0 -84
  303. data/spec/Features/feature_element_spec.rb +0 -144
  304. data/spec/Features/feature_extream_spec.rb +0 -54
  305. data/spec/Features/feature_generate_spec.rb +0 -74
  306. data/spec/Features/feature_index_spec.rb +0 -69
  307. data/spec/Features/feature_mask_spec.rb +0 -580
  308. data/spec/Features/feature_math_spec.rb +0 -97
  309. data/spec/Features/feature_order_spec.rb +0 -146
  310. data/spec/Features/feature_ref_store_spec.rb +0 -209
  311. data/spec/Features/feature_serialization_spec.rb +0 -125
  312. data/spec/Features/feature_stat_spec.rb +0 -397
  313. data/spec/Features/feature_virtual_spec.rb +0 -48
  314. data/spec/Features/method_eq_spec.rb +0 -81
  315. data/spec/Features/method_is_nan_spec.rb +0 -12
  316. data/spec/Features/method_map_spec.rb +0 -54
  317. data/spec/Features/method_max_with.rb +0 -20
  318. data/spec/Features/method_min_with.rb +0 -19
  319. data/spec/Features/method_ne_spec.rb +0 -18
  320. data/spec/Features/method_project_spec.rb +0 -188
  321. data/spec/Features/method_ref_spec.rb +0 -27
  322. data/spec/Features/method_round_spec.rb +0 -11
  323. data/spec/Features/method_s_linspace_spec.rb +0 -48
  324. data/spec/Features/method_s_span_spec.rb +0 -14
  325. data/spec/Features/method_seq_spec.rb +0 -47
  326. data/spec/Features/method_sort_with.rb +0 -43
  327. data/spec/Features/method_sorted_with.rb +0 -29
  328. data/spec/Features/method_span_spec.rb +0 -42
  329. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  330. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  331. data/spec/spec_all.rb +0 -10
  332. data/utils/ca_ase.rb +0 -21
  333. data/utils/ca_methods.rb +0 -15
  334. data/utils/cast_checker.rb +0 -30
  335. data/utils/convert_test.rb +0 -73
  336. data/utils/extract_yard.rb +0 -22
  337. data/utils/guess_shape.rb +0 -76
  338. data/utils/monkey_patch_methods.rb +0 -62
  339. data/utils/remove_resource_fork.sh +0 -5
@@ -1,10 +1,9 @@
1
1
  /* ---------------------------------------------------------------------------
2
2
 
3
- carray_generate.c
4
-
5
- This file is part of Ruby/CArray extension library.
6
-
7
- Copyright (C) 2005-2020 Hiroki Motoyoshi
3
+ Population helpers that fill a CArray in place: #where (collect flat
4
+ addresses of non-zero / true cells) and the #seq / #seq! family
5
+ (arithmetic / object-method progressions). User-facing docs live in
6
+ yard-stubs/carray_generate.rb.
8
7
 
9
8
  ---------------------------------------------------------------------------- */
10
9
 
@@ -13,52 +12,13 @@
13
12
 
14
13
  /* ----------------------------------------------------------------- */
15
14
 
16
- /* @overload set (*idx)
17
-
18
- (Boolean, Modification)
19
- Sets true at the given index for the boolean array and returns self.
20
- It accept the arguments same as for CArray#[].
21
- */
22
-
23
- static VALUE
24
- rb_ca_boolean_set (int argc, VALUE *argv, VALUE self)
25
- {
26
- VALUE one = INT2NUM(1);
27
- rb_ca_modify(self);
28
- if ( ! rb_ca_is_boolean_type(self) ) {
29
- rb_raise(rb_eCADataTypeError, "reciever should be a boolean array");
30
- }
31
- rb_ca_store2(self, argc, argv, one);
32
- return self;
33
- }
34
-
35
- /* @overload unset (*idx)
36
-
37
- (Boolean, Modification)
38
- Sets false at the given index for the boolean array and returns self.
39
- It accept the arguments same as for CArray#[].
40
- */
41
-
42
- static VALUE
43
- rb_ca_boolean_unset (int argc, VALUE *argv, VALUE self)
44
- {
45
- VALUE zero = INT2NUM(0);
46
- rb_ca_modify(self);
47
- if ( ! rb_ca_is_boolean_type(self) ) {
48
- rb_raise(rb_eCADataTypeError, "reciever should be a boolean array");
49
- }
50
- rb_ca_store2(self, argc, argv, zero);
51
- return self;
52
- }
53
-
54
- /* ----------------------------------------------------------------- */
55
-
56
- /* @overload where
57
-
58
- (Conversion)
59
- Returns the 1d index array for non-zero elements of self
60
- */
15
+ /* CArray#where -- collect the flat addresses of all non-zero (or
16
+ true) cells in self into a fresh 1-D CA_SIZE array. Non-boolean
17
+ inputs are first coerced to boolean via rb_ca_to_boolean. Masked
18
+ cells are excluded.
61
19
 
20
+ Also used internally by ext/ca_obj_grid.c when it needs to extract
21
+ the addresses of true cells from a boolean axis selector. */
62
22
  VALUE
63
23
  rb_ca_where (VALUE self)
64
24
  {
@@ -119,6 +79,7 @@ rb_ca_where (VALUE self)
119
79
 
120
80
  /* ----------------------------------------------------------------- */
121
81
 
82
+ /* Fill the whole array in row-major order with `step*i + offset`. */
122
83
  #define proc_seq_bang(type, from, to) \
123
84
  { \
124
85
  type *p = (type *)ca->ptr; \
@@ -145,44 +106,118 @@ rb_ca_where (VALUE self)
145
106
  } \
146
107
  }
147
108
 
148
- #define proc_seq_bang_with_block(type, from, to) \
149
- { \
150
- type *p = (type *)ca->ptr; \
151
- ca_size_t i; \
152
- if ( NIL_P(roffset) && NIL_P(rstep) ) { \
153
- for (i=0; i<ca->elements; i++) { \
154
- *p++ = (type) from(rb_yield(SIZE2NUM(i))); \
155
- } \
156
- } \
157
- else if ( rb_obj_is_kind_of(rstep, rb_cFloat) || \
158
- rb_obj_is_kind_of(roffset, rb_cFloat)) { \
159
- type offset = (NIL_P(roffset)) ? (type) 0 : (type) from(roffset); \
160
- double step = (NIL_P(rstep)) ? 1 : NUM2DBL(rstep); \
161
- for (i=0; i<ca->elements; i++) { \
162
- *p++ = (type) from(rb_yield(rb_float_new(step*i+offset))); \
163
- } \
164
- } \
165
- else { \
166
- type offset = (NIL_P(roffset)) ? (type) 0 : (type) from(roffset); \
167
- type step = (NIL_P(rstep)) ? (type) 1 : (type) from(rstep); \
168
- for (i=0; i<ca->elements; i++) { \
169
- *p++ = (type) from(rb_yield(SIZE2NUM(step*i+offset))); \
170
- } \
171
- } \
109
+ /* Per-axis fill: the value depends only on the coordinate along the seq
110
+ axis, so it is constant over the `inner_size` cells inside that axis
111
+ and repeats for each of the `outer_size` blocks outside it. Writing
112
+ these as contiguous constant runs keeps the sweep fully streaming
113
+ (memset-class); when the seq axis is innermost, inner_size collapses
114
+ to 1 and this degenerates to a ramp. `len`, `inner_size`,
115
+ `outer_size` come from the enclosing scope (ca_seq_geometry). */
116
+ #define proc_seq_bang_axis(type, from, to) \
117
+ { \
118
+ type *p = (type *)ca->ptr; \
119
+ ca_size_t o, k, in; \
120
+ if ( rb_obj_is_kind_of(rstep, rb_cFloat) || \
121
+ rb_obj_is_kind_of(roffset, rb_cFloat) ) { \
122
+ type offset = (NIL_P(roffset)) ? (type) 0 : (type) from(roffset); \
123
+ double step = (NIL_P(rstep)) ? 1 : NUM2DBL(rstep); \
124
+ for (o=0; o<outer_size; o++) { \
125
+ for (k=0; k<len; k++) { \
126
+ type v = (type) to(step*k+offset); \
127
+ for (in=0; in<inner_size; in++) { *p++ = v; } \
128
+ } \
129
+ } \
130
+ } \
131
+ else { \
132
+ type offset = (NIL_P(roffset)) ? (type) 0 : (type) from(roffset); \
133
+ type step = (NIL_P(rstep)) ? (type) 1 : (type) from(rstep); \
134
+ for (o=0; o<outer_size; o++) { \
135
+ for (k=0; k<len; k++) { \
136
+ type v = (type) to(step*k+offset); \
137
+ for (in=0; in<inner_size; in++) { *p++ = v; } \
138
+ } \
139
+ } \
140
+ } \
141
+ }
142
+
143
+ #ifdef HAVE_COMPLEX_H
144
+ #define seq_complex_cases(PROC) \
145
+ case CA_CMPLX64: PROC(cmplx64_t, (cmplx64_t) NUM2CC, ); break; \
146
+ case CA_CMPLX128: PROC(cmplx128_t, NUM2CC, ); break;
147
+ #else
148
+ #define seq_complex_cases(PROC)
149
+ #endif
150
+
151
+ /* Dispatch `PROC` (proc_seq_bang or proc_seq_bang_axis) over the numeric
152
+ data types. */
153
+ #define seq_bang_switch(PROC) \
154
+ switch ( ca->data_type ) { \
155
+ case CA_INT8: PROC(int8_t, NUM2LONG, ); break; \
156
+ case CA_UINT8: PROC(uint8_t, NUM2ULONG, ); break; \
157
+ case CA_INT16: PROC(int16_t, NUM2LONG, ); break; \
158
+ case CA_UINT16: PROC(uint16_t, NUM2ULONG, ); break; \
159
+ case CA_INT32: PROC(int32_t, NUM2LONG, ); break; \
160
+ case CA_UINT32: PROC(uint32_t, NUM2ULONG, ); break; \
161
+ case CA_INT64: PROC(int64_t, NUM2LL, ); break; \
162
+ case CA_UINT64: PROC(uint64_t, rb_num2ull, ); break; \
163
+ case CA_FLOAT32: PROC(float32_t, NUM2DBL, ); break; \
164
+ case CA_FLOAT64: PROC(float64_t, NUM2DBL, ); break; \
165
+ seq_complex_cases(PROC) \
166
+ default: rb_raise(rb_eCADataTypeError, \
167
+ "invalid data type of receiver"); \
172
168
  }
173
169
 
170
+ /* Resolve the `axis:` kwarg to a concrete axis, or -1 for a flat fill.
171
+ Rejects a non-integer (e.g. an Array: multi-axis seq is not
172
+ supported) and an out-of-range axis; normalizes a negative axis. */
173
+ static int
174
+ ca_seq_resolve_axis (CArray *ca, VALUE raxis)
175
+ {
176
+ int axis;
177
+ if ( NIL_P(raxis) ) {
178
+ return -1;
179
+ }
180
+ if ( TYPE(raxis) == T_ARRAY ) {
181
+ rb_raise(rb_eArgError,
182
+ "seq axis must be a single integer (multi-axis seq is not supported)");
183
+ }
184
+ axis = NUM2INT(raxis);
185
+ if ( axis < 0 ) {
186
+ axis += ca->ndim;
187
+ }
188
+ if ( axis < 0 || axis >= ca->ndim ) {
189
+ rb_raise(rb_eArgError,
190
+ "axis out of range for seq (0...%d)", ca->ndim);
191
+ }
192
+ return axis;
193
+ }
194
+
195
+ /* Row-major geometry of a per-axis fill: `len` = length of the seq
196
+ axis, `inner` = product of the trailing dims (contiguous run held
197
+ constant), `outer` = product of the leading dims. */
198
+ static void
199
+ ca_seq_geometry (CArray *ca, int axis,
200
+ ca_size_t *len, ca_size_t *inner, ca_size_t *outer)
201
+ {
202
+ int i;
203
+ ca_size_t in = 1, out = 1;
204
+ for (i=axis+1; i<ca->ndim; i++) { in *= ca->dim[i]; }
205
+ for (i=0; i<axis; i++) { out *= ca->dim[i]; }
206
+ *len = ca->dim[axis];
207
+ *inner = in;
208
+ *outer = out;
209
+ }
210
+
174
211
  static VALUE
175
- rb_ca_seq_bang_object (int argc, VALUE *argv, VALUE self)
212
+ rb_ca_seq_bang_object (VALUE self, VALUE roffset, VALUE rstep, int axis)
176
213
  {
177
- volatile VALUE roffset, rstep, rval, rmethod = Qnil;
214
+ volatile VALUE rval, rmethod = Qnil;
178
215
  CArray *ca;
179
216
  VALUE *p;
180
217
  ca_size_t i;
181
218
 
182
219
  TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
183
220
 
184
- rb_scan_args((argc>2) ? 2 : argc, argv, "02", (VALUE *) &roffset, (VALUE *) &rstep);
185
-
186
221
  if ( TYPE(rstep) == T_SYMBOL ) { /* e.g. a.seq("a", :succ) */
187
222
  rmethod = rstep;
188
223
  rstep = Qnil;
@@ -194,45 +229,92 @@ rb_ca_seq_bang_object (int argc, VALUE *argv, VALUE self)
194
229
  ca_clear_mask(ca); /* clear all mask */
195
230
  }
196
231
 
197
- p = (VALUE *)ca->ptr;
198
- if ( rb_obj_is_kind_of(roffset, rb_cFloat) ||
199
- rb_obj_is_kind_of(rstep, rb_cFloat) ) { /* a.seq(0.0, 1.0) */
200
- double offset = ( NIL_P(roffset) ) ? 0 : NUM2DBL(roffset);
201
- double step = ( NIL_P(rstep) ) ? 1 : NUM2DBL(rstep);
202
- for (i=0; i<ca->elements; i++) {
203
- *p++ = rb_float_new(step*i+offset);
232
+ if ( axis < 0 ) { /* flat fill */
233
+ p = (VALUE *)ca->ptr;
234
+ if ( rb_obj_is_kind_of(roffset, rb_cFloat) ||
235
+ rb_obj_is_kind_of(rstep, rb_cFloat) ) { /* a.seq(0.0, 1.0) */
236
+ double offset = ( NIL_P(roffset) ) ? 0 : NUM2DBL(roffset);
237
+ double step = ( NIL_P(rstep) ) ? 1 : NUM2DBL(rstep);
238
+ for (i=0; i<ca->elements; i++) {
239
+ *p++ = rb_float_new(step*i+offset);
240
+ }
204
241
  }
205
- }
206
- else if ( NIL_P(roffset) ) {
207
- if ( ! NIL_P(rstep) ) { /* a.seq(nil, 1) */
208
- rb_raise(rb_eArgError,
209
- "nil is invalid as offset for seq([offset[,step])");
242
+ else if ( NIL_P(roffset) ) {
243
+ if ( ! NIL_P(rstep) ) { /* a.seq(nil, 1) */
244
+ rb_raise(rb_eArgError,
245
+ "nil is invalid as offset for seq([offset[,step])");
246
+ }
247
+ for (i=0; i<ca->elements; i++) { /* a.seq() */
248
+ *p++ = LL2NUM(i);
249
+ }
210
250
  }
211
- for (i=0; i<ca->elements; i++) { /* a.seq() */
212
- *p++ = INT2NUM(i);
251
+ else if ( ! NIL_P(rmethod) ) { /* a.seq(obj, :method) */
252
+ ID id_method = SYM2ID(rmethod);
253
+ *p++ = rval = roffset;
254
+ for (i=1; i<ca->elements; i++) {
255
+ *p++ = rval = rb_funcall(rval, id_method, 0);
256
+ }
213
257
  }
214
- }
215
- else if ( ! NIL_P(rmethod) ) { /* a.seq(obj, :method) */
216
- ID id_method = SYM2ID(rmethod);
217
- *p++ = rval = roffset;
218
- for (i=1; i<ca->elements; i++) {
219
- *p++ = rval = rb_funcall2(rval, id_method, argc-2, argv+2);
258
+ else { /* a.seq(obj, step) */
259
+ ID id_plus = rb_intern("+");
260
+ rstep = ( NIL_P(rstep) ) ? INT2NUM(1) : rstep;
261
+ *p++ = rval = roffset;
262
+ for (i=1; i<ca->elements; i++) {
263
+ *p++ = rval = rb_funcall(rval, id_plus, 1, rstep);
264
+ }
220
265
  }
221
266
  }
222
- else { /* a.seq(obj, step) */
223
- ID id_plus = rb_intern("+");
224
- rstep = ( NIL_P(rstep) ) ? INT2NUM(1) : rstep;
225
- *p++ = rval = roffset;
226
- for (i=1; i<ca->elements; i++) {
227
- *p++ = rval = rb_funcall(rval, id_plus, 1, rstep);
267
+ else { /* per-axis fill */
268
+ /* Build the length-`len` progression first, then broadcast it over
269
+ the outer/inner dims. The generated VALUEs are held in a Ruby
270
+ Array so the GC keeps them live across the progression's method
271
+ calls (rb_funcall may trigger a collection). */
272
+ ca_size_t len, inner_size, outer_size, o, k, in;
273
+ volatile VALUE vtbl;
274
+ ca_seq_geometry(ca, axis, &len, &inner_size, &outer_size);
275
+ vtbl = rb_ary_new_capa(len);
276
+ if ( rb_obj_is_kind_of(roffset, rb_cFloat) ||
277
+ rb_obj_is_kind_of(rstep, rb_cFloat) ) {
278
+ double offset = ( NIL_P(roffset) ) ? 0 : NUM2DBL(roffset);
279
+ double step = ( NIL_P(rstep) ) ? 1 : NUM2DBL(rstep);
280
+ for (k=0; k<len; k++) {
281
+ rb_ary_push(vtbl, rb_float_new(step*k+offset));
282
+ }
283
+ }
284
+ else if ( NIL_P(roffset) ) {
285
+ if ( ! NIL_P(rstep) ) {
286
+ rb_raise(rb_eArgError,
287
+ "nil is invalid as offset for seq([offset[,step])");
288
+ }
289
+ for (k=0; k<len; k++) {
290
+ rb_ary_push(vtbl, LL2NUM(k));
291
+ }
292
+ }
293
+ else if ( ! NIL_P(rmethod) ) {
294
+ ID id_method = SYM2ID(rmethod);
295
+ rval = roffset;
296
+ rb_ary_push(vtbl, rval);
297
+ for (k=1; k<len; k++) {
298
+ rval = rb_funcall(rval, id_method, 0);
299
+ rb_ary_push(vtbl, rval);
300
+ }
301
+ }
302
+ else {
303
+ ID id_plus = rb_intern("+");
304
+ rstep = ( NIL_P(rstep) ) ? INT2NUM(1) : rstep;
305
+ rval = roffset;
306
+ rb_ary_push(vtbl, rval);
307
+ for (k=1; k<len; k++) {
308
+ rval = rb_funcall(rval, id_plus, 1, rstep);
309
+ rb_ary_push(vtbl, rval);
310
+ }
228
311
  }
229
- }
230
-
231
- if ( rb_block_given_p() ) {
232
312
  p = (VALUE *)ca->ptr;
233
- for(i=0; i<ca->elements; i++) {
234
- *p = rb_yield(*p);
235
- p++;
313
+ for (o=0; o<outer_size; o++) {
314
+ for (k=0; k<len; k++) {
315
+ VALUE v = RARRAY_AREF(vtbl, k);
316
+ for (in=0; in<inner_size; in++) { *p++ = v; }
317
+ }
236
318
  }
237
319
  }
238
320
 
@@ -242,91 +324,48 @@ rb_ca_seq_bang_object (int argc, VALUE *argv, VALUE self)
242
324
  return self;
243
325
  }
244
326
 
245
- /* @overload seq! (init_val=0, step=1) {|elem| ... }
246
-
247
- (Conversion, Destructive)
248
- Generates sequential data with initial value `init_val`
249
- and step value `step`. For object array, if the second argument
250
- is Symbol object, it will be interpreted as stepping method and
251
- it is called for the last element in each step.
252
- # call-seq:
253
- # seq (init_val=0, step=1)
254
- # seq (init_val=0, step=1) {|x| ... }
255
- # seq (init_val=0, step=A_symbol) ### for object array
256
- # seq (init_val=0, step=A_symbol) {|x| ...} ### for object array
257
- #
258
- # Generates sequential data with initial value `init_val`
259
- # and step value `step`. For object array, if the second argument
260
- # is Symbol object, it will be interpreted as stepping method and
261
- # it is called for the last element in each step.
262
- #
263
- */
264
-
327
+ /* CArray#seq!(init_val=0, step=1, axis: nil) -- arithmetic-progression
328
+ fill, in place. Without `axis:` the fill runs in row-major order
329
+ over the whole array; with `axis: k` the progression runs along axis
330
+ k and repeats across the other axes. Numeric arrays use the typed
331
+ proc_seq_bang / proc_seq_bang_axis macros; object arrays delegate to
332
+ rb_ca_seq_bang_object (which also accepts a Symbol `step` to drive
333
+ per-element method calls like `:succ`). Mutates self and clears any
334
+ existing mask. */
265
335
  static VALUE
266
336
  rb_ca_seq_bang_method (int argc, VALUE *argv, VALUE self)
267
337
  {
268
- volatile VALUE roffset, rstep;
338
+ volatile VALUE roffset = Qnil, rstep = Qnil, rkw = Qnil, raxis = Qnil;
269
339
  CArray *ca;
340
+ int axis;
270
341
 
271
342
  rb_ca_modify(self);
272
343
  TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
273
344
 
345
+ rb_scan_args(argc, argv, "02:", (VALUE *) &roffset, (VALUE *) &rstep,
346
+ (VALUE *) &rkw);
347
+ rb_scan_options(rkw, "axis", (VALUE *) &raxis);
348
+
349
+ axis = ca_seq_resolve_axis(ca, raxis); /* -1 = flat; validates */
350
+
274
351
  /* delegate to rb_ca_seq_bang_object if data_type is object */
275
352
  if ( ca_is_object_type(ca) ) {
276
- return rb_ca_seq_bang_object(argc, argv, self);
353
+ return rb_ca_seq_bang_object(self, roffset, rstep, axis);
277
354
  }
278
355
 
279
- rb_scan_args(argc, argv, "02", (VALUE *) &roffset, (VALUE *) &rstep);
280
-
281
356
  ca_allocate(ca);
282
357
 
283
358
  if ( ca_has_mask(ca) ) {
284
359
  ca_clear_mask(ca); /* clear all mask */
285
360
  }
286
361
 
287
- if ( rb_block_given_p() ) { /* with block */
288
- switch ( ca->data_type ) {
289
- case CA_INT8: proc_seq_bang_with_block(int8_t, NUM2LONG, ); break;
290
- case CA_UINT8: proc_seq_bang_with_block(uint8_t, NUM2ULONG, ); break;
291
- case CA_INT16: proc_seq_bang_with_block(int16_t, NUM2LONG, ) ; break;
292
- case CA_UINT16: proc_seq_bang_with_block(uint16_t, NUM2ULONG, ); break;
293
- case CA_INT32: proc_seq_bang_with_block(int32_t, NUM2LONG, ); break;
294
- case CA_UINT32: proc_seq_bang_with_block(uint32_t, NUM2ULONG, ); break;
295
- case CA_INT64: proc_seq_bang_with_block(int64_t, NUM2LL, ); break;
296
- case CA_UINT64: proc_seq_bang_with_block(uint64_t, rb_num2ull, ); break;
297
- case CA_FLOAT32: proc_seq_bang_with_block(float32_t, NUM2DBL, ); break;
298
- case CA_FLOAT64: proc_seq_bang_with_block(float64_t, NUM2DBL, ); break;
299
- case CA_FLOAT128: proc_seq_bang_with_block(float128_t, NUM2DBL, ); break;
300
- #ifdef HAVE_COMPLEX_H
301
- case CA_CMPLX64: proc_seq_bang_with_block(cmplx64_t, (cmplx64_t) NUM2CC,); break;
302
- case CA_CMPLX128: proc_seq_bang_with_block(cmplx128_t, NUM2CC, ); break;
303
- case CA_CMPLX256: proc_seq_bang_with_block(cmplx256_t, (cmplx256_t) NUM2CC, ); break;
304
- #endif
305
- default: rb_raise(rb_eCADataTypeError,
306
- "invalid data type of receiver");
307
- }
362
+ if ( axis < 0 ) {
363
+ seq_bang_switch(proc_seq_bang);
308
364
  }
309
- else { /* without block */
310
- switch ( ca->data_type ) {
311
- case CA_INT8: proc_seq_bang(int8_t, NUM2LONG, ); break;
312
- case CA_UINT8: proc_seq_bang(uint8_t, NUM2ULONG, ); break;
313
- case CA_INT16: proc_seq_bang(int16_t, NUM2LONG, ) ; break;
314
- case CA_UINT16: proc_seq_bang(uint16_t, NUM2ULONG, ); break;
315
- case CA_INT32: proc_seq_bang(int32_t, NUM2LONG, ); break;
316
- case CA_UINT32: proc_seq_bang(uint32_t, NUM2ULONG, ); break;
317
- case CA_INT64: proc_seq_bang(int64_t, NUM2LL, ); break;
318
- case CA_UINT64: proc_seq_bang(uint64_t, rb_num2ull, ); break;
319
- case CA_FLOAT32: proc_seq_bang(float32_t, NUM2DBL, ); break;
320
- case CA_FLOAT64: proc_seq_bang(float64_t, NUM2DBL, ); break;
321
- case CA_FLOAT128: proc_seq_bang(float128_t, NUM2DBL, ); break;
322
- #ifdef HAVE_COMPLEX_H
323
- case CA_CMPLX64: proc_seq_bang(cmplx64_t, (cmplx64_t) NUM2CC, ); break;
324
- case CA_CMPLX128: proc_seq_bang(cmplx128_t, NUM2CC, ); break;
325
- case CA_CMPLX256: proc_seq_bang(cmplx256_t, (cmplx256_t) NUM2CC, ); break;
326
- #endif
327
- default: rb_raise(rb_eCADataTypeError,
328
- "invalid data type of reciever");
329
- }
365
+ else {
366
+ ca_size_t len, inner_size, outer_size;
367
+ ca_seq_geometry(ca, axis, &len, &inner_size, &outer_size);
368
+ seq_bang_switch(proc_seq_bang_axis);
330
369
  }
331
370
 
332
371
  ca_sync(ca);
@@ -335,26 +374,9 @@ rb_ca_seq_bang_method (int argc, VALUE *argv, VALUE self)
335
374
  return self;
336
375
  }
337
376
 
338
- /* @overload seq (init_val=0, step=1) {|elem| ... }
339
-
340
- (Conversion)
341
- Generates sequential data with initial value `init_val`
342
- and step value `step`. For object array, if the second argument
343
- is Symbol object, it will be interpreted as stepping method and
344
- it is called for the last element in each step.
345
- # call-seq:
346
- # seq (init_val=0, step=1)
347
- # seq (init_val=0, step=1) {|x| ... }
348
- # seq (init_val=0, step=A_symbol) ### for object array
349
- # seq (init_val=0, step=A_symbol) {|x| ...} ### for object array
350
- #
351
- # Generates sequential data with initial value `init_val`
352
- # and step value `step`. For object array, if the second argument
353
- # is Symbol object, it will be interpreted as stepping method and
354
- # it is called for the last element in each step.
355
- #
356
- */
357
-
377
+ /* CArray#seq(init_val=0, step=1, axis: nil) -- non-destructive variant:
378
+ allocate a fresh template like self and fill it via
379
+ rb_ca_seq_bang_method. */
358
380
  static VALUE
359
381
  rb_ca_seq_method (int argc, VALUE *argv, VALUE self)
360
382
  {
@@ -362,6 +384,9 @@ rb_ca_seq_method (int argc, VALUE *argv, VALUE self)
362
384
  return rb_ca_seq_bang_method(argc, argv, out);
363
385
  }
364
386
 
387
+ /* C-call shims: pack the (offset, step) args and route through the
388
+ Ruby-method entries above. Called by ext/carray_cast.c (= the
389
+ Range / ArithmeticSequence to-CArray path uses rb_ca_seq). */
365
390
  VALUE
366
391
  rb_ca_seq_bang (VALUE self, VALUE offset, VALUE step)
367
392
  {
@@ -390,378 +415,24 @@ rb_ca_seq2 (VALUE self, int n, VALUE *args)
390
415
 
391
416
  /* ----------------------------------------------------------------- */
392
417
 
393
-
394
- void
395
- ca_swap_bytes (char *ptr, ca_size_t bytes, ca_size_t elements)
396
- {
397
- char *p;
398
- char val;
399
- ca_size_t i;
400
-
401
- #define SWAP_BYTE(a, b) (val = (a), (a) = (b), (b) = val)
402
-
403
- switch ( bytes ) {
404
- case 1:
405
- break;
406
- case 2:
407
- #ifdef _OPENMP
408
- #pragma omp parallel for private(p)
409
- #endif
410
- for (i=0; i<elements; i++) {
411
- p = ptr + 2*i;
412
- SWAP_BYTE(p[0], p[1]);
413
- }
414
- break;
415
- case 4:
416
- #ifdef _OPENMP
417
- #pragma omp parallel for private(p)
418
- #endif
419
- for (i=0; i<elements; i++) {
420
- p = ptr + 4*i;
421
- SWAP_BYTE(p[0], p[3]);
422
- SWAP_BYTE(p[1], p[2]);
423
- }
424
- break;
425
- case 8:
426
- #ifdef _OPENMP
427
- #pragma omp parallel for private(p)
428
- #endif
429
- for (i=0; i<elements; i++) {
430
- p = ptr + 8*i;
431
- SWAP_BYTE(p[0], p[7]);
432
- SWAP_BYTE(p[1], p[6]);
433
- SWAP_BYTE(p[2], p[5]);
434
- SWAP_BYTE(p[3], p[4]);
435
- }
436
- break;
437
- case 16:
438
- #ifdef _OPENMP
439
- #pragma omp parallel for private(p)
440
- #endif
441
- for (i=0; i<elements; i++) {
442
- p = ptr + 16*i;
443
- SWAP_BYTE(p[0], p[15]);
444
- SWAP_BYTE(p[1], p[14]);
445
- SWAP_BYTE(p[2], p[13]);
446
- SWAP_BYTE(p[3], p[12]);
447
- SWAP_BYTE(p[4], p[11]);
448
- SWAP_BYTE(p[5], p[10]);
449
- SWAP_BYTE(p[6], p[9]);
450
- SWAP_BYTE(p[7], p[8]);
451
- }
452
- break;
453
- default: {
454
- char *p1, *p2;
455
- #ifdef _OPENMP
456
- #pragma omp parallel for private(p,p1,p2)
457
- #endif
458
- for (i=0; i<elements; i++) {
459
- p = ptr + i*bytes;
460
- p1 = p;
461
- p2 = p+bytes-1;
462
- while (p1<p2) {
463
- SWAP_BYTE(*p1, *p2);
464
- p1++; p2--;
465
- }
466
- }
467
- break;
468
- }
469
- }
470
-
471
- #undef SWAP_BYTE
472
-
473
- }
474
-
475
- /* @overload swap_bytes!
476
-
477
- (Conversion, Destructive)
478
- Swaps the byte order of each element.
479
- */
480
-
481
- VALUE
482
- rb_ca_swap_bytes_bang (VALUE self)
483
- {
484
- CArray *ca;
485
- int i;
486
-
487
- rb_ca_modify(self);
488
-
489
- if ( rb_ca_is_object_type(self) ) {
490
- rb_raise(rb_eCADataTypeError, "object array can't swap bytes");
491
- }
492
-
493
- if ( rb_ca_is_fixlen_type(self) ) {
494
- if ( rb_ca_has_data_class(self) ) {
495
- volatile VALUE members = rb_ca_fields(self);
496
- Check_Type(members, T_ARRAY);
497
- for (i=0; i<RARRAY_LEN(members); i++) {
498
- volatile VALUE obj = rb_ary_entry(members, i);
499
- rb_ca_swap_bytes_bang(obj);
500
- }
501
- }
502
- else {
503
- TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
504
- ca_attach(ca);
505
- ca_swap_bytes(ca->ptr, ca->bytes, ca->elements);
506
- ca_sync(ca);
507
- ca_detach(ca);
508
- }
509
- return self;
510
- }
511
-
512
- TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
513
-
514
- switch ( ca->data_type ) {
515
- case CA_INT16:
516
- case CA_UINT16:
517
- ca_attach(ca);
518
- ca_swap_bytes(ca->ptr, 2, ca->elements);
519
- ca_sync(ca);
520
- ca_detach(ca);
521
- break;
522
- case CA_INT32:
523
- case CA_UINT32:
524
- case CA_FLOAT32:
525
- ca_attach(ca);
526
- ca_swap_bytes(ca->ptr, 4, ca->elements);
527
- ca_sync(ca);
528
- ca_detach(ca);
529
- break;
530
- case CA_INT64:
531
- case CA_UINT64:
532
- case CA_FLOAT64:
533
- ca_attach(ca);
534
- ca_swap_bytes(ca->ptr, 8, ca->elements);
535
- ca_sync(ca);
536
- ca_detach(ca);
537
- break;
538
- case CA_FLOAT128:
539
- ca_attach(ca);
540
- ca_swap_bytes(ca->ptr, 16, ca->elements);
541
- ca_sync(ca);
542
- ca_detach(ca);
543
- break;
544
- case CA_CMPLX64:
545
- ca_attach(ca);
546
- ca_swap_bytes(ca->ptr, 4, 2 * ca->elements);
547
- ca_sync(ca);
548
- ca_detach(ca);
549
- break;
550
- case CA_CMPLX128:
551
- ca_attach(ca);
552
- ca_swap_bytes(ca->ptr, 8, 2 * ca->elements);
553
- ca_sync(ca);
554
- ca_detach(ca);
555
- break;
556
- case CA_CMPLX256:
557
- ca_attach(ca);
558
- ca_swap_bytes(ca->ptr, 16, 2 * ca->elements);
559
- ca_sync(ca);
560
- ca_detach(ca);
561
- break;
562
- }
563
-
564
- return self;
565
- }
566
-
567
- /* @overload swap_bytes
568
-
569
- (Conversion)
570
- Swaps the byte order of each element.
571
- */
572
-
573
- VALUE
574
- rb_ca_swap_bytes (VALUE self)
575
- {
576
- volatile VALUE out = rb_ca_copy(self);
577
- return rb_ca_swap_bytes_bang(out);
578
- }
418
+ /* CArray#swap_bytes lives in ext/ca_obj_byte_swap.c (returns a lazy
419
+ CAByteSwap view). Use `arr.swap_bytes.to_ca` when an eager copy is
420
+ wanted. */
579
421
 
580
422
  /* ----------------------------------------------------------------- */
581
423
 
582
- #define proc_trim_bang2(type, from) \
583
- { \
584
- type *ptr = (type *) ca->ptr; \
585
- boolean8_t *m = (ca->mask) ? (boolean8_t*) ca->mask->ptr : NULL; \
586
- type min = (type) from(rmin); \
587
- type max = (type) from(rmax); \
588
- ca_size_t i; \
589
- if ( m && rfval == CA_UNDEF) { \
590
- for (i=ca->elements; i; i--, ptr++, m++) { \
591
- if ( ! *m ) { \
592
- if ( *ptr < min || *ptr >= max ) \
593
- *m = 1; \
594
- } \
595
- } \
596
- } \
597
- else { \
598
- int has_fill = ! ( NIL_P(rfval) ); \
599
- type fill = (has_fill) ? (type) from(rfval) : (type) 0; \
600
- if ( m ) { \
601
- for (i=ca->elements; i; i--, ptr++) { \
602
- if ( ! *m++ ) { \
603
- if ( *ptr >= max ) \
604
- *ptr = (has_fill) ? fill : max; \
605
- else if ( *ptr < min ) \
606
- *ptr = (has_fill) ? fill : min; \
607
- } \
608
- } \
609
- } \
610
- else { \
611
- for (i=ca->elements; i; i--, ptr++) { \
612
- if ( *ptr >= max ) \
613
- *ptr = (has_fill) ? fill : max; \
614
- else if ( *ptr < min ) \
615
- *ptr = (has_fill) ? fill : min; \
616
- } \
617
- } \
618
- } \
619
- }
620
-
621
- #define proc_trim_bang(type, from) \
622
- { \
623
- type *ptr = (type *) ca->ptr; \
624
- boolean8_t *m = (ca->mask) ? (boolean8_t*) ca->mask->ptr : NULL; \
625
- if ( ! NIL_P(rmin) ) { \
626
- type min = (type) from(rmin); \
627
- ca_size_t i; \
628
- if ( m && rfval == CA_UNDEF) { \
629
- for (i=ca->elements; i; i--, ptr++, m++) { \
630
- if ( ! *m ) { \
631
- if ( *ptr < min ) \
632
- *m = 1; \
633
- } \
634
- } \
635
- } \
636
- else { \
637
- int has_fill = ! ( NIL_P(rfval) ); \
638
- type fill = (has_fill) ? (type) from(rfval) : (type) 0; \
639
- if ( m ) { \
640
- for (i=ca->elements; i; i--, ptr++) { \
641
- if ( ! *m++ ) { \
642
- if ( *ptr < min ) \
643
- *ptr = (has_fill) ? fill : min; \
644
- } \
645
- } \
646
- } \
647
- else { \
648
- for (i=ca->elements; i; i--, ptr++) { \
649
- if ( *ptr < min ) \
650
- *ptr = (has_fill) ? fill : min; \
651
- } \
652
- } \
653
- } \
654
- } \
655
- if ( ! NIL_P(rmax) ) { \
656
- type max = (type) from(rmax); \
657
- ca_size_t i; \
658
- if ( m && rfval == CA_UNDEF) { \
659
- for (i=ca->elements; i; i--, ptr++, m++) { \
660
- if ( ! *m ) { \
661
- if ( *ptr >= max ) \
662
- *m = 1; \
663
- } \
664
- } \
665
- } \
666
- else { \
667
- int has_fill = ! ( NIL_P(rfval) ); \
668
- type fill = (has_fill) ? (type) from(rfval) : (type) 0; \
669
- if ( m ) { \
670
- for (i=ca->elements; i; i--, ptr++) { \
671
- if ( ! *m++ ) { \
672
- if ( *ptr >= max ) \
673
- *ptr = (has_fill) ? fill : max; \
674
- } \
675
- } \
676
- } \
677
- else { \
678
- for (i=ca->elements; i; i--, ptr++) { \
679
- if ( *ptr >= max ) \
680
- *ptr = (has_fill) ? fill : max; \
681
- } \
682
- } \
683
- } \
684
- } \
685
- }
686
-
687
-
688
-
689
- /* @overload trim! (min, max, fill_value=nil)
690
-
691
- (Conversion)
692
- Trims the data into the range between min and max. If `fill_value`
693
- is given, the element out of the range between min and max is filled
694
- by `fill_value`
695
- */
696
-
697
- static VALUE
698
- rb_ca_trim_bang (int argc, VALUE *argv, VALUE self)
699
- {
700
- volatile VALUE rmin, rmax, rfval;
701
- CArray *ca;
702
-
703
- rb_ca_modify(self);
704
-
705
- TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
706
-
707
- rb_scan_args(argc, argv, "21", (VALUE *) &rmin, (VALUE *) &rmax, (VALUE *) &rfval);
708
-
709
- if ( rfval == CA_UNDEF ) {
710
- ca_create_mask(ca);
711
- }
712
-
713
- ca_attach(ca);
714
-
715
- switch ( ca->data_type ) {
716
- case CA_INT8: proc_trim_bang(int8_t, NUM2INT); break;
717
- case CA_UINT8: proc_trim_bang(uint8_t, NUM2UINT); break;
718
- case CA_INT16: proc_trim_bang(int16_t, NUM2INT); break;
719
- case CA_UINT16: proc_trim_bang(uint16_t, NUM2INT); break;
720
- case CA_INT32: proc_trim_bang(int32_t, NUM2LONG); break;
721
- case CA_UINT32: proc_trim_bang(uint32_t, NUM2LONG); break;
722
- case CA_INT64: proc_trim_bang(int64_t, NUM2LONG); break;
723
- case CA_UINT64: proc_trim_bang(uint64_t, NUM2LONG); break;
724
- case CA_FLOAT32: proc_trim_bang(float32_t, NUM2DBL); break;
725
- case CA_FLOAT64: proc_trim_bang(float64_t, NUM2DBL); break;
726
- case CA_FLOAT128: proc_trim_bang(float128_t, NUM2DBL); break;
727
- default:
728
- rb_raise(rb_eCADataTypeError,
729
- "can not trim for non-numeric or complex data type");
730
- }
731
-
732
- ca_detach(ca);
733
-
734
- return self;
735
- }
736
-
737
- /* @overload trim (min, max, fill_value=nil)
738
-
739
- (Conversion)
740
- Trims the data into the range between min and max. If `fill_value`
741
- is given, the element out of the range between min and max is filled
742
- by `fill_value`
743
- */
744
-
745
- static VALUE
746
- rb_ca_trim (int argc, VALUE *argv, VALUE self)
747
- {
748
- volatile VALUE out = rb_ca_copy(self);
749
- return rb_ca_trim_bang(argc, argv, out);
750
- }
751
424
 
752
425
  void
753
- Init_carray_generate ()
426
+ Init_carray_generate (void)
754
427
  {
755
- rb_define_method(rb_cCArray, "set", rb_ca_boolean_set, -1);
756
- rb_define_method(rb_cCArray, "unset", rb_ca_boolean_unset, -1);
757
-
758
428
  rb_define_method(rb_cCArray, "where", rb_ca_where, 0);
759
429
  rb_define_method(rb_cCArray, "seq!", rb_ca_seq_bang_method, -1);
760
430
  rb_define_method(rb_cCArray, "seq", rb_ca_seq_method, -1);
761
- rb_define_method(rb_cCArray, "swap_bytes!", rb_ca_swap_bytes_bang, 0);
762
- rb_define_method(rb_cCArray, "swap_bytes", rb_ca_swap_bytes, 0);
763
- rb_define_method(rb_cCArray, "trim!", rb_ca_trim_bang, -1);
764
- rb_define_method(rb_cCArray, "trim", rb_ca_trim, -1);
431
+ /* swap_bytes / swap_bytes! (and the ca_swap_bytes kernel) live in
432
+ ext/ca_obj_byte_swap.c; registered by Init_ca_obj_byte_swap.
433
+ clip / clip! are mkkernel-generated as a triop with signature
434
+ (lo, hi); see ext/mkkernel.rb (MkKernel.triop :clip), registered
435
+ by Init_carray_kernels. */
765
436
  }
766
437
 
767
438