numo-narray 0.9.0.3 → 0.9.0.4

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -6
  3. data/Rakefile +2 -10
  4. data/ext/numo/narray/array.c +1 -6
  5. data/ext/numo/narray/data.c +3 -9
  6. data/ext/numo/narray/depend.erb +1 -1
  7. data/ext/numo/narray/extconf.rb +0 -1
  8. data/ext/numo/narray/gen/def/bit.rb +2 -0
  9. data/ext/numo/narray/gen/def/dcomplex.rb +2 -0
  10. data/ext/numo/narray/gen/def/dfloat.rb +2 -0
  11. data/ext/numo/narray/gen/def/int16.rb +2 -0
  12. data/ext/numo/narray/gen/def/int32.rb +2 -0
  13. data/ext/numo/narray/gen/def/int64.rb +2 -0
  14. data/ext/numo/narray/gen/def/int8.rb +2 -0
  15. data/ext/numo/narray/gen/def/robject.rb +2 -0
  16. data/ext/numo/narray/gen/def/scomplex.rb +2 -0
  17. data/ext/numo/narray/gen/def/sfloat.rb +2 -0
  18. data/ext/numo/narray/gen/def/uint16.rb +2 -0
  19. data/ext/numo/narray/gen/def/uint32.rb +2 -0
  20. data/ext/numo/narray/gen/def/uint64.rb +2 -0
  21. data/ext/numo/narray/gen/def/uint8.rb +2 -0
  22. data/ext/numo/narray/gen/dtype.erb.c +7 -7
  23. data/ext/numo/narray/gen/spec.rb +24 -2
  24. data/ext/numo/narray/gen/tmpl/accum_binary.c +6 -0
  25. data/ext/numo/narray/gen/tmpl/aref.c +6 -4
  26. data/ext/numo/narray/gen/tmpl/aset.c +6 -4
  27. data/ext/numo/narray/gen/tmpl/binary.c +4 -0
  28. data/ext/numo/narray/gen/tmpl/binary2.c +4 -0
  29. data/ext/numo/narray/gen/tmpl/bincount.c +180 -0
  30. data/ext/numo/narray/gen/tmpl/cast.c +4 -0
  31. data/ext/numo/narray/gen/tmpl/cast_array.c +3 -64
  32. data/ext/numo/narray/gen/tmpl/cond_binary.c +4 -0
  33. data/ext/numo/narray/gen/tmpl/inspect.c +4 -0
  34. data/ext/numo/narray/gen/tmpl/pow.c +4 -0
  35. data/ext/numo/narray/gen/tmpl/qsort.c +1 -7
  36. data/ext/numo/narray/gen/tmpl/rand.c +13 -2
  37. data/ext/numo/narray/gen/tmpl/rand_norm.c +89 -16
  38. data/ext/numo/narray/gen/tmpl/store.c +4 -0
  39. data/ext/numo/narray/gen/tmpl/store_array.c +99 -2
  40. data/ext/numo/narray/gen/tmpl_bit/allocate.c +1 -1
  41. data/ext/numo/narray/gen/tmpl_bit/aref.c +6 -4
  42. data/ext/numo/narray/gen/tmpl_bit/aset.c +6 -4
  43. data/ext/numo/narray/gen/tmpl_bit/cast_array.c +3 -65
  44. data/ext/numo/narray/gen/tmpl_bit/mask.c +16 -1
  45. data/ext/numo/narray/gen/tmpl_bit/store_array.c +101 -2
  46. data/ext/numo/narray/gen/tmpl_bit/where.c +7 -23
  47. data/ext/numo/narray/gen/tmpl_bit/where2.c +58 -4
  48. data/ext/numo/narray/index.c +168 -166
  49. data/ext/numo/narray/kwarg.c +1 -6
  50. data/ext/numo/narray/math.c +8 -12
  51. data/ext/numo/narray/narray.c +231 -71
  52. data/ext/numo/narray/ndloop.c +86 -26
  53. data/ext/numo/narray/numo/intern.h +6 -10
  54. data/ext/numo/narray/numo/narray.h +83 -54
  55. data/ext/numo/narray/numo/ndloop.h +0 -5
  56. data/ext/numo/narray/numo/template.h +0 -5
  57. data/ext/numo/narray/numo/types/complex.h +1 -6
  58. data/ext/numo/narray/numo/types/complex_macro.h +30 -3
  59. data/ext/numo/narray/numo/types/dcomplex.h +18 -0
  60. data/ext/numo/narray/numo/types/dfloat.h +18 -0
  61. data/ext/numo/narray/numo/types/float_macro.h +25 -2
  62. data/ext/numo/narray/numo/types/robj_macro.h +2 -4
  63. data/ext/numo/narray/numo/types/scomplex.h +18 -0
  64. data/ext/numo/narray/numo/types/sfloat.h +18 -0
  65. data/ext/numo/narray/rand.c +0 -15
  66. data/ext/numo/narray/step.c +0 -5
  67. data/ext/numo/narray/struct.c +7 -12
  68. data/lib/erbpp/line_number.rb +4 -4
  69. data/lib/erbpp/narray_def.rb +16 -7
  70. data/lib/numo/narray.rb +2 -0
  71. data/lib/numo/narray/extra.rb +465 -0
  72. data/numo-narray.gemspec +2 -2
  73. data/spec/narray_spec.rb +4 -3
  74. metadata +13 -7
  75. data/ext/numo/narray/gen/tmpl/head.c +0 -25
@@ -1,12 +1,7 @@
1
1
  /*
2
2
  kwarg.c : Process keyword arguments for Ruby
3
3
 
4
- Copyright (c) 2001 Masahiro TANAKA <masa@ir.isas.ac.jp>
5
-
6
- This program is free software.
7
- You can distribute/modify this program
8
- under the same terms as Ruby itself.
9
- NO WARRANTY.
4
+ Copyright (c) 2001 Masahiro TANAKA
10
5
  */
11
6
  #include <ruby.h>
12
7
  #include "numo/compat.h"
@@ -2,11 +2,6 @@
2
2
  math.c
3
3
  Numerical Array Extension for Ruby
4
4
  (C) Copyright 1999-2016 by Masahiro TANAKA
5
-
6
- This program is free software.
7
- You can distribute/modify this program
8
- under the same terms as Ruby itself.
9
- NO WARRANTY.
10
5
  */
11
6
  #include <ruby.h>
12
7
  #include "numo/narray.h"
@@ -63,14 +58,14 @@ VALUE nary_mathcast(int argc, VALUE *argv)
63
58
  {
64
59
  VALUE type, type2;
65
60
  int i;
61
+
66
62
  type = na_ary_composition_dtype(argv[0]);
67
63
  for (i=1; i<argc; i++) {
68
64
  type2 = na_ary_composition_dtype(argv[i]);
69
- type = nary_math_cast2(type, type2);
70
- if (NIL_P(type)) {
71
- rb_raise(rb_eTypeError,"%s is unknown for Numo::NMath",
72
- rb_class2name(argv[i]));
73
- }
65
+ type = nary_math_cast2(type, type2);
66
+ if (NIL_P(type)) {
67
+ rb_raise(rb_eTypeError,"includes unknown DataType for upcast");
68
+ }
74
69
  }
75
70
  return type;
76
71
  }
@@ -133,11 +128,12 @@ Init_nary_math()
133
128
  rb_hash_aset(hCast, numo_cDComplex, numo_mDComplexMath);
134
129
  rb_hash_aset(hCast, numo_cSFloat, numo_mSFloatMath);
135
130
  rb_hash_aset(hCast, numo_cSComplex, numo_mSComplexMath);
136
- #ifdef HAVE_RB_CFIXNUM
131
+ #ifdef RUBY_INTEGER_UNIFICATION
132
+ rb_hash_aset(hCast, rb_cInteger, rb_mMath);
133
+ #else
137
134
  rb_hash_aset(hCast, rb_cFixnum, rb_mMath);
138
135
  rb_hash_aset(hCast, rb_cBignum, rb_mMath);
139
136
  #endif
140
- rb_hash_aset(hCast, rb_cInteger, rb_mMath);
141
137
  rb_hash_aset(hCast, rb_cFloat, rb_mMath);
142
138
  rb_hash_aset(hCast, rb_cComplex, numo_mDComplexMath);
143
139
 
@@ -2,11 +2,6 @@
2
2
  narray.c
3
3
  Numerical Array Extension for Ruby
4
4
  (C) Copyright 1999-2016 by Masahiro TANAKA
5
-
6
- This program is free software.
7
- You can distribute/modify this program
8
- under the same terms as Ruby itself.
9
- NO WARRANTY.
10
5
  */
11
6
  #define NARRAY_C
12
7
  #include <ruby.h>
@@ -193,8 +188,8 @@ na_s_allocate(VALUE klass)
193
188
 
194
189
  na->base.ndim = 0;
195
190
  na->base.type = NARRAY_DATA_T;
196
- na->base.flag[0] = 0;
197
- na->base.flag[1] = 0;
191
+ na->base.flag[0] = NA_FL0_INIT;
192
+ na->base.flag[1] = NA_FL1_INIT;
198
193
  na->base.size = 0;
199
194
  na->base.shape = NULL;
200
195
  na->base.reduce = INT2FIX(0);
@@ -210,8 +205,8 @@ na_s_allocate_view(VALUE klass)
210
205
 
211
206
  na->base.ndim = 0;
212
207
  na->base.type = NARRAY_VIEW_T;
213
- na->base.flag[0] = 0;
214
- na->base.flag[1] = 0;
208
+ na->base.flag[0] = NA_FL0_INIT;
209
+ na->base.flag[1] = NA_FL1_INIT;
215
210
  na->base.size = 0;
216
211
  na->base.shape = NULL;
217
212
  na->base.reduce = INT2FIX(0);
@@ -230,14 +225,12 @@ na_array_to_internal_shape(VALUE self, VALUE ary, size_t *shape)
230
225
  size_t i, n, c, s;
231
226
  ssize_t x;
232
227
  VALUE v;
233
- narray_t *na;
234
228
  int flag = 0;
235
229
 
236
230
  n = RARRAY_LEN(ary);
237
231
 
238
232
  if (RTEST(self)) {
239
- GetNArray(self, na);
240
- flag = TEST_COLUMN_MAJOR(na);
233
+ flag = TEST_COLUMN_MAJOR(self);
241
234
  }
242
235
  if (flag) {
243
236
  c = n-1;
@@ -642,9 +635,9 @@ void
642
635
  na_release_lock(VALUE self)
643
636
  {
644
637
  narray_t *na;
645
- GetNArray(self,na);
646
638
 
647
- NA_UNSET_LOCK(na);
639
+ UNSET_LOCK(self);
640
+ GetNArray(self,na);
648
641
 
649
642
  switch(NA_TYPE(na)) {
650
643
  case NARRAY_VIEW_T:
@@ -653,51 +646,6 @@ na_release_lock(VALUE self)
653
646
  }
654
647
  }
655
648
 
656
- // fix name, ex, allow_stride_for_flatten_view
657
- VALUE
658
- na_check_ladder(VALUE self, int start_dim)
659
- {
660
- int i;
661
- ssize_t st0, st1;
662
- narray_t *na1;
663
- narray_view_t *na;
664
- GetNArray(self,na1);
665
-
666
- //puts("pass ladder");
667
-
668
- if (start_dim < -na1->ndim || start_dim >= na1->ndim) {
669
- rb_bug("start_dim (%d) out of range",start_dim);
670
- }
671
-
672
- switch(na1->type) {
673
- case NARRAY_DATA_T:
674
- case NARRAY_FILEMAP_T:
675
- return Qtrue;
676
- case NARRAY_VIEW_T:
677
- GetNArrayView(self,na);
678
- // negative dim -> position from last dim
679
- if (start_dim < 0) {
680
- start_dim += na->base.ndim;
681
- }
682
- // not ladder if it has index
683
- for (i=start_dim; i<na->base.ndim; i++) {
684
- if (SDX_IS_INDEX(na->stridx[i]))
685
- return Qfalse;
686
- }
687
- // check stride
688
- i = start_dim;
689
- st0 = SDX_GET_STRIDE(na->stridx[i]);
690
- for (i++; i<na->base.ndim; i++) {
691
- st1 = SDX_GET_STRIDE(na->stridx[i]);
692
- if (st0 != (ssize_t)(st1*na->base.shape[i])) {
693
- return Qfalse;
694
- }
695
- st0 = st1;
696
- }
697
- return Qtrue;
698
- }
699
- return Qtrue;
700
- }
701
649
 
702
650
 
703
651
  /*
@@ -786,7 +734,7 @@ static VALUE
786
734
 
787
735
  GetNArray(self,na);
788
736
  n = NA_NDIM(na);
789
- if (TEST_COLUMN_MAJOR(na)) {
737
+ if (TEST_COLUMN_MAJOR(self)) {
790
738
  c = n-1;
791
739
  s = -1;
792
740
  } else {
@@ -855,7 +803,7 @@ na_copy_flags(VALUE src, VALUE dst)
855
803
  GetNArray(dst,na2);
856
804
 
857
805
  na2->flag[0] = na1->flag[0];
858
- na2->flag[1] = na1->flag[1];
806
+ //na2->flag[1] = NA_FL1_INIT;
859
807
 
860
808
  RBASIC(dst)->flags |= (RBASIC(src)->flags) &
861
809
  (FL_USER1|FL_USER2|FL_USER3|FL_USER4|FL_USER5|FL_USER6|FL_USER7);
@@ -877,6 +825,70 @@ na_original_data(VALUE self)
877
825
  return self;
878
826
  }
879
827
 
828
+ // fix name, ex, allow_stride_for_flatten_view
829
+ VALUE
830
+ na_check_ladder(VALUE self, int start_dim)
831
+ {
832
+ int i;
833
+ ssize_t st0, st1;
834
+ narray_t *na;
835
+ GetNArray(self,na);
836
+
837
+ if (start_dim < -na->ndim || start_dim >= na->ndim) {
838
+ rb_bug("start_dim (%d) out of range",start_dim);
839
+ }
840
+
841
+ switch(na->type) {
842
+ case NARRAY_DATA_T:
843
+ case NARRAY_FILEMAP_T:
844
+ return Qtrue;
845
+ case NARRAY_VIEW_T:
846
+ // negative dim -> position from last dim
847
+ if (start_dim < 0) {
848
+ start_dim += NA_NDIM(na);
849
+ }
850
+ // not ladder if it has index
851
+ for (i=start_dim; i<NA_NDIM(na); i++) {
852
+ if (NA_IS_INDEX_AT(na,i))
853
+ return Qfalse;
854
+ }
855
+ // check stride
856
+ st0 = NA_STRIDE_AT(na,start_dim);
857
+ for (i=start_dim+1; i<NA_NDIM(na); i++) {
858
+ st1 = NA_STRIDE_AT(na,i);
859
+ if (st0 != (ssize_t)(st1 * NA_SHAPE(na)[i])) {
860
+ return Qfalse;
861
+ }
862
+ st0 = st1;
863
+ }
864
+ }
865
+ return Qtrue;
866
+ }
867
+
868
+ VALUE
869
+ na_check_contiguous(VALUE self)
870
+ {
871
+ ssize_t elmsz;
872
+ narray_t *na;
873
+ GetNArray(self,na);
874
+
875
+ switch(na->type) {
876
+ case NARRAY_DATA_T:
877
+ case NARRAY_FILEMAP_T:
878
+ return Qtrue;
879
+ case NARRAY_VIEW_T:
880
+ if (NA_VIEW_STRIDX(na)==0) {
881
+ return Qtrue;
882
+ }
883
+ if (na_check_ladder(self,0)==Qtrue) {
884
+ elmsz = na_get_elmsz(self);
885
+ if (elmsz == NA_STRIDE_AT(na,NA_NDIM(na)-1)) {
886
+ return Qtrue;
887
+ }
888
+ }
889
+ }
890
+ return Qfalse;
891
+ }
880
892
 
881
893
  //----------------------------------------------------------------------
882
894
 
@@ -1168,13 +1180,13 @@ nary_s_byte_size(VALUE type)
1168
1180
 
1169
1181
  /*
1170
1182
  Returns a new 1-D array initialized from binary raw data in a string.
1171
- @overload from_string(string,[shape])
1183
+ @overload from_binary(string,[shape])
1172
1184
  @param [String] string Binary raw data.
1173
1185
  @param [Array] shape array of integers representing array shape.
1174
1186
  @return [Numo::NArray] NArray containing binary data.
1175
1187
  */
1176
1188
  static VALUE
1177
- nary_s_from_string(int argc, VALUE *argv, VALUE type)
1189
+ nary_s_from_binary(int argc, VALUE *argv, VALUE type)
1178
1190
  {
1179
1191
  size_t len, str_len, byte_size;
1180
1192
  size_t *shape;
@@ -1184,6 +1196,7 @@ nary_s_from_string(int argc, VALUE *argv, VALUE type)
1184
1196
  VALUE velmsz;
1185
1197
 
1186
1198
  narg = rb_scan_args(argc,argv,"11",&vstr,&vshape);
1199
+ Check_Type(vstr,T_STRING);
1187
1200
  str_len = RSTRING_LEN(vstr);
1188
1201
  velmsz = rb_const_get(type, rb_intern(ELEMENT_BYTE_SIZE));
1189
1202
  if (narg==2) {
@@ -1239,30 +1252,164 @@ nary_s_from_string(int argc, VALUE *argv, VALUE type)
1239
1252
  return vna;
1240
1253
  }
1241
1254
 
1255
+ /*
1256
+ Returns a new 1-D array initialized from binary raw data in a string.
1257
+ @overload store_binary(string,[offset])
1258
+ @param [String] string Binary raw data.
1259
+ @param [Integer] (optional) offset Byte offset in string.
1260
+ @return [Integer] stored length.
1261
+ */
1262
+ static VALUE
1263
+ nary_store_binary(int argc, VALUE *argv, VALUE self)
1264
+ {
1265
+ size_t size, str_len, byte_size, offset;
1266
+ char *ptr;
1267
+ int narg;
1268
+ VALUE vstr, voffset;
1269
+ VALUE velmsz;
1270
+ narray_t *na;
1271
+
1272
+ narg = rb_scan_args(argc,argv,"11",&vstr,&voffset);
1273
+ str_len = RSTRING_LEN(vstr);
1274
+ if (narg==2) {
1275
+ offset = NUM2SIZET(voffset);
1276
+ if (str_len < offset) {
1277
+ rb_raise(rb_eArgError, "offset is larger than string length");
1278
+ }
1279
+ str_len -= offset;
1280
+ } else {
1281
+ offset = 0;
1282
+ }
1283
+
1284
+ GetNArray(self,na);
1285
+ size = NA_SIZE(na);
1286
+ velmsz = rb_const_get(CLASS_OF(self), rb_intern(ELEMENT_BYTE_SIZE));
1287
+ if (FIXNUM_P(velmsz)) {
1288
+ byte_size = size * NUM2SIZET(velmsz);
1289
+ } else {
1290
+ byte_size = ceil(size * NUM2DBL(velmsz));
1291
+ }
1292
+ if (byte_size > str_len) {
1293
+ rb_raise(rb_eArgError, "string is too short to store");
1294
+ }
1295
+
1296
+ ptr = na_get_pointer_for_write(self);
1297
+ memcpy(ptr, RSTRING_PTR(vstr)+offset, byte_size);
1298
+
1299
+ return SIZET2NUM(byte_size);
1300
+ }
1301
+
1242
1302
  /*
1243
1303
  Returns string containing the raw data bytes in NArray.
1244
- @overload to_string()
1304
+ @overload to_binary()
1245
1305
  @return [String] String object containing binary raw data.
1246
1306
  */
1247
1307
  static VALUE
1248
- nary_to_string(VALUE self)
1308
+ nary_to_binary(VALUE self)
1249
1309
  {
1250
- size_t len;
1310
+ size_t len, offset=0;
1251
1311
  char *ptr;
1252
1312
  VALUE str;
1253
1313
  narray_t *na;
1254
1314
 
1255
1315
  GetNArray(self,na);
1256
1316
  if (na->type == NARRAY_VIEW_T) {
1257
- self = rb_funcall(self,rb_intern("copy"),0);
1317
+ if (na_check_contiguous(self)==Qtrue) {
1318
+ offset = NA_VIEW_OFFSET(na);
1319
+ } else {
1320
+ self = rb_funcall(self,rb_intern("copy"),0);
1321
+ }
1258
1322
  }
1259
1323
  len = NUM2SIZET(nary_byte_size(self));
1260
1324
  ptr = na_get_pointer_for_read(self);
1261
- str = rb_usascii_str_new(ptr,len);
1325
+ str = rb_usascii_str_new(ptr+offset,len);
1262
1326
  RB_GC_GUARD(self);
1263
1327
  return str;
1264
1328
  }
1265
1329
 
1330
+ /*
1331
+ Dump marshal data.
1332
+ @overload marshal_dump()
1333
+ @return [Array] Array containing marshal data.
1334
+ */
1335
+ static VALUE
1336
+ nary_marshal_dump(VALUE self)
1337
+ {
1338
+ VALUE a;
1339
+
1340
+ a = rb_ary_new();
1341
+ rb_ary_push(a, INT2FIX(1)); // version
1342
+ rb_ary_push(a, na_shape(self));
1343
+ rb_ary_push(a, INT2FIX(NA_FLAG0(self)));
1344
+ if (CLASS_OF(self) == numo_cRObject) {
1345
+ narray_t *na;
1346
+ VALUE *ptr;
1347
+ size_t offset=0;
1348
+ GetNArray(self,na);
1349
+ if (na->type == NARRAY_VIEW_T) {
1350
+ if (na_check_contiguous(self)==Qtrue) {
1351
+ offset = NA_VIEW_OFFSET(na);
1352
+ } else {
1353
+ self = rb_funcall(self,rb_intern("copy"),0);
1354
+ }
1355
+ }
1356
+ ptr = (VALUE*)na_get_pointer_for_read(self);
1357
+ rb_ary_push(a, rb_ary_new4(NA_SIZE(na), ptr+offset));
1358
+ } else {
1359
+ rb_ary_push(a, nary_to_binary(self));
1360
+ }
1361
+ RB_GC_GUARD(self);
1362
+ return a;
1363
+ }
1364
+
1365
+ VALUE na_inplace( VALUE self );
1366
+ /*
1367
+ Load marshal data.
1368
+ @overload marshal_load(data)
1369
+ @params [Array] Array containing marshal data.
1370
+ @return [nil]
1371
+ */
1372
+ static VALUE
1373
+ nary_marshal_load(VALUE self, VALUE a)
1374
+ {
1375
+ VALUE v;
1376
+
1377
+ if (TYPE(a) != T_ARRAY) {
1378
+ rb_raise(rb_eArgError,"marshal argument should be array");
1379
+ }
1380
+ if (RARRAY_LEN(a) != 4) {
1381
+ rb_raise(rb_eArgError,"marshal array size should be 4");
1382
+ }
1383
+ if (RARRAY_AREF(a,0) != INT2FIX(1)) {
1384
+ rb_raise(rb_eArgError,"NArray marshal version %d is not supported "
1385
+ "(only version 1)", NUM2INT(RARRAY_AREF(a,0)));
1386
+ }
1387
+ na_initialize(self,RARRAY_AREF(a,1));
1388
+ NA_FL0_SET(self,FIX2INT(RARRAY_AREF(a,2)));
1389
+ v = RARRAY_AREF(a,3);
1390
+ if (CLASS_OF(self) == numo_cRObject) {
1391
+ narray_t *na;
1392
+ char *ptr;
1393
+ if (TYPE(v) != T_ARRAY) {
1394
+ rb_raise(rb_eArgError,"RObject content should be array");
1395
+ }
1396
+ GetNArray(self,na);
1397
+ if (RARRAY_LEN(v) != (long)NA_SIZE(na)) {
1398
+ rb_raise(rb_eArgError,"RObject content size mismatch");
1399
+ }
1400
+ ptr = na_get_pointer_for_write(self);
1401
+ memcpy(ptr, RARRAY_PTR(v), NA_SIZE(na)*sizeof(VALUE));
1402
+ } else {
1403
+ nary_store_binary(1,&v,self);
1404
+ if (TEST_BYTE_SWAPPED(self)) {
1405
+ rb_funcall(na_inplace(self),rb_intern("to_host"),0);
1406
+ REVERSE_ENDIAN(self); // correct behavior??
1407
+ }
1408
+ }
1409
+ RB_GC_GUARD(a);
1410
+ return self;
1411
+ }
1412
+
1266
1413
 
1267
1414
  /*
1268
1415
  Cast self to another NArray datatype.
@@ -1314,6 +1461,9 @@ na_reduce_dimension(int argc, VALUE *argv, int naryc, VALUE *naryv)
1314
1461
  rb_raise(rb_eRuntimeError,"must be positive: naryc=%d", naryc);
1315
1462
  }
1316
1463
  GetNArray(naryv[0],na);
1464
+ if (na->size==0) {
1465
+ rb_raise(nary_eShapeError,"cannot reduce empty NArray");
1466
+ }
1317
1467
  reduce = na->reduce;
1318
1468
  if (argc==0) {
1319
1469
  //printf("pass argc=0 reduce=%d\n",NUM2INT(reduce));
@@ -1323,6 +1473,9 @@ na_reduce_dimension(int argc, VALUE *argv, int naryc, VALUE *naryv)
1323
1473
  row_major = TEST_COLUMN_MAJOR(naryv[0]);
1324
1474
  for (i=1; i<naryc; i++) {
1325
1475
  GetNArray(naryv[i],na);
1476
+ if (na->size==0) {
1477
+ rb_raise(nary_eShapeError,"cannot reduce empty NArray");
1478
+ }
1326
1479
  if (TEST_COLUMN_MAJOR(naryv[i]) != row_major) {
1327
1480
  rb_raise(nary_eDimensionError,"dimension order is different");
1328
1481
  }
@@ -1462,7 +1615,7 @@ VALUE na_host_order_p( VALUE self )
1462
1615
  VALUE na_inplace( VALUE self )
1463
1616
  {
1464
1617
  VALUE view = self;
1465
- //view = na_clone(self);
1618
+ view = na_make_view(self);
1466
1619
  SET_INPLACE(view);
1467
1620
  return view;
1468
1621
  }
@@ -1675,6 +1828,8 @@ Init_narray()
1675
1828
 
1676
1829
  rb_define_method(cNArray, "debug_info", rb_narray_debug_info, 0);
1677
1830
 
1831
+ rb_define_method(cNArray, "contiguous?", na_check_contiguous, 0);
1832
+
1678
1833
  rb_define_method(cNArray, "view", na_make_view, 0);
1679
1834
  rb_define_method(cNArray, "expand_dims", na_expand_dims, 1);
1680
1835
  rb_define_method(cNArray, "reverse", nary_reverse, -1);
@@ -1682,8 +1837,13 @@ Init_narray()
1682
1837
  rb_define_singleton_method(cNArray, "upcast", numo_na_upcast, 1);
1683
1838
  rb_define_singleton_method(cNArray, "byte_size", nary_s_byte_size, 0);
1684
1839
 
1685
- rb_define_singleton_method(cNArray, "from_string", nary_s_from_string, -1);
1686
- rb_define_method(cNArray, "to_string", nary_to_string, 0);
1840
+ rb_define_singleton_method(cNArray, "from_binary", nary_s_from_binary, -1);
1841
+ rb_define_alias (rb_singleton_class(cNArray), "from_string", "from_binary");
1842
+ rb_define_method(cNArray, "store_binary", nary_store_binary, -1);
1843
+ rb_define_method(cNArray, "to_binary", nary_to_binary, 0);
1844
+ rb_define_alias (cNArray, "to_string", "to_binary");
1845
+ rb_define_method(cNArray, "marshal_dump", nary_marshal_dump, 0);
1846
+ rb_define_method(cNArray, "marshal_load", nary_marshal_load, 1);
1687
1847
 
1688
1848
  rb_define_method(cNArray, "byte_size", nary_byte_size, 0);
1689
1849