numo-narray 0.9.0.3 → 0.9.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -6
  3. data/Rakefile +2 -10
  4. data/ext/numo/narray/array.c +1 -6
  5. data/ext/numo/narray/data.c +3 -9
  6. data/ext/numo/narray/depend.erb +1 -1
  7. data/ext/numo/narray/extconf.rb +0 -1
  8. data/ext/numo/narray/gen/def/bit.rb +2 -0
  9. data/ext/numo/narray/gen/def/dcomplex.rb +2 -0
  10. data/ext/numo/narray/gen/def/dfloat.rb +2 -0
  11. data/ext/numo/narray/gen/def/int16.rb +2 -0
  12. data/ext/numo/narray/gen/def/int32.rb +2 -0
  13. data/ext/numo/narray/gen/def/int64.rb +2 -0
  14. data/ext/numo/narray/gen/def/int8.rb +2 -0
  15. data/ext/numo/narray/gen/def/robject.rb +2 -0
  16. data/ext/numo/narray/gen/def/scomplex.rb +2 -0
  17. data/ext/numo/narray/gen/def/sfloat.rb +2 -0
  18. data/ext/numo/narray/gen/def/uint16.rb +2 -0
  19. data/ext/numo/narray/gen/def/uint32.rb +2 -0
  20. data/ext/numo/narray/gen/def/uint64.rb +2 -0
  21. data/ext/numo/narray/gen/def/uint8.rb +2 -0
  22. data/ext/numo/narray/gen/dtype.erb.c +7 -7
  23. data/ext/numo/narray/gen/spec.rb +24 -2
  24. data/ext/numo/narray/gen/tmpl/accum_binary.c +6 -0
  25. data/ext/numo/narray/gen/tmpl/aref.c +6 -4
  26. data/ext/numo/narray/gen/tmpl/aset.c +6 -4
  27. data/ext/numo/narray/gen/tmpl/binary.c +4 -0
  28. data/ext/numo/narray/gen/tmpl/binary2.c +4 -0
  29. data/ext/numo/narray/gen/tmpl/bincount.c +180 -0
  30. data/ext/numo/narray/gen/tmpl/cast.c +4 -0
  31. data/ext/numo/narray/gen/tmpl/cast_array.c +3 -64
  32. data/ext/numo/narray/gen/tmpl/cond_binary.c +4 -0
  33. data/ext/numo/narray/gen/tmpl/inspect.c +4 -0
  34. data/ext/numo/narray/gen/tmpl/pow.c +4 -0
  35. data/ext/numo/narray/gen/tmpl/qsort.c +1 -7
  36. data/ext/numo/narray/gen/tmpl/rand.c +13 -2
  37. data/ext/numo/narray/gen/tmpl/rand_norm.c +89 -16
  38. data/ext/numo/narray/gen/tmpl/store.c +4 -0
  39. data/ext/numo/narray/gen/tmpl/store_array.c +99 -2
  40. data/ext/numo/narray/gen/tmpl_bit/allocate.c +1 -1
  41. data/ext/numo/narray/gen/tmpl_bit/aref.c +6 -4
  42. data/ext/numo/narray/gen/tmpl_bit/aset.c +6 -4
  43. data/ext/numo/narray/gen/tmpl_bit/cast_array.c +3 -65
  44. data/ext/numo/narray/gen/tmpl_bit/mask.c +16 -1
  45. data/ext/numo/narray/gen/tmpl_bit/store_array.c +101 -2
  46. data/ext/numo/narray/gen/tmpl_bit/where.c +7 -23
  47. data/ext/numo/narray/gen/tmpl_bit/where2.c +58 -4
  48. data/ext/numo/narray/index.c +168 -166
  49. data/ext/numo/narray/kwarg.c +1 -6
  50. data/ext/numo/narray/math.c +8 -12
  51. data/ext/numo/narray/narray.c +231 -71
  52. data/ext/numo/narray/ndloop.c +86 -26
  53. data/ext/numo/narray/numo/intern.h +6 -10
  54. data/ext/numo/narray/numo/narray.h +83 -54
  55. data/ext/numo/narray/numo/ndloop.h +0 -5
  56. data/ext/numo/narray/numo/template.h +0 -5
  57. data/ext/numo/narray/numo/types/complex.h +1 -6
  58. data/ext/numo/narray/numo/types/complex_macro.h +30 -3
  59. data/ext/numo/narray/numo/types/dcomplex.h +18 -0
  60. data/ext/numo/narray/numo/types/dfloat.h +18 -0
  61. data/ext/numo/narray/numo/types/float_macro.h +25 -2
  62. data/ext/numo/narray/numo/types/robj_macro.h +2 -4
  63. data/ext/numo/narray/numo/types/scomplex.h +18 -0
  64. data/ext/numo/narray/numo/types/sfloat.h +18 -0
  65. data/ext/numo/narray/rand.c +0 -15
  66. data/ext/numo/narray/step.c +0 -5
  67. data/ext/numo/narray/struct.c +7 -12
  68. data/lib/erbpp/line_number.rb +4 -4
  69. data/lib/erbpp/narray_def.rb +16 -7
  70. data/lib/numo/narray.rb +2 -0
  71. data/lib/numo/narray/extra.rb +465 -0
  72. data/numo-narray.gemspec +2 -2
  73. data/spec/narray_spec.rb +4 -3
  74. metadata +13 -7
  75. data/ext/numo/narray/gen/tmpl/head.c +0 -25
@@ -2,11 +2,6 @@
2
2
  ndloop.h
3
3
  Numerical Array Extension for Ruby
4
4
  (C) Copyright 1999-2016 by Masahiro TANAKA
5
-
6
- This program is free software.
7
- You can distribute/modify this program
8
- under the same terms as Ruby itself.
9
- NO WARRANTY.
10
5
  */
11
6
  #ifndef NDLOOP_H
12
7
  #define NDLOOP_H
@@ -2,11 +2,6 @@
2
2
  template.h
3
3
  Numerical Array Extension for Ruby
4
4
  (C) Copyright 1999-2016 by Masahiro TANAKA
5
-
6
- This program is free software.
7
- You can distribute/modify this program
8
- under the same terms as Ruby itself.
9
- NO WARRANTY.
10
5
  */
11
6
  #ifndef TEMPLATE_H
12
7
  #define TEMPLATE_H
@@ -1,12 +1,7 @@
1
1
  /*
2
2
  complex.h
3
3
  Numerical Array Extension for Ruby
4
- (C) Copyright 1999-2007 by Masahiro TANAKA
5
-
6
- This program is free software.
7
- You can distribute/modify this program
8
- under the same terms as Ruby itself.
9
- NO WARRANTY.
4
+ (C) Copyright 1999-2016 by Masahiro TANAKA
10
5
  */
11
6
 
12
7
 
@@ -5,7 +5,7 @@ EXTERN double log2(double);
5
5
  EXTERN double exp2(double);
6
6
  EXTERN double exp10(double);
7
7
 
8
- #define r_abs(x) abs(x)
8
+ #define r_abs(x) fabs(x)
9
9
  #define r_sqrt(x) sqrt(x)
10
10
  #define r_exp(x) exp(x)
11
11
  #define r_log(x) log(x)
@@ -73,6 +73,7 @@ static inline dtype c_from_dcomplex(dcomplex x) {
73
73
  #define m_sign(x) c_new( \
74
74
  ((REAL(x)==0) ? 0.0:((REAL(x)>0) ? 1.0:((REAL(x)<0) ? -1.0:REAL(x)))), \
75
75
  ((IMAG(x)==0) ? 0.0:((IMAG(x)>0) ? 1.0:((IMAG(x)<0) ? -1.0:IMAG(x)))))
76
+ #define m_copysign(x,y) c_new(copysign(REAL(x),REAL(y)),copysign(IMAG(x),IMAG(y)))
76
77
 
77
78
  #define m_im(x) c_im(x)
78
79
  #define m_conj(x) c_new(REAL(x),-IMAG(x))
@@ -92,8 +93,6 @@ static inline dtype c_from_dcomplex(dcomplex x) {
92
93
  #define m_mulsum(x,y,z) {z = c_add(c_mul(x,y),z);}
93
94
  #define m_mulsum_init INT2FIX(0)
94
95
 
95
- #define m_rand_norm(a) rand_norm(a)
96
-
97
96
  #define m_sprintf(s,x) sprintf(s,"%g%+gi",REAL(x),IMAG(x))
98
97
 
99
98
  #define m_sqrt(x) c_sqrt(x)
@@ -134,6 +133,34 @@ static inline dtype f_sum(size_t n, char *p, ssize_t stride)
134
133
  return y;
135
134
  }
136
135
 
136
+ static inline dtype f_kahan_sum(size_t n, char *p, ssize_t stride)
137
+ {
138
+ size_t i=n;
139
+ dtype x;
140
+ volatile dtype y,t,r;
141
+
142
+ y = c_zero();
143
+ r = c_zero();
144
+ for (; i--;) {
145
+ x = *(dtype*)p;
146
+ if (!c_isnan(x)) {
147
+ if (fabs(REAL(x)) > fabs(REAL(y))) {
148
+ double z=REAL(x); REAL(x)=REAL(y); REAL(y)=z;
149
+ }
150
+ if (fabs(IMAG(x)) > fabs(IMAG(y))) {
151
+ double z=IMAG(x); IMAG(x)=IMAG(y); IMAG(y)=z;
152
+ }
153
+ r = c_add(x, r);
154
+ t = y;
155
+ y = c_add(r, y);
156
+ t = c_sub(y, t);
157
+ r = c_sub(r, t);
158
+ }
159
+ p += stride;
160
+ }
161
+ return y;
162
+ }
163
+
137
164
  static inline dtype f_prod(size_t n, char *p, ssize_t stride)
138
165
  {
139
166
  size_t i=n;
@@ -18,3 +18,21 @@ inline static dtype m_rand(dtype max)
18
18
  IMAG(z) = genrand_res53_mix() * IMAG(max);
19
19
  return z;
20
20
  }
21
+
22
+ /* generates random numbers from the normal distribution
23
+ using Box-Muller Transformation.
24
+ */
25
+ inline static void m_rand_norm(dtype mu, rtype sigma, dtype *a0)
26
+ {
27
+ rtype x1, x2, w;
28
+ do {
29
+ x1 = genrand_res53_mix();
30
+ x1 = x1*2-1;
31
+ x2 = genrand_res53_mix();
32
+ x2 = x2*2-1;
33
+ w = x1 * x1 + x2 * x2;
34
+ } while (w>=1);
35
+ w = sqrt( (-2*log(w)) / w );
36
+ REAL(*a0) = x1*w * sigma + REAL(mu);
37
+ IMAG(*a0) = x2*w * sigma + IMAG(mu);
38
+ }
@@ -12,6 +12,24 @@ inline static dtype m_rand(dtype max)
12
12
  return genrand_res53_mix() * max;
13
13
  }
14
14
 
15
+ /* generates random numbers from the normal distribution
16
+ using Box-Muller Transformation.
17
+ */
18
+ inline static void m_rand_norm(dtype mu, dtype sigma, dtype *a0, dtype *a1)
19
+ {
20
+ dtype x1, x2, w;
21
+ do {
22
+ x1 = genrand_res53_mix();
23
+ x1 = x1*2-1;
24
+ x2 = genrand_res53_mix();
25
+ x2 = x2*2-1;
26
+ w = x1 * x1 + x2 * x2;
27
+ } while (w>=1);
28
+ w = sqrt( (-2*log(w)) / w );
29
+ if (a0) {*a0 = x1*w * sigma + mu;}
30
+ if (a1) {*a1 = x2*w * sigma + mu;}
31
+ }
32
+
15
33
  #define m_min_init numo_dfloat_new_dim0(0.0/0.0)
16
34
  #define m_max_init numo_dfloat_new_dim0(0.0/0.0)
17
35
  #define m_extract(x) rb_float_new(*(double*)x)
@@ -38,6 +38,7 @@ EXTERN double pow(double, double);
38
38
  #define m_trunc(x) trunc(x)
39
39
  #define m_rint(x) rint(x)
40
40
  #define m_sign(x) (((x)==0) ? 0.0:(((x)>0) ? 1.0:(((x)<0) ? -1.0:(x))))
41
+ #define m_copysign(x,y) copysign(x,y)
41
42
 
42
43
  #define m_eq(x,y) ((x)==(y))
43
44
  #define m_ne(x,y) ((x)!=(y))
@@ -53,8 +54,6 @@ EXTERN double pow(double, double);
53
54
  #define m_mulsum(x,y,z) {z += x*y;}
54
55
  #define m_mulsum_init INT2FIX(0)
55
56
 
56
- #define m_rand_norm(a) rand_norm(a)
57
-
58
57
  #define m_sprintf(s,x) sprintf(s,"%g",x)
59
58
 
60
59
  #define cmp(a,b) \
@@ -135,6 +134,30 @@ static inline dtype f_sum(size_t n, char *p, ssize_t stride)
135
134
  return y;
136
135
  }
137
136
 
137
+ static inline dtype f_kahan_sum(size_t n, char *p, ssize_t stride)
138
+ {
139
+ size_t i=n;
140
+ dtype x;
141
+ volatile dtype y=0;
142
+ volatile dtype t,r=0;
143
+
144
+ for (; i--;) {
145
+ x = *(dtype*)p;
146
+ if (!m_isnan(x)) {
147
+ if (fabs(x) > fabs(y)) {
148
+ dtype z=x; x=y; y=z;
149
+ }
150
+ r += x;
151
+ t = y;
152
+ y += r;
153
+ t = y-t;
154
+ r -= t;
155
+ }
156
+ p += stride;
157
+ }
158
+ return y;
159
+ }
160
+
138
161
  static inline dtype f_prod(size_t n, char *p, ssize_t stride)
139
162
  {
140
163
  size_t i=n;
@@ -28,8 +28,8 @@
28
28
  #define m_trunc(x) rb_funcall(x,id_truncate,0)
29
29
  #define m_sign(x) rb_funcall(x,id_op_ufo,1,INT2FIX(0))
30
30
 
31
- #define m_eq(x,y) RTEST(rb_funcall(x,id_eq,1,y))
32
- #define m_ne(x,y) RTEST(rb_funcall(x,id_ne,1,y))
31
+ #define m_eq(x,y) RTEST(rb_funcall(x,id_op_eq,1,y))
32
+ #define m_ne(x,y) RTEST(rb_funcall(x,id_op_ne,1,y))
33
33
  #define m_gt(x,y) RTEST(rb_funcall(x,id_op_gt,1,y))
34
34
  #define m_ge(x,y) RTEST(rb_funcall(x,id_op_ge,1,y))
35
35
  #define m_lt(x,y) RTEST(rb_funcall(x,id_op_lt,1,y))
@@ -47,8 +47,6 @@
47
47
  #define m_mulsum(x,y,z) {z = m_add(m_mul(x,y),z);}
48
48
  #define m_mulsum_init INT2FIX(0)
49
49
 
50
- #define m_rand_norm(a) rand_norm(a)
51
-
52
50
  #define m_sprintf(s,x) robj_sprintf(s,x)
53
51
 
54
52
  static inline int robj_sprintf(char *s, VALUE x) {
@@ -18,3 +18,21 @@ inline static dtype m_rand(dtype max)
18
18
  IMAG(z) = to_real2(gen_rand32()) * IMAG(max);
19
19
  return z;
20
20
  }
21
+
22
+ /* generates random numbers from the normal distribution
23
+ using Box-Muller Transformation.
24
+ */
25
+ inline static void m_rand_norm(dtype mu, rtype sigma, dtype *a0)
26
+ {
27
+ rtype x1, x2, w;
28
+ do {
29
+ x1 = to_real2(gen_rand32());
30
+ x1 = x1*2-1;
31
+ x2 = to_real2(gen_rand32());
32
+ x2 = x2*2-1;
33
+ w = x1 * x1 + x2 * x2;
34
+ } while (w>=1);
35
+ w = sqrt( (-2*log(w)) / w );
36
+ REAL(*a0) = x1*w * sigma + REAL(mu);
37
+ IMAG(*a0) = x2*w * sigma + IMAG(mu);
38
+ }
@@ -12,6 +12,24 @@ inline static dtype m_rand(dtype max)
12
12
  return to_real2(gen_rand32()) * max;
13
13
  }
14
14
 
15
+ /* generates random numbers from the normal distribution
16
+ using Box-Muller Transformation.
17
+ */
18
+ inline static void m_rand_norm(dtype mu, dtype sigma, dtype *a0, dtype *a1)
19
+ {
20
+ dtype x1, x2, w;
21
+ do {
22
+ x1 = to_real2(gen_rand32());
23
+ x1 = x1*2-1;
24
+ x2 = to_real2(gen_rand32());
25
+ x2 = x2*2-1;
26
+ w = x1 * x1 + x2 * x2;
27
+ } while (w>=1);
28
+ w = sqrt( (-2*log(w)) / w );
29
+ if (a0) {*a0 = x1*w * sigma + mu;}
30
+ if (a1) {*a1 = x2*w * sigma + mu;}
31
+ }
32
+
15
33
  #define m_min_init numo_sfloat_new_dim0(0.0/0.0)
16
34
  #define m_max_init numo_sfloat_new_dim0(0.0/0.0)
17
35
 
@@ -37,21 +37,6 @@ int n_bits(u_int64_t a)
37
37
  return xl;
38
38
  }
39
39
 
40
- void rand_norm(double *a)
41
- {
42
- double x1, x2, w;
43
- do {
44
- x1 = genrand_res53_mix();
45
- x1 = x1*2-1;
46
- x2 = genrand_res53_mix();
47
- x2 = x2*2-1;
48
- w = x1 * x1 + x2 * x2;
49
- } while (w>=1);
50
- w = sqrt( (-2*log(w)) / w );
51
- a[0] = x1*w;
52
- a[1] = x2*w;
53
- }
54
-
55
40
  static u_int64_t
56
41
  random_seed()
57
42
  {
@@ -2,11 +2,6 @@
2
2
  step.c
3
3
  Numerical Array Extension for Ruby
4
4
  (C) Copyright 2007,2013 by Masahiro TANAKA
5
-
6
- This program is free software.
7
- You can distribute/modify this program
8
- under the same terms as Ruby itself.
9
- NO WARRANTY.
10
5
  */
11
6
  #include <ruby.h>
12
7
  #include <math.h>
@@ -2,11 +2,6 @@
2
2
  nstrut.c
3
3
  Numerical Array Extension for Ruby
4
4
  (C) Copyright 1999-2016 by Masahiro TANAKA
5
-
6
- This program is free software.
7
- You can distribute/modify this program
8
- under the same terms as Ruby itself.
9
- NO WARRANTY.
10
5
  */
11
6
  #include <ruby.h>
12
7
  #include "numo/narray.h"
@@ -454,7 +449,7 @@ nary_struct_to_a(VALUE self)
454
449
  volatile VALUE opt;
455
450
  ndfunc_arg_in_t ain[3] = {{Qnil,0},{sym_loop_opt},{sym_option}};
456
451
  ndfunc_arg_out_t aout[1] = {{rb_cArray,0}}; // dummy?
457
- ndfunc_t ndf = { iter_nstruct_to_a, NO_LOOP, 3, 1, ain, aout };
452
+ ndfunc_t ndf = {iter_nstruct_to_a, NO_LOOP, 3, 1, ain, aout};
458
453
 
459
454
  opt = nst_create_member_views(self);
460
455
  return na_ndloop_cast_narray_to_rarray(&ndf, self, opt);
@@ -587,7 +582,7 @@ iter_nstruct_from_a(na_loop_t *const lp)
587
582
  defs = RARRAY_AREF(lp->option,1);
588
583
 
589
584
  len = RARRAY_LEN(types);
590
- ary = lp->args[0].value;
585
+ ary = lp->args[1].value;
591
586
  //rb_p(CLASS_OF(ary));rb_p(ary);
592
587
 
593
588
  for (i=0; i<len; i++) {
@@ -595,7 +590,7 @@ iter_nstruct_from_a(na_loop_t *const lp)
595
590
  ofs = NUM2SIZET(RARRAY_AREF(def,2));
596
591
  elmt = RARRAY_AREF(types,i);
597
592
  GetNArrayView(elmt,ne);
598
- ne->offset = lp->args[1].iter[0].pos + ofs;
593
+ ne->offset = lp->args[0].iter[0].pos + ofs;
599
594
  item = RARRAY_AREF(ary,i);
600
595
  //rb_p(ary);
601
596
  //rb_p(item);
@@ -612,8 +607,8 @@ nary_struct_cast_array(VALUE klass, VALUE rary)
612
607
  narray_t *na;
613
608
  na_compose_t *nc;
614
609
  VALUE opt;
615
- ndfunc_arg_in_t ain[3] = {{rb_cArray,0},{Qnil,0},{sym_option}};
616
- ndfunc_t ndf = { iter_nstruct_from_a, NO_LOOP, 3, 0, ain, 0 };
610
+ ndfunc_arg_in_t ain[3] = {{OVERWRITE,0},{rb_cArray,0},{sym_option}};
611
+ ndfunc_t ndf = {iter_nstruct_from_a, NO_LOOP, 3, 0, ain, 0};
617
612
 
618
613
  //fprintf(stderr,"rary:");rb_p(rary);
619
614
  //fprintf(stderr,"class_of(rary):");rb_p(CLASS_OF(rary));
@@ -627,7 +622,7 @@ nary_struct_cast_array(VALUE klass, VALUE rary)
627
622
  if (na->size>0) {
628
623
  opt = nst_create_member_views(nary);
629
624
  rb_funcall(nary, rb_intern("allocate"), 0);
630
- na_ndloop_cast_rarray_to_narray2(&ndf, rary, nary, opt);
625
+ na_ndloop_store_rarray2(&ndf, nary, rary, opt);
631
626
  }
632
627
  return nary;
633
628
  }
@@ -689,7 +684,7 @@ static VALUE
689
684
  nary_struct_store_struct(VALUE self, VALUE obj)
690
685
  {
691
686
  ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{Qnil,0}};
692
- ndfunc_t ndf = { iter_struct_store_struct, FULL_LOOP, 2, 0, ain, 0 };
687
+ ndfunc_t ndf = {iter_struct_store_struct, FULL_LOOP, 2, 0, ain, 0};
693
688
 
694
689
  na_ndloop(&ndf, 2, self, obj);
695
690
  return self;
@@ -34,7 +34,7 @@ class CountLnString < String
34
34
  end
35
35
  return if n == @current
36
36
  if @current != @countln || @postpone
37
- if /^\s*$/ =~ @str || /\A#line / =~ @buf
37
+ if /\A\s*\z/ =~ @str || /\A#line / =~ @buf || /\n\z/ !~ self
38
38
  @postpone = true
39
39
  elsif @in_comment
40
40
  @postpone = false
@@ -79,9 +79,9 @@ class CountLnString < String
79
79
  end
80
80
 
81
81
  def d(s)
82
- p [s, [x,y], r]
83
- r
84
- end
82
+ p [s, [x,y], r]
83
+ r
84
+ end
85
85
 
86
86
  end
87
87
 
@@ -178,11 +178,13 @@ class DataType < ErbPP
178
178
  has_math
179
179
  is_bit
180
180
  is_int
181
+ is_unsigned
181
182
  is_float
182
183
  is_real
183
184
  is_complex
184
185
  is_object
185
186
  is_comparable
187
+ is_double_precision
186
188
  mod_var
187
189
  ]
188
190
  define_attrs attrs
@@ -248,13 +250,12 @@ class DataType < ErbPP
248
250
  t = "cT"
249
251
  end
250
252
  if c=="Integer"
251
- if defined?(Fixnum) && Fixnum != Integer
252
- @upcast << "rb_hash_aset(hCast, rb_cFixnum, #{t});"
253
- @upcast << "rb_hash_aset(hCast, rb_cBignum, #{t});"
254
- else
255
- # RUBY_VERSION >= "2.4.0"
256
- @upcast << "rb_hash_aset(hCast, rb_cInteger, #{t});"
257
- end
253
+ @upcast << "#ifdef RUBY_INTEGER_UNIFICATION"
254
+ @upcast << "rb_hash_aset(hCast, rb_cInteger, #{t});"
255
+ @upcast << "#else"
256
+ @upcast << "rb_hash_aset(hCast, rb_cFixnum, #{t});"
257
+ @upcast << "rb_hash_aset(hCast, rb_cBignum, #{t});"
258
+ @upcast << "#endif"
258
259
  else
259
260
  @upcast << "rb_hash_aset(hCast, rb_c#{c}, #{t});"
260
261
  end
@@ -339,4 +340,12 @@ class CastArray < StoreArray
339
340
  def condition
340
341
  nil
341
342
  end
343
+
344
+ def c_func
345
+ "numo_#{tp}_cast_#{tpname}"
346
+ end
347
+
348
+ def c_iter
349
+ "iter_#{tp}_cast_#{tpname}"
350
+ end
342
351
  end
@@ -4,3 +4,5 @@ begin
4
4
  rescue LoadError
5
5
  require "numo/narray.so"
6
6
  end
7
+
8
+ require "numo/narray/extra"
@@ -0,0 +1,465 @@
1
+ module Numo
2
+ class NArray
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)
25
+ klass = (self==NArray) ? NArray.array_type(arrays) : self
26
+ nd = 0
27
+ arrays.map! do |a|
28
+ case a
29
+ when NArray
30
+ # ok
31
+ when Numeric
32
+ a = klass.new(1).store(a)
33
+ when Array
34
+ a = klass.cast(a)
35
+ else
36
+ raise TypeError,"not Numo::NArray"
37
+ end
38
+ if a.ndim > nd
39
+ nd = a.ndim
40
+ end
41
+ a
42
+ end
43
+ if axis < 0
44
+ axis += nd
45
+ end
46
+ if axis < 0 || axis >= nd
47
+ raise ArgumentError,"axis is out of range"
48
+ end
49
+ new_shape = nil
50
+ sum_size = 0
51
+ arrays.each do |a|
52
+ a_shape = a.shape
53
+ if nd != a_shape.size
54
+ a_shape = [1]*(nd-a_shape.size) + a_shape
55
+ end
56
+ sum_size += a_shape.delete_at(axis)
57
+ if new_shape
58
+ if new_shape != a_shape
59
+ raise ShapeError,"shape mismatch"
60
+ end
61
+ else
62
+ new_shape = a_shape
63
+ end
64
+ end
65
+ new_shape.insert(axis,sum_size)
66
+ result = klass.zeros(*new_shape)
67
+ lst = 0
68
+ refs = [true] * nd
69
+ arrays.each do |a|
70
+ fst = lst
71
+ lst = fst + (a.shape[axis-nd]||1)
72
+ refs[axis] = fst...lst
73
+ result[*refs] = a
74
+ end
75
+ result
76
+ 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
120
+ end
121
+ result
122
+ end
123
+
124
+ def self.vstack(arrays)
125
+ self.stack(arrays,axis:0)
126
+ end
127
+
128
+ def self.hstack(arrays)
129
+ self.stack(arrays,axis:1)
130
+ end
131
+
132
+ def self.dstack(arrays)
133
+ self.stack(arrays,axis:2)
134
+ end
135
+ =end
136
+
137
+ def self.vstack(arrays)
138
+ self.concatenate(arrays,axis:0)
139
+ end
140
+
141
+ def self.hstack(arrays)
142
+ self.concatenate(arrays,axis:1)
143
+ end
144
+
145
+ def self.dstack(arrays)
146
+ self.concatenate(arrays,axis:2)
147
+ end
148
+
149
+ # p a = Numo::DFloat[[1, 2], [3, 4]]
150
+ # # Numo::DFloat#shape=[2,2]
151
+ # # [[1, 2],
152
+ # # [3, 4]]
153
+ #
154
+ # p b = Numo::DFloat[[5, 6]]
155
+ # # Numo::DFloat#shape=[1,2]
156
+ # # [[5, 6]]
157
+ #
158
+ # p a.concatenate(b,axis:0)
159
+ # # Numo::DFloat#shape=[3,2]
160
+ # # [[1, 2],
161
+ # # [3, 4],
162
+ # # [5, 6]]
163
+ #
164
+ # p a.concatenate(b.transpose, axis:1)
165
+ # # Numo::DFloat#shape=[2,3]
166
+ # # [[1, 2, 5],
167
+ # # [3, 4, 6]]
168
+
169
+ def concatenate(*arrays,axis:0)
170
+ axis = check_axis(axis)
171
+ self_shape = shape
172
+ self_shape.delete_at(axis)
173
+ sum_size = shape[axis]
174
+ arrays.map! do |a|
175
+ case a
176
+ when NArray
177
+ # ok
178
+ when Numeric
179
+ a = self.class.new(1).store(a)
180
+ when Array
181
+ a = self.class.cast(a)
182
+ else
183
+ raise TypeError,"not Numo::NArray"
184
+ end
185
+ if a.ndim > ndim
186
+ raise ShapeError,"dimension mismatch"
187
+ end
188
+ a_shape = a.shape
189
+ sum_size += a_shape.delete_at(axis-ndim) || 1
190
+ if self_shape != a_shape
191
+ raise ShapeError,"shape mismatch"
192
+ end
193
+ a
194
+ end
195
+ self_shape.insert(axis,sum_size)
196
+ result = self.class.zeros(*self_shape)
197
+ lst = shape[axis]
198
+ refs = [true] * ndim
199
+ refs[axis] = 0...lst
200
+ result[*refs] = self
201
+ arrays.each do |a|
202
+ fst = lst
203
+ lst = fst + (a.shape[axis-ndim] || 1)
204
+ refs[axis] = fst...lst
205
+ result[*refs] = a
206
+ end
207
+ result
208
+ end
209
+
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][]]
236
+
237
+ def split(indices_or_sections, axis:0)
238
+ axis = check_axis(axis)
239
+ size_axis = shape[axis]
240
+ case indices_or_sections
241
+ when Integer
242
+ 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
+ refs = [true]*ndim
247
+ indices_or_sections.times.map do |i|
248
+ refs[axis] = i*div_axis ... (i+1)*div_axis
249
+ self[*refs]
250
+ end
251
+ when NArray
252
+ split(indices_or_sections.to_a,axis:axis)
253
+ when Array
254
+ refs = [true]*ndim
255
+ fst = 0
256
+ (indices_or_sections + [size_axis]).map do |lst|
257
+ lst = size_axis if lst > size_axis
258
+ refs[axis] = (fst < size_axis) ? fst...lst : -1...-1
259
+ fst = lst
260
+ self[*refs]
261
+ end
262
+ else
263
+ raise TypeError,"argument must be Integer or Array"
264
+ end
265
+ end
266
+
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][]]
298
+
299
+ def vsplit(indices_or_sections)
300
+ split(indices_or_sections, axis:0)
301
+ end
302
+
303
+ def hsplit(indices_or_sections)
304
+ split(indices_or_sections, axis:1)
305
+ end
306
+
307
+ def dsplit(indices_or_sections)
308
+ split(indices_or_sections, axis:2)
309
+ end
310
+
311
+
312
+ # p a = Numo::NArray[0,1,2]
313
+ # # Numo::Int32#shape=[3]
314
+ # # [0, 1, 2]
315
+ #
316
+ # p a.tile(2)
317
+ # # Numo::Int32#shape=[6]
318
+ # # [0, 1, 2, 0, 1, 2]
319
+ #
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]]
324
+ #
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]]]
329
+ #
330
+ # p b = Numo::NArray[[1, 2], [3, 4]]
331
+ # # Numo::Int32#shape=[2,2]
332
+ # # [[1, 2],
333
+ # # [3, 4]]
334
+ #
335
+ # p b.tile(2)
336
+ # # Numo::Int32#shape=[2,4]
337
+ # # [[1, 2, 1, 2],
338
+ # # [3, 4, 3, 4]]
339
+ #
340
+ # p b.tile(2,1)
341
+ # # Numo::Int32#shape=[4,2]
342
+ # # [[1, 2],
343
+ # # [3, 4],
344
+ # # [1, 2],
345
+ # # [3, 4]]
346
+ #
347
+ # p c = Numo::NArray[1,2,3,4]
348
+ # # Numo::Int32#shape=[4]
349
+ # # [1, 2, 3, 4]
350
+ #
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]]
357
+
358
+ def tile(*arg)
359
+ arg.each do |i|
360
+ if !i.kind_of?(Integer) || i<1
361
+ raise ArgumentError,"argument should be positive integer"
362
+ end
363
+ end
364
+ ns = arg.size
365
+ nd = self.ndim
366
+ shp = self.shape
367
+ new_shp = []
368
+ src_shp = []
369
+ res_shp = []
370
+ (nd-ns).times do
371
+ new_shp << 1
372
+ new_shp << (n = shp.shift)
373
+ src_shp << :new
374
+ src_shp << true
375
+ res_shp << n
376
+ end
377
+ (ns-nd).times do
378
+ new_shp << (m = arg.shift)
379
+ new_shp << 1
380
+ src_shp << :new
381
+ src_shp << :new
382
+ res_shp << m
383
+ end
384
+ [nd,ns].min.times do
385
+ new_shp << (m = arg.shift)
386
+ new_shp << (n = shp.shift)
387
+ src_shp << :new
388
+ src_shp << true
389
+ res_shp << n*m
390
+ end
391
+ self.class.new(*new_shp).store(self[*src_shp]).reshape(*res_shp)
392
+ end
393
+
394
+
395
+ # p Numo::NArray[3].repeat(4)
396
+ # # Numo::Int32#shape=[4]
397
+ # # [3, 3, 3, 3]
398
+ #
399
+ # p x = Numo::NArray[[1,2],[3,4]]
400
+ # # Numo::Int32#shape=[2,2]
401
+ # # [[1, 2],
402
+ # # [3, 4]]
403
+ #
404
+ # p x.repeat(2)
405
+ # # Numo::Int32#shape=[8]
406
+ # # [1, 1, 2, 2, 3, 3, 4, 4]
407
+ #
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]]
412
+ #
413
+ # p x.repeat([1,2],axis:0)
414
+ # # Numo::Int32#shape=[3,2]
415
+ # # [[1, 2],
416
+ # # [3, 4],
417
+ # # [3, 4]]
418
+
419
+ def repeat(arg,axis:nil)
420
+ case axis
421
+ when Integer
422
+ axis = check_axis(axis)
423
+ c = self
424
+ when NilClass
425
+ c = self.flatten
426
+ axis = 0
427
+ else
428
+ raise ArgumentError,"invalid axis"
429
+ end
430
+ case arg
431
+ when Integer
432
+ if !arg.kind_of?(Integer) || arg<1
433
+ raise ArgumentError,"argument should be positive integer"
434
+ end
435
+ idx = c.shape[axis].times.map{|i| [i]*arg}.flatten
436
+ else
437
+ arg = arg.to_a
438
+ if arg.size != c.shape[axis]
439
+ raise ArgumentError,"repeat size shoud be equal to size along axis"
440
+ end
441
+ arg.each do |i|
442
+ if !i.kind_of?(Integer) || i<0
443
+ raise ArgumentError,"argument should be non-negative integer"
444
+ end
445
+ end
446
+ idx = arg.each_with_index.map{|a,i| [i]*a}.flatten
447
+ end
448
+ ref = [true] * c.ndim
449
+ ref[axis] = idx
450
+ c[*ref].copy
451
+ end
452
+
453
+
454
+ def check_axis(axis)
455
+ if axis < 0
456
+ axis += ndim
457
+ end
458
+ if axis < 0 || axis >= ndim
459
+ raise ArgumentError,"invalid axis"
460
+ end
461
+ axis
462
+ end
463
+
464
+ end
465
+ end