numo-narray-alt 0.9.10 → 0.9.11

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/ext/numo/narray/numo/narray.h +2 -2
  4. data/ext/numo/narray/numo/types/robject.h +1 -1
  5. data/ext/numo/narray/src/mh/argmax.h +154 -0
  6. data/ext/numo/narray/src/mh/argmin.h +154 -0
  7. data/ext/numo/narray/src/mh/clip.h +115 -0
  8. data/ext/numo/narray/src/mh/cumprod.h +98 -0
  9. data/ext/numo/narray/src/mh/cumsum.h +98 -0
  10. data/ext/numo/narray/src/mh/eye.h +82 -0
  11. data/ext/numo/narray/src/mh/logseq.h +69 -0
  12. data/ext/numo/narray/src/mh/max.h +69 -0
  13. data/ext/numo/narray/src/mh/max_index.h +184 -0
  14. data/ext/numo/narray/src/mh/maximum.h +116 -0
  15. data/ext/numo/narray/src/mh/min.h +69 -0
  16. data/ext/numo/narray/src/mh/min_index.h +184 -0
  17. data/ext/numo/narray/src/mh/minimum.h +116 -0
  18. data/ext/numo/narray/src/mh/minmax.h +77 -0
  19. data/ext/numo/narray/src/mh/mulsum.h +185 -0
  20. data/ext/numo/narray/src/mh/prod.h +69 -0
  21. data/ext/numo/narray/src/mh/ptp.h +69 -0
  22. data/ext/numo/narray/src/mh/rand.h +315 -0
  23. data/ext/numo/narray/src/mh/seq.h +130 -0
  24. data/ext/numo/narray/src/mh/sum.h +69 -0
  25. data/ext/numo/narray/src/t_dcomplex.c +131 -667
  26. data/ext/numo/narray/src/t_dfloat.c +40 -1288
  27. data/ext/numo/narray/src/t_int16.c +262 -1161
  28. data/ext/numo/narray/src/t_int32.c +263 -1161
  29. data/ext/numo/narray/src/t_int64.c +262 -1163
  30. data/ext/numo/narray/src/t_int8.c +262 -1159
  31. data/ext/numo/narray/src/t_robject.c +427 -1675
  32. data/ext/numo/narray/src/t_scomplex.c +131 -667
  33. data/ext/numo/narray/src/t_sfloat.c +40 -1288
  34. data/ext/numo/narray/src/t_uint16.c +262 -1161
  35. data/ext/numo/narray/src/t_uint32.c +262 -1161
  36. data/ext/numo/narray/src/t_uint64.c +262 -1163
  37. data/ext/numo/narray/src/t_uint8.c +262 -1161
  38. data/lib/numo/narray.rb +2 -3
  39. metadata +23 -3
@@ -0,0 +1,98 @@
1
+ #ifndef NUMO_NARRAY_MH_CUMSUM_H
2
+ #define NUMO_NARRAY_MH_CUMSUM_H 1
3
+
4
+ #define DEF_NARRAY_FLT_CUMSUM_METHOD_FUNC(tDType, tNAryClass) \
5
+ static void iter_##tDType##_cumsum(na_loop_t* const lp) { \
6
+ size_t n; \
7
+ char* p1; \
8
+ char* p2; \
9
+ ssize_t s1; \
10
+ ssize_t s2; \
11
+ tDType x; \
12
+ tDType y; \
13
+ \
14
+ INIT_COUNTER(lp, n); \
15
+ INIT_PTR(lp, 0, p1, s1); \
16
+ INIT_PTR(lp, 1, p2, s2); \
17
+ \
18
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
19
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
20
+ for (size_t i = 0; i < n - 1; i++) { \
21
+ GET_DATA_STRIDE(p1, s1, tDType, y); \
22
+ m_cumsum(x, y); \
23
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
24
+ } \
25
+ } \
26
+ \
27
+ static void iter_##tDType##_cumsum_nan(na_loop_t* const lp) { \
28
+ size_t n; \
29
+ char* p1; \
30
+ char* p2; \
31
+ ssize_t s1; \
32
+ ssize_t s2; \
33
+ tDType x; \
34
+ tDType y; \
35
+ \
36
+ INIT_COUNTER(lp, n); \
37
+ INIT_PTR(lp, 0, p1, s1); \
38
+ INIT_PTR(lp, 1, p2, s2); \
39
+ \
40
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
41
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
42
+ for (size_t i = 0; i < n - 1; i++) { \
43
+ GET_DATA_STRIDE(p1, s1, tDType, y); \
44
+ m_cumsum_nan(x, y); \
45
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
46
+ } \
47
+ } \
48
+ \
49
+ static VALUE tDType##_cumsum(int argc, VALUE* argv, VALUE self) { \
50
+ VALUE reduce; \
51
+ ndfunc_arg_in_t ain[2] = { { tNAryClass, 0 }, { sym_reduce, 0 } }; \
52
+ ndfunc_arg_out_t aout[1] = { { tNAryClass, 0 } }; \
53
+ ndfunc_t ndf = { \
54
+ iter_##tDType##_cumsum, STRIDE_LOOP | NDF_FLAT_REDUCE | NDF_CUM, 2, 1, ain, aout \
55
+ }; \
56
+ \
57
+ reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_##tDType##_cumsum_nan); \
58
+ \
59
+ return na_ndloop(&ndf, 2, self, reduce); \
60
+ }
61
+
62
+ #define DEF_NARRAY_INT_CUMSUM_METHOD_FUNC(tDType, tNAryClass) \
63
+ static void iter_##tDType##_cumsum(na_loop_t* const lp) { \
64
+ size_t n; \
65
+ char* p1; \
66
+ char* p2; \
67
+ ssize_t s1; \
68
+ ssize_t s2; \
69
+ tDType x; \
70
+ tDType y; \
71
+ \
72
+ INIT_COUNTER(lp, n); \
73
+ INIT_PTR(lp, 0, p1, s1); \
74
+ INIT_PTR(lp, 1, p2, s2); \
75
+ \
76
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
77
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
78
+ for (size_t i = 0; i < n - 1; i++) { \
79
+ GET_DATA_STRIDE(p1, s1, tDType, y); \
80
+ m_cumsum(x, y); \
81
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
82
+ } \
83
+ } \
84
+ \
85
+ static VALUE tDType##_cumsum(int argc, VALUE* argv, VALUE self) { \
86
+ VALUE reduce; \
87
+ ndfunc_arg_in_t ain[2] = { { tNAryClass, 0 }, { sym_reduce, 0 } }; \
88
+ ndfunc_arg_out_t aout[1] = { { tNAryClass, 0 } }; \
89
+ ndfunc_t ndf = { \
90
+ iter_##tDType##_cumsum, STRIDE_LOOP | NDF_FLAT_REDUCE | NDF_CUM, 2, 1, ain, aout \
91
+ }; \
92
+ \
93
+ reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); \
94
+ \
95
+ return na_ndloop(&ndf, 2, self, reduce); \
96
+ }
97
+
98
+ #endif /* NUMO_NARRAY_MH_CUMSUM_H */
@@ -0,0 +1,82 @@
1
+ #ifndef NUMO_NARRAY_MH_EYE_H
2
+ #define NUMO_NARRAY_MH_EYE_H 1
3
+
4
+ #define DEF_NARRAY_EYE_METHOD_FUNC(tDType) \
5
+ static void iter_##tDType##_eye(na_loop_t* const lp) { \
6
+ char* g = (char*)(lp->opt_ptr); \
7
+ ssize_t kofs = *(ssize_t*)g; \
8
+ tDType data = *(tDType*)(g + sizeof(ssize_t)); \
9
+ \
10
+ size_t n0 = lp->args[0].shape[0]; \
11
+ size_t n1 = lp->args[0].shape[1]; \
12
+ ssize_t s0 = lp->args[0].iter[0].step; \
13
+ ssize_t s1 = lp->args[0].iter[1].step; \
14
+ char* p0 = NDL_PTR(lp, 0); \
15
+ \
16
+ for (size_t i0 = 0; i0 < n0; i0++) { \
17
+ char* p1 = p0; \
18
+ for (size_t i1 = 0; i1 < n1; i1++) { \
19
+ *(tDType*)p1 = (i0 + kofs == i1) ? data : m_zero; \
20
+ p1 += s1; \
21
+ } \
22
+ p0 += s0; \
23
+ } \
24
+ } \
25
+ \
26
+ static VALUE tDType##_eye(int argc, VALUE* argv, VALUE self) { \
27
+ ndfunc_arg_in_t ain[1] = { { OVERWRITE, 2 } }; \
28
+ ndfunc_t ndf = { iter_##tDType##_eye, NO_LOOP, 1, 0, ain, 0 }; \
29
+ ssize_t kofs; \
30
+ tDType data; \
31
+ char* g; \
32
+ int nd; \
33
+ narray_t* na; \
34
+ \
35
+ if (argc > 2) { \
36
+ rb_raise(rb_eArgError, "too many arguments (%d for 0..2)", argc); \
37
+ } else if (argc == 2) { \
38
+ data = m_num_to_data(argv[0]); \
39
+ kofs = NUM2SSIZET(argv[1]); \
40
+ } else if (argc == 1) { \
41
+ data = m_num_to_data(argv[0]); \
42
+ kofs = 0; \
43
+ } else { \
44
+ data = m_one; \
45
+ kofs = 0; \
46
+ } \
47
+ \
48
+ GetNArray(self, na); \
49
+ nd = na->ndim; \
50
+ if (nd < 2) { \
51
+ rb_raise(nary_eDimensionError, "less than 2-d array"); \
52
+ } \
53
+ \
54
+ if (kofs >= 0) { \
55
+ if ((size_t)(kofs) >= na->shape[nd - 1]) { \
56
+ rb_raise( \
57
+ rb_eArgError, \
58
+ "invalid diagonal offset(%" SZF "d) for " \
59
+ "last dimension size(%" SZF "d)", \
60
+ kofs, na->shape[nd - 1] \
61
+ ); \
62
+ } \
63
+ } else { \
64
+ if ((size_t)(-kofs) >= na->shape[nd - 2]) { \
65
+ rb_raise( \
66
+ rb_eArgError, \
67
+ "invalid diagonal offset(%" SZF "d) for " \
68
+ "last-1 dimension size(%" SZF "d)", \
69
+ kofs, na->shape[nd - 2] \
70
+ ); \
71
+ } \
72
+ } \
73
+ \
74
+ g = ALLOCA_N(char, sizeof(ssize_t) + sizeof(tDType)); \
75
+ *(ssize_t*)g = kofs; \
76
+ *(dtype*)(g + sizeof(ssize_t)) = data; \
77
+ \
78
+ na_ndloop3(&ndf, g, 1, self); \
79
+ return self; \
80
+ }
81
+
82
+ #endif /* NUMO_NARRAY_MH_EYE_H */
@@ -0,0 +1,69 @@
1
+ #ifndef NUMO_NARRAY_MH_LOGSEQ_H
2
+ #define NUMO_NARRAY_MH_LOGSEQ_H 1
3
+
4
+ #define DEF_NARRAY_FLT_LOGSEQ_METHOD_FUNC(tDType) \
5
+ typedef struct { \
6
+ tDType beg; \
7
+ tDType step; \
8
+ tDType base; \
9
+ double count; \
10
+ } logseq_opt_t; \
11
+ \
12
+ static void iter_##tDType##_logseq(na_loop_t* const lp) { \
13
+ size_t n; \
14
+ char* p1; \
15
+ ssize_t s1; \
16
+ size_t* idx1; \
17
+ tDType x; \
18
+ tDType beg; \
19
+ tDType step; \
20
+ tDType base; \
21
+ double c; \
22
+ logseq_opt_t* g; \
23
+ \
24
+ INIT_COUNTER(lp, n); \
25
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1); \
26
+ g = (logseq_opt_t*)(lp->opt_ptr); \
27
+ beg = g->beg; \
28
+ step = g->step; \
29
+ base = g->base; \
30
+ c = g->count; \
31
+ if (idx1) { \
32
+ for (size_t i = 0; i < n; i++) { \
33
+ x = f_seq(beg, step, c++); \
34
+ *(tDType*)(p1 + *idx1) = m_pow(base, x); \
35
+ idx1++; \
36
+ } \
37
+ } else { \
38
+ for (size_t i = 0; i < n; i++) { \
39
+ x = f_seq(beg, step, c++); \
40
+ *(tDType*)(p1) = m_pow(base, x); \
41
+ p1 += s1; \
42
+ } \
43
+ } \
44
+ g->count = c; \
45
+ } \
46
+ \
47
+ static VALUE tDType##_logseq(int argc, VALUE* argv, VALUE self) { \
48
+ logseq_opt_t* g; \
49
+ VALUE vbeg; \
50
+ VALUE vstep; \
51
+ VALUE vbase = Qnil; \
52
+ ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } }; \
53
+ ndfunc_t ndf = { iter_##tDType##_logseq, FULL_LOOP, 1, 0, ain, 0 }; \
54
+ \
55
+ g = ALLOCA_N(logseq_opt_t, 1); \
56
+ rb_scan_args(argc, argv, "21", &vbeg, &vstep, &vbase); \
57
+ g->beg = m_num_to_data(vbeg); \
58
+ g->step = m_num_to_data(vstep); \
59
+ g->count = 0; \
60
+ if (vbase == Qnil) { \
61
+ g->base = m_from_real(10); \
62
+ } else { \
63
+ g->base = m_num_to_data(vbase); \
64
+ } \
65
+ na_ndloop3(&ndf, g, 1, self); \
66
+ return self; \
67
+ }
68
+
69
+ #endif /* NUMO_NARRAY_MH_LOGSEQ_H */
@@ -0,0 +1,69 @@
1
+ #ifndef NUMO_NARRAY_MH_MAX_H
2
+ #define NUMO_NARRAY_MH_MAX_H 1
3
+
4
+ #define DEF_NARRAY_FLT_MAX_METHOD_FUNC(tDType, tNAryClass) \
5
+ static void iter_##tDType##_max(na_loop_t* const lp) { \
6
+ size_t n; \
7
+ char* p1; \
8
+ char* p2; \
9
+ ssize_t s1; \
10
+ \
11
+ INIT_COUNTER(lp, n); \
12
+ INIT_PTR(lp, 0, p1, s1); \
13
+ p2 = NDL_PTR(lp, 1); \
14
+ \
15
+ *(tDType*)p2 = f_max(n, p1, s1); \
16
+ } \
17
+ \
18
+ static void iter_##tDType##_max_nan(na_loop_t* const lp) { \
19
+ size_t n; \
20
+ char* p1; \
21
+ char* p2; \
22
+ ssize_t s1; \
23
+ \
24
+ INIT_COUNTER(lp, n); \
25
+ INIT_PTR(lp, 0, p1, s1); \
26
+ p2 = NDL_PTR(lp, 1); \
27
+ \
28
+ *(tDType*)p2 = f_max_nan(n, p1, s1); \
29
+ } \
30
+ \
31
+ static VALUE tDType##_max(int argc, VALUE* argv, VALUE self) { \
32
+ ndfunc_arg_in_t ain[2] = { { tNAryClass, 0 }, { sym_reduce, 0 } }; \
33
+ ndfunc_arg_out_t aout[1] = { { tNAryClass, 0 } }; \
34
+ ndfunc_t ndf = { \
35
+ iter_##tDType##_max, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout \
36
+ }; \
37
+ VALUE reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_##tDType##_max_nan); \
38
+ VALUE v = na_ndloop(&ndf, 2, self, reduce); \
39
+ \
40
+ return rb_funcall(v, rb_intern("extract"), 0); \
41
+ }
42
+
43
+ #define DEF_NARRAY_INT_MAX_METHOD_FUNC(tDType, tNAryClass) \
44
+ static void iter_##tDType##_max(na_loop_t* const lp) { \
45
+ size_t n; \
46
+ char* p1; \
47
+ char* p2; \
48
+ ssize_t s1; \
49
+ \
50
+ INIT_COUNTER(lp, n); \
51
+ INIT_PTR(lp, 0, p1, s1); \
52
+ p2 = NDL_PTR(lp, 1); \
53
+ \
54
+ *(tDType*)p2 = f_max(n, p1, s1); \
55
+ } \
56
+ \
57
+ static VALUE tDType##_max(int argc, VALUE* argv, VALUE self) { \
58
+ ndfunc_arg_in_t ain[2] = { { tNAryClass, 0 }, { sym_reduce, 0 } }; \
59
+ ndfunc_arg_out_t aout[1] = { { tNAryClass, 0 } }; \
60
+ ndfunc_t ndf = { \
61
+ iter_##tDType##_max, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout \
62
+ }; \
63
+ VALUE reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); \
64
+ VALUE v = na_ndloop(&ndf, 2, self, reduce); \
65
+ \
66
+ return rb_funcall(v, rb_intern("extract"), 0); \
67
+ }
68
+
69
+ #endif /* NUMO_NARRAY_MH_MAX_H */
@@ -0,0 +1,184 @@
1
+ #ifndef NUMO_NARRAY_MH_MAX_INDEX_H
2
+ #define NUMO_NARRAY_MH_MAX_INDEX_H 1
3
+
4
+ #define DEF_NARRAY_FLT_MAX_INDEX_METHOD_FUNC(tDType) \
5
+ static void iter_##tDType##_max_index_index64(na_loop_t* const lp) { \
6
+ size_t n; \
7
+ size_t idx; \
8
+ char* d_ptr; \
9
+ char* i_ptr; \
10
+ char* o_ptr; \
11
+ ssize_t d_step; \
12
+ ssize_t i_step; \
13
+ \
14
+ INIT_COUNTER(lp, n); \
15
+ INIT_PTR(lp, 0, d_ptr, d_step); \
16
+ \
17
+ idx = f_max_index(n, d_ptr, d_step); \
18
+ \
19
+ INIT_PTR(lp, 1, i_ptr, i_step); \
20
+ o_ptr = NDL_PTR(lp, 2); \
21
+ *(int64_t*)o_ptr = *(int64_t*)(i_ptr + i_step * idx); \
22
+ } \
23
+ \
24
+ static void iter_##tDType##_max_index_index32(na_loop_t* const lp) { \
25
+ size_t n; \
26
+ size_t idx; \
27
+ char* d_ptr; \
28
+ char* i_ptr; \
29
+ char* o_ptr; \
30
+ ssize_t d_step; \
31
+ ssize_t i_step; \
32
+ \
33
+ INIT_COUNTER(lp, n); \
34
+ INIT_PTR(lp, 0, d_ptr, d_step); \
35
+ \
36
+ idx = f_max_index(n, d_ptr, d_step); \
37
+ \
38
+ INIT_PTR(lp, 1, i_ptr, i_step); \
39
+ o_ptr = NDL_PTR(lp, 2); \
40
+ *(int32_t*)o_ptr = *(int32_t*)(i_ptr + i_step * idx); \
41
+ } \
42
+ \
43
+ static void iter_##tDType##_max_index_index64_nan(na_loop_t* const lp) { \
44
+ size_t n; \
45
+ size_t idx; \
46
+ char* d_ptr; \
47
+ char* i_ptr; \
48
+ char* o_ptr; \
49
+ ssize_t d_step; \
50
+ ssize_t i_step; \
51
+ \
52
+ INIT_COUNTER(lp, n); \
53
+ INIT_PTR(lp, 0, d_ptr, d_step); \
54
+ \
55
+ idx = f_max_index_nan(n, d_ptr, d_step); \
56
+ \
57
+ INIT_PTR(lp, 1, i_ptr, i_step); \
58
+ o_ptr = NDL_PTR(lp, 2); \
59
+ *(int64_t*)o_ptr = *(int64_t*)(i_ptr + i_step * idx); \
60
+ } \
61
+ \
62
+ static void iter_##tDType##_max_index_index32_nan(na_loop_t* const lp) { \
63
+ size_t n; \
64
+ size_t idx; \
65
+ char* d_ptr; \
66
+ char* i_ptr; \
67
+ char* o_ptr; \
68
+ ssize_t d_step; \
69
+ ssize_t i_step; \
70
+ \
71
+ INIT_COUNTER(lp, n); \
72
+ INIT_PTR(lp, 0, d_ptr, d_step); \
73
+ \
74
+ idx = f_max_index_nan(n, d_ptr, d_step); \
75
+ \
76
+ INIT_PTR(lp, 1, i_ptr, i_step); \
77
+ o_ptr = NDL_PTR(lp, 2); \
78
+ *(int32_t*)o_ptr = *(int32_t*)(i_ptr + i_step * idx); \
79
+ } \
80
+ \
81
+ static VALUE tDType##_max_index(int argc, VALUE* argv, VALUE self) { \
82
+ narray_t* na; \
83
+ VALUE idx; \
84
+ VALUE reduce; \
85
+ ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { Qnil, 0 }, { sym_reduce, 0 } }; \
86
+ ndfunc_arg_out_t aout[1] = { { 0, 0, 0 } }; \
87
+ ndfunc_t ndf = { 0, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE | NDF_EXTRACT, 3, 1, ain, aout }; \
88
+ \
89
+ GetNArray(self, na); \
90
+ if (na->ndim == 0) { \
91
+ return INT2FIX(0); \
92
+ } \
93
+ \
94
+ if (na->size > (~(u_int32_t)0)) { \
95
+ aout[0].type = numo_cInt64; \
96
+ idx = nary_new(numo_cInt64, na->ndim, na->shape); \
97
+ ndf.func = iter_##tDType##_max_index_index64; \
98
+ reduce = na_reduce_dimension( \
99
+ argc, argv, 1, &self, &ndf, iter_##tDType##_max_index_index64_nan \
100
+ ); \
101
+ } else { \
102
+ aout[0].type = numo_cInt32; \
103
+ idx = nary_new(numo_cInt32, na->ndim, na->shape); \
104
+ ndf.func = iter_##tDType##_max_index_index32; \
105
+ reduce = na_reduce_dimension( \
106
+ argc, argv, 1, &self, &ndf, iter_##tDType##_max_index_index32_nan \
107
+ ); \
108
+ } \
109
+ \
110
+ rb_funcall(idx, rb_intern("seq"), 0); \
111
+ \
112
+ return na_ndloop(&ndf, 3, self, idx, reduce); \
113
+ }
114
+
115
+ #define DEF_NARRAY_INT_MAX_INDEX_METHOD_FUNC(tDType) \
116
+ static void iter_##tDType##_max_index_index64(na_loop_t* const lp) { \
117
+ size_t n; \
118
+ size_t idx; \
119
+ char* d_ptr; \
120
+ char* i_ptr; \
121
+ char* o_ptr; \
122
+ ssize_t d_step; \
123
+ ssize_t i_step; \
124
+ \
125
+ INIT_COUNTER(lp, n); \
126
+ INIT_PTR(lp, 0, d_ptr, d_step); \
127
+ \
128
+ idx = f_max_index(n, d_ptr, d_step); \
129
+ \
130
+ INIT_PTR(lp, 1, i_ptr, i_step); \
131
+ o_ptr = NDL_PTR(lp, 2); \
132
+ *(int64_t*)o_ptr = *(int64_t*)(i_ptr + i_step * idx); \
133
+ } \
134
+ \
135
+ static void iter_##tDType##_max_index_index32(na_loop_t* const lp) { \
136
+ size_t n; \
137
+ size_t idx; \
138
+ char* d_ptr; \
139
+ char* i_ptr; \
140
+ char* o_ptr; \
141
+ ssize_t d_step; \
142
+ ssize_t i_step; \
143
+ \
144
+ INIT_COUNTER(lp, n); \
145
+ INIT_PTR(lp, 0, d_ptr, d_step); \
146
+ \
147
+ idx = f_max_index(n, d_ptr, d_step); \
148
+ \
149
+ INIT_PTR(lp, 1, i_ptr, i_step); \
150
+ o_ptr = NDL_PTR(lp, 2); \
151
+ *(int32_t*)o_ptr = *(int32_t*)(i_ptr + i_step * idx); \
152
+ } \
153
+ \
154
+ static VALUE tDType##_max_index(int argc, VALUE* argv, VALUE self) { \
155
+ narray_t* na; \
156
+ VALUE idx; \
157
+ VALUE reduce; \
158
+ ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { Qnil, 0 }, { sym_reduce, 0 } }; \
159
+ ndfunc_arg_out_t aout[1] = { { 0, 0, 0 } }; \
160
+ ndfunc_t ndf = { 0, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE | NDF_EXTRACT, 3, 1, ain, aout }; \
161
+ \
162
+ GetNArray(self, na); \
163
+ if (na->ndim == 0) { \
164
+ return INT2FIX(0); \
165
+ } \
166
+ \
167
+ if (na->size > (~(u_int32_t)0)) { \
168
+ aout[0].type = numo_cInt64; \
169
+ idx = nary_new(numo_cInt64, na->ndim, na->shape); \
170
+ ndf.func = iter_##tDType##_max_index_index64; \
171
+ reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); \
172
+ } else { \
173
+ aout[0].type = numo_cInt32; \
174
+ idx = nary_new(numo_cInt32, na->ndim, na->shape); \
175
+ ndf.func = iter_##tDType##_max_index_index32; \
176
+ reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); \
177
+ } \
178
+ \
179
+ rb_funcall(idx, rb_intern("seq"), 0); \
180
+ \
181
+ return na_ndloop(&ndf, 3, self, idx, reduce); \
182
+ }
183
+
184
+ #endif /* NUMO_NARRAY_MH_MAX_INDEX_H */