carray 3.0.0 → 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 (180) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -1
  3. data/CHANGELOG.md +325 -3
  4. data/{NEWS.md → CHANGELOG.v1.md} +1 -1
  5. data/README.md +32 -32
  6. data/carray.gemspec +12 -8
  7. data/ext/ca_axis_group.c +55 -19
  8. data/ext/ca_binop_dispatch.c +5 -6
  9. data/ext/ca_binop_dispatch.h +0 -7
  10. data/ext/ca_categorical_iterator.c +13 -13
  11. data/ext/ca_for_each_element.h +6 -8
  12. data/ext/ca_group_iter.c +1 -1
  13. data/ext/ca_kernel_iterator.c +69 -23
  14. data/ext/ca_kernel_iterator.h +3 -10
  15. data/ext/ca_obj_bincmp.c +57 -27
  16. data/ext/ca_obj_binop.c +86 -30
  17. data/ext/ca_obj_const_string.c +3 -1
  18. data/ext/ca_obj_face.c +80 -0
  19. data/ext/ca_obj_face.h +33 -1
  20. data/ext/ca_obj_fake.c +11 -0
  21. data/ext/ca_obj_fixlen_string.c +3 -1
  22. data/ext/ca_obj_grid.c +11 -3
  23. data/ext/ca_obj_meld.c +13 -8
  24. data/ext/ca_obj_moncmp.c +33 -14
  25. data/ext/ca_obj_monop.c +19 -7
  26. data/ext/ca_obj_object.c +99 -4
  27. data/ext/ca_obj_record.c +3 -1
  28. data/ext/ca_obj_refer.c +30 -6
  29. data/ext/ca_obj_roll.c +13 -5
  30. data/ext/ca_obj_select_axis.c +16 -6
  31. data/ext/ca_obj_shift.c +3 -3
  32. data/ext/ca_obj_stride.c +106 -23
  33. data/ext/ca_obj_string.c +3 -1
  34. data/ext/ca_obj_tile.c +13 -5
  35. data/ext/ca_obj_time.c +3 -1
  36. data/ext/ca_obj_timedelta.c +3 -1
  37. data/ext/ca_obj_transpose.c +1 -1
  38. data/ext/ca_obj_triop.c +62 -23
  39. data/ext/ca_obj_window.c +86 -17
  40. data/ext/ca_op_cmplx64.h +123 -0
  41. data/ext/ca_op_ipower.c +0 -3
  42. data/ext/ca_sort_kernels.h +5 -5
  43. data/ext/ca_sweep_engine.c +78 -35
  44. data/ext/ca_sweep_engine.h +13 -4
  45. data/ext/ca_transform_common.c +7 -0
  46. data/ext/carray.h +127 -130
  47. data/ext/carray_access.c +56 -34
  48. data/ext/carray_bincount.c +8 -8
  49. data/ext/carray_broadcast.c +99 -6
  50. data/ext/carray_build_flags.h +3 -0
  51. data/ext/carray_call_cfunc.c +1491 -0
  52. data/ext/carray_call_cfunc.h +153 -0
  53. data/ext/carray_cast.c +69 -31
  54. data/ext/carray_conversion.c +22 -22
  55. data/ext/carray_copy.c +12 -2
  56. data/ext/carray_core.c +57 -10
  57. data/ext/carray_count.c +1 -1
  58. data/ext/carray_element.c +7 -7
  59. data/ext/carray_factorize.c +28 -28
  60. data/ext/carray_hold.c +1 -1
  61. data/ext/carray_index_classifier.c +7 -21
  62. data/ext/carray_internal.h +19 -3
  63. data/ext/carray_kernels_bincmp.c +1 -0
  64. data/ext/carray_kernels_binop.c +320 -298
  65. data/ext/carray_kernels_init.c +1095 -0
  66. data/ext/carray_kernels_map.c +1 -0
  67. data/ext/carray_kernels_moncmp.c +1 -0
  68. data/ext/carray_kernels_monop.c +412 -411
  69. data/ext/carray_kernels_reduce_aggregate.c +88 -87
  70. data/ext/carray_kernels_reduce_boolean.c +1 -0
  71. data/ext/carray_kernels_reduce_cumulative.c +54 -53
  72. data/ext/carray_kernels_reduce_extreme.c +51 -50
  73. data/ext/carray_kernels_reduce_variance.c +1 -0
  74. data/ext/carray_kernels_scan.c +1 -0
  75. data/ext/carray_kernels_search.c +93 -92
  76. data/ext/carray_kernels_sort.c +1 -0
  77. data/ext/carray_kernels_triop.c +1 -0
  78. data/ext/carray_lazy.c +175 -5
  79. data/ext/carray_mask.c +6 -5
  80. data/ext/carray_median_percentile.c +1 -1
  81. data/ext/carray_memory_view.c +46 -21
  82. data/ext/carray_operator.c +46 -49
  83. data/ext/carray_partition.c +4 -4
  84. data/ext/carray_random.c +7 -7
  85. data/ext/carray_scatter.c +1 -1
  86. data/ext/carray_sort.c +3 -3
  87. data/ext/carray_sort_kernel.c +10 -10
  88. data/ext/carray_test.c +1 -1
  89. data/ext/extconf.rb +18 -0
  90. data/ext/mk_call_cfunc.rb +243 -52
  91. data/ext/mkkernel.rb +354 -100
  92. data/ext/ruby_carray.c +18 -16
  93. data/ext/version.h +4 -4
  94. data/lib/carray/autoload_carray.rb +19 -0
  95. data/lib/carray/autoload_method_extension.rb +2 -1
  96. data/lib/carray/axis_group.rb +7 -7
  97. data/lib/carray/basics.rb +59 -59
  98. data/lib/carray/bincount_nd.rb +12 -12
  99. data/lib/carray/block_iterator.rb +24 -14
  100. data/lib/carray/categorical.rb +4 -4
  101. data/lib/carray/categorical_iterator.rb +98 -76
  102. data/lib/carray/conditional.rb +14 -14
  103. data/lib/carray/construct.rb +21 -0
  104. data/lib/carray/core_extensions.rb +62 -5
  105. data/lib/carray/data_type_extension.rb +18 -1
  106. data/lib/carray/frame/concat.rb +3 -3
  107. data/lib/carray/frame/convert.rb +1 -1
  108. data/lib/carray/frame/frame.rb +4 -11
  109. data/lib/carray/frame/io.rb +159 -2
  110. data/lib/carray/frame/sort.rb +1 -1
  111. data/lib/carray/frame/verbs.rb +18 -1
  112. data/lib/carray/fuse_source.rb +123 -0
  113. data/lib/carray/fusion.rb +218 -0
  114. data/lib/carray/histogram.rb +16 -16
  115. data/lib/carray/inspect.rb +1 -7
  116. data/lib/carray/iterator.rb +4 -3
  117. data/lib/carray/lazy.rb +125 -73
  118. data/lib/carray/meld_reduce.rb +2 -2
  119. data/lib/carray/methods/align_addr.rb +1 -1
  120. data/lib/carray/methods/composition.rb +1 -1
  121. data/lib/carray/methods/is_in.rb +12 -12
  122. data/lib/carray/methods/locate_addr.rb +6 -1
  123. data/lib/carray/methods/mask_duplicates.rb +1 -1
  124. data/lib/carray/methods/meshgrid.rb +4 -5
  125. data/lib/carray/methods/mode.rb +2 -2
  126. data/lib/carray/methods/nunique.rb +1 -1
  127. data/lib/carray/methods/snap.rb +7 -2
  128. data/lib/carray/methods/unique.rb +3 -3
  129. data/lib/carray/methods/value_counts.rb +2 -2
  130. data/lib/carray/runtime.rb +0 -19
  131. data/lib/carray/slab_iterator.rb +20 -7
  132. data/lib/carray/string_operation_extension.rb +5 -5
  133. data/lib/carray/time.rb +890 -491
  134. data/lib/carray/window_iterator.rb +285 -13
  135. data/lib/carray.rb +5 -5
  136. data/yard-stubs/ca_obj_array.rb +385 -0
  137. data/yard-stubs/ca_obj_bitarray.rb +38 -0
  138. data/yard-stubs/ca_obj_bitfield.rb +43 -0
  139. data/yard-stubs/ca_obj_block.rb +73 -0
  140. data/yard-stubs/ca_obj_byte_swap.rb +56 -0
  141. data/yard-stubs/ca_obj_fake.rb +31 -0
  142. data/yard-stubs/ca_obj_farray.rb +32 -0
  143. data/yard-stubs/ca_obj_field.rb +45 -0
  144. data/yard-stubs/ca_obj_grid.rb +35 -0
  145. data/yard-stubs/ca_obj_refer.rb +72 -0
  146. data/yard-stubs/ca_obj_roll.rb +45 -0
  147. data/yard-stubs/ca_obj_shift.rb +43 -0
  148. data/yard-stubs/ca_obj_stride.rb +181 -0
  149. data/yard-stubs/ca_obj_tile.rb +29 -0
  150. data/yard-stubs/ca_obj_transpose.rb +40 -0
  151. data/yard-stubs/ca_obj_window.rb +49 -0
  152. data/yard-stubs/carray_access.rb +131 -0
  153. data/yard-stubs/carray_attribute.rb +246 -0
  154. data/yard-stubs/carray_broadcast.rb +37 -0
  155. data/yard-stubs/carray_cast.rb +489 -0
  156. data/yard-stubs/carray_class.rb +65 -0
  157. data/yard-stubs/carray_conversion.rb +76 -0
  158. data/yard-stubs/carray_copy.rb +79 -0
  159. data/yard-stubs/carray_core.rb +114 -0
  160. data/yard-stubs/carray_count.rb +79 -0
  161. data/yard-stubs/carray_element.rb +108 -0
  162. data/yard-stubs/carray_generate.rb +66 -0
  163. data/yard-stubs/carray_lazy.rb +23 -0
  164. data/yard-stubs/carray_loop.rb +140 -0
  165. data/yard-stubs/carray_mask.rb +259 -0
  166. data/yard-stubs/carray_math.rb +132 -0
  167. data/yard-stubs/carray_mathfunc.rb +45 -0
  168. data/yard-stubs/carray_median_percentile.rb +89 -0
  169. data/yard-stubs/carray_memory_view.rb +163 -0
  170. data/yard-stubs/carray_order.rb +312 -0
  171. data/yard-stubs/carray_random.rb +89 -0
  172. data/yard-stubs/carray_scatter.rb +106 -0
  173. data/yard-stubs/carray_slab.rb +57 -0
  174. data/yard-stubs/carray_sort.rb +163 -0
  175. data/yard-stubs/carray_test.rb +85 -0
  176. data/yard-stubs/carray_undef.rb +64 -0
  177. data/yard-stubs/carray_utils.rb +97 -0
  178. data/yard-stubs/ruby_carray.rb +193 -0
  179. metadata +59 -10
  180. data/ext/ca_obj_unbound_repeat.c +0 -496
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7deb551fcc14866b90ad75e9d74ce716922de103148507bcb8b53c039b9afa48
4
- data.tar.gz: d8efa03d7f0852a15223329545c5ad3bb0abfcb0c48191978b1e0e6755d50f6b
3
+ metadata.gz: 3fd3c3099973bb94e29628f609cf27b65ccd9f318a5a707273fd86586e89e9a2
4
+ data.tar.gz: c9a01c64bc228fd8c4e92d2ef01043678608fa31f68a2a357f3ace5bf9f8b7af
5
5
  SHA512:
6
- metadata.gz: d1b4817095544fa7fae956207a3356f3300afab2b3e6b25b2c646e8c52b6db9a3ce9553131bb80ba5899f8d393de9dfd9f8136f1a8224402a372076f74556e89
7
- data.tar.gz: 859f3082f6c44a5f340fbf5ddd057e52f2fcacbadf5c5452c117b15faf683c9f915dc1f47ee59ba2fa37fa416fbf050b4747fbb1934971a472e74861c3b32ec4
6
+ metadata.gz: 84056c479f21558ffac49f051d4efdd6d34f4e7fa18218f097ab7ecabc3a7791782060358605c26265a90928ae2911253e5f6f6ca31acd3b70f3e069b5001bf5
7
+ data.tar.gz: a20917afb47f7c2ed0e3968678bd834680f41ceacf05d2c3771729d381ba7cb9a93c8e89aeca9f609a5811b9168b33fc446c1bd0cedc28c590c65eb02b070e2d
data/.yardopts CHANGED
@@ -1,11 +1,12 @@
1
1
  --markup markdown
2
+ --output-dir .yard-html
2
3
  --markup-provider redcarpet
3
4
  --no-private
4
5
  --exclude lib/carray/obsolete.rb
5
6
  --exclude lib/carray/autoload.rb
6
7
  --exclude 'lib/carray/autoload/'
7
8
  --readme README.md
8
- --files CHANGELOG.md,NEWS.md
9
+ --files CHANGELOG.md,CHANGELOG.v1.md
9
10
  lib/carray.rb
10
11
  lib/carray/**/*.rb
11
12
  yard-stubs/**/*.rb
data/CHANGELOG.md CHANGED
@@ -1,9 +1,331 @@
1
1
  # Changelog
2
2
 
3
- Releases from 3.0.0 onward are recorded here. For the pre-3.0 history
4
- (1.4.x through 2.0.1) see [NEWS.md](NEWS.md).
3
+ Releases from 3.0.0 onward are recorded here. There is no separate NEWS
4
+ file: this is where to look for what changed between the version you have
5
+ and a newer one. The 1.x history, up to the 2.0.0 release, is in
6
+ [CHANGELOG.v1.md](CHANGELOG.v1.md); 2.0.1 went unrecorded.
5
7
 
6
- ## 3.0.0 2026-08-25
8
+ <!-- Newest first, at both levels: a new release section goes above the
9
+ ones below it, and a new entry goes directly under its own release
10
+ heading -- not at the end of the section. The kind of change is
11
+ carried by the `- Fix:` / `- Change:` / `- New:` that opens the
12
+ entry; there are no per-kind subheadings.
13
+
14
+ A section is written newest-first while the release is open, and
15
+ sorted into New, Change, Fix when it closes -- in the same commit
16
+ that drops `(unreleased)`. Within Change, the ones that ask the
17
+ reader to change code come first. It is a reading order rather than
18
+ a classification: where it is not obvious, either place will do.
19
+
20
+ An entry says three things and stops: what changed, what to do about
21
+ it (the migration, the replacement, the condition under which nothing
22
+ changes), and what is excluded. It does not say how the code was
23
+ broken, name the internals that were fixed, break down where the
24
+ speed came from, or argue the design -- those belong in the commit
25
+ message. Two to six lines.
26
+
27
+ It is written for someone using the library, not someone working on
28
+ it: with no NEWS file, this is what a reader consults before
29
+ upgrading. An entry naming something only a C extension touches says
30
+ so in its opening words.
31
+
32
+ Every entry has to read on its own. Entries are looked at one at a
33
+ time and move about within a section, so none may lean on a
34
+ neighbour ("as well", "the producer above") or leave unnamed the
35
+ method, class or keyword it is about. -->
36
+
37
+ ## 3.0.1
38
+
39
+ - New: `CArray.jit_for`, `CArray.jit_each` and `CArray.jit_map` name a block
40
+ that is compiled rather than run. Compiling needs the carray-jit gem;
41
+ without it they raise `NotImplementedError`. An expression over whole
42
+ arrays wants `CArray.fuse`, which needs no compiler.
43
+
44
+ - New: every iterator answers `accumulate` beside `sum`; some of them did not.
45
+ It is the same fold kept in the source's own data type, where `sum` answers
46
+ in the type the core promotes to -- a window or tile count over `uint8` cells
47
+ stays one byte wide.
48
+
49
+ - New: `CArray::CoreExtensions` adds postfix math on `Complex`, so `a[0].tanh`
50
+ reads the way `a.tanh` does. It covers the seventeen functions a complex
51
+ array supports and agrees with the array form exactly, branch cuts and the
52
+ sign of a zero included. Opt in with `using CArray::CoreExtensions`.
53
+
54
+ - New: `ca_is_stride_family(ca)` in `carray.h`, for a C extension that folds a
55
+ view into `root->ptr + base + sum(idx[k] * strides[k])` itself. True for
56
+ CAStride, CARefer, CABlock, CARepeat, CATranspose, CAFarray and CAField and
57
+ the mask array of each, and for an externally installed view that shares
58
+ their operation table.
59
+
60
+ - New: `divmod` returns `[quotient, remainder]` element-wise with the quotient
61
+ floored, the pair Ruby's `Integer#divmod` and `Float#divmod` return. The
62
+ quotient keeps the receiver's data type.
63
+
64
+ - New: two optional CAObject callbacks take a partial fill as a region instead
65
+ of one `store_addr` per cell: `fill_block(starts, counts, steps, val)` for a
66
+ forward per-axis sub-region, `fill_addrs(addrs, val)` otherwise. Defining
67
+ neither keeps the old behaviour. Filling a 1000x1000 region of a 2000x2000
68
+ CAObject: 116 ms to 0.6 ms.
69
+
70
+ - New: `CAFrame#to_table` renders the frame as an aligned text table, and
71
+ `inspect` / `to_s` sit on it: `p df` summarises the first 8 and last 2 rows,
72
+ `puts df` prints the whole frame. `rows:` caps the printed rows, `precision:`
73
+ rounds float cells for display (default 6), masked cells show as `_`.
74
+
75
+ - New: `CAFrame#to_time` takes a `CATime::Grid`, positionally or as `unit:`, so
76
+ a netCDF `units` attribute goes in whole. The grid also carries an epoch phase
77
+ the `unit:` / `epoch:` pair cannot -- that pair reads the epoch on the coarse
78
+ grid and loses the time of day. The keyword form is unchanged.
79
+
80
+ - New: `CATime::Grid` packages the `(unit:, origin:)` pair that `#timesteps`,
81
+ `#snap` and `.from_timesteps` take, so it is built once and passed as one
82
+ value: `t.snap(g, direction: :floor)`, `t.timesteps(g)`, `g.at(k)`. It parses
83
+ and prints the udunits `"<unit> since <instant>"` form, holding a phased
84
+ origin that the keyword pair cannot (`"12 hours since 2017-11-30 09:00"`).
85
+ `CATime#grid` is the grid an array is stored on. Storage is unchanged.
86
+
87
+ - New: `CATime#snap(grid, direction:)` rounds to a tick grid, the shape
88
+ `CArray#snap` has for numbers. `#floor` / `#ceil` / `#round` are its
89
+ fixed-direction forms; their results and keyword forms are unchanged.
90
+
91
+ - New: a time element is taken directly as a start or origin literal, so a
92
+ `floor` / `ceil` / `to_unit` answer feeds back into `CArray.time`,
93
+ `time_range`, `time_series`, `CArray#time` and an `origin:`; it used to have
94
+ to go out through `DateTime` and be re-parsed. A `:M` or `:Y` element names
95
+ the first midnight of its granule. What an origin must satisfy is unchanged.
96
+
97
+ - New: `CArray.time` parses a year-month (`"2019-09"`) and a bare year
98
+ (`"2019"`), so the form a `:M` / `:Y` element prints reads back in. A
99
+ missing finer field names the head of that period.
100
+
101
+ - Change: `abs`, `abs2` and `arg` on a `cmplx64` array now return `float32`
102
+ instead of `float64` -- the width that type carries its real values in, the
103
+ same one `real` and `imag` already returned. `arg` on a `float32` array
104
+ likewise returns `float32` rather than widening. `cmplx128` and `float64`
105
+ are unchanged, and `arg` on an integer array still gives `float64`. To keep
106
+ the old width, add `.to_type(:float64)`.
107
+
108
+ - Change: `CArray.fuse` takes the expression rather than the arrays it is
109
+ over -- `CArray.fuse { (a + b) * c }` in place of
110
+ `CArray.fuse(a, b, c) { |x, y, z| (x + y) * z }`. What comes back is the
111
+ expression, so `x = CArray.fuse { ... }` now wants `.to_ca` for an array.
112
+ Where the block's source cannot be read -- an `irb` prompt, inside `eval` --
113
+ write `a.lazy + b.lazy`. `CArray.lazy(*args) { ... }` is gone.
114
+
115
+ - Change: a lazy expression (`a.lazy + b`, `CArray.fuse`) builds its mask when
116
+ something reads it, rather than when the expression is built. A mask set on
117
+ either operand after the expression was built is now seen; before, only the
118
+ left one was. `root_array` and `ancestors` now stop at a lazy operation
119
+ instead of walking into its left operand. Building a long masked expression
120
+ is also no longer quadratic in the length of the chain.
121
+
122
+ - Change: the top-level constant `CA_NIL` is now `CArray::UNSPECIFIED`
123
+ (`CA_UNSPECIFIED` in C). It is an internal sentinel for "the caller gave no
124
+ argument", not a value to pass in; `unmask`, `shift(fill_value:)` and
125
+ `window(fill_value:)` behave as before.
126
+
127
+ - Change: `group_by_category` reductions answer in the data type the core
128
+ reduction promotes the value to, instead of one chosen per reduction. `sum`
129
+ on an integer value now answers in float64 (`accumulate` is the spelling
130
+ that stays in the value's type), and `mean`, `variance` and `median` on an
131
+ object value stay exact. `sum` on a boolean value and `prod` or `mean` on a
132
+ complex one, which raised, now work.
133
+
134
+ - Change: the `:*` unbound repeat is retired. `a[:*, nil]` raises `IndexError`;
135
+ `CArray#unbound_repeat`, `CAUnboundRepeat` and `insert_axis(repeat: :*)` are
136
+ gone. Use `:_`, which gives the same shape and now stretches on a store as
137
+ well as in an operation. `CArray#broadcast_to` and
138
+ `CArray.meshgrid(sparse: true)` are unaffected.
139
+
140
+ - Change: a binary operation requires shapes to agree, or to differ only in
141
+ size-1 axes at equal ndim. `(3,2) + (2,3)` and `(3,2) + (6)` raise
142
+ `ArgumentError` where they used to answer in one operand's shape; flatten
143
+ both sides to combine the values in the order they lie. Comparisons, `fma`
144
+ and the lazy forms follow the same rule. Scalars are unaffected, but a
145
+ one-element 1-D array such as `CArray.int32(1)` counts as a shape.
146
+
147
+ - Change: an assignment requires the shapes to match. `t[] = src` with a
148
+ differently shaped source raises `RuntimeError`; use `src.flatten`. In
149
+ exchange a smaller source is repeated to fit, so `t[] = row[:_, nil, nil]`
150
+ and `t[] = col` (shape `(n,1)`) work where they used to raise. A 1-D side on
151
+ either end still passes, as do shapes differing only in size-1 axes; Ruby
152
+ Arrays and scalars are unchanged.
153
+
154
+ - Change: `to_ca` on a view derived from a lazy marker returns a new entity
155
+ rather than the view itself -- `a.lazy.shift(1, 0).to_ca`, inside a `fuse`
156
+ block or not. `copy` behaves as before.
157
+
158
+ - Change: `/` and `%` follow Ruby instead of C. Integer division floors and the
159
+ remainder carries the sign of the divisor; float `%` floors too, float `/` is
160
+ unchanged. For the old behaviour use `fmod`, which now takes integers as well
161
+ as floats.
162
+
163
+ - Change: `reminder` is removed -- it was IEEE 754 remainder on floats but C `%`
164
+ on integers. Use `fmod` for the truncated remainder. The IEEE form has no
165
+ replacement.
166
+
167
+ - Change: the result-type override of `CArray#conditional` and
168
+ `CArray.select` is now `data_type:`, spelled the way the rest of the
169
+ library spells it. There is no alias: `dtype:` raises `unknown keyword`.
170
+
171
+ - Change: a calendar-grid `origin:` given to the bucket-grid methods of a
172
+ `CATime` array -- `timesteps`, `snap`, `floor`, `ceil`, `round`,
173
+ `is_righttime` -- now has to be a month head (the 1st at 00:00); it used to
174
+ drop the day and time silently. A `:Y` tick likewise has to start in
175
+ January. `from_timesteps` already refused an off-grid origin.
176
+
177
+ - Change: the MemoryView producer emits the format vocabulary
178
+ `ruby/memory_view.h` specifies rather than PEP 3118's, so below 32 bits it
179
+ writes `c` / `C` / `s` / `S` in place of `b` / `B` / `h` / `H`. From 32 bits
180
+ up the two already agreed, and `?`, `Zf` / `Zd`, `T{...}` and `Ns` stay PEP
181
+ 3118, which Ruby has no spelling for. The consumer side already accepted
182
+ both, so views produced by 3.0.0 still import.
183
+
184
+ - Change: multiplying and dividing a `cmplx64` array (`*`, `/`, `rcp`,
185
+ `rcp_mul`) is computed in double and rounded once, so both are correctly
186
+ rounded; the old route could be off by about 1800 units in the last place.
187
+ A product that overflows a float but not a double no longer comes back NaN.
188
+ Division is 4.2-5.3x faster and multiplication 1.3x slower. `+`, `-` and
189
+ every `cmplx128` operation are unchanged.
190
+
191
+ - Change: element-wise math on a `float32` or `cmplx64` array is computed at
192
+ that width rather than widened and rounded back, so `sqrt`, `exp`, `log`,
193
+ the trigonometric and hyperbolic families, `atan2`, `hypot`, `abs` and `arg`
194
+ are 1.1-3.5x faster there and can move by a bit or two in the last place.
195
+ Complex `log`, `power`, `exp2` and `exp10` are unchanged, as are the
196
+ rounding, min / max, comparison and variance families and the wider types.
197
+
198
+ - Change: a rolling `sum`, `mean`, `prod`, `min`, `max`, `all` or `any` --
199
+ `a.windows(-1..1).sum` and the like -- over a window up to five cells wide on
200
+ every axis is 2-5x faster, and 1.3-4x over a masked source; `min_count:` and
201
+ `fill_value:` come along. `min`, `max` and `prod` answer exactly as before;
202
+ `sum` and `mean` may differ in the last bits. A wider window, or any other
203
+ reduction, is unchanged.
204
+
205
+ - Change: `CATime#to_unit` floors to a coarser grid instead of raising, and
206
+ crosses the calendar / fixed-length boundary (`:M` <-> `:D`) through
207
+ civil-date algebra. `:Y` / `:M` -> `:W` still raises.
208
+
209
+ - Change: `CATimedelta#to_unit` truncates toward zero instead of raising on a
210
+ coarser target. Crossing the calendar boundary still raises.
211
+
212
+ - Fix: `nextafter` on a `float32` array returned its own input. The step was
213
+ taken in double, and the next double above a float rounds back to that same
214
+ float. It now steps by one float32 ulp.
215
+
216
+ - Fix: a lazy expression over an object array (`CArray.object`,
217
+ `CA_OBJECT`) returned wrong values, and crashed when materialised
218
+ repeatedly. Affects `to_ca` and `copy` on a lazy view, an eager operation
219
+ with a lazy operand, and a reduction over one. Other data types were never
220
+ affected.
221
+
222
+ - Fix: reading a concatenated view (`CArray.concat`, `CAFrame.concat`)
223
+ backwards along the concatenated axis -- `m.reverse` and any other negative
224
+ step -- raised IndexError instead of answering.
225
+
226
+ - Fix: reading a lazy expression (`a.lazy + b`, `CArray.fuse`) with a step
227
+ other than one -- `expr[[0, 3, 2]]`, `expr.reverse` and the like -- returned
228
+ values the expression cannot produce, because its operands were read from
229
+ the wrong cells. Comparisons carried the same fault, `a.lazy > b` and
230
+ one-operand ones such as `a.lazy.is_nan` alike. Contiguous reads were never
231
+ affected.
232
+
233
+ - Fix: `a.value + b` raised `can not create mask array for the value array`
234
+ when `b` carried a mask. It now propagates `b`'s mask.
235
+
236
+ - Fix: a rolling window that does not cover the cell it is centred on --
237
+ `windows(1..2)`, the two cells after this one -- was read as if it started at
238
+ the array's edge, so every answer came out shifted by the range's start, and
239
+ `bounds: :truncate` produced anchors whose window did not fit. `windows(1..2)`
240
+ on `[1..8]` now sums to `[5, 7, 9, 11, 13, 15, 8, 0]`. A window that covers
241
+ its anchor, which is every centred one, is unaffected.
242
+
243
+ - Fix: storing a `Complex` into a `cmplx64` or `cmplx128` array kept the sign
244
+ of a negative zero real part only when the imaginary part was also negative,
245
+ so `Complex(-0.0, 0.0)` came back as `0.0+0.0i`. The sign of a zero picks the
246
+ side of a branch cut, so a value stored this way could be carried to the
247
+ wrong branch. All four sign combinations now round-trip, through element
248
+ assignment and through `to_type`.
249
+
250
+ - Fix: `sinh`, `cosh`, `tanh`, `asinh`, `acosh` and `atanh` on a complex array
251
+ gave the hyperbolic function of the real part alone: `cmplx128` and
252
+ `cmplx64` arrays came back with `tanh(Re z)` where `ctanh(z)` was meant,
253
+ wrong in both parts, and `acosh` and `atanh` also returned 0 or infinity
254
+ where the true value is finite. They now agree with C99 `complex.h`. Real
255
+ and object arrays were never affected.
256
+
257
+ - Fix: a C extension reading a view in column-major order -- axes and steps
258
+ reversed against the view's own -- got wrong values from a view with a
259
+ length-1 axis, such as `v[nil, :_]`, `v.reshape(n, 1)` or a one-column slice:
260
+ the first cell repeated, a read out of bounds, or a hang.
261
+ `carray-linalg-accelerate`'s `solve(a, b)` returned `b[0]` repeated for a
262
+ single-column right-hand side.
263
+
264
+ - Fix: an operation between two views of an array that computes its values --
265
+ a lazy expression such as `(a.lazy + b)`, or a `CAObject` over a file -- no
266
+ longer reads that source one cell at a time. `+`, `fma` and comparisons on
267
+ such a pair now run at the speed of copying each operand first, so the
268
+ `.copy` that worked around it is no longer needed. Single-operand
269
+ operations, copies, region transfers and reductions were already unaffected.
270
+
271
+ - Fix: views built inside a `CArray.fuse` block stay part of the expression
272
+ instead of dropping out of it, so a stencil written the natural way is fused.
273
+ `[]`, `shift`, `roll`, `flip`/`reverse`, `transpose`/`T`, `reshape`,
274
+ `flatten`, `window`, `diagonal`, `tile` and `refer` keep the chain;
275
+ `unbound_repeat` and `[:*, ...]` deliberately do not.
276
+
277
+ - Fix: a window or shift over a view parent no longer copies that parent in
278
+ full on every transfer. `a[nil, nil].shift(1, 0)` and friends now read at
279
+ parity with an entity parent and write several times faster.
280
+
281
+ - Fix: reductions over a bare `.lazy` marker no longer raise. Per-axis forms
282
+ and anything over a masked array failed, so `a.lazy.sum(axis: 0)` raised
283
+ while `a.lazy.sum` worked.
284
+
285
+ - Fix: `ca_test_flag` / `ca_set_flag` / `ca_unset_flag` in `carray.h`, which
286
+ only a C extension calls, did not parenthesise their flag argument, so
287
+ testing two flags at once was true for every array.
288
+
289
+ - Fix: a Face no longer hands back its storage bytes through the type casts.
290
+ `as_type`, `fake` and `CArray.wrap_writable` raise; `CArray.wrap_readonly`
291
+ converts as `to_type` does, which also makes `t.eq(o)` and `o.eq(t)` agree.
292
+ Reach the storage explicitly with `t.parent.fake(...)`. Numeric Faces are
293
+ unaffected.
294
+
295
+ - Fix: `arange` raised `NoMethodError` in every form; it builds the array now.
296
+ Integer arguments count exactly, so a step dividing the span evenly no longer
297
+ picks up an extra element. A zero step or a wrong argument count raises
298
+ `ArgumentError`.
299
+
300
+ - Fix: `from_timesteps` on a week grid answered Thursdays. The week grid counts
301
+ from the epoch, which is one, so it cannot hold an ISO Monday head; a week
302
+ bucket now answers on the day grid and round-trips against `floor` cell for
303
+ cell. A day-or-finer array keeps the Monday default, a week-stored array its
304
+ own epoch-anchored ticks.
305
+
306
+ - Fix: a masked cell decided whether a `CATime` conversion fit. The range
307
+ guards took their extremes with the mask stripped, so `to_unit` raised
308
+ `RangeError` over a wide value that was masked out. They now answer UNDEF
309
+ when there is nothing to bound -- an empty array, or every cell masked.
310
+
311
+ - Fix: `CATimedelta::Element#/` floored a negative duration, so `-30h / 4`
312
+ answered `-8h` where the array form answered `-7h`. A duration is a
313
+ magnitude, so it shrinks toward zero, matching the array form in all four
314
+ sign combinations.
315
+
316
+ - Fix: `CArray.time` no longer rolls a field that is out of range over into
317
+ another date. `"2019-02-31"` parsed to 2019-03-03, and `"201909"` -- a valid
318
+ YYMMDD to Ruby, 2020-19-09 -- to 2021-07; both now raise.
319
+
320
+ - Fix: `CATime#to_unit` and `CATimedelta#to_unit` were wrong between two
321
+ resolutions where neither tick is a whole multiple of the other: converting
322
+ 3 hours to a `"90 minutes"` grid gave 1 unit rather than 2.
323
+
324
+ - Fix: importing a MemoryView whose mask is published as `C` or `c` no longer
325
+ fails. The check knew only PEP 3118's `B`, `b` and `?`, so a producer that
326
+ spells a byte in Ruby's format vocabulary was refused.
327
+
328
+ ## 3.0.0
7
329
 
8
330
  First public release. Earlier versions existed on RubyGems, but the library
9
331
  was developed for the author's own use; 3.0 is where it is packaged,
@@ -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
132
  Up to version 2.0, CArray was authored 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
+ CArray 3.0 was designed and reviewed by a human developer; the implementation was produced in collaboration with AI coding tools.
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.1"
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) }