carray 1.5.2 → 1.5.7

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +32 -0
  3. data/NEWS.md +56 -3
  4. data/README.md +34 -18
  5. data/Rakefile +1 -1
  6. data/TODO.md +5 -4
  7. data/carray.gemspec +10 -11
  8. data/ext/ca_obj_bitarray.c +4 -7
  9. data/ext/ca_obj_bitfield.c +3 -5
  10. data/ext/ca_obj_block.c +1 -6
  11. data/ext/ca_obj_refer.c +6 -8
  12. data/ext/ca_obj_unbound_repeat.c +21 -52
  13. data/ext/carray.h +4 -0
  14. data/ext/carray_access.c +77 -45
  15. data/ext/carray_attribute.c +16 -1
  16. data/ext/carray_cast.c +1 -1
  17. data/ext/carray_conversion.c +8 -1
  18. data/ext/carray_core.c +22 -16
  19. data/ext/carray_generate.c +3 -3
  20. data/ext/carray_mask.c +12 -2
  21. data/ext/carray_math.rb +20 -2
  22. data/ext/carray_numeric.c +32 -51
  23. data/ext/carray_order.c +159 -0
  24. data/ext/carray_test.c +13 -0
  25. data/ext/carray_undef.c +0 -8
  26. data/ext/carray_utils.c +126 -47
  27. data/ext/extconf.rb +13 -1
  28. data/ext/mkmath.rb +1 -1
  29. data/ext/ruby_carray.c +8 -1
  30. data/ext/ruby_ccomplex.c +1 -1
  31. data/ext/version.h +4 -4
  32. data/lib/carray.rb +7 -9
  33. data/lib/carray/autoload.rb +0 -2
  34. data/lib/carray/basic.rb +3 -5
  35. data/lib/carray/broadcast.rb +78 -22
  36. data/lib/carray/compose.rb +34 -10
  37. data/lib/carray/construct.rb +36 -14
  38. data/lib/carray/info.rb +1 -3
  39. data/lib/carray/inspect.rb +3 -5
  40. data/lib/carray/io/imagemagick.rb +1 -3
  41. data/lib/carray/iterator.rb +2 -3
  42. data/lib/carray/mask.rb +18 -7
  43. data/lib/carray/math.rb +4 -6
  44. data/lib/carray/math/histogram.rb +1 -3
  45. data/lib/carray/math/recurrence.rb +1 -3
  46. data/lib/carray/mkmf.rb +1 -3
  47. data/lib/carray/object/ca_obj_iterator.rb +1 -3
  48. data/lib/carray/object/ca_obj_link.rb +1 -3
  49. data/lib/carray/object/ca_obj_pack.rb +1 -3
  50. data/lib/carray/obsolete.rb +1 -17
  51. data/lib/carray/ordering.rb +1 -3
  52. data/lib/carray/serialize.rb +34 -25
  53. data/lib/carray/string.rb +1 -3
  54. data/lib/carray/struct.rb +3 -5
  55. data/lib/carray/testing.rb +5 -10
  56. data/lib/carray/time.rb +1 -3
  57. data/lib/carray/transform.rb +12 -3
  58. data/misc/NOTE +16 -38
  59. data/spec/Classes/CAUnboudRepeat_spec.rb +24 -0
  60. data/spec/Features/feature_attributes_spec.rb +6 -6
  61. data/spec/Features/feature_boolean_spec.rb +15 -14
  62. data/spec/Features/feature_broadcast.rb +16 -0
  63. data/spec/Features/feature_cast_spec.rb +1 -1
  64. data/spec/Features/feature_mask_spec.rb +6 -0
  65. metadata +10 -11
data/ext/carray_order.c CHANGED
@@ -869,6 +869,162 @@ rb_ca_linear_search_nearest_index (VALUE self, VALUE value)
869
869
  return ( NIL_P(raddr) ) ? Qnil : rb_ca_addr2index(self, raddr);
870
870
  }
871
871
 
872
+ /* ----------------------------------------------------------------- */
873
+
874
+ static ca_size_t
875
+ linear_index (ca_size_t n, double *y, double yy, double *idx)
876
+ {
877
+ ca_size_t a, b, c, x1;
878
+ double ya, yb, yc;
879
+ double y1, y2;
880
+ double rest;
881
+
882
+ if ( yy <= y[0] ) {
883
+ x1 = 0;
884
+ goto found;
885
+ }
886
+
887
+ if ( yy >= y[n-1] ) {
888
+ x1 = n-2;
889
+ goto found;
890
+ }
891
+
892
+ /* check for equally spaced scale */
893
+
894
+ a = (ca_size_t)((yy-y[0])/(y[n-1]-y[0])*(n-1));
895
+
896
+ if ( a >= 0 && a < n-1 ) {
897
+ if ( (y[a] - yy) * (y[a+1] - yy) <= 0 ) { /* lucky case */
898
+ x1 = a;
899
+ goto found;
900
+ }
901
+ }
902
+
903
+ /* binary section method */
904
+
905
+ a = 0;
906
+ b = n-1;
907
+
908
+ ya = y[a];
909
+ yb = y[b];
910
+
911
+ if ( ya > yb ) {
912
+ return -1; /* input scale array should have accending order */
913
+ }
914
+
915
+ while ( (b - a) >= 1 ) {
916
+
917
+ c = (a + b)/2;
918
+ yc = y[c];
919
+ if ( a == c ) {
920
+ break;
921
+ }
922
+
923
+ if ( yc == yy ) {
924
+ a = c;
925
+ break;
926
+ }
927
+ else if ( (ya - yy) * (yc - yy) <= 0 ) {
928
+ b = c;
929
+ yb = yc;
930
+ }
931
+ else {
932
+ a = c;
933
+ ya = yc;
934
+ }
935
+
936
+ if ( ya > yb ) {
937
+ return -1; /* input scale array should have accending order */
938
+ }
939
+ }
940
+
941
+ x1 = a;
942
+
943
+ found:
944
+
945
+ y1 = y[x1];
946
+ y2 = y[x1+1];
947
+ rest = (yy-y1)/(y2-y1);
948
+
949
+ if ( fabs(y2-yy)/fabs(y2) < DBL_EPSILON*100 ) {
950
+ *idx = (double) (x1 + 1);
951
+ }
952
+ else if ( fabs(y1-yy)/fabs(y1) < DBL_EPSILON*100 ) {
953
+ *idx = (double) x1;
954
+ }
955
+ else {
956
+ *idx = rest + (double) x1;
957
+ }
958
+
959
+ return 0;
960
+ }
961
+
962
+ static VALUE
963
+ rb_ca_binary_search_linear_index (volatile VALUE self, volatile VALUE vx)
964
+ {
965
+ volatile VALUE out, out0;
966
+ CArray *ca, *sc, *cx, *co0, *co;
967
+ ca_size_t n;
968
+ double *x;
969
+ double *px;
970
+ double *po;
971
+ ca_size_t i;
972
+
973
+ Data_Get_Struct(self, CArray, ca);
974
+
975
+ if ( rb_ca_is_any_masked(self) ) {
976
+ rb_raise(rb_eRuntimeError, "self should not have any masked elements");
977
+ }
978
+
979
+ sc = ca_wrap_readonly(self, CA_FLOAT64);
980
+ cx = ca_wrap_readonly(vx, CA_FLOAT64);
981
+
982
+ co0 = carray_new(ca->data_type, cx->ndim, cx->dim, 0, NULL);
983
+ out = out0 = ca_wrap_struct(co0);
984
+ co = ca_wrap_writable(out, CA_FLOAT64);
985
+
986
+ ca_attach_n(3, sc, cx, co);
987
+
988
+ n = sc->elements;
989
+ x = (double*) sc->ptr;
990
+ px = (double*) cx->ptr;
991
+ po = (double*) co->ptr;
992
+
993
+ ca_update_mask(cx);
994
+ if ( cx->mask ) {
995
+ boolean8_t *mx, *mo;
996
+ ca_create_mask(co);
997
+ mx = (boolean8_t *) cx->mask->ptr;
998
+ mo = (boolean8_t *) co->mask->ptr;
999
+ for (i=0; i<cx->elements; i++) {
1000
+ if ( ! *mx ) {
1001
+ linear_index(n, x, *px, po);
1002
+ }
1003
+ else {
1004
+ *mo = 1;
1005
+ }
1006
+ mx++; mo++; px++, po++;
1007
+ }
1008
+ }
1009
+ else {
1010
+ for (i=0; i<cx->elements; i++) {
1011
+ linear_index(n, x, *px, po);
1012
+ px++, po++;
1013
+ }
1014
+ }
1015
+
1016
+ ca_sync(co);
1017
+ ca_detach_n(3, sc, cx, co);
1018
+
1019
+ if ( rb_ca_is_scalar(vx) ) {
1020
+ return rb_funcall(out0, rb_intern("[]"), 1, INT2NUM(0));
1021
+ }
1022
+ else {
1023
+ return out0;
1024
+ }
1025
+ }
1026
+
1027
+
872
1028
  void
873
1029
  Init_carray_order ()
874
1030
  {
@@ -893,4 +1049,7 @@ Init_carray_order ()
893
1049
  rb_define_method(rb_cCArray, "search_nearest_index",
894
1050
  rb_ca_linear_search_nearest_index, 1);
895
1051
 
1052
+ rb_define_method(rb_cCArray, "section",
1053
+ rb_ca_binary_search_linear_index, 1);
1054
+
896
1055
  }
data/ext/carray_test.c CHANGED
@@ -216,6 +216,12 @@ rb_obj_is_data_class (VALUE rtype)
216
216
  return Qfalse;
217
217
  }
218
218
 
219
+ static VALUE
220
+ rb_ca_s_is_data_class (VALUE self, VALUE rklass)
221
+ {
222
+ return rb_obj_is_data_class(rklass);
223
+ }
224
+
219
225
  /* ------------------------------------------------------------- */
220
226
 
221
227
  /* @overload valid_index? (*idx)
@@ -239,9 +245,11 @@ rb_ca_is_valid_index (int argc, VALUE *argv, VALUE self)
239
245
  }
240
246
  for (i=0; i<ca->ndim; i++) {
241
247
  idx = NUM2SIZE(argv[i]);
248
+ /*
242
249
  if ( idx < 0 ) {
243
250
  idx += ca->dim[i];
244
251
  }
252
+ */
245
253
  if ( idx < 0 || idx >= ca->dim[i] ) {
246
254
  return Qfalse;
247
255
  }
@@ -264,9 +272,11 @@ rb_ca_is_valid_addr (VALUE self, VALUE raddr)
264
272
 
265
273
  Data_Get_Struct(self, CArray, ca);
266
274
  addr = NUM2SIZE(raddr);
275
+ /*
267
276
  if ( addr < 0 ) {
268
277
  addr += ca->elements;
269
278
  }
279
+ */
270
280
  if ( addr < 0 || addr >= ca->elements ) {
271
281
  return Qfalse;
272
282
  }
@@ -598,4 +608,7 @@ Init_carray_test ()
598
608
  rb_define_method(rb_cCArray, "==", rb_ca_equal, 1);
599
609
  rb_define_alias(rb_cCArray, "eql?", "==");
600
610
  rb_define_method(rb_cCArray, "hash", rb_ca_hash, 0);
611
+
612
+ rb_define_singleton_method(rb_cCArray, "data_class?", rb_ca_s_is_data_class, 1);
613
+
601
614
  }
data/ext/carray_undef.c CHANGED
@@ -41,12 +41,6 @@ static VALUE rb_ud_equal (VALUE self, VALUE other)
41
41
  return ( self == other ) ? Qtrue : Qfalse;
42
42
  }
43
43
 
44
-
45
- static VALUE rb_obj_is_undef (VALUE self)
46
- {
47
- return ( self == CA_UNDEF ) ? Qtrue : Qfalse;
48
- }
49
-
50
44
  void
51
45
  Init_carray_undef ()
52
46
  {
@@ -61,7 +55,5 @@ Init_carray_undef ()
61
55
  CA_UNDEF = rb_funcall(rb_cUNDEF, rb_intern("new"), 0);
62
56
  rb_undef_method(CLASS_OF(rb_cUNDEF), "new");
63
57
  rb_const_set(rb_cObject, rb_intern("UNDEF"), CA_UNDEF);
64
-
65
- rb_define_method(rb_cObject, "undef?", rb_obj_is_undef, 0);
66
58
  }
67
59
 
data/ext/carray_utils.c CHANGED
@@ -18,36 +18,10 @@
18
18
  #include "st.h"
19
19
  #endif
20
20
 
21
- #if RUBY_VERSION_CODE >= 240
22
- #define RSTRUCT_EMBED_LEN_MAX RSTRUCT_EMBED_LEN_MAX
23
- enum {
24
- RSTRUCT_EMBED_LEN_MAX = 3,
25
- RSTRUCT_ENUM_END
26
- };
27
- struct RStruct {
28
- struct RBasic basic;
29
- union {
30
- struct {
31
- long len;
32
- const VALUE *ptr;
33
- } heap;
34
- const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
35
- } as;
36
- };
37
- #define RSTRUCT(obj) (R_CAST(RStruct)(obj))
38
- #endif
39
-
40
- #if RUBY_VERSION_CODE >= 190
41
- #define RANGE_BEG(r) (RSTRUCT(r)->as.ary[0])
42
- #define RANGE_END(r) (RSTRUCT(r)->as.ary[1])
43
- #define RANGE_EXCL(r) (RSTRUCT(r)->as.ary[2])
44
- #else
45
- static ID id_beg, id_end, id_excl;
46
- #define RANGE_BEG(r) (rb_ivar_get(r, id_beg))
47
- #define RANGE_END(r) (rb_ivar_get(r, id_end))
48
- #define RANGE_EXCL(r) (rb_ivar_get(r, id_excl))
49
- #endif
50
-
21
+ static ID id_begin, id_end, id_excl_end;
22
+ #define RANGE_BEG(r) (rb_funcall(r, id_begin, 0))
23
+ #define RANGE_END(r) (rb_funcall(r, id_end, 0))
24
+ #define RANGE_EXCL(r) (rb_funcall(r, id_excl_end, 0))
51
25
 
52
26
  /* ------------------------------------------------------------------- */
53
27
 
@@ -163,7 +137,7 @@ void
163
137
  ca_parse_range (VALUE arg, ca_size_t size,
164
138
  ca_size_t *poffset, ca_size_t *pcount, ca_size_t *pstep)
165
139
  {
166
- ca_size_t first, start, last, count, step, bound, excl;
140
+ ca_size_t start, last, count, step, bound, excl;
167
141
 
168
142
  retry:
169
143
 
@@ -182,24 +156,59 @@ ca_parse_range (VALUE arg, ca_size_t size,
182
156
  }
183
157
  else if ( rb_obj_is_kind_of(arg, rb_cRange) ) {
184
158
  /* i..j */
185
- first = NUM2SIZE(RANGE_BEG(arg));
159
+ start = NUM2SIZE(RANGE_BEG(arg));
186
160
  last = NUM2SIZE(RANGE_END(arg));
187
161
  excl = RTEST(RANGE_EXCL(arg));
188
- CA_CHECK_INDEX(first, size);
162
+ CA_CHECK_INDEX(start, size);
189
163
  if ( last < 0 ) {
190
164
  last += size;
191
165
  }
192
166
  if ( excl ) {
193
- last += ( (last>=first) ? -1 : 1 );
167
+ last += ( (last>=start) ? -1 : 1 );
194
168
  }
195
169
  if ( last < 0 || last >= size ) {
196
170
  rb_raise(rb_eIndexError,
197
171
  "invalid index range");
198
172
  }
199
- *poffset = first;
200
- *pcount = llabs(last - first) + 1;
173
+ *poffset = start;
174
+ *pcount = llabs(last - start) + 1;
201
175
  *pstep = 1;
202
176
  }
177
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
178
+ else if ( rb_obj_is_kind_of(arg, rb_cArithSeq) ) { /* ca[--,ArithSeq,--]*/
179
+ rb_arithmetic_sequence_components_t x;
180
+ rb_arithmetic_sequence_extract(arg, &x);
181
+
182
+ start = NUM2SIZE(x.begin);
183
+ last = NUM2SIZE(x.end);
184
+ excl = RTEST(x.exclude_end);
185
+ step = NUM2SIZE(x.step);
186
+ if ( step == 0 ) {
187
+ rb_raise(rb_eRuntimeError, "step should not be 0");
188
+ }
189
+ if ( last < 0 ) {
190
+ last += size;
191
+ }
192
+ if ( excl ) {
193
+ last += ( (last>=start) ? -1 : 1 );
194
+ }
195
+ if ( last < 0 || last >= size ) {
196
+ rb_raise(rb_eIndexError, "index out of range");
197
+ }
198
+ CA_CHECK_INDEX(start, size);
199
+ if ( (last - start) * step < 0 ) {
200
+ count = 1;
201
+ }
202
+ else {
203
+ count = llabs(last - start)/llabs(step) + 1;
204
+ }
205
+ bound = start + (count - 1)*step;
206
+ CA_CHECK_INDEX(bound, size);
207
+ *poffset = start;
208
+ *pcount = count;
209
+ *pstep = step;
210
+ }
211
+ #endif
203
212
  else if ( TYPE(arg) == T_ARRAY ) {
204
213
  if ( RARRAY_LEN(arg) == 1 ) { /* [nil] or [i..j] or [i] */
205
214
  arg = rb_ary_entry(arg, 0);
@@ -252,6 +261,41 @@ ca_parse_range (VALUE arg, ca_size_t size,
252
261
  *pcount = count;
253
262
  *pstep = step;
254
263
  }
264
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
265
+ else if ( rb_obj_is_kind_of(arg0, rb_cArithSeq) ) { /* ca[--,ArithSeq,--]*/
266
+ rb_arithmetic_sequence_components_t x;
267
+ rb_arithmetic_sequence_extract(arg0, &x);
268
+
269
+ start = NUM2SIZE(x.begin);
270
+ last = NUM2SIZE(x.end);
271
+ excl = RTEST(x.exclude_end);
272
+ step = NUM2SIZE(x.step);
273
+ if ( step == 0 ) {
274
+ rb_raise(rb_eRuntimeError, "step should not be 0");
275
+ }
276
+ if ( last < 0 ) {
277
+ last += size;
278
+ }
279
+ if ( excl ) {
280
+ last += ( (last>=start) ? -1 : 1 );
281
+ }
282
+ if ( last < 0 || last >= size ) {
283
+ rb_raise(rb_eIndexError, "index out of range");
284
+ }
285
+ CA_CHECK_INDEX(start, size);
286
+ if ( (last - start) * step < 0 ) {
287
+ count = 1;
288
+ }
289
+ else {
290
+ count = llabs(last - start)/llabs(step) + 1;
291
+ }
292
+ bound = start + (count - 1)*step;
293
+ CA_CHECK_INDEX(bound, size);
294
+ *poffset = start;
295
+ *pcount = count;
296
+ *pstep = step;
297
+ }
298
+ #endif
255
299
  else { /* [i,n] */
256
300
  start = NUM2SIZE(arg0);
257
301
  count = NUM2SIZE(arg1);
@@ -290,7 +334,7 @@ void
290
334
  ca_parse_range_without_check (VALUE arg, ca_size_t size,
291
335
  ca_size_t *poffset, ca_size_t *pcount, ca_size_t *pstep)
292
336
  {
293
- ca_size_t first, start, last, count, step, bound, excl;
337
+ ca_size_t start, last, count, step, bound, excl;
294
338
 
295
339
  retry:
296
340
 
@@ -308,16 +352,35 @@ ca_parse_range_without_check (VALUE arg, ca_size_t size,
308
352
  }
309
353
  else if ( rb_obj_is_kind_of(arg, rb_cRange) ) {
310
354
  /* i..j */
311
- first = NUM2SIZE(RANGE_BEG(arg));
355
+ start = NUM2SIZE(RANGE_BEG(arg));
312
356
  last = NUM2SIZE(RANGE_END(arg));
313
357
  excl = RTEST(RANGE_EXCL(arg));
314
358
  if ( excl ) {
315
- last += ( (last>=first) ? -1 : 1 );
359
+ last += ( (last>=start) ? -1 : 1 );
316
360
  }
317
- *poffset = first;
318
- *pcount = last - first + 1;
361
+ *poffset = start;
362
+ *pcount = last - start + 1;
319
363
  *pstep = 1;
320
364
  }
365
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
366
+ else if ( rb_obj_is_kind_of(arg, rb_cArithSeq) ) { /* ca[--,ArithSeq,--]*/
367
+ rb_arithmetic_sequence_components_t x;
368
+ rb_arithmetic_sequence_extract(arg, &x);
369
+
370
+ start = NUM2SIZE(x.begin);
371
+ last = NUM2SIZE(x.end);
372
+ excl = RTEST(x.exclude_end);
373
+ step = NUM2SIZE(x.step);
374
+ if ( excl ) {
375
+ last += ( (last>=start) ? -1 : 1 );
376
+ }
377
+ count = (last - start)/llabs(step) + 1;
378
+ bound = start + (count - 1)*step;
379
+ *poffset = start;
380
+ *pcount = count;
381
+ *pstep = step;
382
+ }
383
+ #endif
321
384
  else if ( TYPE(arg) == T_ARRAY ) {
322
385
  if ( RARRAY_LEN(arg) == 1 ) { /* [nil] or [i..j] or [i] */
323
386
  arg = rb_ary_entry(arg, 0);
@@ -349,6 +412,25 @@ ca_parse_range_without_check (VALUE arg, ca_size_t size,
349
412
  *pcount = count;
350
413
  *pstep = step;
351
414
  }
415
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
416
+ else if ( rb_obj_is_kind_of(arg0, rb_cArithSeq) ) { /* ca[--,ArithSeq,--]*/
417
+ rb_arithmetic_sequence_components_t x;
418
+ rb_arithmetic_sequence_extract(arg0, &x);
419
+
420
+ start = NUM2SIZE(x.begin);
421
+ last = NUM2SIZE(x.end);
422
+ excl = RTEST(x.exclude_end);
423
+ step = NUM2SIZE(x.step);
424
+ if ( excl ) {
425
+ last += ( (last>=start) ? -1 : 1 );
426
+ }
427
+ count = (last - start)/llabs(step) + 1;
428
+ bound = start + (count - 1)*step;
429
+ *poffset = start;
430
+ *pcount = count;
431
+ *pstep = step;
432
+ }
433
+ #endif
352
434
  else { /* [i,n] */
353
435
  start = NUM2SIZE(arg0);
354
436
  count = NUM2SIZE(arg1);
@@ -750,12 +832,9 @@ rb_set_options (VALUE ropt, const char *spec_in, ...)
750
832
  void
751
833
  Init_carray_utils ()
752
834
  {
753
- #if RUBY_VERSION_CODE >= 190
754
- #else
755
- id_beg = rb_intern("begin");
756
- id_end = rb_intern("end");
757
- id_excl = rb_intern("excl");
758
- #endif
835
+ id_begin = rb_intern("begin");
836
+ id_end = rb_intern("end");
837
+ id_excl_end = rb_intern("exclude_end?");
759
838
 
760
839
  rb_define_singleton_method(rb_cCArray, "_scan_float",
761
840
  rb_ca_s_scan_float, -1);