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
@@ -28,10 +28,15 @@
28
28
  #define m_ge(x,y) ((x)>=(y))
29
29
  #define m_lt(x,y) ((x)<(y))
30
30
  #define m_le(x,y) ((x)<=(y))
31
+ #define m_left_shift(x,y) ((x)<<(y))
32
+ #define m_right_shift(x,y) ((x)>>(y))
33
+
31
34
  #define m_isnan(x) 0
32
35
 
33
36
  #define m_mulsum(x,y,z) {z += x*y;}
34
37
  #define m_mulsum_init INT2FIX(0)
38
+ #define m_cumsum(x,y) {x += y;}
39
+ #define m_cumprod(x,y) {x *= y;}
35
40
 
36
41
  #define cmp(a,b) \
37
42
  ((qsort_cast(a)==qsort_cast(b)) ? 0 : \
@@ -132,6 +137,36 @@ static inline size_t f_max_index(size_t n, char *p, ssize_t stride)
132
137
  return j;
133
138
  }
134
139
 
140
+ static inline void
141
+ f_minmax(size_t n, char *p, ssize_t stride, dtype* amin, dtype* amax)
142
+ {
143
+ dtype x,min,max;
144
+ size_t i=n;
145
+
146
+ min = max = *(dtype*)p;
147
+ p += stride;
148
+ for (i--; i--;) {
149
+ x = *(dtype*)p;
150
+ if (m_gt(x,max)) {
151
+ max = x;
152
+ }
153
+ if (m_lt(x,min)) {
154
+ min = x;
155
+ }
156
+ p += stride;
157
+ }
158
+ *amin = min;
159
+ *amax = max;
160
+ return;
161
+ }
162
+
163
+ static inline dtype f_ptp(size_t n, char *p, ssize_t stride)
164
+ {
165
+ dtype min,max;
166
+ f_minmax(n,p,stride,&min,&max);
167
+ return m_sub(max,min);
168
+ }
169
+
135
170
  static inline double f_seq(double x, double y, double c)
136
171
  {
137
172
  return x + y * c;
@@ -1,7 +1,7 @@
1
1
  /*
2
- nstrut.c
2
+ strut.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"
@@ -136,7 +136,7 @@ na_make_view_struct(VALUE self, VALUE dtype, VALUE offset)
136
136
  switch(na->type) {
137
137
  case NARRAY_DATA_T:
138
138
  case NARRAY_FILEMAP_T:
139
- stride = na_get_elmsz(self);
139
+ stride = nary_element_stride(self);
140
140
  for (j=na->ndim; j--;) {
141
141
  SDX_SET_STRIDE(na2->stridx[j], stride);
142
142
  stride *= na->shape[j];
@@ -357,7 +357,7 @@ nstruct_add_type(VALUE type, int argc, VALUE *argv, VALUE nst)
357
357
  ndim = na->ndim;
358
358
  shape = na->shape;
359
359
  }
360
- type = rb_narray_view_new(type,ndim,shape);
360
+ type = nary_view_new(type,ndim,shape);
361
361
  GetNArrayView(type,nt);
362
362
 
363
363
  nt->stridx = ALLOC_N(stridx_t,ndim);
@@ -419,6 +419,21 @@ iter_nstruct_to_a(na_loop_t *const lp)
419
419
  rb_ary_push(lp->args[1].value, vary);
420
420
  }
421
421
 
422
+ static VALUE
423
+ na_original_data(VALUE self)
424
+ {
425
+ narray_t *na;
426
+ narray_view_t *nv;
427
+
428
+ GetNArray(self,na);
429
+ switch(na->type) {
430
+ case NARRAY_VIEW_T:
431
+ GetNArrayView(self, nv);
432
+ return nv->data;
433
+ }
434
+ return self;
435
+ }
436
+
422
437
  static VALUE
423
438
  nst_create_member_views(VALUE self)
424
439
  {
@@ -541,14 +556,16 @@ nst_check_compatibility(VALUE nst, VALUE ary)
541
556
  }
542
557
  } else {
543
558
  // multi-dimension member
544
- volatile VALUE vnc;
545
- na_compose_t *nc;
559
+ //volatile VALUE vnc;
560
+ //na_compose_t *nc;
561
+ VALUE vnc;
562
+ narray_t *nc;
546
563
  int j;
547
564
 
548
- //rb_p(item);
549
- vnc = na_ary_composition(item);
550
- //puts("pass2");
551
- Data_Get_Struct(vnc, na_compose_t, nc);
565
+ //vnc = na_ary_composition(item);
566
+ //Data_Get_Struct(vnc, na_compose_t, nc);
567
+ vnc = na_s_new_like(cNArray, item);
568
+ GetNArray(vnc,nc);
552
569
  if (nt->ndim != nc->ndim) {
553
570
  return Qfalse;
554
571
  }
@@ -603,9 +620,10 @@ iter_nstruct_from_a(na_loop_t *const lp)
603
620
  static VALUE
604
621
  nary_struct_cast_array(VALUE klass, VALUE rary)
605
622
  {
606
- volatile VALUE vnc, nary;
623
+ //volatile VALUE vnc, nary;
624
+ VALUE nary;
607
625
  narray_t *na;
608
- na_compose_t *nc;
626
+ //na_compose_t *nc;
609
627
  VALUE opt;
610
628
  ndfunc_arg_in_t ain[3] = {{OVERWRITE,0},{rb_cArray,0},{sym_option}};
611
629
  ndfunc_t ndf = {iter_nstruct_from_a, NO_LOOP, 3, 0, ain, 0};
@@ -613,9 +631,10 @@ nary_struct_cast_array(VALUE klass, VALUE rary)
613
631
  //fprintf(stderr,"rary:");rb_p(rary);
614
632
  //fprintf(stderr,"class_of(rary):");rb_p(CLASS_OF(rary));
615
633
 
616
- vnc = na_ary_composition_for_struct(klass, rary);
617
- Data_Get_Struct(vnc, na_compose_t, nc);
618
- nary = rb_narray_new(klass, nc->ndim, nc->shape);
634
+ //vnc = na_ary_composition_for_struct(klass, rary);
635
+ //Data_Get_Struct(vnc, na_compose_t, nc);
636
+ //nary = nary_new(klass, nc->ndim, nc->shape);
637
+ nary = na_s_new_like(klass, rary);
619
638
  GetNArray(nary,na);
620
639
  //fprintf(stderr,"na->size=%lu\n",na->size);
621
640
  //fprintf(stderr,"na->ndim=%d\n",na->ndim);
@@ -168,7 +168,10 @@ class Function < ErbPP
168
168
  def initialize(parent,tmpl,**opts)
169
169
  super
170
170
  @aliases = opts[:aliases] || []
171
- @erb_path = File.join(parent.tmpl_dir, tmpl+".c")
171
+ parent.tmpl_dirs.each do |d|
172
+ @erb_path = File.join(d, tmpl+".c")
173
+ break if File.exist?(@erb_path)
174
+ end
172
175
  DEFS.push(self)
173
176
  end
174
177
 
@@ -207,6 +210,7 @@ class Function < ErbPP
207
210
  end
208
211
 
209
212
  def definition
213
+ return nil if n_arg <= -9
210
214
  s = singleton ? "_singleton" : ""
211
215
  check_params(:mod_var, :op_map, :c_func, :n_arg)
212
216
  m = op_map
@@ -7,7 +7,7 @@ class CountLnString < String
7
7
  @str = ""
8
8
  @countln = 1
9
9
  @current = 1
10
- super(report_line)
10
+ super("\n"+report_line)
11
11
  end
12
12
 
13
13
  def report_line
@@ -34,11 +34,14 @@ class CountLnString < String
34
34
  end
35
35
  return if n == @current
36
36
  if @current != @countln || @postpone
37
- if /\A\s*\z/ =~ @str || /\A#line / =~ @buf || /\n\z/ !~ self
37
+ if /\A\s*\z/ =~ @str || /\A#line / =~ @buf
38
38
  @postpone = true
39
39
  elsif @in_comment
40
40
  @postpone = false
41
41
  else
42
+ if self[-1] != "\n"
43
+ concat("\n")
44
+ end
42
45
  concat(report_line)
43
46
  @postpone = false
44
47
  end
@@ -83,6 +86,10 @@ class CountLnString < String
83
86
  r
84
87
  end
85
88
 
89
+ def final
90
+ concat(@buf)
91
+ end
92
+
86
93
  end
87
94
 
88
95
  class ERB
@@ -120,7 +127,7 @@ class ERB
120
127
  line.sub!(/^;/,";_erbout.ln(#{num});")
121
128
  end
122
129
  line
123
- end.join
130
+ end.join+";_erbout.final;"
124
131
  end
125
132
 
126
133
  end
@@ -55,6 +55,7 @@ module DefMethod
55
55
  end
56
56
 
57
57
  def cond_binary(meth,op=nil)
58
+ op = meth unless op
58
59
  def_method(meth, 1, "cond_binary", :op => op)
59
60
  end
60
61
 
@@ -89,23 +90,33 @@ module DefMethod
89
90
  def_method(meth, -1, "accum_binary", :op => ope)
90
91
  end
91
92
 
92
- def qsort(tp, dtype, dcast)
93
- h = {:tp => tp, :dtype => dtype, :dcast => dcast}
93
+ def qsort(tp, dtype, dcast, suffix="")
94
+ h = {:tp => tp, :dtype => dtype, :dcast => dcast, :suffix => suffix}
94
95
  NodefFunction.new(self, "qsort", h)
95
96
  end
96
97
 
97
- def math(meth, n=1)
98
- h = {:meth => meth, :mod_var => 'mTM', :n_arg => n}
99
- case n
100
- when 1
101
- ModuleFunction.new(self, "unary_s", h)
102
- when 2
103
- ModuleFunction.new(self, "binary_s", h)
104
- when 3
105
- ModuleFunction.new(self, "ternary_s", h)
106
- else
107
- raise "invalid n=#{n}"
98
+ def def_mod_func(meth, n_arg, tmpl=nil, opts={})
99
+ h = {:meth => meth, :n_arg => n_arg}
100
+ h.merge!(opts)
101
+ tmpl ||= meth
102
+ ModuleFunction.new(self, tmpl, h)
103
+ end
104
+
105
+ def math(meth, n=1, tmpl=nil)
106
+ h = {:mod_var => 'mTM'}
107
+ if tmpl.nil?
108
+ case n
109
+ when 1
110
+ tmpl = "unary_s"
111
+ when 2
112
+ tmpl = "binary_s"
113
+ when 3
114
+ tmpl = "ternary_s"
115
+ else
116
+ raise "invalid n=#{n}"
117
+ end
108
118
  end
119
+ def_mod_func(meth, n, tmpl, h)
109
120
  end
110
121
 
111
122
  def store_numeric
@@ -156,11 +167,11 @@ class DataType < ErbPP
156
167
  @upcast = []
157
168
  @mod_var = "cT"
158
169
  load_type(type_file) if type_file
159
- dir = template_dir || "tmpl"
160
- @tmpl_dir = File.join(File.dirname(erb_path),dir)
170
+ dirs = template_dir || ["tmpl"]
171
+ @tmpl_dirs = dirs.map{|d| File.join(File.dirname(erb_path),d)}
161
172
  end
162
173
 
163
- attr_reader :tmpl_dir
174
+ attr_reader :tmpl_dirs
164
175
 
165
176
  def load_type(file)
166
177
  eval File.read(file)
@@ -299,14 +310,33 @@ class Store < Function
299
310
  nil
300
311
  end
301
312
 
302
- def condition
303
- "rb_obj_is_kind_of(obj,#{tpclass})"
313
+ def condition(klass)
314
+ "#{klass}==#{tpclass}"
315
+ end
316
+
317
+ def extract_data(ptr,pos,x)
318
+ case tpname
319
+ when "bit"
320
+ "{BIT_DIGIT b; LOAD_BIT(#{ptr},#{pos},b); x = m_from_real(b);}"
321
+ when "robject"
322
+ "#{x} = m_num_to_data(*(#{dtype}*)(#{ptr}+#{pos}))"
323
+ when /complex/
324
+ "{#{dtype} *p = (#{dtype}*)(#{ptr}+#{pos}); #{x} = c_new(REAL(*p),IMAG(*p));}"
325
+ else
326
+ "#{x} = m_from_real(*(#{dtype}*)(#{ptr}+#{pos}))"
327
+ end
304
328
  end
305
329
 
306
330
  def self.definitions
307
331
  a = []
308
- DEFS.each do |i|
309
- a.push(i) if i.condition
332
+ DEFS.each do |x|
333
+ if x.condition("")
334
+ if x.tpname == x.parents[0].class_name.downcase
335
+ a.unshift(x)
336
+ else
337
+ a.push(x)
338
+ end
339
+ end
310
340
  end
311
341
  a
312
342
  end
@@ -317,8 +347,8 @@ class StoreNum < Store
317
347
  super(parent,tmpl,"numeric",nil,nil,nil)
318
348
  end
319
349
 
320
- def condition
321
- "FIXNUM_P(obj) || TYPE(obj)==T_FLOAT || TYPE(obj)==T_BIGNUM || rb_obj_is_kind_of(obj,rb_cComplex)"
350
+ def condition(klass)
351
+ "IS_INTEGER_CLASS(#{klass}) || #{klass}==rb_cFloat || #{klass}==rb_cComplex"
322
352
  end
323
353
  end
324
354
 
@@ -331,13 +361,13 @@ class StoreArray < Store
331
361
  "numo_#{tp}_#{tmpl}"
332
362
  end
333
363
 
334
- def condition
335
- "TYPE(obj)==T_ARRAY"
364
+ def condition(klass)
365
+ "#{klass}==rb_cArray"
336
366
  end
337
367
  end
338
368
 
339
369
  class CastArray < StoreArray
340
- def condition
370
+ def condition(klass)
341
371
  nil
342
372
  end
343
373
 
@@ -1,39 +1,342 @@
1
1
  module Numo
2
2
  class NArray
3
3
 
4
- # p a = Numo::DFloat[[1, 2], [3, 4]]
5
- # # Numo::DFloat#shape=[2,2]
6
- # # [[1, 2],
7
- # # [3, 4]]
8
- #
9
- # p b = Numo::DFloat[[5, 6]]
10
- # # Numo::DFloat#shape=[1,2]
11
- # # [[5, 6]]
12
- #
13
- # p Numo::NArray.concatenate([a,b],axis:0)
14
- # # Numo::DFloat#shape=[3,2]
15
- # # [[1, 2],
16
- # # [3, 4],
17
- # # [5, 6]]
18
- #
19
- # p Numo::NArray.concatenate([a,b.transpose], axis:1)
20
- # # Numo::DFloat#shape=[2,3]
21
- # # [[1, 2, 5],
22
- # # [3, 4, 6]]
23
-
24
- def self.concatenate(arrays,axis:0)
4
+ # Return an unallocated array with the same shape and type as self.
5
+ def new_narray
6
+ self.class.new(*shape)
7
+ end
8
+
9
+ # Return an array of zeros with the same shape and type as self.
10
+ def new_zeros
11
+ self.class.zeros(*shape)
12
+ end
13
+
14
+ # Return an array of ones with the same shape and type as self.
15
+ def new_ones
16
+ self.class.ones(*shape)
17
+ end
18
+
19
+ # Return an array filled with value with the same shape and type as self.
20
+ def new_fill(value)
21
+ self.class.new(*shape).fill(value)
22
+ end
23
+
24
+ # Convert angles from radians to degrees.
25
+ def rad2deg
26
+ self * (180/Math::PI)
27
+ end
28
+
29
+ # Convert angles from degrees to radians.
30
+ def deg2rad
31
+ self * (Math::PI/180)
32
+ end
33
+
34
+ # Flip each row in the left/right direction.
35
+ # Same as a[true, (-1..0).step(-1), ...].
36
+ def fliplr
37
+ reverse(1)
38
+ end
39
+
40
+ # Flip each column in the up/down direction.
41
+ # Same as a[(-1..0).step(-1), ...].
42
+ def flipud
43
+ reverse(0)
44
+ end
45
+
46
+ # Rotate in the plane specified by axes.
47
+ # @example
48
+ # p a = Numo::Int32.new(2,2).seq
49
+ # # Numo::Int32#shape=[2,2]
50
+ # # [[0, 1],
51
+ # # [2, 3]]
52
+ #
53
+ # p a.rot90
54
+ # # Numo::Int32(view)#shape=[2,2]
55
+ # # [[1, 3],
56
+ # # [0, 2]]
57
+ #
58
+ # p a.rot90(2)
59
+ # # Numo::Int32(view)#shape=[2,2]
60
+ # # [[3, 2],
61
+ # # [1, 0]]
62
+ #
63
+ # p a.rot90(3)
64
+ # # Numo::Int32(view)#shape=[2,2]
65
+ # # [[2, 0],
66
+ # # [3, 1]]
67
+ def rot90(k=1,axes=[0,1])
68
+ case k % 4
69
+ when 0
70
+ view
71
+ when 1
72
+ swapaxes(*axes).reverse(axes[0])
73
+ when 2
74
+ reverse(*axes)
75
+ when 3
76
+ swapaxes(*axes).reverse(axes[1])
77
+ end
78
+ end
79
+
80
+ def to_i
81
+ if size==1
82
+ self[0].to_i
83
+ else
84
+ # convert to Int?
85
+ raise TypeError, "can't convert #{self.class} into Integer"
86
+ end
87
+ end
88
+
89
+ def to_f
90
+ if size==1
91
+ self[0].to_f
92
+ else
93
+ # convert to DFloat?
94
+ raise TypeError, "can't convert #{self.class} into Float"
95
+ end
96
+ end
97
+
98
+ def to_c
99
+ if size==1
100
+ Complex(self[0])
101
+ else
102
+ # convert to DComplex?
103
+ raise TypeError, "can't convert #{self.class} into Complex"
104
+ end
105
+ end
106
+
107
+ # Convert the argument to an narray if not an narray.
108
+ def self.cast(a)
109
+ a.kind_of?(NArray) ? a : NArray.array_type(a).cast(a)
110
+ end
111
+
112
+ def self.asarray(a)
113
+ case a
114
+ when NArray
115
+ a
116
+ when Numeric,Range
117
+ self[a]
118
+ else
119
+ cast(a)
120
+ end
121
+ end
122
+
123
+ # Append values to the end of an narray.
124
+ # @example
125
+ # a = Numo::DFloat[1, 2, 3]
126
+ # p a.append([[4, 5, 6], [7, 8, 9]])
127
+ # # Numo::DFloat#shape=[9]
128
+ # # [1, 2, 3, 4, 5, 6, 7, 8, 9]
129
+ #
130
+ # a = Numo::DFloat[[1, 2, 3]]
131
+ # p a.append([[4, 5, 6], [7, 8, 9]],axis:0)
132
+ # # Numo::DFloat#shape=[3,3]
133
+ # # [[1, 2, 3],
134
+ # # [4, 5, 6],
135
+ # # [7, 8, 9]]
136
+ #
137
+ # a = Numo::DFloat[[1, 2, 3], [4, 5, 6]]
138
+ # p a.append([7, 8, 9], axis:0)
139
+ # # in `append': dimension mismatch (Numo::NArray::DimensionError)
140
+
141
+ def append(other,axis:nil)
142
+ other = self.class.cast(other)
143
+ if axis
144
+ if ndim != other.ndim
145
+ raise DimensionError, "dimension mismatch"
146
+ end
147
+ return concatenate(other,axis:axis)
148
+ else
149
+ a = self.class.zeros(size+other.size)
150
+ a[0...size] = self[true]
151
+ a[size..-1] = other[true]
152
+ return a
153
+ end
154
+ end
155
+
156
+ # Return a new array with sub-arrays along an axis deleted.
157
+ # If axis is not given, obj is applied to the flattened array.
158
+
159
+ # @example
160
+ # a = Numo::DFloat[[1,2,3,4], [5,6,7,8], [9,10,11,12]]
161
+ # p a.delete(1,0)
162
+ # # Numo::DFloat(view)#shape=[2,4]
163
+ # # [[1, 2, 3, 4],
164
+ # # [9, 10, 11, 12]]
165
+ #
166
+ # p a.delete((0..-1).step(2),1)
167
+ # # Numo::DFloat(view)#shape=[3,2]
168
+ # # [[2, 4],
169
+ # # [6, 8],
170
+ # # [10, 12]]
171
+ #
172
+ # p a.delete([1,3,5])
173
+ # # Numo::DFloat(view)#shape=[9]
174
+ # # [1, 3, 5, 7, 8, 9, 10, 11, 12]
175
+
176
+ def delete(indice,axis=nil)
177
+ if axis
178
+ bit = Bit.ones(shape[axis])
179
+ bit[indice] = 0
180
+ idx = [true]*ndim
181
+ idx[axis] = bit.where
182
+ return self[*idx].copy
183
+ else
184
+ bit = Bit.ones(size)
185
+ bit[indice] = 0
186
+ return self[bit.where].copy
187
+ end
188
+ end
189
+
190
+ # Insert values along the axis before the indices.
191
+ # @example
192
+ # p a = Numo::DFloat[[1, 2], [3, 4]]
193
+ # a = Numo::Int32[[1, 1], [2, 2], [3, 3]]
194
+ #
195
+ # p a.insert(1,5)
196
+ # # Numo::Int32#shape=[7]
197
+ # # [1, 5, 1, 2, 2, 3, 3]
198
+ #
199
+ # p a.insert(1, 5, axis:1)
200
+ # # Numo::Int32#shape=[3,3]
201
+ # # [[1, 5, 1],
202
+ # # [2, 5, 2],
203
+ # # [3, 5, 3]]
204
+ #
205
+ # p a.insert([1], [[11],[12],[13]], axis:1)
206
+ # # Numo::Int32#shape=[3,3]
207
+ # # [[1, 11, 1],
208
+ # # [2, 12, 2],
209
+ # # [3, 13, 3]]
210
+ #
211
+ # p a.insert(1, [11, 12, 13], axis:1)
212
+ # # Numo::Int32#shape=[3,3]
213
+ # # [[1, 11, 1],
214
+ # # [2, 12, 2],
215
+ # # [3, 13, 3]]
216
+ #
217
+ # p a.insert([1], [11, 12, 13], axis:1)
218
+ # # Numo::Int32#shape=[3,5]
219
+ # # [[1, 11, 12, 13, 1],
220
+ # # [2, 11, 12, 13, 2],
221
+ # # [3, 11, 12, 13, 3]]
222
+ #
223
+ # p b = a.flatten
224
+ # # Numo::Int32(view)#shape=[6]
225
+ # # [1, 1, 2, 2, 3, 3]
226
+ #
227
+ # p b.insert(2,[15,16])
228
+ # # Numo::Int32#shape=[8]
229
+ # # [1, 1, 15, 16, 2, 2, 3, 3]
230
+ #
231
+ # p b.insert([2,2],[15,16])
232
+ # # Numo::Int32#shape=[8]
233
+ # # [1, 1, 15, 16, 2, 2, 3, 3]
234
+ #
235
+ # p b.insert([2,1],[15,16])
236
+ # # Numo::Int32#shape=[8]
237
+ # # [1, 16, 1, 15, 2, 2, 3, 3]
238
+ #
239
+ # p b.insert([2,0,1],[15,16,17])
240
+ # # Numo::Int32#shape=[9]
241
+ # # [16, 1, 17, 1, 15, 2, 2, 3, 3]
242
+ #
243
+ # p b.insert(2..3, [15, 16])
244
+ # # Numo::Int32#shape=[8]
245
+ # # [1, 1, 15, 2, 16, 2, 3, 3]
246
+ #
247
+ # p b.insert(2, [7.13, 0.5])
248
+ # # Numo::Int32#shape=[8]
249
+ # # [1, 1, 7, 0, 2, 2, 3, 3]
250
+ #
251
+ # p x = Numo::DFloat.new(2,4).seq
252
+ # # Numo::DFloat#shape=[2,4]
253
+ # # [[0, 1, 2, 3],
254
+ # # [4, 5, 6, 7]]
255
+ #
256
+ # p x.insert([1,3],999,axis:1)
257
+ # # Numo::DFloat#shape=[2,6]
258
+ # # [[0, 999, 1, 2, 999, 3],
259
+ # # [4, 999, 5, 6, 999, 7]]
260
+
261
+ def insert(indice,values,axis:nil)
262
+ if axis
263
+ values = self.class.asarray(values)
264
+ nd = values.ndim
265
+ midx = [:new]*(ndim-nd) + [true]*nd
266
+ case indice
267
+ when Numeric
268
+ midx[-nd-1] = true
269
+ midx[axis] = :new
270
+ end
271
+ values = values[*midx]
272
+ else
273
+ values = self.class.asarray(values).flatten
274
+ end
275
+ idx = Int64.asarray(indice)
276
+ nidx = idx.size
277
+ if nidx == 1
278
+ nidx = values.shape[axis||0]
279
+ idx = idx + Int64.new(nidx).seq
280
+ else
281
+ sidx = idx.sort_index
282
+ idx[sidx] += Int64.new(nidx).seq
283
+ end
284
+ if axis
285
+ bit = Bit.ones(shape[axis]+nidx)
286
+ bit[idx] = 0
287
+ new_shape = shape
288
+ new_shape[axis] += nidx
289
+ a = self.class.zeros(new_shape)
290
+ mdidx = [true]*ndim
291
+ mdidx[axis] = bit.where
292
+ a[*mdidx] = self
293
+ mdidx[axis] = idx
294
+ a[*mdidx] = values
295
+ else
296
+ bit = Bit.ones(size+nidx)
297
+ bit[idx] = 0
298
+ a = self.class.zeros(size+nidx)
299
+ a[bit.where] = self.flatten
300
+ a[idx] = values
301
+ end
302
+ return a
303
+ end
304
+
305
+ class << self
306
+ # @example
307
+ # p a = Numo::DFloat[[1, 2], [3, 4]]
308
+ # # Numo::DFloat#shape=[2,2]
309
+ # # [[1, 2],
310
+ # # [3, 4]]
311
+ #
312
+ # p b = Numo::DFloat[[5, 6]]
313
+ # # Numo::DFloat#shape=[1,2]
314
+ # # [[5, 6]]
315
+ #
316
+ # p Numo::NArray.concatenate([a,b],axis:0)
317
+ # # Numo::DFloat#shape=[3,2]
318
+ # # [[1, 2],
319
+ # # [3, 4],
320
+ # # [5, 6]]
321
+ #
322
+ # p Numo::NArray.concatenate([a,b.transpose], axis:1)
323
+ # # Numo::DFloat#shape=[2,3]
324
+ # # [[1, 2, 5],
325
+ # # [3, 4, 6]]
326
+
327
+ def concatenate(arrays,axis:0)
25
328
  klass = (self==NArray) ? NArray.array_type(arrays) : self
26
329
  nd = 0
27
- arrays.map! do |a|
330
+ arrays = arrays.map do |a|
28
331
  case a
29
332
  when NArray
30
333
  # ok
31
334
  when Numeric
32
- a = klass.new(1).store(a)
335
+ a = klass[a]
33
336
  when Array
34
337
  a = klass.cast(a)
35
338
  else
36
- raise TypeError,"not Numo::NArray"
339
+ raise TypeError,"not Numo::NArray: #{a.inspect[0..48]}"
37
340
  end
38
341
  if a.ndim > nd
39
342
  nd = a.ndim
@@ -74,97 +377,151 @@ module Numo
74
377
  end
75
378
  result
76
379
  end
77
- =begin
78
- # arrays = 10.times.map{Numo::DFloat.new(3,4).rand(10)}
79
- # p Numo::NArray.stack(arrays, axis:0).shape
80
- # # [10, 3, 4]
81
- # p Numo::NArray.stack(arrays, axis:1).shape
82
- # # [3, 10, 4]
83
- # p Numo::NArray.stack(arrays, axis:2).shape
84
- # # [3, 4, 10]
85
- # a = Numo::NArray[1,2,3]
86
- # b = Numo::NArray[2,3,4]
87
- # p Numo::NArray.stack([a,b])
88
- # # Numo::Int32#shape=[2,3]
89
- # # [[1, 2, 3],
90
- # # [2, 3, 4]]
91
- # p Numo::NArray.stack([a,b],axis:-1)
92
- # # Numo::Int32#shape=[3,2]
93
- # # [[1, 2],
94
- # # [2, 3],
95
- # # [3, 4]]
96
-
97
- def self.stack(arrays,axis:0)
98
- if !arrays.kind_of?(Array)
99
- raise TypeError, "argument should be array"
100
- end
101
- if self == NArray
102
- klass = self.array_type(arrays)
103
- else
104
- klass = self
105
- end
106
- new_shape = self.array_shape(arrays)[1..-1]
107
- nd = new_shape.length + 1
108
- if axis < 0
109
- axis += nd
110
- end
111
- if axis < 0 || axis >= nd
112
- raise ArgumentError,"axis is out of range"
113
- end
114
- new_shape.insert(axis, arrays.length)
115
- result = klass.zeros(*new_shape)
116
- refs = [true] * nd
117
- arrays.each_with_index do |a,i|
118
- refs[axis] = i
119
- result[*refs] = a
380
+
381
+ # Stack arrays vertically (row wise).
382
+ # @example
383
+ # a = Numo::Int32[1,2,3]
384
+ # b = Numo::Int32[2,3,4]
385
+ # p Numo::NArray.vstack([a,b])
386
+ # # Numo::Int32#shape=[2,3]
387
+ # # [[1, 2, 3],
388
+ # # [2, 3, 4]]
389
+ #
390
+ # a = Numo::Int32[[1],[2],[3]]
391
+ # b = Numo::Int32[[2],[3],[4]]
392
+ # p Numo::NArray.vstack([a,b])
393
+ # # Numo::Int32#shape=[6,1]
394
+ # # [[1],
395
+ # # [2],
396
+ # # [3],
397
+ # # [2],
398
+ # # [3],
399
+ # # [4]]
400
+
401
+ def vstack(arrays)
402
+ arys = arrays.map do |a|
403
+ _atleast_2d(cast(a))
120
404
  end
121
- result
405
+ concatenate(arys,axis:0)
122
406
  end
123
407
 
124
- def self.vstack(arrays)
125
- self.stack(arrays,axis:0)
126
- end
408
+ # Stack arrays horizontally (column wise).
409
+ # @example
410
+ # a = Numo::Int32[1,2,3]
411
+ # b = Numo::Int32[2,3,4]
412
+ # p Numo::NArray.hstack([a,b])
413
+ # # Numo::Int32#shape=[6]
414
+ # # [1, 2, 3, 2, 3, 4]
415
+ #
416
+ # a = Numo::Int32[[1],[2],[3]]
417
+ # b = Numo::Int32[[2],[3],[4]]
418
+ # p Numo::NArray.hstack([a,b])
419
+ # # Numo::Int32#shape=[3,2]
420
+ # # [[1, 2],
421
+ # # [2, 3],
422
+ # # [3, 4]]
127
423
 
128
- def self.hstack(arrays)
129
- self.stack(arrays,axis:1)
424
+ def hstack(arrays)
425
+ klass = (self==NArray) ? NArray.array_type(arrays) : self
426
+ nd = 0
427
+ arys = arrays.map do |a|
428
+ a = klass.cast(a)
429
+ nd = a.ndim if a.ndim > nd
430
+ a
431
+ end
432
+ dim = (nd >= 2) ? 1 : 0
433
+ concatenate(arys,axis:dim)
130
434
  end
131
435
 
132
- def self.dstack(arrays)
133
- self.stack(arrays,axis:2)
436
+ # Stack arrays in depth wise (along third axis).
437
+ # @example
438
+ # a = Numo::Int32[1,2,3]
439
+ # b = Numo::Int32[2,3,4]
440
+ # p Numo::NArray.dstack([a,b])
441
+ # # Numo::Int32#shape=[1,3,2]
442
+ # # [[[1, 2],
443
+ # # [2, 3],
444
+ # # [3, 4]]]
445
+ #
446
+ # a = Numo::Int32[[1],[2],[3]]
447
+ # b = Numo::Int32[[2],[3],[4]]
448
+ # p Numo::NArray.dstack([a,b])
449
+ # # Numo::Int32#shape=[3,1,2]
450
+ # # [[[1, 2]],
451
+ # # [[2, 3]],
452
+ # # [[3, 4]]]
453
+
454
+ def dstack(arrays)
455
+ arys = arrays.map do |a|
456
+ _atleast_3d(cast(a))
457
+ end
458
+ concatenate(arys,axis:2)
134
459
  end
135
- =end
136
460
 
137
- def self.vstack(arrays)
138
- self.concatenate(arrays,axis:0)
461
+ # Stack 1-d arrays into columns of a 2-d array.
462
+ # @example
463
+ # x = Numo::Int32[1,2,3]
464
+ # y = Numo::Int32[2,3,4]
465
+ # p Numo::NArray.column_stack([x,y])
466
+ # # Numo::Int32#shape=[3,2]
467
+ # # [[1, 2],
468
+ # # [2, 3],
469
+ # # [3, 4]]
470
+
471
+ def column_stack(arrays)
472
+ arys = arrays.map do |a|
473
+ a = cast(a)
474
+ case a.ndim
475
+ when 0; a[:new,:new]
476
+ when 1; a[true,:new]
477
+ else; a
478
+ end
479
+ end
480
+ concatenate(arys,axis:1)
139
481
  end
140
482
 
141
- def self.hstack(arrays)
142
- self.concatenate(arrays,axis:1)
483
+ private
484
+ # Return an narray with at least two dimension.
485
+ def _atleast_2d(a)
486
+ case a.ndim
487
+ when 0; a[:new,:new]
488
+ when 1; a[:new,true]
489
+ else; a
490
+ end
143
491
  end
144
492
 
145
- def self.dstack(arrays)
146
- self.concatenate(arrays,axis:2)
493
+ # Return an narray with at least three dimension.
494
+ def _atleast_3d(a)
495
+ case a.ndim
496
+ when 0; a[:new,:new,:new]
497
+ when 1; a[:new,true,:new]
498
+ when 2; a[true,true,:new]
499
+ else; a
500
+ end
147
501
  end
148
502
 
149
- # p a = Numo::DFloat[[1, 2], [3, 4]]
150
- # # Numo::DFloat#shape=[2,2]
151
- # # [[1, 2],
152
- # # [3, 4]]
503
+ end # class << self
504
+
505
+ # @example
506
+ # p a = Numo::DFloat[[1, 2], [3, 4]]
507
+ # # Numo::DFloat#shape=[2,2]
508
+ # # [[1, 2],
509
+ # # [3, 4]]
153
510
  #
154
- # p b = Numo::DFloat[[5, 6]]
155
- # # Numo::DFloat#shape=[1,2]
156
- # # [[5, 6]]
511
+ # p b = Numo::DFloat[[5, 6]]
512
+ # # Numo::DFloat#shape=[1,2]
513
+ # # [[5, 6]]
157
514
  #
158
- # p a.concatenate(b,axis:0)
159
- # # Numo::DFloat#shape=[3,2]
160
- # # [[1, 2],
161
- # # [3, 4],
162
- # # [5, 6]]
515
+ # p a.concatenate(b,axis:0)
516
+ # # Numo::DFloat#shape=[3,2]
517
+ # # [[1, 2],
518
+ # # [3, 4],
519
+ # # [5, 6]]
163
520
  #
164
- # p a.concatenate(b.transpose, axis:1)
165
- # # Numo::DFloat#shape=[2,3]
166
- # # [[1, 2, 5],
167
- # # [3, 4, 6]]
521
+ # p a.concatenate(b.transpose, axis:1)
522
+ # # Numo::DFloat#shape=[2,3]
523
+ # # [[1, 2, 5],
524
+ # # [3, 4, 6]]
168
525
 
169
526
  def concatenate(*arrays,axis:0)
170
527
  axis = check_axis(axis)
@@ -180,7 +537,7 @@ module Numo
180
537
  when Array
181
538
  a = self.class.cast(a)
182
539
  else
183
- raise TypeError,"not Numo::NArray"
540
+ raise TypeError,"not Numo::NArray: #{a.inspect[0..48]}"
184
541
  end
185
542
  if a.ndim > ndim
186
543
  raise ShapeError,"dimension mismatch"
@@ -207,32 +564,33 @@ module Numo
207
564
  result
208
565
  end
209
566
 
210
- # p x = Numo::DFloat.new(9).seq
211
- # # Numo::DFloat#shape=[9]
212
- # # [0, 1, 2, 3, 4, 5, 6, 7, 8]
213
- #
214
- # pp x.split(3)
215
- # # [Numo::DFloat(view)#shape=[3]
216
- # # [0, 1, 2],
217
- # # Numo::DFloat(view)#shape=[3]
218
- # # [3, 4, 5],
219
- # # Numo::DFloat(view)#shape=[3]
220
- # # [6, 7, 8]]
221
- #
222
- # p x = Numo::DFloat.new(8).seq
223
- # # Numo::DFloat#shape=[8]
224
- # # [0, 1, 2, 3, 4, 5, 6, 7]
225
- #
226
- # pp x.split([3, 5, 6, 10])
227
- # # [Numo::DFloat(view)#shape=[3]
228
- # # [0, 1, 2],
229
- # # Numo::DFloat(view)#shape=[2]
230
- # # [3, 4],
231
- # # Numo::DFloat(view)#shape=[1]
232
- # # [5],
233
- # # Numo::DFloat(view)#shape=[2]
234
- # # [6, 7],
235
- # # Numo::DFloat(view)#shape=[0][]]
567
+ # @example
568
+ # p x = Numo::DFloat.new(9).seq
569
+ # # Numo::DFloat#shape=[9]
570
+ # # [0, 1, 2, 3, 4, 5, 6, 7, 8]
571
+ #
572
+ # pp x.split(3)
573
+ # # [Numo::DFloat(view)#shape=[3]
574
+ # # [0, 1, 2],
575
+ # # Numo::DFloat(view)#shape=[3]
576
+ # # [3, 4, 5],
577
+ # # Numo::DFloat(view)#shape=[3]
578
+ # # [6, 7, 8]]
579
+ #
580
+ # p x = Numo::DFloat.new(8).seq
581
+ # # Numo::DFloat#shape=[8]
582
+ # # [0, 1, 2, 3, 4, 5, 6, 7]
583
+ #
584
+ # pp x.split([3, 5, 6, 10])
585
+ # # [Numo::DFloat(view)#shape=[3]
586
+ # # [0, 1, 2],
587
+ # # Numo::DFloat(view)#shape=[2]
588
+ # # [3, 4],
589
+ # # Numo::DFloat(view)#shape=[1]
590
+ # # [5],
591
+ # # Numo::DFloat(view)#shape=[2]
592
+ # # [6, 7],
593
+ # # Numo::DFloat(view)#shape=[0][]]
236
594
 
237
595
  def split(indices_or_sections, axis:0)
238
596
  axis = check_axis(axis)
@@ -240,12 +598,18 @@ module Numo
240
598
  case indices_or_sections
241
599
  when Integer
242
600
  div_axis, mod_axis = size_axis.divmod(indices_or_sections)
243
- if mod_axis != 0
244
- raise "not equally divide the axis"
245
- end
246
601
  refs = [true]*ndim
247
- indices_or_sections.times.map do |i|
248
- refs[axis] = i*div_axis ... (i+1)*div_axis
602
+ beg_idx = 0
603
+ mod_axis.times.map do |i|
604
+ end_idx = beg_idx + div_axis + 1
605
+ refs[axis] = beg_idx ... end_idx
606
+ beg_idx = end_idx
607
+ self[*refs]
608
+ end +
609
+ (indices_or_sections-mod_axis).times.map do |i|
610
+ end_idx = beg_idx + div_axis
611
+ refs[axis] = beg_idx ... end_idx
612
+ beg_idx = end_idx
249
613
  self[*refs]
250
614
  end
251
615
  when NArray
@@ -264,37 +628,38 @@ module Numo
264
628
  end
265
629
  end
266
630
 
267
- # p x = Numo::DFloat.new(4,4).seq
268
- # # Numo::DFloat#shape=[4,4]
269
- # # [[0, 1, 2, 3],
270
- # # [4, 5, 6, 7],
271
- # # [8, 9, 10, 11],
272
- # # [12, 13, 14, 15]]
273
- #
274
- # pp x.hsplit(2)
275
- # # [Numo::DFloat(view)#shape=[4,2]
276
- # # [[0, 1],
277
- # # [4, 5],
278
- # # [8, 9],
279
- # # [12, 13]],
280
- # # Numo::DFloat(view)#shape=[4,2]
281
- # # [[2, 3],
282
- # # [6, 7],
283
- # # [10, 11],
284
- # # [14, 15]]]
285
- #
286
- # pp x.hsplit([3, 6])
287
- # # [Numo::DFloat(view)#shape=[4,3]
288
- # # [[0, 1, 2],
289
- # # [4, 5, 6],
290
- # # [8, 9, 10],
291
- # # [12, 13, 14]],
292
- # # Numo::DFloat(view)#shape=[4,1]
293
- # # [[3],
294
- # # [7],
295
- # # [11],
296
- # # [15]],
297
- # # Numo::DFloat(view)#shape=[4,0][]]
631
+ # @example
632
+ # p x = Numo::DFloat.new(4,4).seq
633
+ # # Numo::DFloat#shape=[4,4]
634
+ # # [[0, 1, 2, 3],
635
+ # # [4, 5, 6, 7],
636
+ # # [8, 9, 10, 11],
637
+ # # [12, 13, 14, 15]]
638
+ #
639
+ # pp x.hsplit(2)
640
+ # # [Numo::DFloat(view)#shape=[4,2]
641
+ # # [[0, 1],
642
+ # # [4, 5],
643
+ # # [8, 9],
644
+ # # [12, 13]],
645
+ # # Numo::DFloat(view)#shape=[4,2]
646
+ # # [[2, 3],
647
+ # # [6, 7],
648
+ # # [10, 11],
649
+ # # [14, 15]]]
650
+ #
651
+ # pp x.hsplit([3, 6])
652
+ # # [Numo::DFloat(view)#shape=[4,3]
653
+ # # [[0, 1, 2],
654
+ # # [4, 5, 6],
655
+ # # [8, 9, 10],
656
+ # # [12, 13, 14]],
657
+ # # Numo::DFloat(view)#shape=[4,1]
658
+ # # [[3],
659
+ # # [7],
660
+ # # [11],
661
+ # # [15]],
662
+ # # Numo::DFloat(view)#shape=[4,0][]]
298
663
 
299
664
  def vsplit(indices_or_sections)
300
665
  split(indices_or_sections, axis:0)
@@ -308,52 +673,52 @@ module Numo
308
673
  split(indices_or_sections, axis:2)
309
674
  end
310
675
 
311
-
312
- # p a = Numo::NArray[0,1,2]
313
- # # Numo::Int32#shape=[3]
314
- # # [0, 1, 2]
676
+ # @example
677
+ # p a = Numo::NArray[0,1,2]
678
+ # # Numo::Int32#shape=[3]
679
+ # # [0, 1, 2]
315
680
  #
316
- # p a.tile(2)
317
- # # Numo::Int32#shape=[6]
318
- # # [0, 1, 2, 0, 1, 2]
681
+ # p a.tile(2)
682
+ # # Numo::Int32#shape=[6]
683
+ # # [0, 1, 2, 0, 1, 2]
319
684
  #
320
- # p a.tile(2,2)
321
- # # Numo::Int32#shape=[2,6]
322
- # # [[0, 1, 2, 0, 1, 2],
323
- # # [0, 1, 2, 0, 1, 2]]
685
+ # p a.tile(2,2)
686
+ # # Numo::Int32#shape=[2,6]
687
+ # # [[0, 1, 2, 0, 1, 2],
688
+ # # [0, 1, 2, 0, 1, 2]]
324
689
  #
325
- # p a.tile(2,1,2)
326
- # # Numo::Int32#shape=[2,1,6]
327
- # # [[[0, 1, 2, 0, 1, 2]],
328
- # # [[0, 1, 2, 0, 1, 2]]]
690
+ # p a.tile(2,1,2)
691
+ # # Numo::Int32#shape=[2,1,6]
692
+ # # [[[0, 1, 2, 0, 1, 2]],
693
+ # # [[0, 1, 2, 0, 1, 2]]]
329
694
  #
330
- # p b = Numo::NArray[[1, 2], [3, 4]]
331
- # # Numo::Int32#shape=[2,2]
332
- # # [[1, 2],
333
- # # [3, 4]]
695
+ # p b = Numo::NArray[[1, 2], [3, 4]]
696
+ # # Numo::Int32#shape=[2,2]
697
+ # # [[1, 2],
698
+ # # [3, 4]]
334
699
  #
335
- # p b.tile(2)
336
- # # Numo::Int32#shape=[2,4]
337
- # # [[1, 2, 1, 2],
338
- # # [3, 4, 3, 4]]
700
+ # p b.tile(2)
701
+ # # Numo::Int32#shape=[2,4]
702
+ # # [[1, 2, 1, 2],
703
+ # # [3, 4, 3, 4]]
339
704
  #
340
- # p b.tile(2,1)
341
- # # Numo::Int32#shape=[4,2]
342
- # # [[1, 2],
343
- # # [3, 4],
344
- # # [1, 2],
345
- # # [3, 4]]
705
+ # p b.tile(2,1)
706
+ # # Numo::Int32#shape=[4,2]
707
+ # # [[1, 2],
708
+ # # [3, 4],
709
+ # # [1, 2],
710
+ # # [3, 4]]
346
711
  #
347
- # p c = Numo::NArray[1,2,3,4]
348
- # # Numo::Int32#shape=[4]
349
- # # [1, 2, 3, 4]
712
+ # p c = Numo::NArray[1,2,3,4]
713
+ # # Numo::Int32#shape=[4]
714
+ # # [1, 2, 3, 4]
350
715
  #
351
- # p c.tile(4,1)
352
- # # Numo::Int32#shape=[4,4]
353
- # # [[1, 2, 3, 4],
354
- # # [1, 2, 3, 4],
355
- # # [1, 2, 3, 4],
356
- # # [1, 2, 3, 4]]
716
+ # p c.tile(4,1)
717
+ # # Numo::Int32#shape=[4,4]
718
+ # # [[1, 2, 3, 4],
719
+ # # [1, 2, 3, 4],
720
+ # # [1, 2, 3, 4],
721
+ # # [1, 2, 3, 4]]
357
722
 
358
723
  def tile(*arg)
359
724
  arg.each do |i|
@@ -391,30 +756,30 @@ module Numo
391
756
  self.class.new(*new_shp).store(self[*src_shp]).reshape(*res_shp)
392
757
  end
393
758
 
394
-
395
- # p Numo::NArray[3].repeat(4)
396
- # # Numo::Int32#shape=[4]
397
- # # [3, 3, 3, 3]
759
+ # @example
760
+ # p Numo::NArray[3].repeat(4)
761
+ # # Numo::Int32#shape=[4]
762
+ # # [3, 3, 3, 3]
398
763
  #
399
- # p x = Numo::NArray[[1,2],[3,4]]
400
- # # Numo::Int32#shape=[2,2]
401
- # # [[1, 2],
402
- # # [3, 4]]
764
+ # p x = Numo::NArray[[1,2],[3,4]]
765
+ # # Numo::Int32#shape=[2,2]
766
+ # # [[1, 2],
767
+ # # [3, 4]]
403
768
  #
404
- # p x.repeat(2)
405
- # # Numo::Int32#shape=[8]
406
- # # [1, 1, 2, 2, 3, 3, 4, 4]
769
+ # p x.repeat(2)
770
+ # # Numo::Int32#shape=[8]
771
+ # # [1, 1, 2, 2, 3, 3, 4, 4]
407
772
  #
408
- # p x.repeat(3,axis:1)
409
- # # Numo::Int32#shape=[2,6]
410
- # # [[1, 1, 1, 2, 2, 2],
411
- # # [3, 3, 3, 4, 4, 4]]
773
+ # p x.repeat(3,axis:1)
774
+ # # Numo::Int32#shape=[2,6]
775
+ # # [[1, 1, 1, 2, 2, 2],
776
+ # # [3, 3, 3, 4, 4, 4]]
412
777
  #
413
- # p x.repeat([1,2],axis:0)
414
- # # Numo::Int32#shape=[3,2]
415
- # # [[1, 2],
416
- # # [3, 4],
417
- # # [3, 4]]
778
+ # p x.repeat([1,2],axis:0)
779
+ # # Numo::Int32#shape=[3,2]
780
+ # # [[1, 2],
781
+ # # [3, 4],
782
+ # # [3, 4]]
418
783
 
419
784
  def repeat(arg,axis:nil)
420
785
  case axis
@@ -450,7 +815,61 @@ module Numo
450
815
  c[*ref].copy
451
816
  end
452
817
 
818
+ # Calculate the n-th discrete difference along given axis.
819
+ # @example
820
+ # p x = Numo::DFloat[1, 2, 4, 7, 0]
821
+ # # Numo::DFloat#shape=[5]
822
+ # # [1, 2, 4, 7, 0]
823
+ #
824
+ # p x.diff
825
+ # # Numo::DFloat#shape=[4]
826
+ # # [1, 2, 3, -7]
827
+ #
828
+ # p x.diff(2)
829
+ # # Numo::DFloat#shape=[3]
830
+ # # [1, 1, -10]
831
+ #
832
+ # p x = Numo::DFloat[[1, 3, 6, 10], [0, 5, 6, 8]]
833
+ # # Numo::DFloat#shape=[2,4]
834
+ # # [[1, 3, 6, 10],
835
+ # # [0, 5, 6, 8]]
836
+ #
837
+ # p x.diff
838
+ # # Numo::DFloat#shape=[2,3]
839
+ # # [[2, 3, 4],
840
+ # # [5, 1, 2]]
841
+ #
842
+ # p x.diff(axis:0)
843
+ # # Numo::DFloat#shape=[1,4]
844
+ # # [[-1, 2, 0, -2]]
845
+
846
+ def diff(n=1,axis:-1)
847
+ axis = check_axis(axis)
848
+ if n < 0 || n >= shape[axis]
849
+ raise ShapeError,"n=#{n} is invalid for shape[#{axis}]=#{shape[axis]}"
850
+ end
851
+ # calculate polynomial coefficient
852
+ c = self.class[-1,1]
853
+ 2.upto(n) do |i|
854
+ x = self.class.zeros(i+1)
855
+ x[0..-2] = c
856
+ y = self.class.zeros(i+1)
857
+ y[1..-1] = c
858
+ c = y - x
859
+ end
860
+ s = [true]*ndim
861
+ s[axis] = n..-1
862
+ result = self[*s].dup
863
+ sum = result.inplace
864
+ (n-1).downto(0) do |i|
865
+ s = [true]*ndim
866
+ s[axis] = i..-n-1+i
867
+ sum + self[*s] * c[i] # inplace addition
868
+ end
869
+ return result
870
+ end
453
871
 
872
+ private
454
873
  def check_axis(axis)
455
874
  if axis < 0
456
875
  axis += ndim