numo-narray 0.9.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +50 -0
  4. data/Rakefile +64 -0
  5. data/ext/numo/narray/SFMT-params.h +97 -0
  6. data/ext/numo/narray/SFMT-params19937.h +46 -0
  7. data/ext/numo/narray/SFMT.c +620 -0
  8. data/ext/numo/narray/SFMT.h +157 -0
  9. data/ext/numo/narray/array.c +525 -0
  10. data/ext/numo/narray/data.c +901 -0
  11. data/ext/numo/narray/depend.erb +33 -0
  12. data/ext/numo/narray/extconf.rb +118 -0
  13. data/ext/numo/narray/gen/bit.erb.c +811 -0
  14. data/ext/numo/narray/gen/cogen.rb +18 -0
  15. data/ext/numo/narray/gen/def/dcomplex.rb +32 -0
  16. data/ext/numo/narray/gen/def/dfloat.rb +30 -0
  17. data/ext/numo/narray/gen/def/int16.rb +29 -0
  18. data/ext/numo/narray/gen/def/int32.rb +29 -0
  19. data/ext/numo/narray/gen/def/int64.rb +29 -0
  20. data/ext/numo/narray/gen/def/int8.rb +29 -0
  21. data/ext/numo/narray/gen/def/robject.rb +30 -0
  22. data/ext/numo/narray/gen/def/scomplex.rb +32 -0
  23. data/ext/numo/narray/gen/def/sfloat.rb +30 -0
  24. data/ext/numo/narray/gen/def/uint16.rb +29 -0
  25. data/ext/numo/narray/gen/def/uint32.rb +29 -0
  26. data/ext/numo/narray/gen/def/uint64.rb +29 -0
  27. data/ext/numo/narray/gen/def/uint8.rb +29 -0
  28. data/ext/numo/narray/gen/dtype.erb.c +328 -0
  29. data/ext/numo/narray/gen/tmpl/accum.c +36 -0
  30. data/ext/numo/narray/gen/tmpl/accum_binary.c +75 -0
  31. data/ext/numo/narray/gen/tmpl/accum_index.c +58 -0
  32. data/ext/numo/narray/gen/tmpl/allocate.c +35 -0
  33. data/ext/numo/narray/gen/tmpl/aref.c +51 -0
  34. data/ext/numo/narray/gen/tmpl/aset.c +61 -0
  35. data/ext/numo/narray/gen/tmpl/binary.c +53 -0
  36. data/ext/numo/narray/gen/tmpl/binary2.c +55 -0
  37. data/ext/numo/narray/gen/tmpl/binary_s.c +34 -0
  38. data/ext/numo/narray/gen/tmpl/bit_binary.c +94 -0
  39. data/ext/numo/narray/gen/tmpl/bit_count.c +82 -0
  40. data/ext/numo/narray/gen/tmpl/bit_unary.c +77 -0
  41. data/ext/numo/narray/gen/tmpl/cast.c +37 -0
  42. data/ext/numo/narray/gen/tmpl/cast_array.c +79 -0
  43. data/ext/numo/narray/gen/tmpl/cast_numeric.c +22 -0
  44. data/ext/numo/narray/gen/tmpl/coerce_cast.c +8 -0
  45. data/ext/numo/narray/gen/tmpl/cond_binary.c +51 -0
  46. data/ext/numo/narray/gen/tmpl/cond_unary.c +45 -0
  47. data/ext/numo/narray/gen/tmpl/cum.c +42 -0
  48. data/ext/numo/narray/gen/tmpl/each.c +43 -0
  49. data/ext/numo/narray/gen/tmpl/each_with_index.c +64 -0
  50. data/ext/numo/narray/gen/tmpl/extract.c +23 -0
  51. data/ext/numo/narray/gen/tmpl/eye.c +91 -0
  52. data/ext/numo/narray/gen/tmpl/fill.c +38 -0
  53. data/ext/numo/narray/gen/tmpl/format.c +60 -0
  54. data/ext/numo/narray/gen/tmpl/format_to_a.c +47 -0
  55. data/ext/numo/narray/gen/tmpl/head.c +25 -0
  56. data/ext/numo/narray/gen/tmpl/inspect.c +16 -0
  57. data/ext/numo/narray/gen/tmpl/map_with_index.c +94 -0
  58. data/ext/numo/narray/gen/tmpl/median.c +44 -0
  59. data/ext/numo/narray/gen/tmpl/minmax.c +47 -0
  60. data/ext/numo/narray/gen/tmpl/poly.c +49 -0
  61. data/ext/numo/narray/gen/tmpl/pow.c +74 -0
  62. data/ext/numo/narray/gen/tmpl/powint.c +17 -0
  63. data/ext/numo/narray/gen/tmpl/qsort.c +149 -0
  64. data/ext/numo/narray/gen/tmpl/rand.c +33 -0
  65. data/ext/numo/narray/gen/tmpl/rand_norm.c +46 -0
  66. data/ext/numo/narray/gen/tmpl/robj_allocate.c +32 -0
  67. data/ext/numo/narray/gen/tmpl/seq.c +61 -0
  68. data/ext/numo/narray/gen/tmpl/set2.c +56 -0
  69. data/ext/numo/narray/gen/tmpl/sort.c +36 -0
  70. data/ext/numo/narray/gen/tmpl/sort_index.c +86 -0
  71. data/ext/numo/narray/gen/tmpl/store.c +31 -0
  72. data/ext/numo/narray/gen/tmpl/store_array.c +5 -0
  73. data/ext/numo/narray/gen/tmpl/store_from.c +53 -0
  74. data/ext/numo/narray/gen/tmpl/store_numeric.c +22 -0
  75. data/ext/numo/narray/gen/tmpl/to_a.c +41 -0
  76. data/ext/numo/narray/gen/tmpl/unary.c +58 -0
  77. data/ext/numo/narray/gen/tmpl/unary2.c +58 -0
  78. data/ext/numo/narray/gen/tmpl/unary_s.c +57 -0
  79. data/ext/numo/narray/index.c +822 -0
  80. data/ext/numo/narray/kwarg.c +79 -0
  81. data/ext/numo/narray/math.c +142 -0
  82. data/ext/numo/narray/narray.c +1541 -0
  83. data/ext/numo/narray/ndloop.c +1928 -0
  84. data/ext/numo/narray/numo/compat.h +23 -0
  85. data/ext/numo/narray/numo/intern.h +112 -0
  86. data/ext/numo/narray/numo/narray.h +411 -0
  87. data/ext/numo/narray/numo/ndloop.h +99 -0
  88. data/ext/numo/narray/numo/template.h +140 -0
  89. data/ext/numo/narray/numo/types/bit.h +19 -0
  90. data/ext/numo/narray/numo/types/complex.h +410 -0
  91. data/ext/numo/narray/numo/types/complex_macro.h +205 -0
  92. data/ext/numo/narray/numo/types/dcomplex.h +11 -0
  93. data/ext/numo/narray/numo/types/dfloat.h +12 -0
  94. data/ext/numo/narray/numo/types/float_def.h +34 -0
  95. data/ext/numo/narray/numo/types/float_macro.h +277 -0
  96. data/ext/numo/narray/numo/types/int16.h +12 -0
  97. data/ext/numo/narray/numo/types/int32.h +12 -0
  98. data/ext/numo/narray/numo/types/int64.h +12 -0
  99. data/ext/numo/narray/numo/types/int8.h +12 -0
  100. data/ext/numo/narray/numo/types/int_macro.h +34 -0
  101. data/ext/numo/narray/numo/types/robj_macro.h +218 -0
  102. data/ext/numo/narray/numo/types/robject.h +21 -0
  103. data/ext/numo/narray/numo/types/scomplex.h +11 -0
  104. data/ext/numo/narray/numo/types/sfloat.h +13 -0
  105. data/ext/numo/narray/numo/types/uint16.h +12 -0
  106. data/ext/numo/narray/numo/types/uint32.h +12 -0
  107. data/ext/numo/narray/numo/types/uint64.h +12 -0
  108. data/ext/numo/narray/numo/types/uint8.h +12 -0
  109. data/ext/numo/narray/numo/types/uint_macro.h +31 -0
  110. data/ext/numo/narray/numo/types/xint_macro.h +133 -0
  111. data/ext/numo/narray/rand.c +87 -0
  112. data/ext/numo/narray/step.c +506 -0
  113. data/ext/numo/narray/struct.c +871 -0
  114. data/lib/erbpp.rb +286 -0
  115. data/lib/erbpp/line_number.rb +126 -0
  116. data/lib/erbpp/narray_def.rb +342 -0
  117. data/lib/numo/narray.rb +6 -0
  118. data/numo-narray.gemspec +35 -0
  119. data/spec/bit_spec.rb +93 -0
  120. data/spec/narray_spec.rb +249 -0
  121. metadata +238 -0
@@ -0,0 +1,22 @@
1
+ static VALUE
2
+ numo_<%=tp%>_new_dim0(dtype x)
3
+ {
4
+ VALUE v;
5
+ dtype *ptr;
6
+
7
+ v = rb_narray_new(cT, 0, NULL);
8
+ ptr = (dtype*)(char*)na_get_pointer_for_write(v);
9
+ *ptr = x;
10
+ na_release_lock(v);
11
+ return v;
12
+ }
13
+
14
+ static VALUE
15
+ <%=c_func%>(VALUE self, VALUE obj)
16
+ {
17
+ dtype x;
18
+ x = m_num_to_data(obj);
19
+ obj = numo_<%=tp%>_new_dim0(x);
20
+ <%=find_tmpl("store").c_func%>(self,obj);
21
+ return self;
22
+ }
@@ -0,0 +1,41 @@
1
+ void
2
+ <%=c_iter%>(na_loop_t *const lp)
3
+ {
4
+ size_t i, s1;
5
+ char *p1;
6
+ size_t *idx1;
7
+ dtype x;
8
+ volatile VALUE a, y;
9
+
10
+ INIT_COUNTER(lp, i);
11
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
12
+ a = rb_ary_new2(i);
13
+ rb_ary_push(lp->args[1].value, a);
14
+ if (idx1) {
15
+ for (; i--;) {
16
+ GET_DATA_INDEX(p1,idx1,dtype,x);
17
+ y = m_data_to_num(x);
18
+ rb_ary_push(a,y);
19
+ }
20
+ } else {
21
+ for (; i--;) {
22
+ GET_DATA_STRIDE(p1,s1,dtype,x);
23
+ y = m_data_to_num(x);
24
+ rb_ary_push(a,y);
25
+ }
26
+ }
27
+ }
28
+
29
+ /*
30
+ Convert self to Array.
31
+ @overload <%=method%>
32
+ @return [Array]
33
+ */
34
+ static VALUE
35
+ <%=c_func%>(VALUE self)
36
+ {
37
+ ndfunc_arg_in_t ain[3] = {{Qnil,0},{sym_loop_opt},{sym_option}};
38
+ ndfunc_arg_out_t aout[1] = {{rb_cArray,0}}; // dummy?
39
+ ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP_NIP, 3, 1, ain, aout };
40
+ return na_ndloop_cast_narray_to_rarray(&ndf, self, Qnil);
41
+ }
@@ -0,0 +1,58 @@
1
+ static void
2
+ <%=c_iter%>(na_loop_t *const lp)
3
+ {
4
+ size_t i;
5
+ char *p1, *p2;
6
+ ssize_t s1, s2;
7
+ size_t *idx1, *idx2;
8
+ dtype x;
9
+
10
+ INIT_COUNTER(lp, i);
11
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
12
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
13
+
14
+ if (idx1) {
15
+ if (idx2) {
16
+ for (; i--;) {
17
+ GET_DATA_INDEX(p1,idx1,dtype,x);
18
+ x = m_<%=method%>(x);
19
+ SET_DATA_INDEX(p2,idx2,dtype,x);
20
+ }
21
+ } else {
22
+ for (; i--;) {
23
+ GET_DATA_INDEX(p1,idx1,dtype,x);
24
+ x = m_<%=method%>(x);
25
+ SET_DATA_STRIDE(p2,s2,dtype,x);
26
+ }
27
+ }
28
+ } else {
29
+ if (idx2) {
30
+ for (; i--;) {
31
+ GET_DATA_STRIDE(p1,s1,dtype,x);
32
+ x = m_<%=method%>(x);
33
+ SET_DATA_INDEX(p2,idx2,dtype,x);
34
+ }
35
+ } else {
36
+ for (; i--;) {
37
+ GET_DATA_STRIDE(p1,s1,dtype,x);
38
+ x = m_<%=method%>(x);
39
+ SET_DATA_STRIDE(p2,s2,dtype,x);
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ /*
46
+ Unary <%=method%>.
47
+ @overload <%=op_map%>
48
+ @return [Numo::<%=class_name%>] <%=method%> of self.
49
+ */
50
+ static VALUE
51
+ <%=c_func%>(VALUE self)
52
+ {
53
+ ndfunc_arg_in_t ain[1] = {{cT,0}};
54
+ ndfunc_arg_out_t aout[1] = {{cT,0}};
55
+ ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 1,1, ain,aout};
56
+
57
+ return na_ndloop(&ndf, 1, self);
58
+ }
@@ -0,0 +1,58 @@
1
+ static void
2
+ <%=c_iter%>(na_loop_t *const lp)
3
+ {
4
+ size_t i;
5
+ char *p1, *p2;
6
+ ssize_t s1, s2;
7
+ size_t *idx1, *idx2;
8
+ dtype x;
9
+ <%=dtype%> y;
10
+ INIT_COUNTER(lp, i);
11
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
12
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
13
+ if (idx1) {
14
+ if (idx2) {
15
+ for (; i--;) {
16
+ GET_DATA_INDEX(p1,idx1,dtype,x);
17
+ y = m_<%=method%>(x);
18
+ SET_DATA_INDEX(p2,idx2,<%=dtype%>,y);
19
+ }
20
+ } else {
21
+ for (; i--;) {
22
+ GET_DATA_INDEX(p1,idx1,dtype,x);
23
+ y = m_<%=method%>(x);
24
+ SET_DATA_STRIDE(p2,s2,<%=dtype%>,y);
25
+ }
26
+ }
27
+ } else {
28
+ if (idx2) {
29
+ for (; i--;) {
30
+ GET_DATA_STRIDE(p1,s1,dtype,x);
31
+ y = m_<%=method%>(x);
32
+ SET_DATA_INDEX(p2,idx2,<%=dtype%>,y);
33
+ }
34
+ } else {
35
+ for (; i--;) {
36
+ GET_DATA_STRIDE(p1,s1,dtype,x);
37
+ y = m_<%=method%>(x);
38
+ SET_DATA_STRIDE(p2,s2,<%=dtype%>,y);
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+
45
+ /*
46
+ <%=method%> of self.
47
+ @overload <%=method%>
48
+ @return [Numo::<%=real_class_name%>] <%=method%> of self.
49
+ */
50
+ static VALUE
51
+ <%=c_func%>(VALUE self)
52
+ {
53
+ ndfunc_arg_in_t ain[1] = {{cT,0}};
54
+ ndfunc_arg_out_t aout[1] = {{<%=tpclass%>,0}};
55
+ ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP, 1, 1, ain, aout };
56
+
57
+ return na_ndloop(&ndf, 1, self);
58
+ }
@@ -0,0 +1,57 @@
1
+ static void
2
+ <%=c_iter%>(na_loop_t *const lp)
3
+ {
4
+ size_t i;
5
+ char *p1, *p2;
6
+ ssize_t s1, s2;
7
+ size_t *idx1, *idx2;
8
+ dtype x;
9
+ INIT_COUNTER(lp, i);
10
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
11
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
12
+ if (idx1) {
13
+ if (idx2) {
14
+ for (; i--;) {
15
+ GET_DATA_INDEX(p1,idx1,dtype,x);
16
+ x = m_<%=method%>(x);
17
+ SET_DATA_INDEX(p2,idx2,dtype,x);
18
+ }
19
+ } else {
20
+ for (; i--;) {
21
+ GET_DATA_INDEX(p1,idx1,dtype,x);
22
+ x = m_<%=method%>(x);
23
+ SET_DATA_STRIDE(p2,s2,dtype,x);
24
+ }
25
+ }
26
+ } else {
27
+ if (idx2) {
28
+ for (; i--;) {
29
+ GET_DATA_STRIDE(p1,s1,dtype,x);
30
+ x = m_<%=method%>(x);
31
+ SET_DATA_INDEX(p2,idx2,dtype,x);
32
+ }
33
+ } else {
34
+ for (; i--;) {
35
+ GET_DATA_STRIDE(p1,s1,dtype,x);
36
+ x = m_<%=method%>(x);
37
+ SET_DATA_STRIDE(p2,s2,dtype,x);
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ /*
44
+ Calculate <%=method%>(x).
45
+ @overload <%=method%>(x)
46
+ @param [Numo::NArray,Numeric] x input value
47
+ @return [Numo::<%=class_name%>] result of <%=method%>(x).
48
+ */
49
+ static VALUE
50
+ <%=c_func%>(VALUE mod, VALUE a1)
51
+ {
52
+ ndfunc_arg_in_t ain[1] = {{cT,0}};
53
+ ndfunc_arg_out_t aout[1] = {{cT,0}};
54
+ ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP, 1, 1, ain, aout };
55
+
56
+ return na_ndloop(&ndf, 1, a1);
57
+ }
@@ -0,0 +1,822 @@
1
+ /*
2
+ index.c
3
+ Numerical Array Extension for Ruby
4
+ (C) Copyright 1999-2011 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
+ */
11
+ //#define NARRAY_C
12
+
13
+ #include <string.h>
14
+ #include <ruby.h>
15
+ #include "numo/narray.h"
16
+ #include "numo/template.h"
17
+
18
+ #if SIZEOF_VOIDP == 8
19
+ #define cIndex numo_cInt64
20
+ #elif SIZEOF_VOIDP == 4
21
+ #define cIndex numo_cInt32
22
+ #endif
23
+
24
+ // note: the memory refed by this pointer is not freed and causes memroy leak.
25
+ typedef struct {
26
+ size_t n; // the number of elements of the dimesnion
27
+ size_t beg; // the starting point in the dimension
28
+ ssize_t step; // the step size of the dimension
29
+ size_t *idx; // list of indices
30
+ int reduce; // true if the dimension is reduced by addition
31
+ int orig_dim; // the dimension of original array
32
+ } na_index_arg_t;
33
+
34
+
35
+ static void
36
+ print_index_arg(na_index_arg_t *q, int n)
37
+ {
38
+ int i;
39
+ printf("na_index_arg_t = 0x%"SZF"x {\n",(size_t)q);
40
+ for (i=0; i<n; i++) {
41
+ printf(" q[%d].n=%"SZF"d\n",i,q[i].n);
42
+ printf(" q[%d].beg=%"SZF"d\n",i,q[i].beg);
43
+ printf(" q[%d].step=%"SZF"d\n",i,q[i].step);
44
+ printf(" q[%d].idx=0x%"SZF"x\n",i,(size_t)q[i].idx);
45
+ printf(" q[%d].reduce=0x%x\n",i,q[i].reduce);
46
+ printf(" q[%d].orig_dim=%d\n",i,q[i].orig_dim);
47
+ }
48
+ printf("}\n");
49
+ }
50
+
51
+ static VALUE sym_ast;
52
+ static VALUE sym_all;
53
+ //static VALUE sym_reduce;
54
+ static VALUE sym_minus;
55
+ static VALUE sym_new;
56
+ static VALUE sym_reverse;
57
+ static VALUE sym_plus;
58
+ static VALUE sym_sum;
59
+ static VALUE sym_tilde;
60
+ 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
+ }
104
+
105
+
106
+ void
107
+ na_index_set_step(na_index_arg_t *q, int i, size_t n, size_t beg, ssize_t step)
108
+ {
109
+ q->n = n;
110
+ q->beg = beg;
111
+ q->step = step;
112
+ q->idx = NULL;
113
+ q->reduce = 0;
114
+ q->orig_dim = i;
115
+ }
116
+
117
+
118
+ void
119
+ na_index_set_scalar(na_index_arg_t *q, int i, ssize_t size, ssize_t x)
120
+ {
121
+ if (x < -size || x >= size)
122
+ rb_raise(rb_eRangeError,
123
+ "array index (%"SZF"d) is out of array size (%"SZF"d)",
124
+ x, size);
125
+ if (x < 0)
126
+ x += size;
127
+ q->n = 1;
128
+ q->beg = x;
129
+ q->step = 0;
130
+ q->idx = NULL;
131
+ q->reduce = 0;
132
+ q->orig_dim = i;
133
+ }
134
+
135
+ static inline ssize_t
136
+ na_range_check(ssize_t pos, ssize_t size, int dim)
137
+ {
138
+ ssize_t idx=pos;
139
+
140
+ if (idx < 0) idx += size;
141
+ if (idx < 0 || idx >= size) {
142
+ rb_raise(rb_eIndexError, "index=%"SZF"d out of shape[%d]=%"SZF"d",
143
+ pos, dim, size);
144
+ }
145
+ return idx;
146
+ }
147
+
148
+ static void
149
+ na_parse_array(VALUE ary, int orig_dim, ssize_t size, na_index_arg_t *q)
150
+ {
151
+ int k;
152
+ int n = RARRAY_LEN(ary);
153
+ q->idx = ALLOC_N(size_t, n);
154
+ for (k=0; k<n; k++) {
155
+ q->idx[k] = na_range_check(NUM2SSIZE(RARRAY_AREF(ary,k)), size, orig_dim);
156
+ }
157
+ q->n = n;
158
+ q->beg = 0;
159
+ q->step = 1;
160
+ q->reduce = 0;
161
+ q->orig_dim = orig_dim;
162
+ }
163
+
164
+ static void
165
+ na_parse_narray_index(VALUE a, int orig_dim, ssize_t size, na_index_arg_t *q)
166
+ {
167
+ VALUE idx;
168
+ narray_t *na;
169
+ narray_data_t *nidx;
170
+
171
+ GetNArray(a,na);
172
+ if (NA_NDIM(na) != 1) {
173
+ rb_raise(rb_eIndexError, "should be 1-d NArray");
174
+ }
175
+ idx = rb_narray_new(cIndex,1,&NA_SIZE(na));
176
+ na_store(idx,a);
177
+
178
+ GetNArrayData(idx,nidx);
179
+ q->idx = (size_t*)nidx->ptr;
180
+ nidx->ptr = NULL;
181
+ q->n = na->size;
182
+ q->beg = 0;
183
+ q->step = 1;
184
+ q->reduce = 0;
185
+ q->orig_dim = orig_dim;
186
+ }
187
+
188
+ static void
189
+ na_parse_range(VALUE range, int orig_dim, ssize_t size, na_index_arg_t *q)
190
+ {
191
+ int n;
192
+ ssize_t beg, end;
193
+
194
+ beg = NUM2LONG(rb_funcall(range,id_beg,0));
195
+ if (beg<0) {
196
+ beg += size;
197
+ }
198
+
199
+ end = NUM2LONG(rb_funcall(range,id_end,0));
200
+ if (end<0) {
201
+ end += size;
202
+ }
203
+
204
+ if (RTEST(rb_funcall(range,id_exclude_end,0))) {
205
+ end--;
206
+ }
207
+ if (beg < -size || beg >= size ||
208
+ end < -size || end >= size) {
209
+ rb_raise(rb_eRangeError,
210
+ "beg=%ld,end=%ld is out of array size (%ld)",
211
+ beg, end, size);
212
+ }
213
+ n = end-beg+1;
214
+ if (n<0) n=0;
215
+ na_index_set_step(q,orig_dim,n,beg,1);
216
+
217
+ }
218
+
219
+ // Analyze *a* which is *i*-th index object and store the information to q
220
+ //
221
+ // a: a ruby object of i-th index
222
+ // size: size of i-th dimension of original NArray
223
+ // i: parse i-th index
224
+ // q: parsed information is stored to *q
225
+ static void
226
+ na_index_parse_each(volatile VALUE a, ssize_t size, int i, na_index_arg_t *q)
227
+ {
228
+ switch(TYPE(a)) {
229
+
230
+ case T_FIXNUM:
231
+ na_index_set_scalar(q,i,size,FIX2LONG(a));
232
+ break;
233
+
234
+ case T_BIGNUM:
235
+ na_index_set_scalar(q,i,size,NUM2SSIZE(a));
236
+ break;
237
+
238
+ case T_FLOAT:
239
+ na_index_set_scalar(q,i,size,NUM2SSIZE(a));
240
+ break;
241
+
242
+ case T_NIL:
243
+ case T_TRUE:
244
+ na_index_set_step(q,i,size,0,1);
245
+ break;
246
+
247
+ case T_SYMBOL:
248
+ if (a==sym_all || a==sym_ast) {
249
+ na_index_set_step(q,i,size,0,1);
250
+ }
251
+ else if (a==sym_reverse) {
252
+ na_index_set_step(q,i,size,size-1,-1);
253
+ }
254
+ else if (a==sym_new) {
255
+ na_index_set_step(q,i,1,0,1);
256
+ }
257
+ else if (a==sym_reduce || a==sym_sum || a==sym_plus) {
258
+ na_index_set_step(q,i,size,0,1);
259
+ q->reduce = 1;
260
+ }
261
+ break;
262
+
263
+ case T_ARRAY:
264
+ na_parse_array(a, i, size, q);
265
+ break;
266
+
267
+ default:
268
+ if (rb_obj_is_kind_of(a, rb_cRange)) {
269
+ na_parse_range(a, i, size, q);
270
+ }
271
+ else if (rb_obj_is_kind_of(a, na_cStep)) {
272
+ ssize_t beg, step, n;
273
+ nary_step_array_index(a, size, (size_t*)(&n), &beg, &step);
274
+ na_index_set_step(q,i,n,beg,step);
275
+ }
276
+ // NArray index
277
+ else if (NA_IsNArray(a)) {
278
+ na_parse_narray_index(a, i, size, q);
279
+ }
280
+ else {
281
+ rb_raise(rb_eIndexError, "not allowed type");
282
+ }
283
+ }
284
+ }
285
+
286
+
287
+ static size_t
288
+ na_index_parse_args(VALUE args, narray_t *na, na_index_arg_t *q, int ndim)
289
+ {
290
+ int i, j, k, l, nidx;
291
+ size_t total=1;
292
+ VALUE v;
293
+
294
+ nidx = RARRAY_LEN(args);
295
+
296
+ for (i=j=k=0; i<nidx; i++) {
297
+ v = RARRAY_AREF(args,i);
298
+ // rest dimension
299
+ if (v==Qfalse) {
300
+ for (l = ndim - (nidx-1); l>0; l--) {
301
+ na_index_parse_each(Qtrue, na->shape[k], k, &q[j]);
302
+ if (q[j].n > 1) {
303
+ total *= q[j].n;
304
+ }
305
+ j++;
306
+ k++;
307
+ }
308
+ }
309
+ // new dimension
310
+ else if (v==sym_new) {
311
+ na_index_parse_each(v, 1, k, &q[j]);
312
+ j++;
313
+ }
314
+ // other dimention
315
+ else {
316
+ na_index_parse_each(v, na->shape[k], k, &q[j]);
317
+ if (q[j].n > 1) {
318
+ total *= q[j].n;
319
+ }
320
+ j++;
321
+ k++;
322
+ }
323
+ }
324
+ return total;
325
+ }
326
+
327
+
328
+ static void
329
+ na_get_strides_nadata(const narray_data_t *na, ssize_t *strides, ssize_t elmsz)
330
+ {
331
+ int i = na->base.ndim - 1;
332
+ strides[i] = elmsz;
333
+ for (; i>0; i--) {
334
+ strides[i-1] = strides[i] * na->base.shape[i];
335
+ }
336
+ }
337
+
338
+ static void
339
+ na_index_aref_nadata(narray_data_t *na1, narray_view_t *na2,
340
+ na_index_arg_t *q, ssize_t elmsz, int ndim, int keep_dim)
341
+ {
342
+ int i, j;
343
+ ssize_t size, k, total=1;
344
+ ssize_t stride1;
345
+ ssize_t *strides_na1;
346
+ size_t *index;
347
+ ssize_t beg, step;
348
+ VALUE m;
349
+
350
+ strides_na1 = ALLOCA_N(ssize_t, na1->base.ndim);
351
+ na_get_strides_nadata(na1, strides_na1, elmsz);
352
+
353
+ for (i=j=0; i<ndim; i++) {
354
+ stride1 = strides_na1[q[i].orig_dim];
355
+
356
+ // numeric index -- trim dimension
357
+ if (!keep_dim && q[i].n==1 && q[i].step==0) {
358
+ beg = q[i].beg;
359
+ na2->offset += stride1 * beg;
360
+ continue;
361
+ }
362
+
363
+ na2->base.shape[j] = size = q[i].n;
364
+
365
+ if (q[i].reduce != 0) {
366
+ m = rb_funcall(INT2FIX(1),rb_intern("<<"),1,INT2FIX(j));
367
+ na2->base.reduce = rb_funcall(m,rb_intern("|"),1,na2->base.reduce);
368
+ }
369
+
370
+ // array index
371
+ if (q[i].idx != NULL) {
372
+ index = q[i].idx;
373
+ SDX_SET_INDEX(na2->stridx[j],index);
374
+ q[i].idx = NULL;
375
+ for (k=0; k<size; k++) {
376
+ index[k] = index[k] * stride1;
377
+ }
378
+ } else {
379
+ beg = q[i].beg;
380
+ step = q[i].step;
381
+ na2->offset += stride1*beg;
382
+ SDX_SET_STRIDE(na2->stridx[j], stride1*step);
383
+ }
384
+ j++;
385
+ total *= size;
386
+ }
387
+ na2->base.size = total;
388
+ }
389
+
390
+
391
+ static void
392
+ na_index_aref_naview(narray_view_t *na1, narray_view_t *na2,
393
+ na_index_arg_t *q, int ndim, int keep_dim)
394
+ {
395
+ int i, j;
396
+ ssize_t total=1;
397
+
398
+ for (i=j=0; i<ndim; i++) {
399
+ stridx_t sdx1 = na1->stridx[q[i].orig_dim];
400
+ ssize_t size;
401
+
402
+ // numeric index -- trim dimension
403
+ if (!keep_dim && q[i].n==1 && q[i].step==0) {
404
+ if (SDX_IS_INDEX(sdx1)) {
405
+ na2->offset += SDX_GET_INDEX(sdx1)[q[i].beg];
406
+ } else {
407
+ na2->offset += SDX_GET_STRIDE(sdx1)*q[i].beg;
408
+ }
409
+ continue;
410
+ }
411
+
412
+ na2->base.shape[j] = size = q[i].n;
413
+
414
+ if (q[i].reduce != 0) {
415
+ VALUE m = rb_funcall(INT2FIX(1),rb_intern("<<"),1,INT2FIX(j));
416
+ na2->base.reduce = rb_funcall(m,rb_intern("|"),1,na2->base.reduce);
417
+ }
418
+
419
+ if (q[i].idx != NULL && SDX_IS_INDEX(sdx1)) {
420
+ // index <- index
421
+ int k;
422
+ size_t *index = q[i].idx;
423
+ SDX_SET_INDEX(na2->stridx[j], index);
424
+ q[i].idx = NULL;
425
+
426
+ for (k=0; k<size; k++) {
427
+ index[k] = SDX_GET_INDEX(sdx1)[index[k]];
428
+ }
429
+ }
430
+ else if (q[i].idx != NULL && SDX_IS_STRIDE(sdx1)) {
431
+ // index <- step
432
+ ssize_t stride1 = SDX_GET_STRIDE(sdx1);
433
+ size_t *index = q[i].idx;
434
+ SDX_SET_INDEX(na2->stridx[j],index);
435
+ q[i].idx = NULL;
436
+
437
+ if (stride1<0) {
438
+ size_t last;
439
+ int k;
440
+ stride1 = -stride1;
441
+ last = na1->base.shape[q[i].orig_dim] - 1;
442
+ if (na2->offset < last * stride1) {
443
+ rb_raise(rb_eStandardError,"bug: negative offset");
444
+ }
445
+ na2->offset -= last * stride1;
446
+ for (k=0; k<size; k++) {
447
+ index[k] = (last - index[k]) * stride1;
448
+ }
449
+ } else {
450
+ int k;
451
+ for (k=0; k<size; k++) {
452
+ index[k] = index[k] * stride1;
453
+ }
454
+ }
455
+ }
456
+ else if (q[i].idx == NULL && SDX_IS_INDEX(sdx1)) {
457
+ // step <- index
458
+ int k;
459
+ size_t beg = q[i].beg;
460
+ ssize_t step = q[i].step;
461
+ size_t *index = ALLOC_N(size_t, size);
462
+ SDX_SET_INDEX(na2->stridx[j],index);
463
+ for (k=0; k<size; k++) {
464
+ index[k] = SDX_GET_INDEX(sdx1)[beg+step*k];
465
+ }
466
+ }
467
+ else if (q[i].idx == NULL && SDX_IS_STRIDE(sdx1)) {
468
+ // step <- step
469
+ size_t beg = q[i].beg;
470
+ ssize_t step = q[i].step;
471
+ ssize_t stride1 = SDX_GET_STRIDE(sdx1);
472
+ na2->offset += stride1*beg;
473
+ SDX_SET_STRIDE(na2->stridx[j], stride1*step);
474
+ }
475
+
476
+ j++;
477
+ total *= size;
478
+ }
479
+ na2->base.size = total;
480
+ }
481
+
482
+
483
+ static int
484
+ na_ndim_new_narray(int ndim, const na_index_arg_t *q)
485
+ {
486
+ int i, ndim_new=0;
487
+ for (i=0; i<ndim; i++) {
488
+ if (q[i].n>1 || q[i].step!=0) {
489
+ ndim_new++;
490
+ }
491
+ }
492
+ return ndim_new;
493
+ }
494
+
495
+ typedef struct {
496
+ VALUE args, self, store;
497
+ int ndim;
498
+ na_index_arg_t *q;
499
+ narray_t *na1;
500
+ int keep_dim;
501
+ } na_aref_md_data_t;
502
+
503
+ static na_index_arg_t*
504
+ na_allocate_index_args(int ndim)
505
+ {
506
+ na_index_arg_t *q = ALLOC_N(na_index_arg_t, ndim);
507
+ int i;
508
+
509
+ for (i=0; i<ndim; i++) {
510
+ q[i].idx = NULL;
511
+ }
512
+ return q;
513
+ }
514
+
515
+ static
516
+ VALUE na_aref_md_protected(VALUE data_value)
517
+ {
518
+ na_aref_md_data_t *data = (na_aref_md_data_t*)(data_value);
519
+ VALUE self = data->self;
520
+ VALUE args = data->args;
521
+ VALUE store = data->store;
522
+ int ndim = data->ndim;
523
+ na_index_arg_t *q = data->q;
524
+ narray_t *na1 = data->na1;
525
+ int keep_dim = data->keep_dim;
526
+
527
+ int ndim_new;
528
+ VALUE view;
529
+ narray_view_t *na2;
530
+
531
+ na_index_parse_args(args, na1, q, ndim);
532
+
533
+ if (na_debug_flag) print_index_arg(q,ndim);
534
+
535
+ if (keep_dim) {
536
+ ndim_new = ndim;
537
+ } else {
538
+ ndim_new = na_ndim_new_narray(ndim, q);
539
+ }
540
+ view = na_s_allocate_view(CLASS_OF(self));
541
+
542
+ na_copy_flags(self, view);
543
+ GetNArrayView(view,na2);
544
+
545
+ na_alloc_shape((narray_t*)na2, ndim_new);
546
+
547
+ na2->stridx = ALLOC_N(stridx_t,ndim_new);
548
+
549
+ switch(na1->type) {
550
+ case NARRAY_DATA_T:
551
+ case NARRAY_FILEMAP_T:
552
+ na_index_aref_nadata((narray_data_t *)na1,na2,q,na_get_elmsz(self),ndim,keep_dim);
553
+ na2->data = self;
554
+ break;
555
+ case NARRAY_VIEW_T:
556
+ na_index_aref_naview((narray_view_t *)na1,na2,q,ndim,keep_dim);
557
+ na2->data = ((narray_view_t *)na1)->data;
558
+ break;
559
+ }
560
+ if (store) {
561
+ na_get_pointer_for_write(store); // allocate memory
562
+ na_store(na_flatten_dim(store,0),view);
563
+ return store;
564
+ }
565
+ return view;
566
+ }
567
+
568
+ static VALUE
569
+ na_aref_md_ensure(VALUE data_value)
570
+ {
571
+ na_aref_md_data_t *data = (na_aref_md_data_t*)(data_value);
572
+ int i;
573
+ for (i=0; i<data->ndim; i++) {
574
+ xfree(data->q[i].idx);
575
+ }
576
+ xfree(data->q);
577
+ return Qnil;
578
+ }
579
+
580
+ VALUE
581
+ na_aref_md(int argc, VALUE *argv, VALUE self, int keep_dim)
582
+ {
583
+ VALUE args; // should be GC protected
584
+ narray_t *na1;
585
+ int count_new, ndim;
586
+ na_aref_md_data_t data;
587
+ VALUE store = 0;
588
+ VALUE idx;
589
+ narray_t *nidx;
590
+
591
+ GetNArray(self,na1);
592
+
593
+ //printf("argc=%d\n",argc);
594
+
595
+ args = rb_ary_new4(argc,argv);
596
+
597
+ count_new = na_index_preprocess(args, na1->ndim);
598
+
599
+ if (RARRAY_LEN(args)==1) {
600
+ idx = RARRAY_AREF(args,0);
601
+ if (rb_obj_is_kind_of(idx, rb_cArray)) {
602
+ idx = rb_apply(numo_cNArray,rb_intern("[]"),idx);
603
+ }
604
+ if (rb_obj_is_kind_of(idx, numo_cNArray)) {
605
+ GetNArray(idx,nidx);
606
+ if (NA_NDIM(nidx)>1) {
607
+ store = rb_narray_new(CLASS_OF(self),NA_NDIM(nidx),NA_SHAPE(nidx));
608
+ idx = na_flatten(idx);
609
+ RARRAY_ASET(args,0,idx);
610
+ }
611
+ }
612
+ // flatten should be done only for narray-view with non-uniform stride.
613
+ self = na_flatten(self);
614
+ GetNArray(self,na1);
615
+ }
616
+ ndim = na1->ndim + count_new;
617
+
618
+ data.args = args;
619
+ data.self = self;
620
+ data.store = store;
621
+ data.ndim = ndim;
622
+ data.q = na_allocate_index_args(ndim);
623
+ data.na1 = na1;
624
+ data.keep_dim = keep_dim;
625
+
626
+ return rb_ensure(na_aref_md_protected, (VALUE)&data, na_aref_md_ensure, (VALUE)&data);
627
+ }
628
+
629
+
630
+
631
+
632
+ /* method: [](idx1,idx2,...,idxN) */
633
+ VALUE
634
+ na_aref_main(int nidx, VALUE *idx, VALUE self, int keep_dim)
635
+ {
636
+ na_index_arg_to_internal_order(nidx, idx, self);
637
+
638
+ if (nidx==0) {
639
+ return na_copy(self);
640
+ }
641
+ if (nidx==1) {
642
+ if (CLASS_OF(*idx)==numo_cBit) {
643
+ return rb_funcall(*idx,rb_intern("mask"),1,self);
644
+ }
645
+ }
646
+ return na_aref_md(nidx, idx, self, keep_dim);
647
+ }
648
+
649
+
650
+ /* method: [](idx1,idx2,...,idxN) */
651
+ static VALUE na_aref(int argc, VALUE *argv, VALUE self)
652
+ {
653
+ VALUE view;
654
+ view = na_aref_main(argc, argv, self, 0);
655
+ return rb_funcall(view, rb_intern("extract"), 0);
656
+ }
657
+
658
+
659
+ /* method: slice(idx1,idx2,...,idxN) */
660
+ static VALUE na_slice(int argc, VALUE *argv, VALUE self)
661
+ {
662
+ return na_aref_main(argc, argv, self, 1);
663
+ }
664
+
665
+
666
+
667
+
668
+ /* method: []=(idx1,idx2,...,idxN,val) */
669
+ static VALUE
670
+ na_aset(int argc, VALUE *argv, VALUE self)
671
+ {
672
+ VALUE a;
673
+ argc--;
674
+
675
+ if (argc==0)
676
+ na_store(self, argv[argc]);
677
+ else {
678
+ a = na_aref_main(argc, argv, self, 0);
679
+ na_store(a, argv[argc]);
680
+ }
681
+ return argv[argc];
682
+ }
683
+
684
+
685
+ // convert reduce dims to 0-th element
686
+ // for initialization of min/max func
687
+ // ['*,+,*'] -> [true,0,true]
688
+ VALUE nary_init_accum_aref0(VALUE self, VALUE reduce)
689
+ {
690
+ narray_t *na;
691
+ VALUE a;
692
+ ID id_bra;
693
+ unsigned long m;
694
+ int i, ndim;
695
+
696
+ GetNArray(self,na);
697
+ ndim = na->ndim;
698
+ a = rb_ary_new();
699
+ if (FIXNUM_P(reduce)) {
700
+ m = NUM2ULONG(reduce);
701
+ if (m==0)
702
+ for (i=0; i<ndim; i++)
703
+ rb_ary_push(a,INT2FIX(0));
704
+ else
705
+ for (i=0; i<ndim; i++)
706
+ if ((m>>i) & 1u)
707
+ rb_ary_push(a,INT2FIX(0));
708
+ else
709
+ rb_ary_push(a,Qtrue);
710
+ } else {
711
+ id_bra = rb_intern("[]");
712
+ for (i=0; i<ndim; i++)
713
+ if (rb_funcall(reduce,id_bra,1,INT2FIX(i)) == INT2FIX(1))
714
+ rb_ary_push(a,INT2FIX(0));
715
+ else
716
+ rb_ary_push(a,Qtrue);
717
+ }
718
+ return na_aref_md(RARRAY_LEN(a), RARRAY_PTR(a), self, 0);
719
+ }
720
+
721
+
722
+ ssize_t
723
+ na_get_scalar_position(VALUE self, int argc, VALUE *argv, ssize_t stride)
724
+ {
725
+ int i;
726
+ ssize_t x, s, m, pos, *idx;
727
+ narray_t *na;
728
+ narray_view_t *nv;
729
+ stridx_t sdx;
730
+
731
+ GetNArray(self,na);
732
+ if (na->size == 0) {
733
+ rb_raise(rb_eRuntimeError, "cannot get index of empty array");
734
+ return -1;
735
+ }
736
+ if (argc != 1 && argc != na->ndim) {
737
+ return -1;
738
+ }
739
+ idx = ALLOCA_N(ssize_t, argc);
740
+ for (i=0; i<argc; i++) {
741
+ switch(TYPE(argv[i])) {
742
+ case T_FIXNUM:
743
+ idx[i] = FIX2LONG(argv[i]);
744
+ break;
745
+ case T_BIGNUM:
746
+ case T_FLOAT:
747
+ idx[i] = NUM2SSIZE(argv[i]);
748
+ break;
749
+ default:
750
+ return -1;
751
+ }
752
+ }
753
+ switch(na->type) {
754
+ case NARRAY_VIEW_T:
755
+ GetNArrayView(self,nv);
756
+ pos = nv->offset;
757
+ if (argc==1) {
758
+ x = na_range_check(idx[0], na->size, 0);
759
+ for (i=na->ndim-1; i>=0; i--) {
760
+ s = na->shape[i];
761
+ m = x % s;
762
+ x = x / s;
763
+ sdx = nv->stridx[i];
764
+ if (SDX_IS_INDEX(sdx)) {
765
+ pos += SDX_GET_INDEX(sdx)[m];
766
+ } else {
767
+ pos += SDX_GET_STRIDE(sdx)*m;
768
+ }
769
+ }
770
+ } else {
771
+ for (i=argc-1; i>=0; i--) {
772
+ x = na_range_check(idx[i], na->shape[i], i);
773
+ sdx = nv->stridx[i];
774
+ if (SDX_IS_INDEX(sdx)) {
775
+ pos += SDX_GET_INDEX(sdx)[x];
776
+ } else {
777
+ pos += SDX_GET_STRIDE(sdx)*x;
778
+ }
779
+ }
780
+ }
781
+ break;
782
+ default:
783
+ if (!stride) {
784
+ stride = na_get_elmsz(self);
785
+ }
786
+ if (argc==1) {
787
+ x = na_range_check(idx[0], na->size, 0);
788
+ pos = stride*x;
789
+ } else {
790
+ pos = 0;
791
+ for (i=argc-1; i>=0; i--) {
792
+ x = na_range_check(idx[i], na->shape[i], i);
793
+ pos += stride*x;
794
+ stride *= na->shape[i];
795
+ }
796
+ }
797
+ }
798
+ return pos;
799
+ }
800
+
801
+
802
+ void
803
+ Init_nary_index()
804
+ {
805
+ rb_define_method(cNArray, "[]", na_aref, -1);
806
+ rb_define_method(cNArray, "slice", na_slice, -1);
807
+ rb_define_method(cNArray, "[]=", na_aset, -1);
808
+
809
+ sym_ast = ID2SYM(rb_intern("*"));
810
+ sym_all = ID2SYM(rb_intern("all"));
811
+ sym_minus = ID2SYM(rb_intern("-"));
812
+ sym_new = ID2SYM(rb_intern("new"));
813
+ sym_reverse = ID2SYM(rb_intern("reverse"));
814
+ sym_plus = ID2SYM(rb_intern("+"));
815
+ //sym_reduce = ID2SYM(rb_intern("reduce"));
816
+ sym_sum = ID2SYM(rb_intern("sum"));
817
+ sym_tilde = ID2SYM(rb_intern("~"));
818
+ sym_rest = ID2SYM(rb_intern("rest"));
819
+ id_beg = rb_intern("begin");
820
+ id_end = rb_intern("end");
821
+ id_exclude_end = rb_intern("exclude_end?");
822
+ }