numo-narray-alt 0.11.0 → 0.11.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b2e2bc7cc99b7ef2b868b588360ff66299a6570b4d6ea98c45bbb357eed661b
4
- data.tar.gz: '0887ab3061ad5add393ecd99921ca88e3a06545c9617ffc9686550cb87b3e843'
3
+ metadata.gz: 62b615bb540e3a9d9783fa984943437f42ad5bbcf93041dead8d770317d8fcf6
4
+ data.tar.gz: 895c80b9b6544f09d04412a6a96439999752a9636d1b243127d96007f2574ba5
5
5
  SHA512:
6
- metadata.gz: '09f47d21922f7e24e7915222eb9ddacadf4392156e53a15aee05d4f2fc6ebdafce244c3624de375b10411768d7f1a38de7d081504ef0fe21b6b1b82156ef9410'
7
- data.tar.gz: 4cc3900b5631971fc76195eee5ecf66a6c1647a604d19997b0bcece1d1341f9245ace1c405c3f5e9dbc493389f456c4c9c817ea145a1c3a47f2180edea52ae36
6
+ metadata.gz: d6b5ac1dbfd8bb0f448a8c073de8f7951a9f571b20c9f88b864549f31dd828209cd67c4e7b629f2756ece9e98de6ad26a5b37a8f6131f836de259e25895bfd23
7
+ data.tar.gz: eea7716214274464d8e4fb4874d4415cf49a97ad7e0f15c15211257cb531604c7822913cf15d7a5ebba49df58de845b788a8558b04ac98ec3d5540fc62b527b3
@@ -325,9 +325,17 @@ static void na_check_reshape(int argc, VALUE* argv, VALUE self, size_t* shape) {
325
325
  /* get shape from argument */
326
326
  for (i = 0; i < argc; ++i) {
327
327
  switch (TYPE(argv[i])) {
328
- case T_FIXNUM:
329
- total *= shape[i] = NUM2INT(argv[i]);
328
+ case T_FIXNUM: {
329
+ ssize_t x = NUM2SSIZET(argv[i]);
330
+ if (x < 0) {
331
+ rb_raise(rb_eArgError, "size must be non-negative");
332
+ }
333
+ if (x != 0 && total > SIZE_MAX / (size_t)x) {
334
+ rb_raise(rb_eArgError, "total size is too large");
335
+ }
336
+ total *= shape[i] = (size_t)x;
330
337
  break;
338
+ }
331
339
  case T_NIL:
332
340
  case T_TRUE:
333
341
  if (unfixed >= 0) {
@@ -341,6 +349,9 @@ static void na_check_reshape(int argc, VALUE* argv, VALUE self, size_t* shape) {
341
349
  }
342
350
 
343
351
  if (unfixed >= 0) {
352
+ if (total == 0) {
353
+ rb_raise(rb_eArgError, "cannot determine unfixed dimension when total size is zero");
354
+ }
344
355
  if (NA_SIZE(na) % total != 0) {
345
356
  rb_raise(rb_eArgError, "Total size size must be divisor");
346
357
  }
@@ -126,7 +126,7 @@ static void na_parse_narray_index(VALUE a, int orig_dim, ssize_t size, na_index_
126
126
  GetNArray(idx, nidx);
127
127
  n = NA_SIZE(nidx);
128
128
  q->idx = ALLOC_N(size_t, n);
129
- if (na->type != NARRAY_DATA_T) {
129
+ if (nidx->type != NARRAY_DATA_T) {
130
130
  rb_bug("NArray#where returned wrong type of NArray");
131
131
  }
132
132
  if (rb_obj_class(idx) == numo_cInt32) {
@@ -183,7 +183,13 @@ na_parse_range(VALUE range, ssize_t step, int orig_dim, ssize_t size, na_index_a
183
183
 
184
184
  rb_arithmetic_sequence_components_t x;
185
185
  rb_arithmetic_sequence_extract(range, &x);
186
+ if (!RB_INTEGER_TYPE_P(x.step)) {
187
+ rb_raise(rb_eArgError, "step must be an Integer");
188
+ }
186
189
  step = NUM2SSIZET(x.step);
190
+ if (step == 0) {
191
+ rb_raise(rb_eArgError, "step must not be zero");
192
+ }
187
193
 
188
194
  beg = beg_orig = NUM2SSIZET(x.begin);
189
195
  if (beg < 0) {
@@ -475,13 +481,17 @@ static void na_index_aref_nadata(
475
481
  na_get_strides_nadata(na1, strides_na1, elmsz);
476
482
 
477
483
  for (i = j = 0; i < ndim; i++) {
478
- stride1 = strides_na1[q[i].orig_dim];
484
+ const int qi_orig_dim = q[i].orig_dim;
485
+ stride1 = 0;
486
+ if (qi_orig_dim < na1->base.ndim) {
487
+ stride1 = strides_na1[qi_orig_dim];
479
488
 
480
- // numeric index -- trim dimension
481
- if (!keep_dim && q[i].n == 1 && q[i].step == 0) {
482
- beg = q[i].beg;
483
- na2->offset += stride1 * beg;
484
- continue;
489
+ // numeric index -- trim dimension
490
+ if (!keep_dim && q[i].n == 1 && q[i].step == 0) {
491
+ beg = q[i].beg;
492
+ na2->offset += stride1 * beg;
493
+ continue;
494
+ }
485
495
  }
486
496
 
487
497
  na2->base.shape[j] = size = q[i].n;
@@ -491,8 +501,11 @@ static void na_index_aref_nadata(
491
501
  na2->base.reduce = rb_funcall(m, '|', 1, na2->base.reduce);
492
502
  }
493
503
 
494
- // array index
495
- if (q[i].idx != NULL) {
504
+ if (qi_orig_dim >= na1->base.ndim) {
505
+ // new dimension
506
+ SDX_SET_STRIDE(na2->stridx[j], elmsz);
507
+ } else if (q[i].idx != NULL) {
508
+ // array index
496
509
  index = q[i].idx;
497
510
  SDX_SET_INDEX(na2->stridx[j], index);
498
511
  q[i].idx = NULL;
@@ -1322,6 +1322,7 @@ static VALUE nary_store_binary(int argc, VALUE* argv, VALUE self) {
1322
1322
  narray_t* na;
1323
1323
 
1324
1324
  narg = rb_scan_args(argc, argv, "11", &vstr, &voffset);
1325
+ Check_Type(vstr, T_STRING);
1325
1326
  str_len = RSTRING_LEN(vstr);
1326
1327
  if (narg == 2) {
1327
1328
  offset = NUM2SIZET(voffset);
@@ -13,10 +13,10 @@ extern "C" {
13
13
  #endif
14
14
  #endif
15
15
 
16
- #define NARRAY_VERSION "0.11.0"
16
+ #define NARRAY_VERSION "0.11.2"
17
17
  #define NARRAY_VERSION_MAJOR 0
18
18
  #define NARRAY_VERSION_MINOR 11
19
- #define NARRAY_VERSION_PATCH 0
19
+ #define NARRAY_VERSION_PATCH 2
20
20
  #define NARRAY_VERSION_CODE \
21
21
  (NARRAY_VERSION_MAJOR * 10000 + NARRAY_VERSION_MINOR * 100 + NARRAY_VERSION_PATCH)
22
22
 
@@ -68,13 +68,6 @@
68
68
 
69
69
  #define m_mulsum_init INT2FIX(0)
70
70
 
71
- #define m_sprintf(s, x) robj_sprintf(s, x)
72
-
73
- static inline int robj_sprintf(char* s, VALUE x) {
74
- VALUE v = rb_funcall(x, rb_intern("to_s"), 0);
75
- return sprintf(s, "%s", StringValuePtr(v));
76
- }
77
-
78
71
  #define m_sqrt(x) \
79
72
  rb_funcall(rb_const_get(rb_mKernel, rb_intern("Math")), rb_intern("sqrt"), 1, x);
80
73
 
@@ -1,7 +1,7 @@
1
1
  #ifndef NUMO_NARRAY_MH_FORMAT_H
2
2
  #define NUMO_NARRAY_MH_FORMAT_H 1
3
3
 
4
- #define DEF_NARRAY_FORMAT_METHOD_FUNC(tDType) \
4
+ #define DEF_NARRAY_FORMAT_ELEMENT_FUNC(tDType) \
5
5
  static VALUE format_##tDType(VALUE fmt, tDType* x) { \
6
6
  if (NIL_P(fmt)) { \
7
7
  char s[48]; \
@@ -9,8 +9,22 @@
9
9
  return rb_str_new(s, n); \
10
10
  } \
11
11
  return rb_funcall(fmt, '%', 1, m_data_to_num(*x)); \
12
- } \
13
- \
12
+ }
13
+
14
+ /* robject formats its element without the fixed buffer above: the element is an
15
+ arbitrary Ruby object, so the length of its to_s is not bounded by anything
16
+ this side controls. */
17
+ #define DEF_NARRAY_ROBJ_FORMAT_ELEMENT_FUNC() \
18
+ static VALUE format_robject(VALUE fmt, robject* x) { \
19
+ if (NIL_P(fmt)) { \
20
+ VALUE v = rb_funcall(*x, id_to_s, 0); \
21
+ StringValue(v); \
22
+ return rb_str_new(RSTRING_PTR(v), RSTRING_LEN(v)); \
23
+ } \
24
+ return rb_funcall(fmt, '%', 1, m_data_to_num(*x)); \
25
+ }
26
+
27
+ #define DEF_NARRAY_FORMAT_LOOP_METHOD_FUNC(tDType) \
14
28
  static void iter_##tDType##_format(na_loop_t* const lp) { \
15
29
  size_t n; \
16
30
  char* p1; \
@@ -52,4 +66,12 @@
52
66
  return na_ndloop(&ndf, 2, self, fmt); \
53
67
  }
54
68
 
69
+ #define DEF_NARRAY_FORMAT_METHOD_FUNC(tDType) \
70
+ DEF_NARRAY_FORMAT_ELEMENT_FUNC(tDType) \
71
+ DEF_NARRAY_FORMAT_LOOP_METHOD_FUNC(tDType)
72
+
73
+ #define DEF_NARRAY_ROBJ_FORMAT_METHOD_FUNC() \
74
+ DEF_NARRAY_ROBJ_FORMAT_ELEMENT_FUNC() \
75
+ DEF_NARRAY_FORMAT_LOOP_METHOD_FUNC(robject)
76
+
55
77
  #endif /* NUMO_NARRAY_MH_FORMAT_H */
@@ -45,6 +45,7 @@ static ID id_reciprocal;
45
45
  static ID id_round;
46
46
  static ID id_square;
47
47
  static ID id_to_a;
48
+ static ID id_to_s;
48
49
  static ID id_truncate;
49
50
 
50
51
  #include <numo/types/robject.h>
@@ -141,7 +142,7 @@ DEF_NARRAY_ASET_METHOD_FUNC(robject)
141
142
  DEF_NARRAY_COERCE_CAST_METHOD_FUNC(robject)
142
143
  DEF_NARRAY_TO_A_METHOD_FUNC(robject)
143
144
  DEF_NARRAY_FILL_METHOD_FUNC(robject)
144
- DEF_NARRAY_FORMAT_METHOD_FUNC(robject)
145
+ DEF_NARRAY_ROBJ_FORMAT_METHOD_FUNC()
145
146
  DEF_NARRAY_FORMAT_TO_A_METHOD_FUNC(robject)
146
147
  DEF_NARRAY_ROBJ_INSPECT_METHOD_FUNC()
147
148
  DEF_NARRAY_EACH_METHOD_FUNC(robject)
@@ -365,6 +366,7 @@ void Init_numo_robject(void) {
365
366
  id_round = rb_intern("round");
366
367
  id_square = rb_intern("square");
367
368
  id_to_a = rb_intern("to_a");
369
+ id_to_s = rb_intern("to_s");
368
370
  id_truncate = rb_intern("truncate");
369
371
 
370
372
  /**
@@ -137,6 +137,10 @@ module Numo
137
137
  # # [[2, -3, 5],
138
138
  # # [4, 9, 7],
139
139
  # # [2, -1, 6]]
140
+ # @example
141
+ # a = Numo::NArray.parse('true false nil')
142
+ # # => Numo::Bit#shape=[1,3]
143
+ # # [[1, 0, 0]]
140
144
 
141
145
  def self.parse(str, split1d: /\s+/, split2d: /;?$|;/,
142
146
  split3d: /\s*\n(\s*\n)+/m)
@@ -151,7 +155,8 @@ module Numo
151
155
 
152
156
  c = []
153
157
  line.split(split1d).each do |item|
154
- c << eval(item.strip) unless item.empty? # rubocop:disable Security/Eval
158
+ item = item.strip
159
+ c << parse_token(item) unless item.empty?
155
160
  end
156
161
  b << c unless c.empty?
157
162
  end
@@ -164,6 +169,42 @@ module Numo
164
169
  end
165
170
  end
166
171
 
172
+ # Convert one token of {parse} input into a value.
173
+ #
174
+ # Only the literals that describe an element are accepted: integer, float
175
+ # and complex numbers, and +true+, +false+ and +nil+, which {cast} turns
176
+ # into a {Numo::Bit}. Anything else -- an expression, a method call, a bare
177
+ # word -- raises ArgumentError, so text handed to {parse} is never executed
178
+ # as Ruby code.
179
+ #
180
+ # @param item [String] one whitespace-delimited token, already stripped
181
+ # @return [Integer, Float, Complex, true, false, nil] the parsed value
182
+ # @raise [ArgumentError] if the token is not one of those literals
183
+ def self.parse_token(item)
184
+ case item
185
+ when 'true' then return true
186
+ when 'false' then return false
187
+ when 'nil' then return nil
188
+ end
189
+
190
+ v = Integer(item, exception: false)
191
+ return v if v
192
+
193
+ v = Float(item, exception: false)
194
+ return v if v
195
+
196
+ if item.end_with?('i')
197
+ begin
198
+ return Complex(item)
199
+ rescue ArgumentError, TypeError
200
+ nil
201
+ end
202
+ end
203
+
204
+ raise ArgumentError, "invalid literal: #{item.inspect}"
205
+ end
206
+ private_class_method :parse_token
207
+
167
208
  # Iterate over an axis
168
209
  # @example
169
210
  # > a = Numo::DFloat.new(2,2,2).seq
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: numo-narray-alt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.11.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - yoshoku
@@ -214,7 +214,7 @@ licenses:
214
214
  metadata:
215
215
  homepage_uri: https://github.com/yoshoku/numo-narray-alt
216
216
  changelog_uri: https://github.com/yoshoku/numo-narray-alt/blob/main/CHANGELOG.md
217
- documentation_uri: https://gemdocs.org/gems/numo-narray-alt/0.11.0/
217
+ documentation_uri: https://gemdocs.org/gems/numo-narray-alt/0.11.2/
218
218
  rubygems_mfa_required: 'true'
219
219
  post_install_message: |
220
220
  ===
@@ -238,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
238
238
  - !ruby/object:Gem::Version
239
239
  version: '0'
240
240
  requirements: []
241
- rubygems_version: 4.0.13
241
+ rubygems_version: 4.0.16
242
242
  specification_version: 4
243
243
  summary: Numo::NArray Alternative is a project forked from Numo::NArray.
244
244
  test_files: []