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
@@ -87,6 +87,8 @@ static VALUE
87
87
  volatile VALUE idx_1, view;
88
88
  narray_data_t *nidx;
89
89
  narray_view_t *nv;
90
+ narray_t *na;
91
+ narray_view_t *na1;
90
92
  stridx_t stridx0;
91
93
  size_t n_1;
92
94
  where_opt_t g;
@@ -112,6 +114,19 @@ static VALUE
112
114
  nv->stridx = ALLOC_N(stridx_t,1);
113
115
  nv->stridx[0] = stridx0;
114
116
  nv->offset = 0;
115
- nv->data = val;
117
+
118
+ GetNArray(val, na);
119
+ switch(NA_TYPE(na)) {
120
+ case NARRAY_DATA_T:
121
+ nv->data = val;
122
+ break;
123
+ case NARRAY_VIEW_T:
124
+ GetNArrayView(val, na1);
125
+ nv->data = na1->data;
126
+ break;
127
+ default:
128
+ rb_raise(rb_eRuntimeError,"invalid NA_TYPE: %d",NA_TYPE(na));
129
+ }
130
+
116
131
  return view;
117
132
  }
@@ -1,5 +1,104 @@
1
+ static void
2
+ <%=c_iter%>(na_loop_t *const lp)
3
+ {
4
+ size_t i, n;
5
+ size_t i1, n1;
6
+ VALUE v1, *ptr;
7
+ BIT_DIGIT *a1;
8
+ size_t p1;
9
+ size_t s1, *idx1;
10
+ VALUE x;
11
+ double y;
12
+ BIT_DIGIT z;
13
+ size_t len, c;
14
+ double beg, step;
15
+
16
+ INIT_COUNTER(lp, n);
17
+ INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
18
+ v1 = lp->args[1].value;
19
+ i = 0;
20
+
21
+ if (lp->args[1].ptr) {
22
+ if (v1 == Qtrue) {
23
+ iter_<%=tp%>_store_<%=tp%>(lp);
24
+ i = lp->args[1].shape[0];
25
+ if (idx1) {
26
+ idx1 += i;
27
+ } else {
28
+ p1 += s1 * i;
29
+ }
30
+ }
31
+ goto loop_end;
32
+ }
33
+
34
+ ptr = &v1;
35
+
36
+ switch(TYPE(v1)) {
37
+ case T_ARRAY:
38
+ n1 = RARRAY_LEN(v1);
39
+ ptr = RARRAY_PTR(v1);
40
+ break;
41
+ case T_NIL:
42
+ n1 = 0;
43
+ break;
44
+ default:
45
+ n1 = 1;
46
+ }
47
+
48
+ if (idx1) {
49
+ for (i=i1=0; i1<n1 && i<n; i++,i1++) {
50
+ x = ptr[i1];
51
+ if (rb_obj_is_kind_of(x, rb_cRange) || rb_obj_is_kind_of(x, na_cStep)) {
52
+ nary_step_sequence(x,&len,&beg,&step);
53
+ for (c=0; c<len && i<n; c++,i++) {
54
+ y = beg + step * c;
55
+ z = m_from_double(y);
56
+ STORE_BIT(a1, p1+*idx1, z); idx1++;
57
+ }
58
+ }
59
+ if (TYPE(x) != T_ARRAY) {
60
+ if (x == Qnil) x = INT2FIX(0);
61
+ z = m_num_to_data(x);
62
+ STORE_BIT(a1, p1+*idx1, z); idx1++;
63
+ }
64
+ }
65
+ } else {
66
+ for (i=i1=0; i1<n1 && i<n; i++,i1++) {
67
+ x = ptr[i1];
68
+ if (rb_obj_is_kind_of(x, rb_cRange) || rb_obj_is_kind_of(x, na_cStep)) {
69
+ nary_step_sequence(x,&len,&beg,&step);
70
+ for (c=0; c<len && i<n; c++,i++) {
71
+ y = beg + step * c;
72
+ z = m_from_double(y);
73
+ STORE_BIT(a1, p1, z); p1+=s1;
74
+ }
75
+ }
76
+ if (TYPE(x) != T_ARRAY) {
77
+ z = m_num_to_data(x);
78
+ STORE_BIT(a1, p1, z); p1+=s1;
79
+ }
80
+ }
81
+ }
82
+
83
+ loop_end:
84
+ z = m_zero;
85
+ if (idx1) {
86
+ for (; i<n; i++) {
87
+ STORE_BIT(a1, p1+*idx1, z); idx1++;
88
+ }
89
+ } else {
90
+ for (; i<n; i++) {
91
+ STORE_BIT(a1, p1, z); p1+=s1;
92
+ }
93
+ }
94
+ }
95
+
1
96
  static VALUE
2
- <%=c_func%>(VALUE self, VALUE obj)
97
+ <%=c_func%>(VALUE self, VALUE rary)
3
98
  {
4
- return <%=find_tmpl("store").c_func%>(self,<%=find_tmpl("cast_array").c_func%>(obj));
99
+ ndfunc_arg_in_t ain[2] = {{OVERWRITE,0}, {rb_cArray,0}};
100
+ ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 2, 0, ain, 0};
101
+
102
+ na_ndloop_store_rarray(&ndf, self, rary);
103
+ return self;
5
104
  }
@@ -16,14 +16,13 @@ iter_bit_where(na_loop_t *const lp)
16
16
  ssize_t s;
17
17
  size_t *idx;
18
18
  BIT_DIGIT x=0;
19
- char *idx0, *idx1;
19
+ char *idx1;
20
20
  size_t count;
21
21
  size_t e;
22
22
  where_opt_t *g;
23
23
 
24
24
  g = (where_opt_t*)(lp->opt_ptr);
25
25
  count = g->count;
26
- idx0 = g->idx0;
27
26
  idx1 = g->idx1;
28
27
  e = g->elmsz;
29
28
  INIT_COUNTER(lp, i);
@@ -32,16 +31,9 @@ iter_bit_where(na_loop_t *const lp)
32
31
  for (; i--;) {
33
32
  LOAD_BIT(a, p+*idx, x);
34
33
  idx++;
35
- if (x==0) {
36
- if (idx0) {
37
- STORE_INT(idx0,e,count);
38
- idx0 += e;
39
- }
40
- } else {
41
- if (idx1) {
42
- STORE_INT(idx1,e,count);
43
- idx1 += e;
44
- }
34
+ if (x!=0) {
35
+ STORE_INT(idx1,e,count);
36
+ idx1 += e;
45
37
  }
46
38
  count++;
47
39
  }
@@ -49,22 +41,14 @@ iter_bit_where(na_loop_t *const lp)
49
41
  for (; i--;) {
50
42
  LOAD_BIT(a, p, x);
51
43
  p+=s;
52
- if (x==0) {
53
- if (idx0) {
54
- STORE_INT(idx0,e,count);
55
- idx0 += e;
56
- }
57
- } else {
58
- if (idx1) {
59
- STORE_INT(idx1,e,count);
60
- idx1 += e;
61
- }
44
+ if (x!=0) {
45
+ STORE_INT(idx1,e,count);
46
+ idx1 += e;
62
47
  }
63
48
  count++;
64
49
  }
65
50
  }
66
51
  g->count = count;
67
- g->idx0 = idx0;
68
52
  g->idx1 = idx1;
69
53
  }
70
54
 
@@ -1,3 +1,56 @@
1
+ static void
2
+ iter_bit_where2(na_loop_t *const lp)
3
+ {
4
+ size_t i;
5
+ BIT_DIGIT *a;
6
+ size_t p;
7
+ ssize_t s;
8
+ size_t *idx;
9
+ BIT_DIGIT x=0;
10
+ char *idx0, *idx1;
11
+ size_t count;
12
+ size_t e;
13
+ where_opt_t *g;
14
+
15
+ g = (where_opt_t*)(lp->opt_ptr);
16
+ count = g->count;
17
+ idx0 = g->idx0;
18
+ idx1 = g->idx1;
19
+ e = g->elmsz;
20
+ INIT_COUNTER(lp, i);
21
+ INIT_PTR_BIT_IDX(lp, 0, a, p, s, idx);
22
+ if (idx) {
23
+ for (; i--;) {
24
+ LOAD_BIT(a, p+*idx, x);
25
+ idx++;
26
+ if (x==0) {
27
+ STORE_INT(idx0,e,count);
28
+ idx0 += e;
29
+ } else {
30
+ STORE_INT(idx1,e,count);
31
+ idx1 += e;
32
+ }
33
+ count++;
34
+ }
35
+ } else {
36
+ for (; i--;) {
37
+ LOAD_BIT(a, p, x);
38
+ p+=s;
39
+ if (x==0) {
40
+ STORE_INT(idx0,e,count);
41
+ idx0 += e;
42
+ } else {
43
+ STORE_INT(idx1,e,count);
44
+ idx1 += e;
45
+ }
46
+ count++;
47
+ }
48
+ }
49
+ g->count = count;
50
+ g->idx0 = idx0;
51
+ g->idx1 = idx1;
52
+ }
53
+
1
54
  /*
2
55
  Returns two index arrays.
3
56
  The first array contains index where the bit is one (true).
@@ -9,23 +62,24 @@ static VALUE
9
62
  numo_bit_where2(VALUE self)
10
63
  {
11
64
  VALUE idx_1, idx_0;
12
- size_t size, n_1;
65
+ size_t size, n_1, n_0;
13
66
  where_opt_t *g;
14
67
 
15
68
  ndfunc_arg_in_t ain[1] = {{cT,0}};
16
- ndfunc_t ndf = { iter_bit_where, FULL_LOOP, 1, 0, ain, 0 };
69
+ ndfunc_t ndf = { iter_bit_where2, FULL_LOOP, 1, 0, ain, 0 };
17
70
 
18
71
  size = RNARRAY_SIZE(self);
19
72
  n_1 = NUM2SIZET(numo_bit_count_true(0, NULL, self));
73
+ n_0 = size - n_1;
20
74
  g = ALLOCA_N(where_opt_t,1);
21
75
  g->count = 0;
22
76
  if (size>4294967295ul) {
23
77
  idx_1 = rb_narray_new(numo_cInt64, 1, &n_1);
24
- idx_0 = rb_narray_new(numo_cInt64, 1, &n_1);
78
+ idx_0 = rb_narray_new(numo_cInt64, 1, &n_0);
25
79
  g->elmsz = 8;
26
80
  } else {
27
81
  idx_1 = rb_narray_new(numo_cInt32, 1, &n_1);
28
- idx_0 = rb_narray_new(numo_cInt32, 1, &n_1);
82
+ idx_0 = rb_narray_new(numo_cInt32, 1, &n_0);
29
83
  g->elmsz = 4;
30
84
  }
31
85
  g->idx1 = na_get_pointer_for_write(idx_1);
@@ -2,11 +2,6 @@
2
2
  index.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
  //#define NARRAY_C
12
7
 
@@ -21,6 +16,24 @@
21
16
  #define cIndex numo_cInt32
22
17
  #endif
23
18
 
19
+ // from ruby/enumerator.c
20
+ struct enumerator {
21
+ VALUE obj;
22
+ ID meth;
23
+ VALUE args;
24
+ // use only above in this source
25
+ VALUE fib;
26
+ VALUE dst;
27
+ VALUE lookahead;
28
+ VALUE feedvalue;
29
+ VALUE stop_exc;
30
+ VALUE size;
31
+ // incompatible below depending on ruby version
32
+ //VALUE procs; // ruby 2.4
33
+ //rb_enumerator_size_func *size_fn; // ruby 2.1-2.4
34
+ //VALUE (*size_fn)(ANYARGS); // ruby 2.0
35
+ };
36
+
24
37
  // note: the memory refed by this pointer is not freed and causes memroy leak.
25
38
  typedef struct {
26
39
  size_t n; // the number of elements of the dimesnion
@@ -58,49 +71,10 @@ static VALUE sym_plus;
58
71
  static VALUE sym_sum;
59
72
  static VALUE sym_tilde;
60
73
  static VALUE sym_rest;
61
- static VALUE id_beg;
62
- static VALUE id_end;
63
- static VALUE id_exclude_end;
64
-
65
- static int
66
- na_index_preprocess(VALUE args, int na_ndim)
67
- {
68
- int i;
69
- int count_new=0, count_rest=0;
70
- int count_other_indices;
71
- int nidx = RARRAY_LEN(args);
72
- VALUE a;
73
-
74
- for (i=0; i<nidx; i++) {
75
- a = rb_ary_entry(args, i);
76
-
77
- if (a==sym_new || a==sym_minus) {
78
- RARRAY_ASET(args, i, sym_new);
79
- count_new++;
80
- } else if (a==sym_rest || a==sym_tilde || a==Qfalse) {
81
- RARRAY_ASET(args, i, Qfalse);
82
- count_rest++;
83
- }
84
- }
85
-
86
- count_other_indices = nidx - count_new - count_rest;
87
-
88
- if (count_rest>1) {
89
- rb_raise(rb_eIndexError,"multiple rest-dimension is not allowd");
90
- }
91
- else if (count_rest==0) {
92
- // if (!(count_new==0 && nidx==1) && ..
93
- if (count_other_indices != 1 && count_other_indices != na_ndim)
94
- rb_raise(rb_eIndexError,"# of index(=%i) should be one or "
95
- "equal to narray.ndim(=%i)",count_rest,na_ndim);
96
- }
97
- else if (count_rest==1) {
98
- if (count_other_indices >= na_ndim)
99
- rb_raise(rb_eIndexError,"# of index(=%i) >= narray.ndim(=%i) with :rest",
100
- count_other_indices,na_ndim);
101
- }
102
- return count_new;
103
- }
74
+ static ID id_beg;
75
+ static ID id_end;
76
+ static ID id_exclude_end;
77
+ static ID id_each, id_step;
104
78
 
105
79
 
106
80
  void
@@ -114,7 +88,6 @@ na_index_set_step(na_index_arg_t *q, int i, size_t n, size_t beg, ssize_t step)
114
88
  q->orig_dim = i;
115
89
  }
116
90
 
117
-
118
91
  void
119
92
  na_index_set_scalar(na_index_arg_t *q, int i, ssize_t size, ssize_t x)
120
93
  {
@@ -167,18 +140,24 @@ na_parse_narray_index(VALUE a, int orig_dim, ssize_t size, na_index_arg_t *q)
167
140
  VALUE idx;
168
141
  narray_t *na;
169
142
  narray_data_t *nidx;
143
+ size_t k, n;
144
+ ssize_t *nidxp;
170
145
 
171
146
  GetNArray(a,na);
172
147
  if (NA_NDIM(na) != 1) {
173
148
  rb_raise(rb_eIndexError, "should be 1-d NArray");
174
149
  }
175
- idx = rb_narray_new(cIndex,1,&NA_SIZE(na));
150
+ n = NA_SIZE(na);
151
+ idx = rb_narray_new(cIndex,1,&n);
176
152
  na_store(idx,a);
177
153
 
178
154
  GetNArrayData(idx,nidx);
179
- q->idx = (size_t*)nidx->ptr;
180
- nidx->ptr = NULL;
181
- q->n = na->size;
155
+ nidxp = (ssize_t*)nidx->ptr;
156
+ q->idx = ALLOC_N(size_t, n);
157
+ for (k=0; k<n; k++) {
158
+ q->idx[k] = na_range_check(nidxp[k], size, orig_dim);
159
+ }
160
+ q->n = n;
182
161
  q->beg = 0;
183
162
  q->step = 1;
184
163
  q->reduce = 0;
@@ -186,7 +165,7 @@ na_parse_narray_index(VALUE a, int orig_dim, ssize_t size, na_index_arg_t *q)
186
165
  }
187
166
 
188
167
  static void
189
- na_parse_range(VALUE range, int orig_dim, ssize_t size, na_index_arg_t *q)
168
+ na_parse_range(VALUE range, ssize_t step, int orig_dim, ssize_t size, na_index_arg_t *q)
190
169
  {
191
170
  int n;
192
171
  ssize_t beg, end;
@@ -210,10 +189,44 @@ na_parse_range(VALUE range, int orig_dim, ssize_t size, na_index_arg_t *q)
210
189
  "beg=%"SZF"d,end=%"SZF"d is out of array size (%"SZF"d)",
211
190
  beg, end, size);
212
191
  }
213
- n = end-beg+1;
192
+ n = (end-beg)/step+1;
214
193
  if (n<0) n=0;
215
- na_index_set_step(q,orig_dim,n,beg,1);
194
+ na_index_set_step(q,orig_dim,n,beg,step);
195
+
196
+ }
197
+
198
+ static void
199
+ na_parse_enumerator(VALUE enum_obj, int orig_dim, ssize_t size, na_index_arg_t *q)
200
+ {
201
+ int len;
202
+ ssize_t step;
203
+ struct enumerator *e;
204
+
205
+ if (!RB_TYPE_P(enum_obj, T_DATA)) {
206
+ rb_raise(rb_eTypeError,"wrong argument type (not T_DATA)");
207
+ }
208
+ e = (struct enumerator *)DATA_PTR(enum_obj);
216
209
 
210
+ if (rb_obj_is_kind_of(e->obj, rb_cRange)) {
211
+ if (e->meth == id_each) {
212
+ na_parse_range(e->obj, 1, orig_dim, size, q);
213
+ }
214
+ else if (e->meth == id_step) {
215
+ if (TYPE(e->args) != T_ARRAY) {
216
+ rb_raise(rb_eArgError,"no argument for step");
217
+ }
218
+ len = RARRAY_LEN(e->args);
219
+ if (len != 1) {
220
+ rb_raise(rb_eArgError,"invalid number of step argument (1 for %d)",len);
221
+ }
222
+ step = NUM2SSIZET(RARRAY_AREF(e->args,0));
223
+ na_parse_range(e->obj, step, orig_dim, size, q);
224
+ } else {
225
+ rb_raise(rb_eTypeError,"unknown Range method: %s",rb_id2name(e->meth));
226
+ }
227
+ } else {
228
+ rb_raise(rb_eTypeError,"not Range object");
229
+ }
217
230
  }
218
231
 
219
232
  // Analyze *a* which is *i*-th index object and store the information to q
@@ -268,7 +281,10 @@ na_index_parse_each(volatile VALUE a, ssize_t size, int i, na_index_arg_t *q)
268
281
 
269
282
  default:
270
283
  if (rb_obj_is_kind_of(a, rb_cRange)) {
271
- na_parse_range(a, i, size, q);
284
+ na_parse_range(a, 1, i, size, q);
285
+ }
286
+ else if (rb_obj_is_kind_of(a, rb_cEnumerator)) {
287
+ na_parse_enumerator(a, i, size, q);
272
288
  }
273
289
  else if (rb_obj_is_kind_of(a, na_cStep)) {
274
290
  ssize_t beg, step, n;
@@ -297,9 +313,10 @@ na_index_parse_args(VALUE args, narray_t *na, na_index_arg_t *q, int ndim)
297
313
 
298
314
  for (i=j=k=0; i<nidx; i++) {
299
315
  v = RARRAY_AREF(args,i);
300
- // rest dimension
316
+ // rest (ellipsis) dimension
301
317
  if (v==Qfalse) {
302
318
  for (l = ndim - (nidx-1); l>0; l--) {
319
+ //printf("i=%d j=%d k=%d l=%d ndim=%d nidx=%d\n",i,j,k,l,ndim,nidx);
303
320
  na_index_parse_each(Qtrue, na->shape[k], k, &q[j]);
304
321
  if (q[j].n > 1) {
305
322
  total *= q[j].n;
@@ -555,8 +572,9 @@ VALUE na_aref_md_protected(VALUE data_value)
555
572
  na2->data = self;
556
573
  break;
557
574
  case NARRAY_VIEW_T:
558
- na_index_aref_naview((narray_view_t *)na1,na2,q,ndim,keep_dim);
575
+ na2->offset = ((narray_view_t *)na1)->offset;
559
576
  na2->data = ((narray_view_t *)na1)->data;
577
+ na_index_aref_naview((narray_view_t *)na1,na2,q,ndim,keep_dim);
560
578
  break;
561
579
  }
562
580
  if (store) {
@@ -580,11 +598,10 @@ na_aref_md_ensure(VALUE data_value)
580
598
  }
581
599
 
582
600
  VALUE
583
- na_aref_md(int argc, VALUE *argv, VALUE self, int keep_dim)
601
+ na_aref_md(int argc, VALUE *argv, VALUE self, int keep_dim, int result_nd)
584
602
  {
585
603
  VALUE args; // should be GC protected
586
604
  narray_t *na1;
587
- int count_new, ndim;
588
605
  na_aref_md_data_t data;
589
606
  VALUE store = 0;
590
607
  VALUE idx;
@@ -592,14 +609,10 @@ na_aref_md(int argc, VALUE *argv, VALUE self, int keep_dim)
592
609
 
593
610
  GetNArray(self,na1);
594
611
 
595
- //printf("argc=%d\n",argc);
596
-
597
612
  args = rb_ary_new4(argc,argv);
598
613
 
599
- count_new = na_index_preprocess(args, na1->ndim);
600
-
601
- if (RARRAY_LEN(args)==1) {
602
- idx = RARRAY_AREF(args,0);
614
+ if (argc == 1 && result_nd == 1) {
615
+ idx = argv[0];
603
616
  if (rb_obj_is_kind_of(idx, rb_cArray)) {
604
617
  idx = rb_apply(numo_cNArray,rb_intern("[]"),idx);
605
618
  }
@@ -612,16 +625,17 @@ na_aref_md(int argc, VALUE *argv, VALUE self, int keep_dim)
612
625
  }
613
626
  }
614
627
  // flatten should be done only for narray-view with non-uniform stride.
615
- self = na_flatten(self);
616
- GetNArray(self,na1);
628
+ if (na1->ndim > 1) {
629
+ self = na_flatten(self);
630
+ GetNArray(self,na1);
631
+ }
617
632
  }
618
- ndim = na1->ndim + count_new;
619
633
 
620
634
  data.args = args;
621
635
  data.self = self;
622
636
  data.store = store;
623
- data.ndim = ndim;
624
- data.q = na_allocate_index_args(ndim);
637
+ data.ndim = result_nd;
638
+ data.q = na_allocate_index_args(result_nd);
625
639
  data.na1 = na1;
626
640
  data.keep_dim = keep_dim;
627
641
 
@@ -629,11 +643,9 @@ na_aref_md(int argc, VALUE *argv, VALUE self, int keep_dim)
629
643
  }
630
644
 
631
645
 
632
-
633
-
634
646
  /* method: [](idx1,idx2,...,idxN) */
635
647
  VALUE
636
- na_aref_main(int nidx, VALUE *idx, VALUE self, int keep_dim)
648
+ na_aref_main(int nidx, VALUE *idx, VALUE self, int keep_dim, int nd)
637
649
  {
638
650
  na_index_arg_to_internal_order(nidx, idx, self);
639
651
 
@@ -645,118 +657,111 @@ na_aref_main(int nidx, VALUE *idx, VALUE self, int keep_dim)
645
657
  return rb_funcall(*idx,rb_intern("mask"),1,self);
646
658
  }
647
659
  }
648
- return na_aref_md(nidx, idx, self, keep_dim);
649
- }
650
-
651
-
652
- /* method: [](idx1,idx2,...,idxN) */
653
- static VALUE na_aref(int argc, VALUE *argv, VALUE self)
654
- {
655
- VALUE view;
656
- view = na_aref_main(argc, argv, self, 0);
657
- return rb_funcall(view, rb_intern("extract"), 0);
660
+ return na_aref_md(nidx, idx, self, keep_dim, nd);
658
661
  }
659
662
 
660
663
 
661
664
  /* method: slice(idx1,idx2,...,idxN) */
662
665
  static VALUE na_slice(int argc, VALUE *argv, VALUE self)
663
666
  {
664
- return na_aref_main(argc, argv, self, 1);
665
- }
666
-
667
-
668
-
667
+ int nd;
668
+ size_t pos;
669
669
 
670
- /* method: []=(idx1,idx2,...,idxN,val) */
671
- static VALUE
672
- na_aset(int argc, VALUE *argv, VALUE self)
673
- {
674
- VALUE a;
675
- argc--;
676
-
677
- if (argc==0)
678
- na_store(self, argv[argc]);
679
- else {
680
- a = na_aref_main(argc, argv, self, 0);
681
- na_store(a, argv[argc]);
682
- }
683
- return argv[argc];
670
+ nd = na_get_result_dimension(self, argc, argv, 0, &pos);
671
+ return na_aref_main(argc, argv, self, 1, nd);
684
672
  }
685
673
 
686
674
 
687
- // convert reduce dims to 0-th element
688
- // for initialization of min/max func
689
- // ['*,+,*'] -> [true,0,true]
690
- VALUE nary_init_accum_aref0(VALUE self, VALUE reduce)
675
+ static int
676
+ check_index_count(int argc, int na_ndim, int count_new, int count_rest)
691
677
  {
692
- narray_t *na;
693
- VALUE a;
694
- ID id_bra;
695
- unsigned long m;
696
- int i, ndim;
697
-
698
- GetNArray(self,na);
699
- ndim = na->ndim;
700
- a = rb_ary_new();
701
- if (FIXNUM_P(reduce)) {
702
- m = NUM2ULONG(reduce);
703
- if (m==0)
704
- for (i=0; i<ndim; i++)
705
- rb_ary_push(a,INT2FIX(0));
706
- else
707
- for (i=0; i<ndim; i++)
708
- if ((m>>i) & 1u)
709
- rb_ary_push(a,INT2FIX(0));
710
- else
711
- rb_ary_push(a,Qtrue);
712
- } else {
713
- id_bra = rb_intern("[]");
714
- for (i=0; i<ndim; i++)
715
- if (rb_funcall(reduce,id_bra,1,INT2FIX(i)) == INT2FIX(1))
716
- rb_ary_push(a,INT2FIX(0));
717
- else
718
- rb_ary_push(a,Qtrue);
678
+ int result_nd = na_ndim + count_new;
679
+
680
+ switch(count_rest) {
681
+ case 0:
682
+ if (count_new == 0 && argc == 1) return 1;
683
+ if (argc == result_nd) return result_nd;
684
+ rb_raise(rb_eIndexError,"# of index(=%i) should be "
685
+ "equal to ndim(=%i)",argc,na_ndim);
686
+ break;
687
+ case 1:
688
+ if (argc-1 <= result_nd) return result_nd;
689
+ rb_raise(rb_eIndexError,"# of index(=%i) > ndim(=%i) with :rest",
690
+ argc,na_ndim);
691
+ break;
719
692
  }
720
- return na_aref_md(RARRAY_LEN(a), RARRAY_PTR(a), self, 0);
693
+ return -1;
721
694
  }
722
695
 
723
-
724
- ssize_t
725
- na_get_scalar_position(VALUE self, int argc, VALUE *argv, ssize_t stride)
696
+ int
697
+ na_get_result_dimension(VALUE self, int argc, VALUE *argv, ssize_t stride, size_t *pos_idx)
726
698
  {
727
- int i;
699
+ int i, j;
700
+ int count_new=0;
701
+ int count_rest=0;
702
+ int count_else=0;
728
703
  ssize_t x, s, m, pos, *idx;
729
704
  narray_t *na;
730
705
  narray_view_t *nv;
731
706
  stridx_t sdx;
707
+ VALUE a;
732
708
 
733
709
  GetNArray(self,na);
734
710
  if (na->size == 0) {
735
711
  rb_raise(rb_eRuntimeError, "cannot get index of empty array");
736
712
  return -1;
737
713
  }
738
- if (argc != 1 && argc != na->ndim) {
739
- return -1;
740
- }
741
714
  idx = ALLOCA_N(ssize_t, argc);
742
- for (i=0; i<argc; i++) {
743
- switch(TYPE(argv[i])) {
715
+ for (i=j=0; i<argc; i++) {
716
+ a = argv[i];
717
+ switch(TYPE(a)) {
744
718
  case T_FIXNUM:
745
- idx[i] = FIX2LONG(argv[i]);
719
+ idx[j++] = FIX2LONG(a);
746
720
  break;
747
721
  case T_BIGNUM:
748
722
  case T_FLOAT:
749
- idx[i] = NUM2SSIZET(argv[i]);
723
+ idx[j++] = NUM2SSIZET(a);
750
724
  break;
725
+ case T_FALSE:
726
+ case T_SYMBOL:
727
+ if (a==sym_rest || a==sym_tilde || a==Qfalse) {
728
+ argv[i] = Qfalse;
729
+ count_rest++;
730
+ break;
731
+ } else if (a==sym_new || a==sym_minus) {
732
+ argv[i] = sym_new;
733
+ count_new++;
734
+ }
735
+ // not break
751
736
  default:
752
- return -1;
737
+ count_else++;
753
738
  }
754
739
  }
740
+
741
+ if (count_rest > 1) {
742
+ rb_raise(rb_eIndexError,"multiple rest-dimension is not allowd");
743
+ }
744
+ if (count_else != 0) {
745
+ return check_index_count(argc, na->ndim, count_new, count_rest);
746
+ }
747
+
755
748
  switch(na->type) {
756
749
  case NARRAY_VIEW_T:
757
750
  GetNArrayView(self,nv);
758
751
  pos = nv->offset;
759
- if (argc==1) {
752
+ if (j == na->ndim) {
753
+ for (i=j-1; i>=0; i--) {
754
+ x = na_range_check(idx[i], na->shape[i], i);
755
+ sdx = nv->stridx[i];
756
+ if (SDX_IS_INDEX(sdx)) {
757
+ pos += SDX_GET_INDEX(sdx)[x];
758
+ } else {
759
+ pos += SDX_GET_STRIDE(sdx)*x;
760
+ }
761
+ }
762
+ *pos_idx = pos;
763
+ }
764
+ else if (argc==1 && j==1) {
760
765
  x = na_range_check(idx[0], na->size, 0);
761
766
  for (i=na->ndim-1; i>=0; i--) {
762
767
  s = na->shape[i];
@@ -769,44 +774,39 @@ na_get_scalar_position(VALUE self, int argc, VALUE *argv, ssize_t stride)
769
774
  pos += SDX_GET_STRIDE(sdx)*m;
770
775
  }
771
776
  }
777
+ *pos_idx = pos;
772
778
  } else {
773
- for (i=argc-1; i>=0; i--) {
774
- x = na_range_check(idx[i], na->shape[i], i);
775
- sdx = nv->stridx[i];
776
- if (SDX_IS_INDEX(sdx)) {
777
- pos += SDX_GET_INDEX(sdx)[x];
778
- } else {
779
- pos += SDX_GET_STRIDE(sdx)*x;
780
- }
781
- }
779
+ return check_index_count(argc, na->ndim, count_new, count_rest);
782
780
  }
783
781
  break;
784
782
  default:
785
783
  if (!stride) {
786
784
  stride = na_get_elmsz(self);
787
785
  }
788
- if (argc==1) {
786
+ if (argc==1 && j==1) {
789
787
  x = na_range_check(idx[0], na->size, 0);
790
- pos = stride*x;
791
- } else {
788
+ *pos_idx = stride * x;
789
+ }
790
+ else if (j == na->ndim) {
792
791
  pos = 0;
793
- for (i=argc-1; i>=0; i--) {
792
+ for (i=j-1; i>=0; i--) {
794
793
  x = na_range_check(idx[i], na->shape[i], i);
795
- pos += stride*x;
794
+ pos += stride * x;
796
795
  stride *= na->shape[i];
797
796
  }
797
+ *pos_idx = pos;
798
+ } else {
799
+ return check_index_count(argc, na->ndim, count_new, count_rest);
798
800
  }
799
801
  }
800
- return pos;
802
+ return 0;
801
803
  }
802
804
 
803
805
 
804
806
  void
805
807
  Init_nary_index()
806
808
  {
807
- rb_define_method(cNArray, "[]", na_aref, -1);
808
809
  rb_define_method(cNArray, "slice", na_slice, -1);
809
- rb_define_method(cNArray, "[]=", na_aset, -1);
810
810
 
811
811
  sym_ast = ID2SYM(rb_intern("*"));
812
812
  sym_all = ID2SYM(rb_intern("all"));
@@ -821,4 +821,6 @@ Init_nary_index()
821
821
  id_beg = rb_intern("begin");
822
822
  id_end = rb_intern("end");
823
823
  id_exclude_end = rb_intern("exclude_end?");
824
+ id_each = rb_intern("each");
825
+ id_step = rb_intern("step");
824
826
  }