numo-narray 0.9.0.4 → 0.9.0.5

Sign up to get free protection for your applications and to get access to all the features.
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
  }