numo-narray-alt 0.9.12 → 0.9.13

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90bcb68c4b90224af8196f103f31646f653f9a495ff7b47e24c1f03c3ba8f3d2
4
- data.tar.gz: f3105f5bd8c5a2ae27a21ac27f05ad7382a2db76a13529639951ecd98459462b
3
+ metadata.gz: 51d818d5b1d990bb12a358f15adae53ef1b5d488d172dd275abd2d96d4c74ab4
4
+ data.tar.gz: 8f521c4247a54185936fa6f06ebcd322cc90babde98c093ac7287ccc93f443fd
5
5
  SHA512:
6
- metadata.gz: 7e81366c927e13e1da39ab2675d9dd11ba75498ee144570728eaf8f9181b471a83d5b7034fdc6e3ce155cbe080f64444c0f17316f64c854d34e950de7b8398b4
7
- data.tar.gz: a18a12e36781c4a06f02e2e92835778559e5afa3d3fed7c1b71a257bd7ed91e5523c856db685a1b3c3a527c9dc43f54e229df545a6edfafeaf539c136331ae42
6
+ metadata.gz: d01294b516c33ac3173da16947700e8ae5e0db4e5d99bcb9f4c279c98a4880fb6c23a6559426aaae197b6b066400964b77aa2689b797907b52f16f78af4aff56
7
+ data.tar.gz: 6ca130060197c3a3a1a9c2191e820dd7fb0c1d9c514058356bf0b4851a20eb1ac3db5fb0b7e65d161ac606948147b555090a94436febee83a89261829a312bba
@@ -13,8 +13,8 @@ extern "C" {
13
13
  #endif
14
14
  #endif
15
15
 
16
- #define NARRAY_VERSION "0.9.12"
17
- #define NARRAY_VERSION_CODE 9120
16
+ #define NARRAY_VERSION "0.9.13"
17
+ #define NARRAY_VERSION_CODE 9130
18
18
 
19
19
  #include <math.h>
20
20
  #include "numo/compat.h"
@@ -0,0 +1,125 @@
1
+ #ifndef NUMO_NARRAY_MH_MINUS_H
2
+ #define NUMO_NARRAY_MH_MINUS_H 1
3
+
4
+ #define DEF_NARRAY_MINUS_METHOD_FUNC(tDType, tNAryClass) \
5
+ static void iter_##tDType##_minus(na_loop_t* const lp) { \
6
+ size_t n; \
7
+ char* p1; \
8
+ char* p2; \
9
+ ssize_t s1; \
10
+ ssize_t s2; \
11
+ size_t* idx1; \
12
+ size_t* idx2; \
13
+ INIT_COUNTER(lp, n); \
14
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1); \
15
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2); \
16
+ tDType x; \
17
+ if (idx1) { \
18
+ if (idx2) { \
19
+ for (size_t i = 0; i < n; i++) { \
20
+ GET_DATA_INDEX(p1, idx1, tDType, x); \
21
+ x = m_minus(x); \
22
+ SET_DATA_INDEX(p2, idx2, tDType, x); \
23
+ } \
24
+ } else { \
25
+ for (size_t i = 0; i < n; i++) { \
26
+ GET_DATA_INDEX(p1, idx1, tDType, x); \
27
+ x = m_minus(x); \
28
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
29
+ } \
30
+ } \
31
+ } else { \
32
+ if (idx2) { \
33
+ for (size_t i = 0; i < n; i++) { \
34
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
35
+ x = m_minus(x); \
36
+ SET_DATA_INDEX(p2, idx2, tDType, x); \
37
+ } \
38
+ } else { \
39
+ if (is_aligned(p1, sizeof(tDType)) && is_aligned(p2, sizeof(tDType))) { \
40
+ if (s1 == sizeof(tDType) && s2 == sizeof(tDType)) { \
41
+ for (size_t i = 0; i < n; i++) { \
42
+ ((tDType*)p2)[i] = m_minus(((tDType*)p1)[i]); \
43
+ } \
44
+ return; \
45
+ } \
46
+ if (is_aligned_step(s1, sizeof(tDType)) && is_aligned_step(s2, sizeof(tDType))) { \
47
+ for (size_t i = 0; i < n; i++) { \
48
+ *(tDType*)p2 = m_minus(*(tDType*)p1); \
49
+ p1 += s1; \
50
+ p2 += s2; \
51
+ } \
52
+ return; \
53
+ } \
54
+ } \
55
+ for (size_t i = 0; i < n; i++) { \
56
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
57
+ x = m_minus(x); \
58
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
59
+ } \
60
+ } \
61
+ } \
62
+ } \
63
+ \
64
+ static VALUE tDType##_minus(VALUE self) { \
65
+ ndfunc_arg_in_t ain[1] = { { tNAryClass, 0 } }; \
66
+ ndfunc_arg_out_t aout[1] = { { tNAryClass, 0 } }; \
67
+ ndfunc_t ndf = { iter_##tDType##_minus, FULL_LOOP, 1, 1, ain, aout }; \
68
+ return na_ndloop(&ndf, 1, self); \
69
+ }
70
+
71
+ #define DEF_NARRAY_INT8_MINUS_METHOD_FUNC(tDType, tNAryClass) \
72
+ static void iter_##tDType##_minus(na_loop_t* const lp) { \
73
+ size_t n; \
74
+ char* p1; \
75
+ char* p2; \
76
+ ssize_t s1; \
77
+ ssize_t s2; \
78
+ size_t* idx1; \
79
+ size_t* idx2; \
80
+ INIT_COUNTER(lp, n); \
81
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1); \
82
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2); \
83
+ tDType x; \
84
+ if (idx1) { \
85
+ if (idx2) { \
86
+ for (size_t i = 0; i < n; i++) { \
87
+ GET_DATA_INDEX(p1, idx1, tDType, x); \
88
+ x = m_minus(x); \
89
+ SET_DATA_INDEX(p2, idx2, tDType, x); \
90
+ } \
91
+ } else { \
92
+ for (size_t i = 0; i < n; i++) { \
93
+ GET_DATA_INDEX(p1, idx1, tDType, x); \
94
+ x = m_minus(x); \
95
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
96
+ } \
97
+ } \
98
+ } else { \
99
+ if (idx2) { \
100
+ for (size_t i = 0; i < n; i++) { \
101
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
102
+ x = m_minus(x); \
103
+ SET_DATA_INDEX(p2, idx2, tDType, x); \
104
+ } \
105
+ } else { \
106
+ for (size_t i = 0; i < n; i++) { \
107
+ *(tDType*)p2 = m_minus(*(tDType*)p1); \
108
+ p1 += s1; \
109
+ p2 += s2; \
110
+ } \
111
+ } \
112
+ } \
113
+ } \
114
+ \
115
+ static VALUE tDType##_minus(VALUE self) { \
116
+ ndfunc_arg_in_t ain[1] = { { tNAryClass, 0 } }; \
117
+ ndfunc_arg_out_t aout[1] = { { tNAryClass, 0 } }; \
118
+ ndfunc_t ndf = { iter_##tDType##_minus, FULL_LOOP, 1, 1, ain, aout }; \
119
+ return na_ndloop(&ndf, 1, self); \
120
+ }
121
+
122
+ #define DEF_NARRAY_ROBJ_MINUS_METHOD_FUNC() \
123
+ DEF_NARRAY_INT8_MINUS_METHOD_FUNC(robject, numo_cRObject)
124
+
125
+ #endif /* NUMO_NARRAY_MH_MINUS_H */
@@ -0,0 +1,197 @@
1
+ #ifndef NUMO_NARRAY_MH_POW_H
2
+ #define NUMO_NARRAY_MH_POW_H 1
3
+
4
+ #define DEF_NARRAY_POW_METHOD_FUNC(tDType, tNAryClass) \
5
+ static void iter_##tDType##_pow(na_loop_t* const lp) { \
6
+ size_t n; \
7
+ char* p1; \
8
+ char* p2; \
9
+ char* p3; \
10
+ ssize_t s1; \
11
+ ssize_t s2; \
12
+ ssize_t s3; \
13
+ INIT_COUNTER(lp, n); \
14
+ INIT_PTR(lp, 0, p1, s1); \
15
+ INIT_PTR(lp, 1, p2, s2); \
16
+ INIT_PTR(lp, 2, p3, s3); \
17
+ tDType x; \
18
+ tDType y; \
19
+ for (size_t i = 0; i < n; i++) { \
20
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
21
+ GET_DATA_STRIDE(p2, s2, tDType, y); \
22
+ x = m_pow(x, y); \
23
+ SET_DATA_STRIDE(p3, s3, tDType, x); \
24
+ } \
25
+ } \
26
+ \
27
+ static void iter_##tDType##_pow_int32(na_loop_t* const lp) { \
28
+ size_t n; \
29
+ char* p1; \
30
+ char* p2; \
31
+ char* p3; \
32
+ ssize_t s1; \
33
+ ssize_t s2; \
34
+ ssize_t s3; \
35
+ INIT_COUNTER(lp, n); \
36
+ INIT_PTR(lp, 0, p1, s1); \
37
+ INIT_PTR(lp, 1, p2, s2); \
38
+ INIT_PTR(lp, 2, p3, s3); \
39
+ tDType x; \
40
+ int32_t y; \
41
+ for (size_t i = 0; i < n; i++) { \
42
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
43
+ GET_DATA_STRIDE(p2, s2, int32_t, y); \
44
+ x = m_pow_int(x, y); \
45
+ SET_DATA_STRIDE(p3, s3, tDType, x); \
46
+ } \
47
+ } \
48
+ \
49
+ static VALUE tDType##_pow_self(VALUE self, VALUE other) { \
50
+ ndfunc_arg_in_t ain_i[2] = { { tNAryClass, 0 }, { numo_cInt32, 0 } }; \
51
+ ndfunc_arg_in_t ain[2] = { { tNAryClass, 0 }, { tNAryClass, 0 } }; \
52
+ ndfunc_arg_out_t aout[1] = { { tNAryClass, 0 } }; \
53
+ ndfunc_t ndf_i = { iter_##tDType##_pow_int32, STRIDE_LOOP, 2, 1, ain_i, aout }; \
54
+ ndfunc_t ndf = { iter_##tDType##_pow, STRIDE_LOOP, 2, 1, ain, aout }; \
55
+ if (FIXNUM_P(other) || rb_obj_is_kind_of(other, numo_cInt32)) { \
56
+ return na_ndloop(&ndf_i, 2, self, other); \
57
+ } \
58
+ return na_ndloop(&ndf, 2, self, other); \
59
+ } \
60
+ \
61
+ static VALUE tDType##_pow(VALUE self, VALUE other) { \
62
+ VALUE klass = na_upcast(rb_obj_class(self), rb_obj_class(other)); \
63
+ if (klass == tNAryClass) { \
64
+ return tDType##_pow_self(self, other); \
65
+ } \
66
+ VALUE v = rb_funcall(klass, id_cast, 1, self); \
67
+ return rb_funcall(v, id_pow, 1, other); \
68
+ }
69
+
70
+ #define DEF_NARRAY_INT64_POW_METHOD_FUNC(tDType, tNAryClass) \
71
+ static void iter_##tDType##_pow(na_loop_t* const lp) { \
72
+ size_t n; \
73
+ char* p1; \
74
+ char* p2; \
75
+ char* p3; \
76
+ ssize_t s1; \
77
+ ssize_t s2; \
78
+ ssize_t s3; \
79
+ INIT_COUNTER(lp, n); \
80
+ INIT_PTR(lp, 0, p1, s1); \
81
+ INIT_PTR(lp, 1, p2, s2); \
82
+ INIT_PTR(lp, 2, p3, s3); \
83
+ tDType x; \
84
+ tDType y; \
85
+ for (size_t i = 0; i < n; i++) { \
86
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
87
+ GET_DATA_STRIDE(p2, s2, tDType, y); \
88
+ x = m_pow(x, (int)y); \
89
+ SET_DATA_STRIDE(p3, s3, tDType, x); \
90
+ } \
91
+ } \
92
+ \
93
+ static void iter_##tDType##_pow_int32(na_loop_t* const lp) { \
94
+ size_t n; \
95
+ char* p1; \
96
+ char* p2; \
97
+ char* p3; \
98
+ ssize_t s1; \
99
+ ssize_t s2; \
100
+ ssize_t s3; \
101
+ INIT_COUNTER(lp, n); \
102
+ INIT_PTR(lp, 0, p1, s1); \
103
+ INIT_PTR(lp, 1, p2, s2); \
104
+ INIT_PTR(lp, 2, p3, s3); \
105
+ tDType x; \
106
+ int32_t y; \
107
+ for (size_t i = 0; i < n; i++) { \
108
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
109
+ GET_DATA_STRIDE(p2, s2, int32_t, y); \
110
+ x = m_pow_int(x, y); \
111
+ SET_DATA_STRIDE(p3, s3, tDType, x); \
112
+ } \
113
+ } \
114
+ \
115
+ static VALUE tDType##_pow_self(VALUE self, VALUE other) { \
116
+ ndfunc_arg_in_t ain_i[2] = { { tNAryClass, 0 }, { numo_cInt32, 0 } }; \
117
+ ndfunc_arg_in_t ain[2] = { { tNAryClass, 0 }, { tNAryClass, 0 } }; \
118
+ ndfunc_arg_out_t aout[1] = { { tNAryClass, 0 } }; \
119
+ ndfunc_t ndf_i = { iter_##tDType##_pow_int32, STRIDE_LOOP, 2, 1, ain_i, aout }; \
120
+ ndfunc_t ndf = { iter_##tDType##_pow, STRIDE_LOOP, 2, 1, ain, aout }; \
121
+ if (FIXNUM_P(other) || rb_obj_is_kind_of(other, numo_cInt32)) { \
122
+ return na_ndloop(&ndf_i, 2, self, other); \
123
+ } \
124
+ return na_ndloop(&ndf, 2, self, other); \
125
+ } \
126
+ \
127
+ static VALUE tDType##_pow(VALUE self, VALUE other) { \
128
+ VALUE klass = na_upcast(rb_obj_class(self), rb_obj_class(other)); \
129
+ if (klass == tNAryClass) { \
130
+ return tDType##_pow_self(self, other); \
131
+ } \
132
+ VALUE v = rb_funcall(klass, id_cast, 1, self); \
133
+ return rb_funcall(v, id_pow, 1, other); \
134
+ }
135
+
136
+ #define DEF_NARRAY_ROBJ_POW_METHOD_FUNC() \
137
+ static void iter_robject_pow(na_loop_t* const lp) { \
138
+ size_t n; \
139
+ char* p1; \
140
+ char* p2; \
141
+ char* p3; \
142
+ ssize_t s1; \
143
+ ssize_t s2; \
144
+ ssize_t s3; \
145
+ INIT_COUNTER(lp, n); \
146
+ INIT_PTR(lp, 0, p1, s1); \
147
+ INIT_PTR(lp, 1, p2, s2); \
148
+ INIT_PTR(lp, 2, p3, s3); \
149
+ robject x; \
150
+ robject y; \
151
+ for (size_t i = 0; i < n; i++) { \
152
+ GET_DATA_STRIDE(p1, s1, robject, x); \
153
+ GET_DATA_STRIDE(p2, s2, robject, y); \
154
+ x = m_pow(x, y); \
155
+ SET_DATA_STRIDE(p3, s3, robject, x); \
156
+ } \
157
+ } \
158
+ \
159
+ static void iter_robject_pow_int32(na_loop_t* const lp) { \
160
+ size_t n; \
161
+ char* p1; \
162
+ char* p2; \
163
+ char* p3; \
164
+ ssize_t s1; \
165
+ ssize_t s2; \
166
+ ssize_t s3; \
167
+ INIT_COUNTER(lp, n); \
168
+ INIT_PTR(lp, 0, p1, s1); \
169
+ INIT_PTR(lp, 1, p2, s2); \
170
+ INIT_PTR(lp, 2, p3, s3); \
171
+ robject x; \
172
+ int32_t y; \
173
+ for (size_t i = 0; i < n; i++) { \
174
+ GET_DATA_STRIDE(p1, s1, robject, x); \
175
+ GET_DATA_STRIDE(p2, s2, int32_t, y); \
176
+ x = m_pow_int(x, y); \
177
+ SET_DATA_STRIDE(p3, s3, robject, x); \
178
+ } \
179
+ } \
180
+ \
181
+ static VALUE robject_pow_self(VALUE self, VALUE other) { \
182
+ ndfunc_arg_in_t ain_i[2] = { { numo_cRObject, 0 }, { numo_cInt32, 0 } }; \
183
+ ndfunc_arg_in_t ain[2] = { { numo_cRObject, 0 }, { numo_cRObject, 0 } }; \
184
+ ndfunc_arg_out_t aout[1] = { { numo_cRObject, 0 } }; \
185
+ ndfunc_t ndf_i = { iter_robject_pow_int32, STRIDE_LOOP, 2, 1, ain_i, aout }; \
186
+ ndfunc_t ndf = { iter_robject_pow, STRIDE_LOOP, 2, 1, ain, aout }; \
187
+ if (FIXNUM_P(other) || rb_obj_is_kind_of(other, numo_cInt32)) { \
188
+ return na_ndloop(&ndf_i, 2, self, other); \
189
+ } \
190
+ return na_ndloop(&ndf, 2, self, other); \
191
+ } \
192
+ \
193
+ static VALUE robject_pow(VALUE self, VALUE other) { \
194
+ return robject_pow_self(self, other); \
195
+ }
196
+
197
+ #endif /* NUMO_NARRAY_MH_POW_H */
@@ -0,0 +1,125 @@
1
+ #ifndef NUMO_NARRAY_MH_RAND_NORM_H
2
+ #define NUMO_NARRAY_MH_RAND_NORM_H 1
3
+
4
+ #define DEF_NARRAY_CMP_RAND_NORM_METHOD_FUNC(tDType, tRType) \
5
+ typedef struct { \
6
+ tDType mu; \
7
+ tRType sigma; \
8
+ } randn_opt_t; \
9
+ \
10
+ static void iter_##tDType##_rand_norm(na_loop_t* const lp) { \
11
+ size_t n; \
12
+ char* p1; \
13
+ ssize_t s1; \
14
+ size_t* idx1; \
15
+ INIT_COUNTER(lp, n); \
16
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1); \
17
+ tDType mu; \
18
+ tRType sigma; \
19
+ randn_opt_t* g = (randn_opt_t*)(lp->opt_ptr); \
20
+ mu = g->mu; \
21
+ sigma = g->sigma; \
22
+ tDType* a0; \
23
+ if (idx1) { \
24
+ for (size_t i = 0; i < n; i++) { \
25
+ a0 = (tDType*)(p1 + *idx1); \
26
+ m_rand_norm(mu, sigma, a0); \
27
+ idx1 += 1; \
28
+ } \
29
+ } else { \
30
+ for (size_t i = 0; i < n; i++) { \
31
+ a0 = (tDType*)(p1); \
32
+ m_rand_norm(mu, sigma, a0); \
33
+ p1 += s1; \
34
+ } \
35
+ } \
36
+ } \
37
+ \
38
+ static VALUE tDType##_rand_norm(int argc, VALUE* argv, VALUE self) { \
39
+ VALUE v1 = Qnil; \
40
+ VALUE v2 = Qnil; \
41
+ const int n = rb_scan_args(argc, argv, "02", &v1, &v2); \
42
+ randn_opt_t g; \
43
+ if (n == 0) { \
44
+ g.mu = m_zero; \
45
+ } else { \
46
+ g.mu = m_num_to_data(v1); \
47
+ } \
48
+ if (n == 2) { \
49
+ g.sigma = NUM2DBL(v2); \
50
+ } else { \
51
+ g.sigma = 1; \
52
+ } \
53
+ ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } }; \
54
+ ndfunc_t ndf = { iter_##tDType##_rand_norm, FULL_LOOP, 1, 0, ain, 0 }; \
55
+ na_ndloop3(&ndf, &g, 1, self); \
56
+ return self; \
57
+ }
58
+
59
+ #define DEF_NARRAY_FLT_RAND_NORM_METHOD_FUNC(tDType) \
60
+ typedef struct { \
61
+ tDType mu; \
62
+ tDType sigma; \
63
+ } randn_opt_t; \
64
+ \
65
+ static void iter_##tDType##_rand_norm(na_loop_t* const lp) { \
66
+ size_t i; \
67
+ char* p1; \
68
+ ssize_t s1; \
69
+ size_t* idx1; \
70
+ INIT_COUNTER(lp, i); \
71
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1); \
72
+ tDType mu; \
73
+ tDType sigma; \
74
+ randn_opt_t* g = (randn_opt_t*)(lp->opt_ptr); \
75
+ mu = g->mu; \
76
+ sigma = g->sigma; \
77
+ tDType* a0; \
78
+ tDType* a1; \
79
+ if (idx1) { \
80
+ for (; i > 1; i -= 2) { \
81
+ a0 = (tDType*)(p1 + *idx1); \
82
+ a1 = (tDType*)(p1 + *(idx1 + 1)); \
83
+ m_rand_norm(mu, sigma, a0, a1); \
84
+ idx1 += 2; \
85
+ } \
86
+ if (i > 0) { \
87
+ a0 = (tDType*)(p1 + *idx1); \
88
+ m_rand_norm(mu, sigma, a0, 0); \
89
+ } \
90
+ } else { \
91
+ for (; i > 1; i -= 2) { \
92
+ a0 = (tDType*)(p1); \
93
+ a1 = (tDType*)(p1 + s1); \
94
+ m_rand_norm(mu, sigma, a0, a1); \
95
+ p1 += s1 * 2; \
96
+ } \
97
+ if (i > 0) { \
98
+ a0 = (tDType*)(p1); \
99
+ m_rand_norm(mu, sigma, a0, 0); \
100
+ } \
101
+ } \
102
+ } \
103
+ \
104
+ static VALUE tDType##_rand_norm(int argc, VALUE* args, VALUE self) { \
105
+ VALUE v1 = Qnil; \
106
+ VALUE v2 = Qnil; \
107
+ const int n = rb_scan_args(argc, args, "02", &v1, &v2); \
108
+ randn_opt_t g; \
109
+ if (n == 0) { \
110
+ g.mu = m_zero; \
111
+ } else { \
112
+ g.mu = m_num_to_data(v1); \
113
+ } \
114
+ if (n == 2) { \
115
+ g.sigma = NUM2DBL(v2); \
116
+ } else { \
117
+ g.sigma = 1; \
118
+ } \
119
+ ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } }; \
120
+ ndfunc_t ndf = { iter_##tDType##_rand_norm, FULL_LOOP, 1, 0, ain, 0 }; \
121
+ na_ndloop3(&ndf, &g, 1, self); \
122
+ return self; \
123
+ }
124
+
125
+ #endif /* NUMO_NARRAY_MH_RAND_NORM_H */
@@ -0,0 +1,125 @@
1
+ #ifndef NUMO_NARRAY_MH_RECIPROCAL_H
2
+ #define NUMO_NARRAY_MH_RECIPROCAL_H 1
3
+
4
+ #define DEF_NARRAY_RECIPROCAL_METHOD_FUNC(tDType, tNAryClass) \
5
+ static void iter_##tDType##_reciprocal(na_loop_t* const lp) { \
6
+ size_t n; \
7
+ char* p1; \
8
+ char* p2; \
9
+ ssize_t s1; \
10
+ ssize_t s2; \
11
+ size_t* idx1; \
12
+ size_t* idx2; \
13
+ INIT_COUNTER(lp, n); \
14
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1); \
15
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2); \
16
+ tDType x; \
17
+ if (idx1) { \
18
+ if (idx2) { \
19
+ for (size_t i = 0; i < n; i++) { \
20
+ GET_DATA_INDEX(p1, idx1, tDType, x); \
21
+ x = m_reciprocal(x); \
22
+ SET_DATA_INDEX(p2, idx2, tDType, x); \
23
+ } \
24
+ } else { \
25
+ for (size_t i = 0; i < n; i++) { \
26
+ GET_DATA_INDEX(p1, idx1, tDType, x); \
27
+ x = m_reciprocal(x); \
28
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
29
+ } \
30
+ } \
31
+ } else { \
32
+ if (idx2) { \
33
+ for (size_t i = 0; i < n; i++) { \
34
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
35
+ x = m_reciprocal(x); \
36
+ SET_DATA_INDEX(p2, idx2, tDType, x); \
37
+ } \
38
+ } else { \
39
+ if (is_aligned(p1, sizeof(tDType)) && is_aligned(p2, sizeof(tDType))) { \
40
+ if (s1 == sizeof(tDType) && s2 == sizeof(tDType)) { \
41
+ for (size_t i = 0; i < n; i++) { \
42
+ ((tDType*)p2)[i] = m_reciprocal(((tDType*)p1)[i]); \
43
+ } \
44
+ return; \
45
+ } \
46
+ if (is_aligned_step(s1, sizeof(tDType)) && is_aligned_step(s2, sizeof(tDType))) { \
47
+ for (size_t i = 0; i < n; i++) { \
48
+ *(tDType*)p2 = m_reciprocal(*(tDType*)p1); \
49
+ p1 += s1; \
50
+ p2 += s2; \
51
+ } \
52
+ return; \
53
+ } \
54
+ } \
55
+ for (size_t i = 0; i < n; i++) { \
56
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
57
+ x = m_reciprocal(x); \
58
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
59
+ } \
60
+ } \
61
+ } \
62
+ } \
63
+ \
64
+ static VALUE tDType##_reciprocal(VALUE self) { \
65
+ ndfunc_arg_in_t ain[1] = { { tNAryClass, 0 } }; \
66
+ ndfunc_arg_out_t aout[1] = { { tNAryClass, 0 } }; \
67
+ ndfunc_t ndf = { iter_##tDType##_reciprocal, FULL_LOOP, 1, 1, ain, aout }; \
68
+ return na_ndloop(&ndf, 1, self); \
69
+ }
70
+
71
+ #define DEF_NARRAY_INT8_RECIPROCAL_METHOD_FUNC(tDType, tNAryClass) \
72
+ static void iter_##tDType##_reciprocal(na_loop_t* const lp) { \
73
+ size_t n; \
74
+ char* p1; \
75
+ char* p2; \
76
+ ssize_t s1; \
77
+ ssize_t s2; \
78
+ size_t* idx1; \
79
+ size_t* idx2; \
80
+ INIT_COUNTER(lp, n); \
81
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1); \
82
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2); \
83
+ tDType x; \
84
+ if (idx1) { \
85
+ if (idx2) { \
86
+ for (size_t i = 0; i < n; i++) { \
87
+ GET_DATA_INDEX(p1, idx1, tDType, x); \
88
+ x = m_reciprocal(x); \
89
+ SET_DATA_INDEX(p2, idx2, tDType, x); \
90
+ } \
91
+ } else { \
92
+ for (size_t i = 0; i < n; i++) { \
93
+ GET_DATA_INDEX(p1, idx1, tDType, x); \
94
+ x = m_reciprocal(x); \
95
+ SET_DATA_STRIDE(p2, s2, tDType, x); \
96
+ } \
97
+ } \
98
+ } else { \
99
+ if (idx2) { \
100
+ for (size_t i = 0; i < n; i++) { \
101
+ GET_DATA_STRIDE(p1, s1, tDType, x); \
102
+ x = m_reciprocal(x); \
103
+ SET_DATA_INDEX(p2, idx2, tDType, x); \
104
+ } \
105
+ } else { \
106
+ for (size_t i = 0; i < n; i++) { \
107
+ *(tDType*)p2 = m_reciprocal(*(tDType*)p1); \
108
+ p1 += s1; \
109
+ p2 += s2; \
110
+ } \
111
+ } \
112
+ } \
113
+ } \
114
+ \
115
+ static VALUE tDType##_reciprocal(VALUE self) { \
116
+ ndfunc_arg_in_t ain[1] = { { tNAryClass, 0 } }; \
117
+ ndfunc_arg_out_t aout[1] = { { tNAryClass, 0 } }; \
118
+ ndfunc_t ndf = { iter_##tDType##_reciprocal, FULL_LOOP, 1, 1, ain, aout }; \
119
+ return na_ndloop(&ndf, 1, self); \
120
+ }
121
+
122
+ #define DEF_NARRAY_ROBJ_RECIPROCAL_METHOD_FUNC() \
123
+ DEF_NARRAY_INT8_RECIPROCAL_METHOD_FUNC(robject, numo_cRObject)
124
+
125
+ #endif /* NUMO_NARRAY_MH_RECIPROCAL_H */