numo-narray 0.9.0.1-x64-mingw32

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 (124) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +47 -0
  4. data/Rakefile +41 -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 +117 -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 +140 -0
  82. data/ext/numo/narray/narray.c +1539 -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 +872 -0
  114. data/lib/2.1/numo/narray.so +0 -0
  115. data/lib/2.2/numo/narray.so +0 -0
  116. data/lib/2.3/numo/narray.so +0 -0
  117. data/lib/erbpp.rb +286 -0
  118. data/lib/erbpp/line_number.rb +126 -0
  119. data/lib/erbpp/narray_def.rb +338 -0
  120. data/lib/numo/narray.rb +6 -0
  121. data/numo-narray.gemspec +35 -0
  122. data/spec/bit_spec.rb +93 -0
  123. data/spec/narray_spec.rb +249 -0
  124. 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
+ }