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
@@ -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
  }