numo-narray 0.9.0.4 → 0.9.0.5

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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -8
  3. data/Rakefile +9 -0
  4. data/ext/numo/narray/array.c +178 -47
  5. data/ext/numo/narray/data.c +105 -97
  6. data/ext/numo/narray/depend.erb +6 -7
  7. data/ext/numo/narray/gen/cogen.rb +30 -7
  8. data/ext/numo/narray/gen/def/bit.rb +17 -14
  9. data/ext/numo/narray/gen/def/dcomplex.rb +19 -15
  10. data/ext/numo/narray/gen/def/dfloat.rb +17 -13
  11. data/ext/numo/narray/gen/def/int16.rb +16 -12
  12. data/ext/numo/narray/gen/def/int32.rb +16 -12
  13. data/ext/numo/narray/gen/def/int64.rb +16 -12
  14. data/ext/numo/narray/gen/def/int8.rb +16 -12
  15. data/ext/numo/narray/gen/def/robject.rb +18 -14
  16. data/ext/numo/narray/gen/def/scomplex.rb +19 -15
  17. data/ext/numo/narray/gen/def/sfloat.rb +17 -13
  18. data/ext/numo/narray/gen/def/uint16.rb +16 -12
  19. data/ext/numo/narray/gen/def/uint32.rb +16 -12
  20. data/ext/numo/narray/gen/def/uint64.rb +16 -12
  21. data/ext/numo/narray/gen/def/uint8.rb +16 -12
  22. data/ext/numo/narray/gen/erbpp2.rb +324 -0
  23. data/ext/numo/narray/gen/narray_def.rb +252 -0
  24. data/ext/numo/narray/gen/spec.rb +141 -71
  25. data/ext/numo/narray/gen/tmpl/accum.c +22 -9
  26. data/ext/numo/narray/gen/tmpl/accum_binary.c +29 -13
  27. data/ext/numo/narray/gen/tmpl/accum_index.c +38 -16
  28. data/ext/numo/narray/gen/tmpl/alloc_func.c +107 -0
  29. data/ext/numo/narray/gen/tmpl/allocate.c +1 -1
  30. data/ext/numo/narray/gen/tmpl/aref.c +1 -1
  31. data/ext/numo/narray/gen/tmpl/aset.c +4 -2
  32. data/ext/numo/narray/gen/tmpl/binary.c +4 -4
  33. data/ext/numo/narray/gen/tmpl/binary2.c +5 -5
  34. data/ext/numo/narray/gen/tmpl/binary_s.c +5 -5
  35. data/ext/numo/narray/gen/tmpl/bincount.c +4 -4
  36. data/ext/numo/narray/gen/tmpl/cast.c +9 -6
  37. data/ext/numo/narray/gen/tmpl/cast_array.c +4 -9
  38. data/ext/numo/narray/gen/tmpl/class.c +9 -0
  39. data/ext/numo/narray/gen/tmpl/clip.c +118 -0
  40. data/ext/numo/narray/gen/tmpl/coerce_cast.c +4 -2
  41. data/ext/numo/narray/gen/tmpl/cond_binary.c +5 -5
  42. data/ext/numo/narray/gen/tmpl/cond_unary.c +6 -6
  43. data/ext/numo/narray/gen/tmpl/cum.c +18 -9
  44. data/ext/numo/narray/gen/tmpl/each.c +2 -2
  45. data/ext/numo/narray/gen/tmpl/each_with_index.c +2 -2
  46. data/ext/numo/narray/gen/tmpl/extract.c +2 -2
  47. data/ext/numo/narray/gen/tmpl/extract_data.c +48 -0
  48. data/ext/numo/narray/gen/tmpl/eye.c +3 -3
  49. data/ext/numo/narray/gen/tmpl/fill.c +2 -2
  50. data/ext/numo/narray/gen/tmpl/format.c +5 -5
  51. data/ext/numo/narray/gen/tmpl/format_to_a.c +4 -4
  52. data/ext/numo/narray/gen/tmpl/frexp.c +37 -0
  53. data/ext/numo/narray/gen/tmpl/init_class.c +20 -0
  54. data/ext/numo/narray/gen/tmpl/init_module.c +12 -0
  55. data/ext/numo/narray/gen/tmpl/inspect.c +2 -2
  56. data/ext/numo/narray/gen/tmpl/lib.c +45 -0
  57. data/ext/numo/narray/gen/tmpl/logseq.c +1 -1
  58. data/ext/numo/narray/gen/tmpl/map_with_index.c +2 -2
  59. data/ext/numo/narray/gen/tmpl/median.c +31 -8
  60. data/ext/numo/narray/gen/tmpl/minmax.c +24 -24
  61. data/ext/numo/narray/gen/tmpl/module.c +9 -0
  62. data/ext/numo/narray/gen/tmpl/new_dim0.c +12 -0
  63. data/ext/numo/narray/gen/tmpl/poly.c +3 -3
  64. data/ext/numo/narray/gen/tmpl/pow.c +1 -1
  65. data/ext/numo/narray/gen/tmpl/powint.c +1 -1
  66. data/ext/numo/narray/gen/tmpl/qsort.c +10 -3
  67. data/ext/numo/narray/gen/tmpl/rand.c +1 -1
  68. data/ext/numo/narray/gen/tmpl/rand_norm.c +1 -1
  69. data/ext/numo/narray/gen/tmpl/seq.c +1 -1
  70. data/ext/numo/narray/gen/tmpl/set2.c +5 -5
  71. data/ext/numo/narray/gen/tmpl/sort.c +29 -14
  72. data/ext/numo/narray/gen/tmpl/sort_index.c +41 -20
  73. data/ext/numo/narray/gen/tmpl/store.c +11 -5
  74. data/ext/numo/narray/gen/tmpl/store_array.c +1 -1
  75. data/ext/numo/narray/gen/tmpl/store_bit.c +1 -1
  76. data/ext/numo/narray/gen/tmpl/store_from.c +1 -1
  77. data/ext/numo/narray/gen/tmpl/store_numeric.c +3 -16
  78. data/ext/numo/narray/gen/tmpl/to_a.c +2 -2
  79. data/ext/numo/narray/gen/tmpl/unary.c +7 -7
  80. data/ext/numo/narray/gen/tmpl/unary2.c +8 -8
  81. data/ext/numo/narray/gen/tmpl/unary_ret2.c +33 -0
  82. data/ext/numo/narray/gen/tmpl/unary_s.c +8 -8
  83. data/ext/numo/narray/gen/tmpl_bit/allocate.c +1 -5
  84. data/ext/numo/narray/gen/tmpl_bit/aref.c +1 -1
  85. data/ext/numo/narray/gen/tmpl_bit/aset.c +2 -2
  86. data/ext/numo/narray/gen/tmpl_bit/binary.c +8 -8
  87. data/ext/numo/narray/gen/tmpl_bit/bit_count.c +8 -8
  88. data/ext/numo/narray/gen/tmpl_bit/bit_reduce.c +6 -6
  89. data/ext/numo/narray/gen/tmpl_bit/each.c +2 -2
  90. data/ext/numo/narray/gen/tmpl_bit/each_with_index.c +2 -2
  91. data/ext/numo/narray/gen/tmpl_bit/extract.c +1 -1
  92. data/ext/numo/narray/gen/tmpl_bit/fill.c +2 -2
  93. data/ext/numo/narray/gen/tmpl_bit/format.c +5 -5
  94. data/ext/numo/narray/gen/tmpl_bit/format_to_a.c +2 -2
  95. data/ext/numo/narray/gen/tmpl_bit/inspect.c +2 -2
  96. data/ext/numo/narray/gen/tmpl_bit/mask.c +5 -5
  97. data/ext/numo/narray/gen/tmpl_bit/none_p.c +4 -4
  98. data/ext/numo/narray/gen/tmpl_bit/store_array.c +2 -2
  99. data/ext/numo/narray/gen/tmpl_bit/store_bit.c +1 -1
  100. data/ext/numo/narray/gen/tmpl_bit/store_from.c +1 -1
  101. data/ext/numo/narray/gen/tmpl_bit/to_a.c +2 -2
  102. data/ext/numo/narray/gen/tmpl_bit/unary.c +9 -9
  103. data/ext/numo/narray/gen/tmpl_bit/where.c +6 -6
  104. data/ext/numo/narray/gen/tmpl_bit/where2.c +8 -8
  105. data/ext/numo/narray/index.c +46 -30
  106. data/ext/numo/narray/math.c +12 -6
  107. data/ext/numo/narray/narray.c +242 -218
  108. data/ext/numo/narray/ndloop.c +17 -24
  109. data/ext/numo/narray/numo/intern.h +63 -67
  110. data/ext/numo/narray/numo/narray.h +38 -13
  111. data/ext/numo/narray/numo/ndloop.h +1 -1
  112. data/ext/numo/narray/numo/template.h +1 -1
  113. data/ext/numo/narray/numo/types/complex.h +8 -4
  114. data/ext/numo/narray/numo/types/complex_macro.h +118 -1
  115. data/ext/numo/narray/numo/types/float_macro.h +283 -6
  116. data/ext/numo/narray/numo/types/robj_macro.h +261 -9
  117. data/ext/numo/narray/numo/types/xint_macro.h +35 -0
  118. data/ext/numo/narray/struct.c +34 -15
  119. data/lib/erbpp.rb +5 -1
  120. data/lib/erbpp/line_number.rb +10 -3
  121. data/lib/erbpp/narray_def.rb +55 -25
  122. data/lib/numo/narray/extra.rb +638 -219
  123. data/numo-narray.gemspec +1 -0
  124. data/spec/narray_spec.rb +2 -2
  125. metadata +17 -14
  126. data/ext/numo/narray/gen/dtype.erb.c +0 -82
  127. data/ext/numo/narray/gen/tmpl/cast_numeric.c +0 -22
  128. data/ext/numo/narray/gen/tmpl/robj_allocate.c +0 -32
  129. data/ext/numo/narray/gen/tmpl_bit/cast.c +0 -37
  130. data/ext/numo/narray/gen/tmpl_bit/cast_array.c +0 -18
  131. data/ext/numo/narray/gen/tmpl_bit/cast_numeric.c +0 -22
  132. data/ext/numo/narray/gen/tmpl_bit/coerce_cast.c +0 -8
  133. data/ext/numo/narray/gen/tmpl_bit/map_with_index.c +0 -94
  134. data/ext/numo/narray/gen/tmpl_bit/store.c +0 -32
  135. data/ext/numo/narray/gen/tmpl_bit/store_numeric.c +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 344742df38a815d85e70962da4cdb85969d816a2
4
- data.tar.gz: 6da0a54faee1813628901213587213618ce696bc
3
+ metadata.gz: ee92d774c7adbc21131b5d25b83f2cd83ffb2870
4
+ data.tar.gz: 185833b9b03560dfd494a000268f6d920883b343
5
5
  SHA512:
6
- metadata.gz: 908a26721c4d03e7af632747cce53ba41465d6e2917dbb97505a04ab9d8008c6764889bc669d79d83952b36a21467f7d8c8913046cc46ebf8cda23e792d62f9f
7
- data.tar.gz: caa3d25b088c2ab5376ee64daf88581e9eeb64a9febd6456a3780ce05b0535c065867a6f9a64913db96cf422a38843c1d1800f3d53bcb5417f773af42ca123fe
6
+ metadata.gz: 9c4de1ae4febaa26a8b7da95f2e3e97278e0e3ee208194926cc0ecfdc5bcf799dcac372a2b970c0d89102e6210bd239d2ca357a5c7598e7c54719ccc63d5ae35
7
+ data.tar.gz: e474764872f99bb8cab763d268b971674831ddfaafadb457749cc90c54440ff74f014a77b85617946c36ddd17e96f59906112103c3305bdb9d38b78781826b34
data/README.md CHANGED
@@ -13,6 +13,14 @@ This project is the successor to [Ruby/NArray](http://masa16.github.io/narray/).
13
13
 
14
14
  under development
15
15
 
16
+ ## Documentation
17
+ All documents are primitive.
18
+
19
+ * [Numo::NArray API Doc](http://ruby-numo.github.io/narray/narray/frames.html)
20
+ * [Numo::NArray vs numpy](https://github.com/ruby-numo/narray/wiki/Numo-vs-numpy)
21
+ * [Numo::NArray vs ndarray](https://github.com/ruby-numo/narray/wiki/Numo-vs-ndarray)
22
+ * [Numo::NArray Overview](https://github.com/ruby-numo/narray/wiki/Numo::NArray%E6%A6%82%E8%A6%81) (in Japanese)
23
+
16
24
  ## Related Projects
17
25
  * [Numo::Linalg](https://github.com/ruby-numo/linalg) - Linear Algebra library with [LAPACK](http://www.netlib.org/lapack/).
18
26
  * [Numo::GSL](https://github.com/ruby-numo/gsl) - Ruby interface for [GSL (GNU Scientific Library)](http://www.gnu.org/software/gsl/).
@@ -20,6 +28,9 @@ under development
20
28
  * [Numo::Gnuplot](https://github.com/ruby-numo/gnuplot) - Simple and easy-to-use Gnuplot interface.
21
29
 
22
30
  ## Installation
31
+ ### Requirement
32
+ Ruby ver 2.1 and later.
33
+
23
34
  ### Ubuntu, Debian, Bash on Windows
24
35
  ```shell
25
36
  apt install -y git ruby gcc ruby-dev rake make
@@ -47,11 +58,3 @@ An example
47
58
  => 15
48
59
  ```
49
60
  For more examples, check out this [narray version of 100 numpy exercises](https://github.com/ruby-numo/narray/wiki/100-narray-exercises) (and the [IRuby Notebook](https://github.com/ruby-numo/narray/blob/master/100-narray-exercises.ipynb)).
50
-
51
- ## Documentation
52
-
53
- All documents are primitive.
54
-
55
- * [Numo::NArray API Doc](http://ruby-numo.github.io/narray/narray/frames.html)
56
- * [Numo::NArray概要](https://github.com/ruby-numo/narray/wiki/Numo::NArray%E6%A6%82%E8%A6%81) (in Japanese)
57
- * [Numo::NArray vs numpy](https://github.com/ruby-numo/narray/wiki/Numo-vs-numpy)
data/Rakefile CHANGED
@@ -52,5 +52,14 @@ namespace :release do
52
52
  end
53
53
  end
54
54
 
55
+ task :doc do
56
+ dir = "ext/numo/narray"
57
+ src = %w[array.c data.c index.c math.c narray.c rand.c struct.c].
58
+ map{|s| File.join(dir,s)} +
59
+ [File.join(dir,"types/*.c"), "lib/numo/narray/extra.rb"]
60
+ sh "cd ext/numo/narray; ruby extconf.rb; make src"
61
+ sh "rm -rf yard .yardoc; yard doc -o yard -r README.md #{src.join(' ')}"
62
+ end
63
+
55
64
  rescue LoadError
56
65
  end
@@ -1,13 +1,12 @@
1
1
  /*
2
2
  array.c
3
3
  Numerical Array Extension for Ruby
4
- (C) Copyright 1999-2016 by Masahiro TANAKA
4
+ (C) Copyright 1999-2017 by Masahiro TANAKA
5
5
  */
6
6
  #include <ruby.h>
7
7
  #include "numo/narray.h"
8
- //#include "narray_local.h"
9
8
 
10
- /* Multi-Dimensional Array Investigation */
9
+ // mdai: Multi-Dimensional Array Investigation
11
10
  typedef struct {
12
11
  size_t shape;
13
12
  VALUE val;
@@ -25,6 +24,53 @@ typedef struct {
25
24
  enum { NA_NONE, NA_BIT, NA_INT32, NA_INT64, NA_RATIONAL,
26
25
  NA_DFLOAT, NA_DCOMPLEX, NA_ROBJ, NA_NTYPES };
27
26
 
27
+ static ID id_begin;
28
+ static ID id_end;
29
+ static ID id_step;
30
+ static ID id_abs;
31
+ static ID id_cast;
32
+ static ID id_le;
33
+ static ID id_Complex;
34
+
35
+ typedef struct {
36
+ int ndim;
37
+ size_t *shape;
38
+ VALUE dtype;
39
+ } na_compose_t;
40
+
41
+ static size_t
42
+ na_compose_memsize(const void *ptr)
43
+ {
44
+ const na_compose_t *nc = (const na_compose_t*)ptr;
45
+
46
+ return sizeof(na_compose_t) + nc->ndim * sizeof(size_t);
47
+ }
48
+
49
+ static void
50
+ na_compose_free(void *ptr)
51
+ {
52
+ na_compose_t *nc = (na_compose_t*)ptr;
53
+
54
+ if (nc->shape)
55
+ xfree(nc->shape);
56
+ xfree(nc);
57
+ }
58
+
59
+ static void
60
+ na_compose_gc_mark(void* nc)
61
+ {
62
+ rb_gc_mark(((na_compose_t*)nc)->dtype);
63
+ }
64
+
65
+ static const rb_data_type_t compose_data_type = {
66
+ "Numo::NArray/compose",
67
+ {na_compose_gc_mark, na_compose_free, na_compose_memsize,},
68
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
69
+ };
70
+
71
+ #define WrapCompose(p) TypedData_Wrap_Struct(rb_cData, &compose_data_type, (void*)(p));
72
+ #define GetCompose(v,p) TypedData_Get_Struct(v, na_compose_t, &compose_data_type, p)
73
+
28
74
  static VALUE
29
75
  na_object_type(int type, VALUE v)
30
76
  {
@@ -47,8 +93,8 @@ static VALUE
47
93
  return type;
48
94
  case T_BIGNUM:
49
95
  if (type<NA_INT64) {
50
- v = rb_funcall(v,rb_intern("abs"),0);
51
- if (RTEST(rb_funcall(v,rb_intern("<="),1,int32_max))) {
96
+ v = rb_funcall(v,id_abs,0);
97
+ if (RTEST(rb_funcall(v,id_le,1,int32_max))) {
52
98
  if (type<NA_INT32)
53
99
  return NA_INT32;
54
100
  } else {
@@ -78,8 +124,8 @@ static VALUE
78
124
  case T_FIXNUM:
79
125
  case T_BIGNUM:
80
126
  if (type<NA_INT64) {
81
- v = rb_funcall(v,rb_intern("abs"),0);
82
- if (RTEST(rb_funcall(v,rb_intern("<="),1,int32_max))) {
127
+ v = rb_funcall(v,id_abs,0);
128
+ if (RTEST(rb_funcall(v,id_le,1,int32_max))) {
83
129
  if (type<NA_INT32)
84
130
  return NA_INT32;
85
131
  } else {
@@ -98,7 +144,7 @@ static VALUE
98
144
  return type;
99
145
 
100
146
  default:
101
- if (CLASS_OF(v) == rb_const_get( rb_cObject, rb_intern("Complex") )) {
147
+ if (CLASS_OF(v) == rb_const_get( rb_cObject, id_Complex )) {
102
148
  return NA_DCOMPLEX;
103
149
  }
104
150
  }
@@ -107,7 +153,7 @@ static VALUE
107
153
 
108
154
 
109
155
  #define MDAI_ATTR_TYPE(tp,v,attr) \
110
- {tp = na_object_type(tp,rb_funcall(v,rb_intern(attr),0));}
156
+ {tp = na_object_type(tp,rb_funcall(v,id_##attr,0));}
111
157
 
112
158
  void na_mdai_object_type(na_mdai_t *mdai, VALUE v)
113
159
  {
@@ -118,12 +164,12 @@ void na_mdai_object_type(na_mdai_t *mdai, VALUE v)
118
164
  mdai->na_type = na_upcast(CLASS_OF(v), mdai->na_type);
119
165
  }
120
166
  } else if (rb_obj_is_kind_of(v, rb_cRange)) {
121
- MDAI_ATTR_TYPE(mdai->type,v,"begin");
122
- MDAI_ATTR_TYPE(mdai->type,v,"end");
167
+ MDAI_ATTR_TYPE(mdai->type,v,begin);
168
+ MDAI_ATTR_TYPE(mdai->type,v,end);
123
169
  } else if (rb_obj_is_kind_of(v, na_cStep)) {
124
- MDAI_ATTR_TYPE(mdai->type,v,"begin");
125
- MDAI_ATTR_TYPE(mdai->type,v,"end");
126
- MDAI_ATTR_TYPE(mdai->type,v,"step");
170
+ MDAI_ATTR_TYPE(mdai->type,v,begin);
171
+ MDAI_ATTR_TYPE(mdai->type,v,end);
172
+ MDAI_ATTR_TYPE(mdai->type,v,step);
127
173
  } else {
128
174
  mdai->type = na_object_type(mdai->type,v);
129
175
  }
@@ -166,8 +212,9 @@ na_mdai_realloc(na_mdai_t *mdai, int n_extra)
166
212
  }
167
213
 
168
214
  static void
169
- na_mdai_free(na_mdai_t *mdai)
215
+ na_mdai_free(void *ptr)
170
216
  {
217
+ na_mdai_t *mdai = (na_mdai_t*)ptr;
171
218
  xfree(mdai->item);
172
219
  xfree(mdai);
173
220
  }
@@ -255,15 +302,9 @@ na_mdai_result(na_mdai_t *mdai, na_compose_t *nc)
255
302
 
256
303
  if (ndim>0) {
257
304
  // Shape
258
- //shape = ALLOC_N(size_t,i);
259
- //for (i=0; i<*ndim; i++) {
260
- // shape[i] = mdai->item[i].shape;
261
- //}
262
305
  nc->shape = shape = ALLOC_N(size_t,ndim);
263
306
  for (i=0; i<ndim; i++) {
264
307
  shape[i] = mdai->item[i].shape;
265
- //printf("shape[%d]=%d\n",i,shape[i]);
266
- //rb_ary_push( shape, SIZET2NUM(mdai->item[i].shape) );
267
308
  }
268
309
 
269
310
  // DataType
@@ -301,6 +342,20 @@ na_mdai_result(na_mdai_t *mdai, na_compose_t *nc)
301
342
  }
302
343
 
303
344
 
345
+ static size_t
346
+ na_mdai_memsize(const void *ptr)
347
+ {
348
+ const na_mdai_t *mdai = (const na_mdai_t*)ptr;
349
+
350
+ return sizeof(na_mdai_t) + mdai->capa * sizeof(na_mdai_item_t);
351
+ }
352
+
353
+ static const rb_data_type_t mdai_data_type = {
354
+ "Numo::NArray/mdai",
355
+ {NULL, na_mdai_free, na_mdai_memsize,},
356
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
357
+ };
358
+
304
359
  VALUE
305
360
  na_ary_composition(VALUE ary)
306
361
  {
@@ -310,12 +365,19 @@ na_ary_composition(VALUE ary)
310
365
  int j;
311
366
 
312
367
  nc = ALLOC(na_compose_t);
313
- vnc = Data_Wrap_Struct(rb_cData, 0, -1, nc);
368
+ vnc = WrapCompose(nc);
314
369
  if (TYPE(ary) == T_ARRAY) {
315
370
  mdai = na_mdai_alloc(ary);
316
- vmdai = Data_Wrap_Struct(rb_cData, 0, na_mdai_free, mdai);
317
- na_mdai_investigate(mdai, 1);
318
- na_mdai_result(mdai, nc);
371
+ vmdai = TypedData_Wrap_Struct(rb_cData, &mdai_data_type, (void*)mdai);
372
+ if ( na_mdai_investigate(mdai, 1) ) {
373
+ // empty
374
+ nc->ndim = 1;
375
+ nc->shape = ALLOC_N(size_t, 1);
376
+ nc->shape[0] = 0;
377
+ nc->dtype = Qnil;
378
+ } else {
379
+ na_mdai_result(mdai, nc);
380
+ }
319
381
  rb_gc_force_recycle(vmdai);
320
382
  } else if (IsNArray(ary)) {
321
383
  narray_t *na;
@@ -333,28 +395,94 @@ na_ary_composition(VALUE ary)
333
395
  }
334
396
 
335
397
 
398
+ static void
399
+ na_ary_composition2(VALUE ary, VALUE *type, VALUE *shape)
400
+ {
401
+ VALUE vnc, dshape;
402
+ na_compose_t *nc;
403
+ int i;
404
+
405
+ // investigate MD-Array
406
+ vnc = na_ary_composition(ary);
407
+ GetCompose(vnc,nc);
408
+ dshape = rb_ary_new2(nc->ndim);
409
+ for (i=0; i<nc->ndim; i++) {
410
+ rb_ary_push(dshape, SIZET2NUM(nc->shape[i]));
411
+ }
412
+ if (shape) {*shape = dshape;}
413
+ if (type) {*type = nc->dtype;}
414
+ RB_GC_GUARD(vnc);
415
+ }
416
+
336
417
  static VALUE
337
418
  na_s_array_shape(VALUE mod, VALUE ary)
338
419
  {
339
- volatile VALUE vnc;
340
420
  VALUE shape;
341
- na_compose_t *nc;
342
- int i;
343
421
 
344
422
  if (TYPE(ary)!=T_ARRAY) {
345
423
  // 0-dimension
346
424
  return rb_ary_new();
347
425
  }
348
- // investigate MD-Array
349
- vnc = na_ary_composition(ary);
350
- Data_Get_Struct(vnc, na_compose_t, nc);
351
- shape = rb_ary_new2(nc->ndim);
352
- for (i=0; i<nc->ndim; i++) {
353
- rb_ary_push( shape, SIZET2NUM(nc->shape[i]) );
354
- }
426
+ na_ary_composition2(ary, 0, &shape);
355
427
  return shape;
356
428
  }
357
429
 
430
+ static inline void
431
+ check_subclass_of_narray(VALUE dtype) {
432
+ if (RTEST(rb_obj_is_kind_of(dtype, rb_cClass))) {
433
+ if (RTEST(rb_funcall(dtype, id_le, 1, cNArray))) {
434
+ return;
435
+ }
436
+ }
437
+ rb_raise(nary_eCastError, "cannot convert to NArray");
438
+ }
439
+
440
+
441
+ /*
442
+ Generate new unallocated NArray instance with shape and type defined from obj.
443
+ Numo::NArray.new_like(obj) returns instance whose type is defined from obj.
444
+ Numo::DFloat.new_like(obj) returns DFloat instance.
445
+
446
+ @overload new_like(obj)
447
+ @param [Numeric,Array,Numo::NArray] obj
448
+ @return [Numo::NArray]
449
+ @example
450
+ Numo::NArray.new_like([[1,2,3],[4,5,6]])
451
+ => Numo::Int32#shape=[2,3](empty)
452
+ Numo::DFloat.new_like([[1,2],[3,4]])
453
+ => Numo::DFloat#shape=[2,2](empty)
454
+ Numo::NArray.new_like([1,2i,3])
455
+ => Numo::DComplex#shape=[3](empty)
456
+ */
457
+ VALUE
458
+ na_s_new_like(VALUE type, VALUE obj)
459
+ {
460
+ VALUE vnc, newary;
461
+ na_compose_t *nc;
462
+
463
+ if (RTEST(rb_obj_is_kind_of(obj,rb_cNumeric))) {
464
+ // investigate type
465
+ if (type == cNArray) {
466
+ vnc = na_ary_composition(rb_ary_new3(1,obj));
467
+ GetCompose(vnc,nc);
468
+ type = nc->dtype;
469
+ }
470
+ check_subclass_of_narray(type);
471
+ newary = nary_new(type, 0, 0);
472
+ } else {
473
+ // investigate MD-Array
474
+ vnc = na_ary_composition(obj);
475
+ GetCompose(vnc,nc);
476
+ if (type == cNArray) {
477
+ type = nc->dtype;
478
+ }
479
+ check_subclass_of_narray(type);
480
+ newary = nary_new(type, nc->ndim, nc->shape);
481
+ }
482
+ RB_GC_GUARD(vnc);
483
+ return newary;
484
+ }
485
+
358
486
 
359
487
  VALUE
360
488
  na_ary_composition_dtype(VALUE ary)
@@ -365,7 +493,7 @@ na_ary_composition_dtype(VALUE ary)
365
493
  switch(TYPE(ary)) {
366
494
  case T_ARRAY:
367
495
  vnc = na_ary_composition(ary);
368
- Data_Get_Struct(vnc, na_compose_t, nc);
496
+ GetCompose(vnc,nc);
369
497
  return nc->dtype;
370
498
  }
371
499
  return CLASS_OF(ary);
@@ -379,6 +507,7 @@ na_s_array_type(VALUE mod, VALUE ary)
379
507
 
380
508
 
381
509
 
510
+
382
511
  /*
383
512
  Generate NArray object. NArray datatype is automatically selected.
384
513
  @overload [](elements)
@@ -393,16 +522,9 @@ nary_s_bracket(VALUE klass, VALUE ary)
393
522
  if (TYPE(ary)!=T_ARRAY) {
394
523
  rb_bug("Argument is not array");
395
524
  }
396
-
397
525
  dtype = na_ary_composition_dtype(ary);
398
-
399
- if (RTEST(rb_obj_is_kind_of(dtype,rb_cClass))) {
400
- if (RTEST(rb_funcall(dtype,rb_intern("<="),1,cNArray))) {
401
- return rb_funcall(dtype,rb_intern("cast"),1,ary);
402
- }
403
- }
404
- rb_raise(nary_eCastError, "cannot convert to NArray");
405
- return Qnil;
526
+ check_subclass_of_narray(dtype);
527
+ return rb_funcall(dtype, id_cast, 1, ary);
406
528
  }
407
529
 
408
530
 
@@ -497,10 +619,10 @@ na_ary_composition_for_struct(VALUE nstruct, VALUE ary)
497
619
 
498
620
  mdai = na_mdai_alloc(ary);
499
621
  mdai->na_type = nstruct;
500
- vmdai = Data_Wrap_Struct(rb_cData, 0, na_mdai_free, mdai);
622
+ vmdai = TypedData_Wrap_Struct(rb_cData, &mdai_data_type, (void*)mdai);
501
623
  na_mdai_for_struct(mdai, 0);
502
624
  nc = ALLOC(na_compose_t);
503
- vnc = Data_Wrap_Struct(rb_cData, 0, -1, nc);
625
+ vnc = WrapCompose(nc);
504
626
  na_mdai_result(mdai, nc);
505
627
  //fprintf(stderr,"nc->ndim=%d\n",nc->ndim);
506
628
  rb_gc_force_recycle(vmdai);
@@ -515,6 +637,15 @@ Init_nary_array()
515
637
  //rb_define_singleton_method(cNArray, "mdai", na_mdai, 1);
516
638
  rb_define_singleton_method(cNArray, "array_shape", na_s_array_shape, 1);
517
639
  rb_define_singleton_method(cNArray, "array_type", na_s_array_type, 1);
640
+ rb_define_singleton_method(cNArray, "new_like", na_s_new_like, 1);
518
641
 
519
642
  rb_define_singleton_method(cNArray, "[]", nary_s_bracket, -2);
643
+
644
+ id_begin = rb_intern("begin");
645
+ id_end = rb_intern("end");
646
+ id_step = rb_intern("step");
647
+ id_cast = rb_intern("cast");
648
+ id_abs = rb_intern("abs");
649
+ id_le = rb_intern("<=");
650
+ id_Complex = rb_intern("Complex");
520
651
  }
@@ -1,13 +1,19 @@
1
1
  /*
2
2
  data.c
3
3
  Numerical Array Extension for Ruby
4
- (C) Copyright 1999-2016 by Masahiro TANAKA
4
+ (C) Copyright 1999-2017 by Masahiro TANAKA
5
5
  */
6
6
 
7
7
  #include <ruby.h>
8
8
  #include "numo/narray.h"
9
9
  #include "numo/template.h"
10
10
 
11
+ static VALUE sym_mulsum;
12
+ static ID id_mulsum;
13
+ static ID id_respond_to_p;
14
+ static ID id_store;
15
+ static ID id_swap_byte;
16
+
11
17
  // ---------------------------------------------------------------------
12
18
 
13
19
  #define LOOP_UNARY_PTR(lp,proc) \
@@ -74,7 +80,7 @@ na_copy(VALUE self)
74
80
  VALUE
75
81
  na_store(VALUE self, VALUE src)
76
82
  {
77
- return rb_funcall(self,rb_intern("store"),1,src);
83
+ return rb_funcall(self,id_store,1,src);
78
84
  }
79
85
 
80
86
  // ---------------------------------------------------------------------
@@ -125,7 +131,7 @@ nary_to_network(VALUE self)
125
131
  if (TEST_BIG_ENDIAN(self)) {
126
132
  return self;
127
133
  }
128
- return rb_funcall(self, rb_intern("swap_byte"), 0);
134
+ return rb_funcall(self, id_swap_byte, 0);
129
135
  }
130
136
 
131
137
  static VALUE
@@ -134,7 +140,7 @@ nary_to_vacs(VALUE self)
134
140
  if (TEST_LITTLE_ENDIAN(self)) {
135
141
  return self;
136
142
  }
137
- return rb_funcall(self, rb_intern("swap_byte"), 0);
143
+ return rb_funcall(self, id_swap_byte, 0);
138
144
  }
139
145
 
140
146
  static VALUE
@@ -143,7 +149,7 @@ nary_to_host(VALUE self)
143
149
  if (TEST_HOST_ORDER(self)) {
144
150
  return self;
145
151
  }
146
- return rb_funcall(self, rb_intern("swap_byte"), 0);
152
+ return rb_funcall(self, id_swap_byte, 0);
147
153
  }
148
154
 
149
155
  static VALUE
@@ -152,12 +158,79 @@ nary_to_swapped(VALUE self)
152
158
  if (TEST_BYTE_SWAPPED(self)) {
153
159
  return self;
154
160
  }
155
- return rb_funcall(self, rb_intern("swap_byte"), 0);
161
+ return rb_funcall(self, id_swap_byte, 0);
156
162
  }
157
163
 
158
164
 
159
165
  //----------------------------------------------------------------------
160
166
 
167
+ static inline int
168
+ check_axis(int axis, int ndim)
169
+ {
170
+ if (axis < -ndim || axis >= ndim) {
171
+ rb_raise(nary_eDimensionError,"invalid axis (%d for %d-dimension)",
172
+ axis, ndim);
173
+ }
174
+ if (axis < 0) {
175
+ axis += ndim;
176
+ }
177
+ return axis;
178
+ }
179
+
180
+ /*
181
+ Interchange two axes.
182
+ @overload swapaxes(axis1,axis2)
183
+ @param [Integer] axis1
184
+ @param [Integer] axis2
185
+ @return [Numo::NArray] view of NArray.
186
+ @example
187
+ x = Numo::Int32[[1,2,3]]
188
+
189
+ p x.swapaxes(0,1)
190
+ # Numo::Int32(view)#shape=[3,1]
191
+ # [[1],
192
+ # [2],
193
+ # [3]]
194
+
195
+ p x = Numo::Int32[[[0,1],[2,3]],[[4,5],[6,7]]]
196
+ # Numo::Int32#shape=[2,2,2]
197
+ # [[[0, 1],
198
+ # [2, 3]],
199
+ # [[4, 5],
200
+ # [6, 7]]]
201
+
202
+ p x.swapaxes(0,2)
203
+ # Numo::Int32(view)#shape=[2,2,2]
204
+ # [[[0, 4],
205
+ # [2, 6]],
206
+ # [[1, 5],
207
+ # [3, 7]]]
208
+ */
209
+ VALUE
210
+ na_swapaxes(VALUE self, VALUE a1, VALUE a2)
211
+ {
212
+ int i, j, ndim;
213
+ size_t tmp_shape;
214
+ stridx_t tmp_stridx;
215
+ narray_view_t *na;
216
+ volatile VALUE view;
217
+
218
+ view = na_make_view(self);
219
+ GetNArrayView(view,na);
220
+
221
+ ndim = na->base.ndim;
222
+ i = check_axis(NUM2INT(a1), ndim);
223
+ j = check_axis(NUM2INT(a2), ndim);
224
+
225
+ tmp_shape = na->base.shape[i];
226
+ tmp_stridx = na->stridx[i];
227
+ na->base.shape[i] = na->base.shape[j];
228
+ na->stridx[i] = na->stridx[j];
229
+ na->base.shape[j] = tmp_shape;
230
+ na->stridx[j] = tmp_stridx;
231
+
232
+ return view;
233
+ }
161
234
 
162
235
  VALUE
163
236
  na_transpose_map(VALUE self, int *map)
@@ -305,7 +378,7 @@ na_reshape(int argc, VALUE *argv, VALUE self)
305
378
  rb_raise(rb_eArgError, "Total size must be same");
306
379
  }
307
380
 
308
- copy = rb_funcall(self,rb_intern("copy"),0);
381
+ copy = rb_funcall(self,rb_intern("dup"),0);
309
382
  GetNArray(copy,na);
310
383
  //shape_save = NA_SHAPE(na);
311
384
  na_setup_shape(na,argc,shape);
@@ -334,6 +407,9 @@ na_flatten_dim(VALUE self, int sd)
334
407
  GetNArray(self,na);
335
408
  nd = na->ndim;
336
409
 
410
+ if (nd==0) {
411
+ return na_make_view(self);
412
+ }
337
413
  if (sd<0 || sd>=nd) {
338
414
  rb_bug("na_flaten_dim: start_dim (%d) out of range",sd);
339
415
  }
@@ -361,9 +437,9 @@ na_flatten_dim(VALUE self, int sd)
361
437
  switch(na->type) {
362
438
  case NARRAY_DATA_T:
363
439
  case NARRAY_FILEMAP_T:
364
- stride = na_get_elmsz(self);
440
+ stride = nary_element_stride(self);
365
441
  for (i=sd+1; i--; ) {
366
- //printf("data: i=%d stride=%d\n",i,stride);
442
+ //printf("data: i=%d shpae[i]=%ld stride=%ld\n",i,shape[i],stride);
367
443
  SDX_SET_STRIDE(na2->stridx[i],stride);
368
444
  stride *= shape[i];
369
445
  }
@@ -435,85 +511,6 @@ na_flatten(VALUE self)
435
511
  return na_flatten_dim(self,0);
436
512
  }
437
513
 
438
-
439
- VALUE
440
- na_flatten_by_reduce(int argc, VALUE *argv, VALUE self)
441
- {
442
- size_t sz_reduce=1;
443
- int i, j, ndim;
444
- int nd_reduce=0, nd_rest=0;
445
- int *dim_reduce, *dim_rest;
446
- int *map;
447
- volatile VALUE view, reduce;
448
- narray_t *na;
449
-
450
- //puts("pass1");
451
- //rb_p(self);
452
- reduce = na_reduce_dimension(argc, argv, 1, &self);
453
- //reduce = INT2FIX(1);
454
- //rb_p(self);
455
- //puts("pass2");
456
-
457
- if (reduce==INT2FIX(0)) {
458
- //puts("pass flatten_dim");
459
- //rb_funcall(self,rb_intern("debug_info"),0);
460
- //rb_p(self);
461
- view = na_flatten_dim(self,0);
462
- //rb_funcall(view,rb_intern("debug_info"),0);
463
- //rb_p(view);
464
- } else {
465
- //printf("reduce=0x%x\n",NUM2INT(reduce));
466
- GetNArray(self,na);
467
- ndim = na->ndim;
468
- if (ndim==0) {
469
- rb_raise(rb_eStandardError,"cannot flatten scalar(dim-0 array)");
470
- return Qnil;
471
- }
472
- map = ALLOC_N(int,ndim);
473
- dim_reduce = ALLOC_N(int,ndim);
474
- dim_rest = ALLOC_N(int,ndim);
475
- for (i=0; i<ndim; i++) {
476
- if (na_test_reduce( reduce, i )) {
477
- sz_reduce *= na->shape[i];
478
- //printf("i=%d, nd_reduce=%d, na->shape[i]=%ld\n", i, nd_reduce, na->shape[i]);
479
- dim_reduce[nd_reduce++] = i;
480
- } else {
481
- //shape[nd_rest] = na->shape[i];
482
- //sz_rest *= na->shape[i];
483
- //printf("i=%d, nd_rest=%d, na->shape[i]=%ld\n", i, nd_rest, na->shape[i]);
484
- dim_rest[nd_rest++] = i;
485
- }
486
- }
487
- for (i=0; i<nd_rest; i++) {
488
- map[i] = dim_rest[i];
489
- //printf("dim_rest[i=%d]=%d\n",i,dim_rest[i]);
490
- //printf("map[i=%d]=%d\n",i,map[i]);
491
- }
492
- for (j=0; j<nd_reduce; j++,i++) {
493
- map[i] = dim_reduce[j];
494
- //printf("dim_reduce[j=%d]=%d\n",j,dim_reduce[j]);
495
- //printf("map[i=%d]=%d\n",i,map[i]);
496
- }
497
- xfree(dim_reduce);
498
- xfree(dim_rest);
499
- //for (i=0; i<ndim; i++) {
500
- // printf("map[%d]=%d\n",i,map[i]);
501
- //}
502
- //puts("pass transpose_map");
503
- view = na_transpose_map(self,map);
504
- xfree(map);
505
- //rb_p(view);
506
- //rb_funcall(view,rb_intern("debug_print"),0);
507
-
508
- //puts("pass flatten_dim");
509
- view = na_flatten_dim(view,nd_rest);
510
- //rb_funcall(view,rb_intern("debug_print"),0);
511
- //rb_p(view);
512
- }
513
- return view;
514
- }
515
-
516
-
517
514
  //----------------------------------------------------------------------
518
515
 
519
516
  #define MIN(a,b) (((a)<(b))?(a):(b))
@@ -665,7 +662,7 @@ na_diagonal(int argc, VALUE *argv, VALUE self)
665
662
  case NARRAY_FILEMAP_T:
666
663
  na2->offset = 0;
667
664
  na2->data = self;
668
- stride = stride0 = stride1 = na_get_elmsz(self);
665
+ stride = stride0 = stride1 = nary_element_stride(self);
669
666
  for (i=nd,k=nd-2; i--; ) {
670
667
  if (i==ax[1]) {
671
668
  stride1 = stride;
@@ -792,7 +789,7 @@ na_new_dimension_for_dot(VALUE self, int pos, int len, bool transpose)
792
789
  }
793
790
  }
794
791
  na_setup_shape((narray_t*)na2, nd, shape);
795
- stride = na_get_elmsz(self);
792
+ stride = nary_element_stride(self);
796
793
  for (i=nd; i--;) {
797
794
  SDX_SET_STRIDE(na2->stridx[i], stride);
798
795
  stride *= shape[i];
@@ -858,35 +855,40 @@ na_new_dimension_for_dot(VALUE self, int pos, int len, bool transpose)
858
855
  static VALUE
859
856
  numo_na_dot(VALUE self, VALUE other)
860
857
  {
861
- VALUE test, sym_mulsum;
858
+ VALUE test;
862
859
  volatile VALUE a1=self, a2=other;
863
- ID id_mulsum;
864
860
  narray_t *na1, *na2;
865
861
 
866
- id_mulsum = rb_intern("mulsum");
867
- sym_mulsum = ID2SYM(id_mulsum);
868
- test = rb_funcall(a1, rb_intern("respond_to?"), 1, sym_mulsum);
862
+ test = rb_funcall(a1, id_respond_to_p, 1, sym_mulsum);
869
863
  if (!RTEST(test)) {
870
864
  rb_raise(rb_eNoMethodError,"requires mulsum method for dot method");
871
865
  }
872
866
  GetNArray(a1,na1);
873
867
  GetNArray(a2,na2);
868
+ if (na1->ndim==0 || na2->ndim==0) {
869
+ rb_raise(nary_eDimensionError,"zero dimensional narray");
870
+ }
874
871
  if (na2->ndim > 1) {
872
+ if (na1->shape[na1->ndim-1] != na2->shape[na2->ndim-2]) {
873
+ rb_raise(nary_eShapeError,"shape mismatch: self.shape[-1](=%"SZF"d) != other.shape[-2](=%"SZF"d)",
874
+ na1->shape[na1->ndim-1], na2->shape[na2->ndim-2]);
875
+ }
875
876
  // insert new axis [ ..., last-1-dim, newaxis*other.ndim, last-dim ]
876
877
  a1 = na_new_dimension_for_dot(a1, na1->ndim-1, na2->ndim-1, 0);
877
878
  // insert & transpose [ newaxis*self.ndim, ..., last-dim, last-1-dim ]
878
879
  a2 = na_new_dimension_for_dot(a2, 0, na1->ndim-1, 1);
879
880
  }
880
- return rb_funcall(a1,rb_intern("mulsum"),2,a2,INT2FIX(-1));
881
+ return rb_funcall(a1,id_mulsum,2,a2,INT2FIX(-1));
881
882
  }
882
883
 
883
884
 
884
885
  void
885
886
  Init_nary_data()
886
887
  {
887
- rb_define_method(cNArray, "copy", na_copy, 0);
888
+ rb_define_method(cNArray, "copy", na_copy, 0); // deprecated
888
889
 
889
890
  rb_define_method(cNArray, "flatten", na_flatten, 0);
891
+ rb_define_method(cNArray, "swapaxes", na_swapaxes, 2);
890
892
  rb_define_method(cNArray, "transpose", na_transpose, -1);
891
893
 
892
894
  rb_define_method(cNArray, "reshape", na_reshape,-1);
@@ -913,4 +915,10 @@ Init_nary_data()
913
915
  rb_define_method(cNArray, "to_swapped", nary_to_swapped, 0);
914
916
 
915
917
  rb_define_method(cNArray, "dot", numo_na_dot, 1);
918
+
919
+ id_mulsum = rb_intern("mulsum");
920
+ sym_mulsum = ID2SYM(id_mulsum);
921
+ id_respond_to_p = rb_intern("respond_to?");
922
+ id_store = rb_intern("store");
923
+ id_swap_byte = rb_intern("swap_byte");
916
924
  }