carray 3.0.0 → 3.0.2

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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -1
  3. data/CHANGELOG.md +845 -3
  4. data/{NEWS.md → CHANGELOG.v1.md} +1 -1
  5. data/README.md +33 -33
  6. data/carray.gemspec +12 -8
  7. data/ext/ca_axis_dispatch.c +33 -4
  8. data/ext/ca_axis_group.c +256 -114
  9. data/ext/ca_binop_dispatch.c +5 -6
  10. data/ext/ca_binop_dispatch.h +0 -7
  11. data/ext/ca_categorical_iterator.c +121 -67
  12. data/ext/ca_for_each_element.h +6 -8
  13. data/ext/ca_group_iter.c +1 -1
  14. data/ext/ca_kernel_iterator.c +386 -74
  15. data/ext/ca_kernel_iterator.h +145 -45
  16. data/ext/ca_obj_array.c +62 -20
  17. data/ext/ca_obj_bincmp.c +57 -27
  18. data/ext/ca_obj_binop.c +86 -30
  19. data/ext/ca_obj_block.c +4 -4
  20. data/ext/ca_obj_const_string.c +88 -27
  21. data/ext/ca_obj_face.c +104 -0
  22. data/ext/ca_obj_face.h +48 -1
  23. data/ext/ca_obj_fake.c +11 -0
  24. data/ext/ca_obj_fixlen_string.c +21 -6
  25. data/ext/ca_obj_grid.c +11 -3
  26. data/ext/ca_obj_meld.c +125 -22
  27. data/ext/ca_obj_moncmp.c +33 -14
  28. data/ext/ca_obj_monop.c +19 -7
  29. data/ext/ca_obj_object.c +107 -4
  30. data/ext/ca_obj_record.c +3 -1
  31. data/ext/ca_obj_refer.c +30 -6
  32. data/ext/ca_obj_roll.c +13 -5
  33. data/ext/ca_obj_select.c +49 -34
  34. data/ext/ca_obj_select_axis.c +16 -6
  35. data/ext/ca_obj_shift.c +3 -3
  36. data/ext/ca_obj_stack.c +3 -8
  37. data/ext/ca_obj_stride.c +178 -24
  38. data/ext/ca_obj_string.c +11 -5
  39. data/ext/ca_obj_tile.c +13 -5
  40. data/ext/ca_obj_time.c +3 -1
  41. data/ext/ca_obj_timedelta.c +3 -1
  42. data/ext/ca_obj_transpose.c +1 -1
  43. data/ext/ca_obj_triop.c +62 -23
  44. data/ext/ca_obj_window.c +94 -19
  45. data/ext/ca_op_cmplx64.h +123 -0
  46. data/ext/ca_op_ipower.c +1 -5
  47. data/ext/ca_rng_normal.h +42 -0
  48. data/ext/ca_rng_xoshiro256pp.h +105 -0
  49. data/ext/ca_sort_kernels.h +5 -5
  50. data/ext/ca_sweep_engine.c +362 -155
  51. data/ext/ca_sweep_engine.h +39 -9
  52. data/ext/ca_transform_common.c +7 -0
  53. data/ext/carray.h +148 -132
  54. data/ext/carray_access.c +83 -49
  55. data/ext/carray_address_basis.c +590 -0
  56. data/ext/carray_bincount.c +8 -8
  57. data/ext/carray_broadcast.c +102 -9
  58. data/ext/carray_build_flags.h +3 -0
  59. data/ext/carray_call_cfunc.c +2010 -335
  60. data/ext/carray_call_cfunc.h +153 -0
  61. data/ext/carray_cast.c +184 -72
  62. data/ext/carray_conversion.c +22 -22
  63. data/ext/carray_copy.c +67 -32
  64. data/ext/carray_core.c +140 -13
  65. data/ext/carray_count.c +10 -11
  66. data/ext/carray_element.c +7 -7
  67. data/ext/carray_factorize.c +72 -51
  68. data/ext/carray_hold.c +1 -1
  69. data/ext/carray_index_classifier.c +7 -21
  70. data/ext/carray_internal.h +36 -3
  71. data/ext/carray_kernels_bincmp.c +1 -0
  72. data/ext/carray_kernels_binop.c +320 -298
  73. data/ext/carray_kernels_init.c +1095 -0
  74. data/ext/carray_kernels_map.c +1 -0
  75. data/ext/carray_kernels_moncmp.c +1 -0
  76. data/ext/carray_kernels_monop.c +412 -411
  77. data/ext/carray_kernels_reduce_aggregate.c +256 -87
  78. data/ext/carray_kernels_reduce_boolean.c +1 -0
  79. data/ext/carray_kernels_reduce_cumulative.c +324 -54
  80. data/ext/carray_kernels_reduce_extreme.c +605 -58
  81. data/ext/carray_kernels_reduce_variance.c +1 -0
  82. data/ext/carray_kernels_scan.c +5 -4
  83. data/ext/carray_kernels_search.c +187 -106
  84. data/ext/carray_kernels_sort.c +1 -0
  85. data/ext/carray_kernels_triop.c +1 -0
  86. data/ext/carray_lazy.c +175 -5
  87. data/ext/carray_loop.c +7 -1
  88. data/ext/carray_mask.c +29 -13
  89. data/ext/carray_median_percentile.c +56 -1
  90. data/ext/carray_memory_view.c +46 -21
  91. data/ext/carray_operator.c +50 -53
  92. data/ext/carray_order.c +1 -1
  93. data/ext/carray_partition.c +4 -4
  94. data/ext/carray_random.c +391 -47
  95. data/ext/carray_scatter.c +1 -1
  96. data/ext/carray_slab.c +13 -0
  97. data/ext/carray_sort.c +22 -24
  98. data/ext/carray_sort_kernel.c +10 -10
  99. data/ext/carray_test.c +1 -1
  100. data/ext/extconf.rb +18 -0
  101. data/ext/mk_call_cfunc.rb +323 -145
  102. data/ext/mkkernel.rb +651 -129
  103. data/ext/ruby_carray.c +28 -17
  104. data/ext/version.h +4 -4
  105. data/lib/carray/autoload_carray.rb +24 -3
  106. data/lib/carray/autoload_method_extension.rb +14 -1
  107. data/lib/carray/axis_group.rb +84 -7
  108. data/lib/carray/basics.rb +63 -59
  109. data/lib/carray/bincount_nd.rb +12 -12
  110. data/lib/carray/block_iterator.rb +111 -25
  111. data/lib/carray/categorical.rb +154 -37
  112. data/lib/carray/categorical_iterator.rb +300 -151
  113. data/lib/carray/conditional.rb +14 -14
  114. data/lib/carray/const_string.rb +131 -27
  115. data/lib/carray/construct.rb +61 -0
  116. data/lib/carray/core_extensions.rb +62 -5
  117. data/lib/carray/data_type_extension.rb +21 -1
  118. data/lib/carray/data_type_limits.rb +91 -0
  119. data/lib/carray/fixlen_string.rb +1 -1
  120. data/lib/carray/frame/concat.rb +3 -3
  121. data/lib/carray/frame/convert.rb +1 -1
  122. data/lib/carray/frame/csv_parser.rb +11 -4
  123. data/lib/carray/frame/frame.rb +85 -21
  124. data/lib/carray/frame/group.rb +36 -3
  125. data/lib/carray/frame/io.rb +224 -15
  126. data/lib/carray/frame/records.rb +18 -4
  127. data/lib/carray/frame/sort.rb +1 -1
  128. data/lib/carray/frame/verbs.rb +32 -12
  129. data/lib/carray/fuse_source.rb +123 -0
  130. data/lib/carray/fusion.rb +218 -0
  131. data/lib/carray/histogram.rb +16 -16
  132. data/lib/carray/inspect.rb +43 -16
  133. data/lib/carray/iterator.rb +147 -3
  134. data/lib/carray/lazy.rb +88 -73
  135. data/lib/carray/mask_gap_fill.rb +3 -1
  136. data/lib/carray/meld_reduce.rb +2 -2
  137. data/lib/carray/methods/align_addr.rb +1 -1
  138. data/lib/carray/methods/composition.rb +1 -1
  139. data/lib/carray/methods/discovery_along.rb +74 -0
  140. data/lib/carray/methods/factorize.rb +50 -0
  141. data/lib/carray/methods/is_in.rb +25 -14
  142. data/lib/carray/methods/locate_addr.rb +81 -3
  143. data/lib/carray/methods/mask_duplicates.rb +36 -2
  144. data/lib/carray/methods/meshgrid.rb +4 -5
  145. data/lib/carray/methods/mode.rb +2 -2
  146. data/lib/carray/methods/nunique.rb +23 -2
  147. data/lib/carray/methods/repeat.rb +110 -0
  148. data/lib/carray/methods/snap.rb +7 -2
  149. data/lib/carray/methods/unique.rb +44 -4
  150. data/lib/carray/methods/value_counts.rb +2 -2
  151. data/lib/carray/rng.rb +86 -0
  152. data/lib/carray/runtime.rb +0 -19
  153. data/lib/carray/slab_iterator.rb +77 -19
  154. data/lib/carray/string_operation_extension.rb +10 -6
  155. data/lib/carray/time.rb +906 -491
  156. data/lib/carray/window_iterator.rb +421 -27
  157. data/lib/carray.rb +7 -5
  158. data/yard-stubs/ca_obj_array.rb +385 -0
  159. data/yard-stubs/ca_obj_bitarray.rb +38 -0
  160. data/yard-stubs/ca_obj_bitfield.rb +43 -0
  161. data/yard-stubs/ca_obj_block.rb +68 -0
  162. data/yard-stubs/ca_obj_byte_swap.rb +56 -0
  163. data/yard-stubs/ca_obj_fake.rb +31 -0
  164. data/yard-stubs/ca_obj_farray.rb +32 -0
  165. data/yard-stubs/ca_obj_field.rb +45 -0
  166. data/yard-stubs/ca_obj_grid.rb +35 -0
  167. data/yard-stubs/ca_obj_refer.rb +72 -0
  168. data/yard-stubs/ca_obj_roll.rb +45 -0
  169. data/yard-stubs/ca_obj_shift.rb +43 -0
  170. data/yard-stubs/ca_obj_stride.rb +181 -0
  171. data/yard-stubs/ca_obj_tile.rb +29 -0
  172. data/yard-stubs/ca_obj_transpose.rb +40 -0
  173. data/yard-stubs/ca_obj_window.rb +57 -0
  174. data/yard-stubs/carray_access.rb +131 -0
  175. data/yard-stubs/carray_attribute.rb +246 -0
  176. data/yard-stubs/carray_broadcast.rb +37 -0
  177. data/yard-stubs/carray_cast.rb +489 -0
  178. data/yard-stubs/carray_class.rb +65 -0
  179. data/yard-stubs/carray_conversion.rb +76 -0
  180. data/yard-stubs/carray_copy.rb +79 -0
  181. data/yard-stubs/carray_core.rb +34 -0
  182. data/yard-stubs/carray_count.rb +84 -0
  183. data/yard-stubs/carray_element.rb +108 -0
  184. data/yard-stubs/carray_generate.rb +66 -0
  185. data/yard-stubs/carray_lazy.rb +228 -0
  186. data/yard-stubs/carray_loop.rb +140 -0
  187. data/yard-stubs/carray_mask.rb +259 -0
  188. data/yard-stubs/carray_math.rb +1615 -0
  189. data/yard-stubs/carray_mathfunc.rb +45 -0
  190. data/yard-stubs/carray_median_percentile.rb +103 -0
  191. data/yard-stubs/carray_memory_view.rb +163 -0
  192. data/yard-stubs/carray_order.rb +252 -0
  193. data/yard-stubs/carray_random.rb +89 -0
  194. data/yard-stubs/carray_scatter.rb +106 -0
  195. data/yard-stubs/carray_slab.rb +59 -0
  196. data/yard-stubs/carray_sort.rb +165 -0
  197. data/yard-stubs/carray_test.rb +85 -0
  198. data/yard-stubs/carray_undef.rb +64 -0
  199. data/yard-stubs/carray_utils.rb +97 -0
  200. data/yard-stubs/ruby_carray.rb +193 -0
  201. metadata +67 -10
  202. data/ext/ca_obj_unbound_repeat.c +0 -496
@@ -2,7 +2,7 @@ ChangeLog of Ruby/CArray
2
2
  ========================
3
3
 
4
4
  Releases from 3.0.0 onward are in [CHANGELOG.md](CHANGELOG.md).
5
- What follows is the history up to 2.0.1.
5
+ What follows is the history up to the 2.0.0 release; 2.0.1 went unrecorded.
6
6
 
7
7
  1.6.0 -> 2.0.0
8
8
  --------------
data/README.md CHANGED
@@ -1,37 +1,23 @@
1
1
  # Ruby/CArray
2
2
 
3
- Ruby/CArray is an extension library for the multi-dimensional array class.
3
+ Ruby/CArray is an extension library for the multi-dimensional array class. It provides arrays of a single, uniform data type, with indexing and slicing in many forms, element-wise arithmetic and mathematical functions, reductions and statistics over the whole array or along any axis, and broadcasting between shapes that differ in size-1 axes. The features listed below are in addition to these.
4
+
5
+ ## Status
6
+
7
+ 3.0.x still moves: behavior can change between releases — see [CHANGELOG.md](CHANGELOG.md). 3.1 is the first release meant to be depended on. Until then, treat it as a place to try things out.
4
8
 
5
9
  ## Features
6
10
 
7
- * Multidimensional arrays holding values of a single, uniform data type
8
- * Indexing and slicing in many ways — by position, range, boolean mask, or
9
- index/address arrays
10
- * Element-wise arithmetic, mathematical and transcendental functions
11
- * Reduction and statistics computed over the whole array or along any axis
12
- * Built-in per-element mask on every array to represent missing values, properly
13
- accounted for in reductions and statistics
14
- * A rich family of views onto the original data — for indexing, reshaping, and
15
- reinterpreting elements — without copying
16
- * Views compose into chains of any depth, and writing through them reaches all the
17
- way back to the source data
18
- * Explicit broadcasting: operating on arrays of different shapes by stretching
19
- size-1 axes to match, without ever adding axes implicitly
20
- * Fast reductions built on compiler auto-vectorization
21
- * Kernel-style iteration from Ruby: drive a Ruby block over each sub-array spanning
22
- chosen axes
23
- * Faces: a mechanism for building extended data types on top of CArray (time,
24
- categorical and variable-length string columns are such types)
25
- * Easily define record types that bind several data together as one element
26
- * User-defined array classes, written in Ruby, that share the full CArray interface
27
- so your own type behaves like a CArray everywhere
28
- * A DataFrame (`CAFrame`) whose columns are plain CArrays — it adds names and row
29
- operations (select, filter, sort, join, group-by, CSV I/O) and hands a column
30
- back as the array itself, so masks, views and Faces keep working on it
31
- * Writing per-axis methods and functions in C extensions with ease — a single
32
- kernel runs across every view type, with no per-view branching to write yourself
33
- * MemoryView protocol support — interoperate with other numerical libraries as both
34
- producer and consumer
11
+ * Every array carries a per-element mask for missing values, respected by reductions and statistics
12
+ * Views compose without copying — a write through the outermost view reaches the source data
13
+ * MemoryView protocol on both sides: share buffers with other numerical libraries without copying
14
+ * Kernel-style iteration: run a Ruby block over each sub-array spanning the axes you choose
15
+ * Attach domain meaning (time, angle, quantity with units…) without changing storage — a Face
16
+ * Define your own array class in pure Ruby while keeping the full CArray interface
17
+ * Pack multiple values into one element as a record type
18
+ * Comes with a DataFrame (`CAFrame`) whose columns are plain CArrays, so masks and views keep working on them
19
+
20
+ Each of these is shown, briefly and with a runnable example, in [A tour of the features](docs/FeatureTour.md).
35
21
 
36
22
  ## Install
37
23
 
@@ -124,14 +110,28 @@ b.strip_mask(Float::NAN).sum(axis: 0)
124
110
 
125
111
  ## Documentation
126
112
 
127
- * [What is Ruby/CArray](docs/WhatIsCArray.md)
113
+ * [Introduction](guides/users/introduction.md) — what Ruby/CArray is
114
+ * [Getting started](guides/users/00_getting_started.md) — install, and a first array
115
+ * [Creating arrays](guides/users/01_creating_arrays.md) — constructors, data types, filling
116
+ * [Indexing and slicing](guides/users/02_indexing_and_slicing.md) — elements, rows, blocks, conditions
117
+ * [Indexer reference](guides/users/16_indexer_reference.md) — every form `[]` accepts
118
+ * [Element-wise operations](guides/users/03_elementwise.md) — arithmetic and mathematical functions
119
+ * [Broadcasting](guides/users/07_broadcasting.md) — shapes that differ
120
+ * [Views](guides/users/06_views.md) — referring to data without copying
121
+ * [Reduction and statistics](guides/users/04_reduction_and_statistics.md) — summaries, whole or per axis
122
+ * [Masks and missing values](guides/users/05_masks.md) — undefined elements, and how calculations treat them
123
+
124
+ ## Contributing
125
+
126
+ Bug reports and feature requests are welcome — please open an issue.
127
+
128
+ **Before opening a pull request, read [CONTRIBUTING.md](CONTRIBUTING.md).** It is short, and it says which form a contribution is best sent in. A small, self-contained bug fix is fine as a pull request. Anything larger is better started as an issue: code here gets rewritten as a matter of course, so a patch for a larger change is likely to end up reimplemented rather than merged, and describing the problem gets you further than writing one.
128
129
 
129
130
  ## Credits
130
131
 
131
- Up to version 2.0, CArray was authored by himotoyoshi.
132
+ CArray is created and maintained by himotoyoshi.
132
133
 
133
- CArray 3.0 was designed and reviewed by a human developer; the implementation was
134
- produced in collaboration with AI coding tools.
134
+ Versions up to 2.0 were written by the author. For version 3.0, the author provided the design, and most of the implementation was rewritten with AI coding tools; it has been verified primarily through the test suite and practical use.
135
135
 
136
136
  ## License
137
137
 
data/carray.gemspec CHANGED
@@ -1,15 +1,18 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "carray"
3
- s.version = "3.0.0"
3
+ s.version = "3.0.2"
4
4
  s.authors = ["himotoyoshi"]
5
5
  s.email = ["himotoyoshi@users.noreply.github.com"]
6
- s.summary = "Multi-dimesional array class for Ruby"
6
+ s.summary = "Multi-dimensional numerical array class for Ruby"
7
7
  s.description = <<-HERE
8
- Ruby/CArray is an extension library for the multi-dimensional numerical array
9
- class. The name "CArray" comes from the meaning of a wrapper to a numerical array
10
- handled by the C language. CArray stores integers or floating-point numbers in
11
- memory block and treats them collectively to ensure efficient performance.
12
- Therefore, Ruby/CArray is suitable for numerical computation and data analysis.
8
+ Ruby/CArray adds multi-dimensional numerical arrays to Ruby. Elements are held
9
+ in a single flat memory block, so whole-array work -- element-wise arithmetic,
10
+ reductions along any axis, sorting, searching -- runs in C. Slicing, transposing,
11
+ reshaping, and selecting by a boolean condition all return views that share
12
+ storage with the original array and can be chained freely; nothing is copied
13
+ until you ask for a copy. Any array, view included, can carry a mask marking
14
+ individual elements as undefined, and arrays are exchanged with other numerical
15
+ libraries without copying through Ruby's MemoryView protocol.
13
16
  HERE
14
17
  s.homepage = "https://github.com/himotoyoshi/carray"
15
18
  s.license = "MIT"
@@ -17,13 +20,14 @@ Gem::Specification.new do |s|
17
20
  s.required_ruby_version = ">= 3.0"
18
21
  s.files = [
19
22
  *Dir.glob("lib/**/*.rb"),
23
+ *Dir.glob("yard-stubs/**/*.rb"),
20
24
  *(Dir.glob("ext/*.c") - %w[ext/carray_kernels.c ext/carray_cast_func.c ext/carray_math.c]),
21
25
  *Dir.glob("ext/*.h"),
22
26
  *Dir.glob("ext/*.rb"),
23
27
  "LICENSE",
24
28
  "README.md",
25
- "NEWS.md",
26
29
  "CHANGELOG.md",
30
+ "CHANGELOG.v1.md",
27
31
  ".yardopts",
28
32
  "carray.gemspec",
29
33
  ].select { |f| File.file?(f) }
@@ -339,13 +339,27 @@ ca_axis_dispatch_scatter_cb (ca_size_t off, int oob, ca_size_t n, void *vctx)
339
339
  /* Callback context for fill_value (broadcast a single value). parent is set
340
340
  when the value goes through the parent's own fill_stride instead of a
341
341
  buffer this side has attached. */
342
+ /* Same size as the window ca_fill_stride_via_addrs collects into. */
343
+ #define CA_AXIS_FILL_ADDR_WINDOW 1024
344
+
342
345
  typedef struct {
343
346
  const void *val;
344
347
  ca_size_t bytes;
345
348
  char *parent_ptr;
346
349
  CArray *parent;
350
+ ca_size_t window[CA_AXIS_FILL_ADDR_WINDOW];
351
+ ca_size_t nw;
347
352
  } ca_axis_fill_ctx_t;
348
353
 
354
+ static void
355
+ ca_axis_dispatch_fill_flush (ca_axis_fill_ctx_t *c)
356
+ {
357
+ if ( c->nw ) {
358
+ ca_fill_addrs(c->parent, c->nw, c->window, (void *) c->val);
359
+ c->nw = 0;
360
+ }
361
+ }
362
+
349
363
  static void
350
364
  ca_axis_dispatch_fill_value_cb (ca_size_t off, int oob, ca_size_t n, void *vctx)
351
365
  {
@@ -354,11 +368,25 @@ ca_axis_dispatch_fill_value_cb (ca_size_t off, int oob, ca_size_t n, void *vctx)
354
368
  if ( c->parent ) {
355
369
  /* One slab is one contiguous run of parent cells, which is a region the
356
370
  parent can fill for itself -- no borrowed buffer, so nothing outside
357
- the run is read or written. */
371
+ the run is read or written. A run of one cell is not worth a call of
372
+ its own, though: when the innermost selected axis picks individual
373
+ indices every run is one cell, and the same cell count that costs the
374
+ parent eight calls on an outer axis cost it one per cell here. Collect
375
+ those and hand them over as a list. The value is the same for every
376
+ cell and the walk visits each cell once, so batching cannot change
377
+ which cells are written. */
358
378
  ca_size_t count = n / c->bytes;
359
- ca_size_t step = 1;
360
- ca_fill_stride(c->parent, off / c->bytes, 1, &count, &step,
361
- (void *) c->val);
379
+ if ( count == 1 ) {
380
+ c->window[c->nw++] = off / c->bytes;
381
+ if ( c->nw == CA_AXIS_FILL_ADDR_WINDOW ) {
382
+ ca_axis_dispatch_fill_flush(c);
383
+ }
384
+ }
385
+ else {
386
+ ca_size_t step = 1;
387
+ ca_fill_stride(c->parent, off / c->bytes, 1, &count, &step,
388
+ (void *) c->val);
389
+ }
362
390
  }
363
391
  else {
364
392
  ca_axis_dispatch_fill_slab(c->parent_ptr + off, c->val, c->bytes, n);
@@ -895,6 +923,7 @@ ca_axis_dispatch_fill_value_via_parent (CArray *parent,
895
923
  ca_axis_dispatch_for_each_slab(parent, parent_axis_dims, axes, ndim,
896
924
  bytes, total_elements,
897
925
  ca_axis_dispatch_fill_value_cb, &ctx);
926
+ ca_axis_dispatch_fill_flush(&ctx);
898
927
  }
899
928
 
900
929
  /* ==========================================================================