numo-narray 0.9.0.3 → 0.9.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -6
  3. data/Rakefile +2 -10
  4. data/ext/numo/narray/array.c +1 -6
  5. data/ext/numo/narray/data.c +3 -9
  6. data/ext/numo/narray/depend.erb +1 -1
  7. data/ext/numo/narray/extconf.rb +0 -1
  8. data/ext/numo/narray/gen/def/bit.rb +2 -0
  9. data/ext/numo/narray/gen/def/dcomplex.rb +2 -0
  10. data/ext/numo/narray/gen/def/dfloat.rb +2 -0
  11. data/ext/numo/narray/gen/def/int16.rb +2 -0
  12. data/ext/numo/narray/gen/def/int32.rb +2 -0
  13. data/ext/numo/narray/gen/def/int64.rb +2 -0
  14. data/ext/numo/narray/gen/def/int8.rb +2 -0
  15. data/ext/numo/narray/gen/def/robject.rb +2 -0
  16. data/ext/numo/narray/gen/def/scomplex.rb +2 -0
  17. data/ext/numo/narray/gen/def/sfloat.rb +2 -0
  18. data/ext/numo/narray/gen/def/uint16.rb +2 -0
  19. data/ext/numo/narray/gen/def/uint32.rb +2 -0
  20. data/ext/numo/narray/gen/def/uint64.rb +2 -0
  21. data/ext/numo/narray/gen/def/uint8.rb +2 -0
  22. data/ext/numo/narray/gen/dtype.erb.c +7 -7
  23. data/ext/numo/narray/gen/spec.rb +24 -2
  24. data/ext/numo/narray/gen/tmpl/accum_binary.c +6 -0
  25. data/ext/numo/narray/gen/tmpl/aref.c +6 -4
  26. data/ext/numo/narray/gen/tmpl/aset.c +6 -4
  27. data/ext/numo/narray/gen/tmpl/binary.c +4 -0
  28. data/ext/numo/narray/gen/tmpl/binary2.c +4 -0
  29. data/ext/numo/narray/gen/tmpl/bincount.c +180 -0
  30. data/ext/numo/narray/gen/tmpl/cast.c +4 -0
  31. data/ext/numo/narray/gen/tmpl/cast_array.c +3 -64
  32. data/ext/numo/narray/gen/tmpl/cond_binary.c +4 -0
  33. data/ext/numo/narray/gen/tmpl/inspect.c +4 -0
  34. data/ext/numo/narray/gen/tmpl/pow.c +4 -0
  35. data/ext/numo/narray/gen/tmpl/qsort.c +1 -7
  36. data/ext/numo/narray/gen/tmpl/rand.c +13 -2
  37. data/ext/numo/narray/gen/tmpl/rand_norm.c +89 -16
  38. data/ext/numo/narray/gen/tmpl/store.c +4 -0
  39. data/ext/numo/narray/gen/tmpl/store_array.c +99 -2
  40. data/ext/numo/narray/gen/tmpl_bit/allocate.c +1 -1
  41. data/ext/numo/narray/gen/tmpl_bit/aref.c +6 -4
  42. data/ext/numo/narray/gen/tmpl_bit/aset.c +6 -4
  43. data/ext/numo/narray/gen/tmpl_bit/cast_array.c +3 -65
  44. data/ext/numo/narray/gen/tmpl_bit/mask.c +16 -1
  45. data/ext/numo/narray/gen/tmpl_bit/store_array.c +101 -2
  46. data/ext/numo/narray/gen/tmpl_bit/where.c +7 -23
  47. data/ext/numo/narray/gen/tmpl_bit/where2.c +58 -4
  48. data/ext/numo/narray/index.c +168 -166
  49. data/ext/numo/narray/kwarg.c +1 -6
  50. data/ext/numo/narray/math.c +8 -12
  51. data/ext/numo/narray/narray.c +231 -71
  52. data/ext/numo/narray/ndloop.c +86 -26
  53. data/ext/numo/narray/numo/intern.h +6 -10
  54. data/ext/numo/narray/numo/narray.h +83 -54
  55. data/ext/numo/narray/numo/ndloop.h +0 -5
  56. data/ext/numo/narray/numo/template.h +0 -5
  57. data/ext/numo/narray/numo/types/complex.h +1 -6
  58. data/ext/numo/narray/numo/types/complex_macro.h +30 -3
  59. data/ext/numo/narray/numo/types/dcomplex.h +18 -0
  60. data/ext/numo/narray/numo/types/dfloat.h +18 -0
  61. data/ext/numo/narray/numo/types/float_macro.h +25 -2
  62. data/ext/numo/narray/numo/types/robj_macro.h +2 -4
  63. data/ext/numo/narray/numo/types/scomplex.h +18 -0
  64. data/ext/numo/narray/numo/types/sfloat.h +18 -0
  65. data/ext/numo/narray/rand.c +0 -15
  66. data/ext/numo/narray/step.c +0 -5
  67. data/ext/numo/narray/struct.c +7 -12
  68. data/lib/erbpp/line_number.rb +4 -4
  69. data/lib/erbpp/narray_def.rb +16 -7
  70. data/lib/numo/narray.rb +2 -0
  71. data/lib/numo/narray/extra.rb +465 -0
  72. data/numo-narray.gemspec +2 -2
  73. data/spec/narray_spec.rb +4 -3
  74. metadata +13 -7
  75. data/ext/numo/narray/gen/tmpl/head.c +0 -25
@@ -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