numo-narray-alt 0.9.3
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 +7 -0
- data/Gemfile +14 -0
- data/LICENSE +30 -0
- data/README.md +71 -0
- data/Rakefile +24 -0
- data/ext/numo/narray/SFMT-params.h +97 -0
- data/ext/numo/narray/SFMT-params19937.h +48 -0
- data/ext/numo/narray/SFMT.c +602 -0
- data/ext/numo/narray/SFMT.h +147 -0
- data/ext/numo/narray/array.c +575 -0
- data/ext/numo/narray/data.c +958 -0
- data/ext/numo/narray/extconf.rb +84 -0
- data/ext/numo/narray/index.c +1092 -0
- data/ext/numo/narray/kwargs.c +142 -0
- data/ext/numo/narray/math.c +133 -0
- data/ext/numo/narray/narray.c +1976 -0
- data/ext/numo/narray/narray.def +28 -0
- data/ext/numo/narray/ndloop.c +1840 -0
- data/ext/numo/narray/numo/compat.h +23 -0
- data/ext/numo/narray/numo/intern.h +115 -0
- data/ext/numo/narray/numo/narray.h +480 -0
- data/ext/numo/narray/numo/ndloop.h +93 -0
- data/ext/numo/narray/numo/template.h +149 -0
- data/ext/numo/narray/numo/types/bit.h +38 -0
- data/ext/numo/narray/numo/types/complex.h +404 -0
- data/ext/numo/narray/numo/types/complex_macro.h +384 -0
- data/ext/numo/narray/numo/types/dcomplex.h +42 -0
- data/ext/numo/narray/numo/types/dfloat.h +44 -0
- data/ext/numo/narray/numo/types/float_def.h +34 -0
- data/ext/numo/narray/numo/types/float_macro.h +202 -0
- data/ext/numo/narray/numo/types/int16.h +27 -0
- data/ext/numo/narray/numo/types/int32.h +23 -0
- data/ext/numo/narray/numo/types/int64.h +23 -0
- data/ext/numo/narray/numo/types/int8.h +23 -0
- data/ext/numo/narray/numo/types/int_macro.h +66 -0
- data/ext/numo/narray/numo/types/real_accum.h +481 -0
- data/ext/numo/narray/numo/types/robj_macro.h +78 -0
- data/ext/numo/narray/numo/types/robject.h +25 -0
- data/ext/numo/narray/numo/types/scomplex.h +42 -0
- data/ext/numo/narray/numo/types/sfloat.h +45 -0
- data/ext/numo/narray/numo/types/uint16.h +24 -0
- data/ext/numo/narray/numo/types/uint32.h +20 -0
- data/ext/numo/narray/numo/types/uint64.h +20 -0
- data/ext/numo/narray/numo/types/uint8.h +20 -0
- data/ext/numo/narray/numo/types/uint_macro.h +57 -0
- data/ext/numo/narray/numo/types/xint_macro.h +166 -0
- data/ext/numo/narray/rand.c +40 -0
- data/ext/numo/narray/src/t_bit.c +3236 -0
- data/ext/numo/narray/src/t_dcomplex.c +6776 -0
- data/ext/numo/narray/src/t_dfloat.c +9417 -0
- data/ext/numo/narray/src/t_int16.c +5757 -0
- data/ext/numo/narray/src/t_int32.c +5757 -0
- data/ext/numo/narray/src/t_int64.c +5759 -0
- data/ext/numo/narray/src/t_int8.c +5355 -0
- data/ext/numo/narray/src/t_robject.c +5567 -0
- data/ext/numo/narray/src/t_scomplex.c +6731 -0
- data/ext/numo/narray/src/t_sfloat.c +9374 -0
- data/ext/numo/narray/src/t_uint16.c +5753 -0
- data/ext/numo/narray/src/t_uint32.c +5753 -0
- data/ext/numo/narray/src/t_uint64.c +5755 -0
- data/ext/numo/narray/src/t_uint8.c +5351 -0
- data/ext/numo/narray/step.c +266 -0
- data/ext/numo/narray/struct.c +814 -0
- data/lib/numo/narray/extra.rb +1266 -0
- data/lib/numo/narray.rb +4 -0
- metadata +106 -0
@@ -0,0 +1,3236 @@
|
|
1
|
+
/*
|
2
|
+
t_bit.c
|
3
|
+
Ruby/Numo::NArray - Numerical Array class for Ruby
|
4
|
+
|
5
|
+
created on: 2017-03-11
|
6
|
+
Copyright (C) 2017-2020 Masahiro Tanaka
|
7
|
+
*/
|
8
|
+
#include <assert.h>
|
9
|
+
#include <ruby.h>
|
10
|
+
|
11
|
+
#include "SFMT.h"
|
12
|
+
#include "numo/narray.h"
|
13
|
+
#include "numo/template.h"
|
14
|
+
|
15
|
+
#define m_map(x) m_num_to_data(rb_yield(m_data_to_num(x)))
|
16
|
+
|
17
|
+
#ifdef __SSE2__
|
18
|
+
#include <emmintrin.h>
|
19
|
+
#define SIMD_ALIGNMENT_SIZE 16
|
20
|
+
#endif
|
21
|
+
|
22
|
+
static ID id_cast;
|
23
|
+
static ID id_divmod;
|
24
|
+
static ID id_eq;
|
25
|
+
static ID id_mulsum;
|
26
|
+
static ID id_ne;
|
27
|
+
static ID id_to_a;
|
28
|
+
|
29
|
+
#include <numo/types/bit.h>
|
30
|
+
|
31
|
+
VALUE cT;
|
32
|
+
extern VALUE cRT;
|
33
|
+
|
34
|
+
/*
|
35
|
+
class definition: Numo::Bit
|
36
|
+
*/
|
37
|
+
|
38
|
+
VALUE cT;
|
39
|
+
|
40
|
+
static VALUE bit_store(VALUE, VALUE);
|
41
|
+
|
42
|
+
static size_t bit_memsize(const void* ptr) {
|
43
|
+
size_t size = sizeof(narray_data_t);
|
44
|
+
const narray_data_t* na = (const narray_data_t*)ptr;
|
45
|
+
|
46
|
+
assert(na->base.type == NARRAY_DATA_T);
|
47
|
+
|
48
|
+
if (na->ptr != NULL) {
|
49
|
+
|
50
|
+
size += ((na->base.size - 1) / 8 / sizeof(BIT_DIGIT) + 1) * sizeof(BIT_DIGIT);
|
51
|
+
}
|
52
|
+
if (na->base.size > 0) {
|
53
|
+
if (na->base.shape != NULL && na->base.shape != &(na->base.size)) {
|
54
|
+
size += sizeof(size_t) * na->base.ndim;
|
55
|
+
}
|
56
|
+
}
|
57
|
+
return size;
|
58
|
+
}
|
59
|
+
|
60
|
+
static void bit_free(void* ptr) {
|
61
|
+
narray_data_t* na = (narray_data_t*)ptr;
|
62
|
+
|
63
|
+
assert(na->base.type == NARRAY_DATA_T);
|
64
|
+
|
65
|
+
if (na->ptr != NULL) {
|
66
|
+
if (na->owned) {
|
67
|
+
xfree(na->ptr);
|
68
|
+
}
|
69
|
+
na->ptr = NULL;
|
70
|
+
}
|
71
|
+
if (na->base.size > 0) {
|
72
|
+
if (na->base.shape != NULL && na->base.shape != &(na->base.size)) {
|
73
|
+
xfree(na->base.shape);
|
74
|
+
na->base.shape = NULL;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
xfree(na);
|
78
|
+
}
|
79
|
+
|
80
|
+
static narray_type_info_t bit_info = {
|
81
|
+
|
82
|
+
1, // element_bits
|
83
|
+
0, // element_bytes
|
84
|
+
1, // element_stride (in bits)
|
85
|
+
|
86
|
+
};
|
87
|
+
|
88
|
+
static const rb_data_type_t bit_data_type = {
|
89
|
+
"Numo::Bit",
|
90
|
+
{
|
91
|
+
0,
|
92
|
+
bit_free,
|
93
|
+
bit_memsize,
|
94
|
+
},
|
95
|
+
&na_data_type,
|
96
|
+
&bit_info,
|
97
|
+
RUBY_TYPED_FROZEN_SHAREABLE, // flags
|
98
|
+
};
|
99
|
+
|
100
|
+
static VALUE bit_s_alloc_func(VALUE klass) {
|
101
|
+
narray_data_t* na = ALLOC(narray_data_t);
|
102
|
+
|
103
|
+
na->base.ndim = 0;
|
104
|
+
na->base.type = NARRAY_DATA_T;
|
105
|
+
na->base.flag[0] = NA_FL0_INIT;
|
106
|
+
na->base.flag[1] = NA_FL1_INIT;
|
107
|
+
na->base.size = 0;
|
108
|
+
na->base.shape = NULL;
|
109
|
+
na->base.reduce = INT2FIX(0);
|
110
|
+
na->ptr = NULL;
|
111
|
+
na->owned = FALSE;
|
112
|
+
return TypedData_Wrap_Struct(klass, &bit_data_type, (void*)na);
|
113
|
+
}
|
114
|
+
|
115
|
+
static VALUE bit_allocate(VALUE self) {
|
116
|
+
narray_t* na;
|
117
|
+
char* ptr;
|
118
|
+
|
119
|
+
GetNArray(self, na);
|
120
|
+
|
121
|
+
switch (NA_TYPE(na)) {
|
122
|
+
case NARRAY_DATA_T:
|
123
|
+
ptr = NA_DATA_PTR(na);
|
124
|
+
if (na->size > 0 && ptr == NULL) {
|
125
|
+
ptr = xmalloc(((na->size - 1) / 8 / sizeof(BIT_DIGIT) + 1) * sizeof(BIT_DIGIT));
|
126
|
+
NA_DATA_PTR(na) = ptr;
|
127
|
+
NA_DATA_OWNED(na) = TRUE;
|
128
|
+
}
|
129
|
+
break;
|
130
|
+
case NARRAY_VIEW_T:
|
131
|
+
rb_funcall(NA_VIEW_DATA(na), rb_intern("allocate"), 0);
|
132
|
+
break;
|
133
|
+
default:
|
134
|
+
rb_raise(rb_eRuntimeError, "invalid narray type");
|
135
|
+
}
|
136
|
+
return self;
|
137
|
+
}
|
138
|
+
|
139
|
+
/*
|
140
|
+
Extract an element only if self is a dimensionless NArray.
|
141
|
+
@overload extract
|
142
|
+
@return [Numeric,Numo::NArray]
|
143
|
+
--- Extract element value as Ruby Object if self is a dimensionless NArray,
|
144
|
+
otherwise returns self.
|
145
|
+
*/
|
146
|
+
|
147
|
+
static VALUE bit_extract(VALUE self) {
|
148
|
+
BIT_DIGIT *ptr, val;
|
149
|
+
size_t pos;
|
150
|
+
narray_t* na;
|
151
|
+
GetNArray(self, na);
|
152
|
+
|
153
|
+
if (na->ndim == 0) {
|
154
|
+
pos = na_get_offset(self);
|
155
|
+
ptr = (BIT_DIGIT*)na_get_pointer_for_read(self);
|
156
|
+
val = ((*((ptr) + (pos) / NB)) >> ((pos) % NB)) & 1u;
|
157
|
+
na_release_lock(self);
|
158
|
+
return INT2FIX(val);
|
159
|
+
}
|
160
|
+
return self;
|
161
|
+
}
|
162
|
+
|
163
|
+
static VALUE bit_new_dim0(dtype x) {
|
164
|
+
VALUE v;
|
165
|
+
dtype* ptr;
|
166
|
+
|
167
|
+
v = nary_new(cT, 0, NULL);
|
168
|
+
ptr = (dtype*)(char*)na_get_pointer_for_write(v);
|
169
|
+
*ptr = x;
|
170
|
+
na_release_lock(v);
|
171
|
+
return v;
|
172
|
+
}
|
173
|
+
|
174
|
+
static VALUE bit_store_numeric(VALUE self, VALUE obj) {
|
175
|
+
dtype x;
|
176
|
+
x = m_num_to_data(obj);
|
177
|
+
obj = bit_new_dim0(x);
|
178
|
+
bit_store(self, obj);
|
179
|
+
return self;
|
180
|
+
}
|
181
|
+
|
182
|
+
static void iter_bit_store_bit(na_loop_t* const lp) {
|
183
|
+
size_t n;
|
184
|
+
ssize_t p1, p3;
|
185
|
+
ssize_t s1, s3;
|
186
|
+
size_t *idx1, *idx3;
|
187
|
+
int o1, l1, r1, len;
|
188
|
+
BIT_DIGIT *a1, *a3;
|
189
|
+
BIT_DIGIT x;
|
190
|
+
|
191
|
+
INIT_COUNTER(lp, n);
|
192
|
+
INIT_PTR_BIT_IDX(lp, 0, a3, p3, s3, idx3);
|
193
|
+
INIT_PTR_BIT_IDX(lp, 1, a1, p1, s1, idx1);
|
194
|
+
if (s1 != 1 || s3 != 1 || idx1 || idx3) {
|
195
|
+
for (; n--;) {
|
196
|
+
LOAD_BIT_STEP(a1, p1, s1, idx1, x);
|
197
|
+
STORE_BIT_STEP(a3, p3, s3, idx3, x);
|
198
|
+
}
|
199
|
+
} else {
|
200
|
+
a1 += p1 / NB;
|
201
|
+
p1 %= NB;
|
202
|
+
a3 += p3 / NB;
|
203
|
+
p3 %= NB;
|
204
|
+
o1 = (int)(p1 - p3);
|
205
|
+
l1 = NB + o1;
|
206
|
+
r1 = NB - o1;
|
207
|
+
if (p3 > 0 || n < NB) {
|
208
|
+
len = (int)(NB - p3);
|
209
|
+
if ((int)n < len) len = (int)n;
|
210
|
+
if (o1 >= 0)
|
211
|
+
x = *a1 >> o1;
|
212
|
+
else
|
213
|
+
x = *a1 << -o1;
|
214
|
+
if (p1 + len > (ssize_t)NB) x |= *(a1 + 1) << r1;
|
215
|
+
a1++;
|
216
|
+
*a3 = (x & (SLB(len) << p3)) | (*a3 & ~(SLB(len) << p3));
|
217
|
+
a3++;
|
218
|
+
n -= len;
|
219
|
+
}
|
220
|
+
if (o1 == 0) {
|
221
|
+
for (; n >= NB; n -= NB) {
|
222
|
+
x = *(a1++);
|
223
|
+
*(a3++) = x;
|
224
|
+
}
|
225
|
+
} else {
|
226
|
+
for (; n >= NB; n -= NB) {
|
227
|
+
if (o1 == 0) {
|
228
|
+
x = *a1;
|
229
|
+
} else if (o1 > 0) {
|
230
|
+
x = *a1 >> o1 | *(a1 + 1) << r1;
|
231
|
+
} else {
|
232
|
+
x = *a1 << -o1 | *(a1 - 1) >> l1;
|
233
|
+
}
|
234
|
+
a1++;
|
235
|
+
*(a3++) = x;
|
236
|
+
}
|
237
|
+
}
|
238
|
+
if (n > 0) {
|
239
|
+
if (o1 == 0) {
|
240
|
+
x = *a1;
|
241
|
+
} else if (o1 > 0) {
|
242
|
+
x = *a1 >> o1;
|
243
|
+
if ((int)n > r1) {
|
244
|
+
x |= *(a1 + 1) << r1;
|
245
|
+
}
|
246
|
+
} else {
|
247
|
+
x = *(a1 - 1) >> l1;
|
248
|
+
if ((int)n > -o1) {
|
249
|
+
x |= *a1 << -o1;
|
250
|
+
}
|
251
|
+
}
|
252
|
+
*a3 = (x & SLB(n)) | (*a3 & BALL << n);
|
253
|
+
}
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
static VALUE bit_store_bit(VALUE self, VALUE obj) {
|
258
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
259
|
+
ndfunc_t ndf = {iter_bit_store_bit, FULL_LOOP, 2, 0, ain, 0};
|
260
|
+
|
261
|
+
na_ndloop(&ndf, 2, self, obj);
|
262
|
+
return self;
|
263
|
+
}
|
264
|
+
|
265
|
+
static void iter_bit_store_dfloat(na_loop_t* const lp) {
|
266
|
+
ssize_t i, s1, s2;
|
267
|
+
size_t p1;
|
268
|
+
char* p2;
|
269
|
+
size_t *idx1, *idx2;
|
270
|
+
double x;
|
271
|
+
BIT_DIGIT* a1;
|
272
|
+
BIT_DIGIT y;
|
273
|
+
|
274
|
+
INIT_COUNTER(lp, i);
|
275
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
276
|
+
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
277
|
+
|
278
|
+
if (idx2) {
|
279
|
+
if (idx1) {
|
280
|
+
for (; i--;) {
|
281
|
+
GET_DATA_INDEX(p2, idx2, double, x);
|
282
|
+
y = m_from_real(x);
|
283
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
284
|
+
idx1++;
|
285
|
+
}
|
286
|
+
} else {
|
287
|
+
for (; i--;) {
|
288
|
+
GET_DATA_INDEX(p2, idx2, double, x);
|
289
|
+
y = m_from_real(x);
|
290
|
+
STORE_BIT(a1, p1, y);
|
291
|
+
p1 += s1;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
} else {
|
295
|
+
if (idx1) {
|
296
|
+
for (; i--;) {
|
297
|
+
GET_DATA_STRIDE(p2, s2, double, x);
|
298
|
+
y = m_from_real(x);
|
299
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
300
|
+
idx1++;
|
301
|
+
}
|
302
|
+
} else {
|
303
|
+
for (; i--;) {
|
304
|
+
GET_DATA_STRIDE(p2, s2, double, x);
|
305
|
+
y = m_from_real(x);
|
306
|
+
STORE_BIT(a1, p1, y);
|
307
|
+
p1 += s1;
|
308
|
+
}
|
309
|
+
}
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
313
|
+
static VALUE bit_store_dfloat(VALUE self, VALUE obj) {
|
314
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
315
|
+
ndfunc_t ndf = {iter_bit_store_dfloat, FULL_LOOP, 2, 0, ain, 0};
|
316
|
+
|
317
|
+
na_ndloop(&ndf, 2, self, obj);
|
318
|
+
return self;
|
319
|
+
}
|
320
|
+
|
321
|
+
static void iter_bit_store_sfloat(na_loop_t* const lp) {
|
322
|
+
ssize_t i, s1, s2;
|
323
|
+
size_t p1;
|
324
|
+
char* p2;
|
325
|
+
size_t *idx1, *idx2;
|
326
|
+
float x;
|
327
|
+
BIT_DIGIT* a1;
|
328
|
+
BIT_DIGIT y;
|
329
|
+
|
330
|
+
INIT_COUNTER(lp, i);
|
331
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
332
|
+
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
333
|
+
|
334
|
+
if (idx2) {
|
335
|
+
if (idx1) {
|
336
|
+
for (; i--;) {
|
337
|
+
GET_DATA_INDEX(p2, idx2, float, x);
|
338
|
+
y = m_from_real(x);
|
339
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
340
|
+
idx1++;
|
341
|
+
}
|
342
|
+
} else {
|
343
|
+
for (; i--;) {
|
344
|
+
GET_DATA_INDEX(p2, idx2, float, x);
|
345
|
+
y = m_from_real(x);
|
346
|
+
STORE_BIT(a1, p1, y);
|
347
|
+
p1 += s1;
|
348
|
+
}
|
349
|
+
}
|
350
|
+
} else {
|
351
|
+
if (idx1) {
|
352
|
+
for (; i--;) {
|
353
|
+
GET_DATA_STRIDE(p2, s2, float, x);
|
354
|
+
y = m_from_real(x);
|
355
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
356
|
+
idx1++;
|
357
|
+
}
|
358
|
+
} else {
|
359
|
+
for (; i--;) {
|
360
|
+
GET_DATA_STRIDE(p2, s2, float, x);
|
361
|
+
y = m_from_real(x);
|
362
|
+
STORE_BIT(a1, p1, y);
|
363
|
+
p1 += s1;
|
364
|
+
}
|
365
|
+
}
|
366
|
+
}
|
367
|
+
}
|
368
|
+
|
369
|
+
static VALUE bit_store_sfloat(VALUE self, VALUE obj) {
|
370
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
371
|
+
ndfunc_t ndf = {iter_bit_store_sfloat, FULL_LOOP, 2, 0, ain, 0};
|
372
|
+
|
373
|
+
na_ndloop(&ndf, 2, self, obj);
|
374
|
+
return self;
|
375
|
+
}
|
376
|
+
|
377
|
+
static void iter_bit_store_int64(na_loop_t* const lp) {
|
378
|
+
ssize_t i, s1, s2;
|
379
|
+
size_t p1;
|
380
|
+
char* p2;
|
381
|
+
size_t *idx1, *idx2;
|
382
|
+
int64_t x;
|
383
|
+
BIT_DIGIT* a1;
|
384
|
+
BIT_DIGIT y;
|
385
|
+
|
386
|
+
INIT_COUNTER(lp, i);
|
387
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
388
|
+
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
389
|
+
|
390
|
+
if (idx2) {
|
391
|
+
if (idx1) {
|
392
|
+
for (; i--;) {
|
393
|
+
GET_DATA_INDEX(p2, idx2, int64_t, x);
|
394
|
+
y = m_from_int64(x);
|
395
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
396
|
+
idx1++;
|
397
|
+
}
|
398
|
+
} else {
|
399
|
+
for (; i--;) {
|
400
|
+
GET_DATA_INDEX(p2, idx2, int64_t, x);
|
401
|
+
y = m_from_int64(x);
|
402
|
+
STORE_BIT(a1, p1, y);
|
403
|
+
p1 += s1;
|
404
|
+
}
|
405
|
+
}
|
406
|
+
} else {
|
407
|
+
if (idx1) {
|
408
|
+
for (; i--;) {
|
409
|
+
GET_DATA_STRIDE(p2, s2, int64_t, x);
|
410
|
+
y = m_from_int64(x);
|
411
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
412
|
+
idx1++;
|
413
|
+
}
|
414
|
+
} else {
|
415
|
+
for (; i--;) {
|
416
|
+
GET_DATA_STRIDE(p2, s2, int64_t, x);
|
417
|
+
y = m_from_int64(x);
|
418
|
+
STORE_BIT(a1, p1, y);
|
419
|
+
p1 += s1;
|
420
|
+
}
|
421
|
+
}
|
422
|
+
}
|
423
|
+
}
|
424
|
+
|
425
|
+
static VALUE bit_store_int64(VALUE self, VALUE obj) {
|
426
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
427
|
+
ndfunc_t ndf = {iter_bit_store_int64, FULL_LOOP, 2, 0, ain, 0};
|
428
|
+
|
429
|
+
na_ndloop(&ndf, 2, self, obj);
|
430
|
+
return self;
|
431
|
+
}
|
432
|
+
|
433
|
+
static void iter_bit_store_int32(na_loop_t* const lp) {
|
434
|
+
ssize_t i, s1, s2;
|
435
|
+
size_t p1;
|
436
|
+
char* p2;
|
437
|
+
size_t *idx1, *idx2;
|
438
|
+
int32_t x;
|
439
|
+
BIT_DIGIT* a1;
|
440
|
+
BIT_DIGIT y;
|
441
|
+
|
442
|
+
INIT_COUNTER(lp, i);
|
443
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
444
|
+
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
445
|
+
|
446
|
+
if (idx2) {
|
447
|
+
if (idx1) {
|
448
|
+
for (; i--;) {
|
449
|
+
GET_DATA_INDEX(p2, idx2, int32_t, x);
|
450
|
+
y = m_from_int32(x);
|
451
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
452
|
+
idx1++;
|
453
|
+
}
|
454
|
+
} else {
|
455
|
+
for (; i--;) {
|
456
|
+
GET_DATA_INDEX(p2, idx2, int32_t, x);
|
457
|
+
y = m_from_int32(x);
|
458
|
+
STORE_BIT(a1, p1, y);
|
459
|
+
p1 += s1;
|
460
|
+
}
|
461
|
+
}
|
462
|
+
} else {
|
463
|
+
if (idx1) {
|
464
|
+
for (; i--;) {
|
465
|
+
GET_DATA_STRIDE(p2, s2, int32_t, x);
|
466
|
+
y = m_from_int32(x);
|
467
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
468
|
+
idx1++;
|
469
|
+
}
|
470
|
+
} else {
|
471
|
+
for (; i--;) {
|
472
|
+
GET_DATA_STRIDE(p2, s2, int32_t, x);
|
473
|
+
y = m_from_int32(x);
|
474
|
+
STORE_BIT(a1, p1, y);
|
475
|
+
p1 += s1;
|
476
|
+
}
|
477
|
+
}
|
478
|
+
}
|
479
|
+
}
|
480
|
+
|
481
|
+
static VALUE bit_store_int32(VALUE self, VALUE obj) {
|
482
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
483
|
+
ndfunc_t ndf = {iter_bit_store_int32, FULL_LOOP, 2, 0, ain, 0};
|
484
|
+
|
485
|
+
na_ndloop(&ndf, 2, self, obj);
|
486
|
+
return self;
|
487
|
+
}
|
488
|
+
|
489
|
+
static void iter_bit_store_int16(na_loop_t* const lp) {
|
490
|
+
ssize_t i, s1, s2;
|
491
|
+
size_t p1;
|
492
|
+
char* p2;
|
493
|
+
size_t *idx1, *idx2;
|
494
|
+
int16_t x;
|
495
|
+
BIT_DIGIT* a1;
|
496
|
+
BIT_DIGIT y;
|
497
|
+
|
498
|
+
INIT_COUNTER(lp, i);
|
499
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
500
|
+
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
501
|
+
|
502
|
+
if (idx2) {
|
503
|
+
if (idx1) {
|
504
|
+
for (; i--;) {
|
505
|
+
GET_DATA_INDEX(p2, idx2, int16_t, x);
|
506
|
+
y = m_from_sint(x);
|
507
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
508
|
+
idx1++;
|
509
|
+
}
|
510
|
+
} else {
|
511
|
+
for (; i--;) {
|
512
|
+
GET_DATA_INDEX(p2, idx2, int16_t, x);
|
513
|
+
y = m_from_sint(x);
|
514
|
+
STORE_BIT(a1, p1, y);
|
515
|
+
p1 += s1;
|
516
|
+
}
|
517
|
+
}
|
518
|
+
} else {
|
519
|
+
if (idx1) {
|
520
|
+
for (; i--;) {
|
521
|
+
GET_DATA_STRIDE(p2, s2, int16_t, x);
|
522
|
+
y = m_from_sint(x);
|
523
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
524
|
+
idx1++;
|
525
|
+
}
|
526
|
+
} else {
|
527
|
+
for (; i--;) {
|
528
|
+
GET_DATA_STRIDE(p2, s2, int16_t, x);
|
529
|
+
y = m_from_sint(x);
|
530
|
+
STORE_BIT(a1, p1, y);
|
531
|
+
p1 += s1;
|
532
|
+
}
|
533
|
+
}
|
534
|
+
}
|
535
|
+
}
|
536
|
+
|
537
|
+
static VALUE bit_store_int16(VALUE self, VALUE obj) {
|
538
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
539
|
+
ndfunc_t ndf = {iter_bit_store_int16, FULL_LOOP, 2, 0, ain, 0};
|
540
|
+
|
541
|
+
na_ndloop(&ndf, 2, self, obj);
|
542
|
+
return self;
|
543
|
+
}
|
544
|
+
|
545
|
+
static void iter_bit_store_int8(na_loop_t* const lp) {
|
546
|
+
ssize_t i, s1, s2;
|
547
|
+
size_t p1;
|
548
|
+
char* p2;
|
549
|
+
size_t *idx1, *idx2;
|
550
|
+
int8_t x;
|
551
|
+
BIT_DIGIT* a1;
|
552
|
+
BIT_DIGIT y;
|
553
|
+
|
554
|
+
INIT_COUNTER(lp, i);
|
555
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
556
|
+
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
557
|
+
|
558
|
+
if (idx2) {
|
559
|
+
if (idx1) {
|
560
|
+
for (; i--;) {
|
561
|
+
GET_DATA_INDEX(p2, idx2, int8_t, x);
|
562
|
+
y = m_from_sint(x);
|
563
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
564
|
+
idx1++;
|
565
|
+
}
|
566
|
+
} else {
|
567
|
+
for (; i--;) {
|
568
|
+
GET_DATA_INDEX(p2, idx2, int8_t, x);
|
569
|
+
y = m_from_sint(x);
|
570
|
+
STORE_BIT(a1, p1, y);
|
571
|
+
p1 += s1;
|
572
|
+
}
|
573
|
+
}
|
574
|
+
} else {
|
575
|
+
if (idx1) {
|
576
|
+
for (; i--;) {
|
577
|
+
GET_DATA_STRIDE(p2, s2, int8_t, x);
|
578
|
+
y = m_from_sint(x);
|
579
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
580
|
+
idx1++;
|
581
|
+
}
|
582
|
+
} else {
|
583
|
+
for (; i--;) {
|
584
|
+
GET_DATA_STRIDE(p2, s2, int8_t, x);
|
585
|
+
y = m_from_sint(x);
|
586
|
+
STORE_BIT(a1, p1, y);
|
587
|
+
p1 += s1;
|
588
|
+
}
|
589
|
+
}
|
590
|
+
}
|
591
|
+
}
|
592
|
+
|
593
|
+
static VALUE bit_store_int8(VALUE self, VALUE obj) {
|
594
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
595
|
+
ndfunc_t ndf = {iter_bit_store_int8, FULL_LOOP, 2, 0, ain, 0};
|
596
|
+
|
597
|
+
na_ndloop(&ndf, 2, self, obj);
|
598
|
+
return self;
|
599
|
+
}
|
600
|
+
|
601
|
+
static void iter_bit_store_uint64(na_loop_t* const lp) {
|
602
|
+
ssize_t i, s1, s2;
|
603
|
+
size_t p1;
|
604
|
+
char* p2;
|
605
|
+
size_t *idx1, *idx2;
|
606
|
+
u_int64_t x;
|
607
|
+
BIT_DIGIT* a1;
|
608
|
+
BIT_DIGIT y;
|
609
|
+
|
610
|
+
INIT_COUNTER(lp, i);
|
611
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
612
|
+
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
613
|
+
|
614
|
+
if (idx2) {
|
615
|
+
if (idx1) {
|
616
|
+
for (; i--;) {
|
617
|
+
GET_DATA_INDEX(p2, idx2, u_int64_t, x);
|
618
|
+
y = m_from_uint64(x);
|
619
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
620
|
+
idx1++;
|
621
|
+
}
|
622
|
+
} else {
|
623
|
+
for (; i--;) {
|
624
|
+
GET_DATA_INDEX(p2, idx2, u_int64_t, x);
|
625
|
+
y = m_from_uint64(x);
|
626
|
+
STORE_BIT(a1, p1, y);
|
627
|
+
p1 += s1;
|
628
|
+
}
|
629
|
+
}
|
630
|
+
} else {
|
631
|
+
if (idx1) {
|
632
|
+
for (; i--;) {
|
633
|
+
GET_DATA_STRIDE(p2, s2, u_int64_t, x);
|
634
|
+
y = m_from_uint64(x);
|
635
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
636
|
+
idx1++;
|
637
|
+
}
|
638
|
+
} else {
|
639
|
+
for (; i--;) {
|
640
|
+
GET_DATA_STRIDE(p2, s2, u_int64_t, x);
|
641
|
+
y = m_from_uint64(x);
|
642
|
+
STORE_BIT(a1, p1, y);
|
643
|
+
p1 += s1;
|
644
|
+
}
|
645
|
+
}
|
646
|
+
}
|
647
|
+
}
|
648
|
+
|
649
|
+
static VALUE bit_store_uint64(VALUE self, VALUE obj) {
|
650
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
651
|
+
ndfunc_t ndf = {iter_bit_store_uint64, FULL_LOOP, 2, 0, ain, 0};
|
652
|
+
|
653
|
+
na_ndloop(&ndf, 2, self, obj);
|
654
|
+
return self;
|
655
|
+
}
|
656
|
+
|
657
|
+
static void iter_bit_store_uint32(na_loop_t* const lp) {
|
658
|
+
ssize_t i, s1, s2;
|
659
|
+
size_t p1;
|
660
|
+
char* p2;
|
661
|
+
size_t *idx1, *idx2;
|
662
|
+
u_int32_t x;
|
663
|
+
BIT_DIGIT* a1;
|
664
|
+
BIT_DIGIT y;
|
665
|
+
|
666
|
+
INIT_COUNTER(lp, i);
|
667
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
668
|
+
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
669
|
+
|
670
|
+
if (idx2) {
|
671
|
+
if (idx1) {
|
672
|
+
for (; i--;) {
|
673
|
+
GET_DATA_INDEX(p2, idx2, u_int32_t, x);
|
674
|
+
y = m_from_uint32(x);
|
675
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
676
|
+
idx1++;
|
677
|
+
}
|
678
|
+
} else {
|
679
|
+
for (; i--;) {
|
680
|
+
GET_DATA_INDEX(p2, idx2, u_int32_t, x);
|
681
|
+
y = m_from_uint32(x);
|
682
|
+
STORE_BIT(a1, p1, y);
|
683
|
+
p1 += s1;
|
684
|
+
}
|
685
|
+
}
|
686
|
+
} else {
|
687
|
+
if (idx1) {
|
688
|
+
for (; i--;) {
|
689
|
+
GET_DATA_STRIDE(p2, s2, u_int32_t, x);
|
690
|
+
y = m_from_uint32(x);
|
691
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
692
|
+
idx1++;
|
693
|
+
}
|
694
|
+
} else {
|
695
|
+
for (; i--;) {
|
696
|
+
GET_DATA_STRIDE(p2, s2, u_int32_t, x);
|
697
|
+
y = m_from_uint32(x);
|
698
|
+
STORE_BIT(a1, p1, y);
|
699
|
+
p1 += s1;
|
700
|
+
}
|
701
|
+
}
|
702
|
+
}
|
703
|
+
}
|
704
|
+
|
705
|
+
static VALUE bit_store_uint32(VALUE self, VALUE obj) {
|
706
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
707
|
+
ndfunc_t ndf = {iter_bit_store_uint32, FULL_LOOP, 2, 0, ain, 0};
|
708
|
+
|
709
|
+
na_ndloop(&ndf, 2, self, obj);
|
710
|
+
return self;
|
711
|
+
}
|
712
|
+
|
713
|
+
static void iter_bit_store_uint16(na_loop_t* const lp) {
|
714
|
+
ssize_t i, s1, s2;
|
715
|
+
size_t p1;
|
716
|
+
char* p2;
|
717
|
+
size_t *idx1, *idx2;
|
718
|
+
u_int16_t x;
|
719
|
+
BIT_DIGIT* a1;
|
720
|
+
BIT_DIGIT y;
|
721
|
+
|
722
|
+
INIT_COUNTER(lp, i);
|
723
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
724
|
+
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
725
|
+
|
726
|
+
if (idx2) {
|
727
|
+
if (idx1) {
|
728
|
+
for (; i--;) {
|
729
|
+
GET_DATA_INDEX(p2, idx2, u_int16_t, x);
|
730
|
+
y = m_from_sint(x);
|
731
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
732
|
+
idx1++;
|
733
|
+
}
|
734
|
+
} else {
|
735
|
+
for (; i--;) {
|
736
|
+
GET_DATA_INDEX(p2, idx2, u_int16_t, x);
|
737
|
+
y = m_from_sint(x);
|
738
|
+
STORE_BIT(a1, p1, y);
|
739
|
+
p1 += s1;
|
740
|
+
}
|
741
|
+
}
|
742
|
+
} else {
|
743
|
+
if (idx1) {
|
744
|
+
for (; i--;) {
|
745
|
+
GET_DATA_STRIDE(p2, s2, u_int16_t, x);
|
746
|
+
y = m_from_sint(x);
|
747
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
748
|
+
idx1++;
|
749
|
+
}
|
750
|
+
} else {
|
751
|
+
for (; i--;) {
|
752
|
+
GET_DATA_STRIDE(p2, s2, u_int16_t, x);
|
753
|
+
y = m_from_sint(x);
|
754
|
+
STORE_BIT(a1, p1, y);
|
755
|
+
p1 += s1;
|
756
|
+
}
|
757
|
+
}
|
758
|
+
}
|
759
|
+
}
|
760
|
+
|
761
|
+
static VALUE bit_store_uint16(VALUE self, VALUE obj) {
|
762
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
763
|
+
ndfunc_t ndf = {iter_bit_store_uint16, FULL_LOOP, 2, 0, ain, 0};
|
764
|
+
|
765
|
+
na_ndloop(&ndf, 2, self, obj);
|
766
|
+
return self;
|
767
|
+
}
|
768
|
+
|
769
|
+
static void iter_bit_store_uint8(na_loop_t* const lp) {
|
770
|
+
ssize_t i, s1, s2;
|
771
|
+
size_t p1;
|
772
|
+
char* p2;
|
773
|
+
size_t *idx1, *idx2;
|
774
|
+
u_int8_t x;
|
775
|
+
BIT_DIGIT* a1;
|
776
|
+
BIT_DIGIT y;
|
777
|
+
|
778
|
+
INIT_COUNTER(lp, i);
|
779
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
780
|
+
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
781
|
+
|
782
|
+
if (idx2) {
|
783
|
+
if (idx1) {
|
784
|
+
for (; i--;) {
|
785
|
+
GET_DATA_INDEX(p2, idx2, u_int8_t, x);
|
786
|
+
y = m_from_sint(x);
|
787
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
788
|
+
idx1++;
|
789
|
+
}
|
790
|
+
} else {
|
791
|
+
for (; i--;) {
|
792
|
+
GET_DATA_INDEX(p2, idx2, u_int8_t, x);
|
793
|
+
y = m_from_sint(x);
|
794
|
+
STORE_BIT(a1, p1, y);
|
795
|
+
p1 += s1;
|
796
|
+
}
|
797
|
+
}
|
798
|
+
} else {
|
799
|
+
if (idx1) {
|
800
|
+
for (; i--;) {
|
801
|
+
GET_DATA_STRIDE(p2, s2, u_int8_t, x);
|
802
|
+
y = m_from_sint(x);
|
803
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
804
|
+
idx1++;
|
805
|
+
}
|
806
|
+
} else {
|
807
|
+
for (; i--;) {
|
808
|
+
GET_DATA_STRIDE(p2, s2, u_int8_t, x);
|
809
|
+
y = m_from_sint(x);
|
810
|
+
STORE_BIT(a1, p1, y);
|
811
|
+
p1 += s1;
|
812
|
+
}
|
813
|
+
}
|
814
|
+
}
|
815
|
+
}
|
816
|
+
|
817
|
+
static VALUE bit_store_uint8(VALUE self, VALUE obj) {
|
818
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
819
|
+
ndfunc_t ndf = {iter_bit_store_uint8, FULL_LOOP, 2, 0, ain, 0};
|
820
|
+
|
821
|
+
na_ndloop(&ndf, 2, self, obj);
|
822
|
+
return self;
|
823
|
+
}
|
824
|
+
|
825
|
+
static void iter_bit_store_robject(na_loop_t* const lp) {
|
826
|
+
ssize_t i, s1, s2;
|
827
|
+
size_t p1;
|
828
|
+
char* p2;
|
829
|
+
size_t *idx1, *idx2;
|
830
|
+
VALUE x;
|
831
|
+
BIT_DIGIT* a1;
|
832
|
+
BIT_DIGIT y;
|
833
|
+
|
834
|
+
INIT_COUNTER(lp, i);
|
835
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
836
|
+
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
837
|
+
|
838
|
+
if (idx2) {
|
839
|
+
if (idx1) {
|
840
|
+
for (; i--;) {
|
841
|
+
GET_DATA_INDEX(p2, idx2, VALUE, x);
|
842
|
+
y = m_num_to_data(x);
|
843
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
844
|
+
idx1++;
|
845
|
+
}
|
846
|
+
} else {
|
847
|
+
for (; i--;) {
|
848
|
+
GET_DATA_INDEX(p2, idx2, VALUE, x);
|
849
|
+
y = m_num_to_data(x);
|
850
|
+
STORE_BIT(a1, p1, y);
|
851
|
+
p1 += s1;
|
852
|
+
}
|
853
|
+
}
|
854
|
+
} else {
|
855
|
+
if (idx1) {
|
856
|
+
for (; i--;) {
|
857
|
+
GET_DATA_STRIDE(p2, s2, VALUE, x);
|
858
|
+
y = m_num_to_data(x);
|
859
|
+
STORE_BIT(a1, p1 + *idx1, y);
|
860
|
+
idx1++;
|
861
|
+
}
|
862
|
+
} else {
|
863
|
+
for (; i--;) {
|
864
|
+
GET_DATA_STRIDE(p2, s2, VALUE, x);
|
865
|
+
y = m_num_to_data(x);
|
866
|
+
STORE_BIT(a1, p1, y);
|
867
|
+
p1 += s1;
|
868
|
+
}
|
869
|
+
}
|
870
|
+
}
|
871
|
+
}
|
872
|
+
|
873
|
+
static VALUE bit_store_robject(VALUE self, VALUE obj) {
|
874
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
|
875
|
+
ndfunc_t ndf = {iter_bit_store_robject, FULL_LOOP, 2, 0, ain, 0};
|
876
|
+
|
877
|
+
na_ndloop(&ndf, 2, self, obj);
|
878
|
+
return self;
|
879
|
+
}
|
880
|
+
|
881
|
+
static void iter_bit_store_array(na_loop_t* const lp) {
|
882
|
+
size_t i, n;
|
883
|
+
size_t i1, n1;
|
884
|
+
VALUE v1, *ptr;
|
885
|
+
BIT_DIGIT* a1;
|
886
|
+
size_t p1;
|
887
|
+
size_t s1, *idx1;
|
888
|
+
VALUE x;
|
889
|
+
double y;
|
890
|
+
BIT_DIGIT z;
|
891
|
+
size_t len, c;
|
892
|
+
double beg, step;
|
893
|
+
|
894
|
+
INIT_COUNTER(lp, n);
|
895
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
896
|
+
v1 = lp->args[1].value;
|
897
|
+
i = 0;
|
898
|
+
|
899
|
+
if (lp->args[1].ptr) {
|
900
|
+
if (v1 == Qtrue) {
|
901
|
+
iter_bit_store_bit(lp);
|
902
|
+
i = lp->args[1].shape[0];
|
903
|
+
if (idx1) {
|
904
|
+
idx1 += i;
|
905
|
+
} else {
|
906
|
+
p1 += s1 * i;
|
907
|
+
}
|
908
|
+
}
|
909
|
+
goto loop_end;
|
910
|
+
}
|
911
|
+
|
912
|
+
ptr = &v1;
|
913
|
+
|
914
|
+
switch (TYPE(v1)) {
|
915
|
+
case T_ARRAY:
|
916
|
+
n1 = RARRAY_LEN(v1);
|
917
|
+
ptr = RARRAY_PTR(v1);
|
918
|
+
break;
|
919
|
+
case T_NIL:
|
920
|
+
n1 = 0;
|
921
|
+
break;
|
922
|
+
default:
|
923
|
+
n1 = 1;
|
924
|
+
}
|
925
|
+
|
926
|
+
if (idx1) {
|
927
|
+
for (i = i1 = 0; i1 < n1 && i < n; i++, i1++) {
|
928
|
+
x = ptr[i1];
|
929
|
+
if (rb_obj_is_kind_of(x, rb_cRange)
|
930
|
+
#ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
|
931
|
+
|| rb_obj_is_kind_of(x, rb_cArithSeq)
|
932
|
+
#else
|
933
|
+
|| rb_obj_is_kind_of(x, rb_cEnumerator)
|
934
|
+
#endif
|
935
|
+
) {
|
936
|
+
nary_step_sequence(x, &len, &beg, &step);
|
937
|
+
for (c = 0; c < len && i < n; c++, i++) {
|
938
|
+
y = beg + step * c;
|
939
|
+
z = m_from_double(y);
|
940
|
+
STORE_BIT(a1, p1 + *idx1, z);
|
941
|
+
idx1++;
|
942
|
+
}
|
943
|
+
}
|
944
|
+
if (TYPE(x) != T_ARRAY) {
|
945
|
+
if (x == Qnil) x = INT2FIX(0);
|
946
|
+
z = m_num_to_data(x);
|
947
|
+
STORE_BIT(a1, p1 + *idx1, z);
|
948
|
+
idx1++;
|
949
|
+
}
|
950
|
+
}
|
951
|
+
} else {
|
952
|
+
for (i = i1 = 0; i1 < n1 && i < n; i++, i1++) {
|
953
|
+
x = ptr[i1];
|
954
|
+
if (rb_obj_is_kind_of(x, rb_cRange)
|
955
|
+
#ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
|
956
|
+
|| rb_obj_is_kind_of(x, rb_cArithSeq)
|
957
|
+
#else
|
958
|
+
|| rb_obj_is_kind_of(x, rb_cEnumerator)
|
959
|
+
#endif
|
960
|
+
) {
|
961
|
+
nary_step_sequence(x, &len, &beg, &step);
|
962
|
+
for (c = 0; c < len && i < n; c++, i++) {
|
963
|
+
y = beg + step * c;
|
964
|
+
z = m_from_double(y);
|
965
|
+
STORE_BIT(a1, p1, z);
|
966
|
+
p1 += s1;
|
967
|
+
}
|
968
|
+
}
|
969
|
+
if (TYPE(x) != T_ARRAY) {
|
970
|
+
z = m_num_to_data(x);
|
971
|
+
STORE_BIT(a1, p1, z);
|
972
|
+
p1 += s1;
|
973
|
+
}
|
974
|
+
}
|
975
|
+
}
|
976
|
+
|
977
|
+
loop_end:
|
978
|
+
z = m_zero;
|
979
|
+
if (idx1) {
|
980
|
+
for (; i < n; i++) {
|
981
|
+
STORE_BIT(a1, p1 + *idx1, z);
|
982
|
+
idx1++;
|
983
|
+
}
|
984
|
+
} else {
|
985
|
+
for (; i < n; i++) {
|
986
|
+
STORE_BIT(a1, p1, z);
|
987
|
+
p1 += s1;
|
988
|
+
}
|
989
|
+
}
|
990
|
+
}
|
991
|
+
|
992
|
+
static VALUE bit_store_array(VALUE self, VALUE rary) {
|
993
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {rb_cArray, 0}};
|
994
|
+
ndfunc_t ndf = {iter_bit_store_array, FULL_LOOP, 2, 0, ain, 0};
|
995
|
+
|
996
|
+
na_ndloop_store_rarray(&ndf, self, rary);
|
997
|
+
return self;
|
998
|
+
}
|
999
|
+
|
1000
|
+
/*
|
1001
|
+
Store elements to Numo::Bit from other.
|
1002
|
+
@overload store(other)
|
1003
|
+
@param [Object] other
|
1004
|
+
@return [Numo::Bit] self
|
1005
|
+
*/
|
1006
|
+
static VALUE bit_store(VALUE self, VALUE obj) {
|
1007
|
+
VALUE r, klass;
|
1008
|
+
|
1009
|
+
klass = rb_obj_class(obj);
|
1010
|
+
|
1011
|
+
if (klass == numo_cBit) {
|
1012
|
+
bit_store_bit(self, obj);
|
1013
|
+
return self;
|
1014
|
+
}
|
1015
|
+
|
1016
|
+
if (IS_INTEGER_CLASS(klass) || klass == rb_cFloat || klass == rb_cComplex) {
|
1017
|
+
bit_store_numeric(self, obj);
|
1018
|
+
return self;
|
1019
|
+
}
|
1020
|
+
|
1021
|
+
if (klass == numo_cDFloat) {
|
1022
|
+
bit_store_dfloat(self, obj);
|
1023
|
+
return self;
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
if (klass == numo_cSFloat) {
|
1027
|
+
bit_store_sfloat(self, obj);
|
1028
|
+
return self;
|
1029
|
+
}
|
1030
|
+
|
1031
|
+
if (klass == numo_cInt64) {
|
1032
|
+
bit_store_int64(self, obj);
|
1033
|
+
return self;
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
if (klass == numo_cInt32) {
|
1037
|
+
bit_store_int32(self, obj);
|
1038
|
+
return self;
|
1039
|
+
}
|
1040
|
+
|
1041
|
+
if (klass == numo_cInt16) {
|
1042
|
+
bit_store_int16(self, obj);
|
1043
|
+
return self;
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
if (klass == numo_cInt8) {
|
1047
|
+
bit_store_int8(self, obj);
|
1048
|
+
return self;
|
1049
|
+
}
|
1050
|
+
|
1051
|
+
if (klass == numo_cUInt64) {
|
1052
|
+
bit_store_uint64(self, obj);
|
1053
|
+
return self;
|
1054
|
+
}
|
1055
|
+
|
1056
|
+
if (klass == numo_cUInt32) {
|
1057
|
+
bit_store_uint32(self, obj);
|
1058
|
+
return self;
|
1059
|
+
}
|
1060
|
+
|
1061
|
+
if (klass == numo_cUInt16) {
|
1062
|
+
bit_store_uint16(self, obj);
|
1063
|
+
return self;
|
1064
|
+
}
|
1065
|
+
|
1066
|
+
if (klass == numo_cUInt8) {
|
1067
|
+
bit_store_uint8(self, obj);
|
1068
|
+
return self;
|
1069
|
+
}
|
1070
|
+
|
1071
|
+
if (klass == numo_cRObject) {
|
1072
|
+
bit_store_robject(self, obj);
|
1073
|
+
return self;
|
1074
|
+
}
|
1075
|
+
|
1076
|
+
if (klass == rb_cArray) {
|
1077
|
+
bit_store_array(self, obj);
|
1078
|
+
return self;
|
1079
|
+
}
|
1080
|
+
|
1081
|
+
if (IsNArray(obj)) {
|
1082
|
+
r = rb_funcall(obj, rb_intern("coerce_cast"), 1, cT);
|
1083
|
+
if (rb_obj_class(r) == cT) {
|
1084
|
+
bit_store(self, r);
|
1085
|
+
return self;
|
1086
|
+
}
|
1087
|
+
}
|
1088
|
+
|
1089
|
+
rb_raise(nary_eCastError, "unknown conversion from %s to %s", rb_class2name(rb_obj_class(obj)),
|
1090
|
+
rb_class2name(rb_obj_class(self)));
|
1091
|
+
|
1092
|
+
return self;
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
/*
|
1096
|
+
Convert a data value of obj (with a single element) to dtype.
|
1097
|
+
*/
|
1098
|
+
static dtype bit_extract_data(VALUE obj) {
|
1099
|
+
narray_t* na;
|
1100
|
+
dtype x;
|
1101
|
+
char* ptr;
|
1102
|
+
size_t pos;
|
1103
|
+
VALUE r, klass;
|
1104
|
+
|
1105
|
+
if (IsNArray(obj)) {
|
1106
|
+
GetNArray(obj, na);
|
1107
|
+
if (na->size != 1) {
|
1108
|
+
rb_raise(nary_eShapeError, "narray size should be 1");
|
1109
|
+
}
|
1110
|
+
klass = rb_obj_class(obj);
|
1111
|
+
ptr = na_get_pointer_for_read(obj);
|
1112
|
+
pos = na_get_offset(obj);
|
1113
|
+
|
1114
|
+
if (klass == numo_cBit) {
|
1115
|
+
{
|
1116
|
+
BIT_DIGIT b;
|
1117
|
+
LOAD_BIT(ptr, pos, b);
|
1118
|
+
x = m_from_sint(b);
|
1119
|
+
};
|
1120
|
+
return x;
|
1121
|
+
}
|
1122
|
+
|
1123
|
+
if (klass == numo_cDFloat) {
|
1124
|
+
x = m_from_real(*(double*)(ptr + pos));
|
1125
|
+
return x;
|
1126
|
+
}
|
1127
|
+
|
1128
|
+
if (klass == numo_cSFloat) {
|
1129
|
+
x = m_from_real(*(float*)(ptr + pos));
|
1130
|
+
return x;
|
1131
|
+
}
|
1132
|
+
|
1133
|
+
if (klass == numo_cInt64) {
|
1134
|
+
x = m_from_int64(*(int64_t*)(ptr + pos));
|
1135
|
+
return x;
|
1136
|
+
}
|
1137
|
+
|
1138
|
+
if (klass == numo_cInt32) {
|
1139
|
+
x = m_from_int32(*(int32_t*)(ptr + pos));
|
1140
|
+
return x;
|
1141
|
+
}
|
1142
|
+
|
1143
|
+
if (klass == numo_cInt16) {
|
1144
|
+
x = m_from_sint(*(int16_t*)(ptr + pos));
|
1145
|
+
return x;
|
1146
|
+
}
|
1147
|
+
|
1148
|
+
if (klass == numo_cInt8) {
|
1149
|
+
x = m_from_sint(*(int8_t*)(ptr + pos));
|
1150
|
+
return x;
|
1151
|
+
}
|
1152
|
+
|
1153
|
+
if (klass == numo_cUInt64) {
|
1154
|
+
x = m_from_uint64(*(u_int64_t*)(ptr + pos));
|
1155
|
+
return x;
|
1156
|
+
}
|
1157
|
+
|
1158
|
+
if (klass == numo_cUInt32) {
|
1159
|
+
x = m_from_uint32(*(u_int32_t*)(ptr + pos));
|
1160
|
+
return x;
|
1161
|
+
}
|
1162
|
+
|
1163
|
+
if (klass == numo_cUInt16) {
|
1164
|
+
x = m_from_sint(*(u_int16_t*)(ptr + pos));
|
1165
|
+
return x;
|
1166
|
+
}
|
1167
|
+
|
1168
|
+
if (klass == numo_cUInt8) {
|
1169
|
+
x = m_from_sint(*(u_int8_t*)(ptr + pos));
|
1170
|
+
return x;
|
1171
|
+
}
|
1172
|
+
|
1173
|
+
if (klass == numo_cRObject) {
|
1174
|
+
x = m_num_to_data(*(VALUE*)(ptr + pos));
|
1175
|
+
return x;
|
1176
|
+
}
|
1177
|
+
|
1178
|
+
// coerce
|
1179
|
+
r = rb_funcall(obj, rb_intern("coerce_cast"), 1, cT);
|
1180
|
+
if (rb_obj_class(r) == cT) {
|
1181
|
+
return bit_extract_data(r);
|
1182
|
+
}
|
1183
|
+
|
1184
|
+
rb_raise(nary_eCastError, "unknown conversion from %s to %s", rb_class2name(rb_obj_class(obj)), rb_class2name(cT));
|
1185
|
+
}
|
1186
|
+
if (TYPE(obj) == T_ARRAY) {
|
1187
|
+
if (RARRAY_LEN(obj) != 1) {
|
1188
|
+
rb_raise(nary_eShapeError, "array size should be 1");
|
1189
|
+
}
|
1190
|
+
return m_num_to_data(RARRAY_AREF(obj, 0));
|
1191
|
+
}
|
1192
|
+
return m_num_to_data(obj);
|
1193
|
+
}
|
1194
|
+
|
1195
|
+
static VALUE bit_cast_array(VALUE rary) {
|
1196
|
+
VALUE nary;
|
1197
|
+
narray_t* na;
|
1198
|
+
|
1199
|
+
nary = na_s_new_like(cT, rary);
|
1200
|
+
GetNArray(nary, na);
|
1201
|
+
if (na->size > 0) {
|
1202
|
+
bit_store_array(nary, rary);
|
1203
|
+
}
|
1204
|
+
return nary;
|
1205
|
+
}
|
1206
|
+
|
1207
|
+
/*
|
1208
|
+
Cast object to Numo::Bit.
|
1209
|
+
@overload [](elements)
|
1210
|
+
@overload cast(array)
|
1211
|
+
@param [Numeric,Array] elements
|
1212
|
+
@param [Array] array
|
1213
|
+
@return [Numo::Bit]
|
1214
|
+
*/
|
1215
|
+
static VALUE bit_s_cast(VALUE type, VALUE obj) {
|
1216
|
+
VALUE v;
|
1217
|
+
narray_t* na;
|
1218
|
+
dtype x;
|
1219
|
+
|
1220
|
+
if (rb_obj_class(obj) == cT) {
|
1221
|
+
return obj;
|
1222
|
+
}
|
1223
|
+
if (RTEST(rb_obj_is_kind_of(obj, rb_cNumeric))) {
|
1224
|
+
x = m_num_to_data(obj);
|
1225
|
+
return bit_new_dim0(x);
|
1226
|
+
}
|
1227
|
+
if (RTEST(rb_obj_is_kind_of(obj, rb_cArray))) {
|
1228
|
+
return bit_cast_array(obj);
|
1229
|
+
}
|
1230
|
+
if (IsNArray(obj)) {
|
1231
|
+
GetNArray(obj, na);
|
1232
|
+
v = nary_new(cT, NA_NDIM(na), NA_SHAPE(na));
|
1233
|
+
if (NA_SIZE(na) > 0) {
|
1234
|
+
bit_store(v, obj);
|
1235
|
+
}
|
1236
|
+
return v;
|
1237
|
+
}
|
1238
|
+
if (rb_respond_to(obj, id_to_a)) {
|
1239
|
+
obj = rb_funcall(obj, id_to_a, 0);
|
1240
|
+
if (TYPE(obj) != T_ARRAY) {
|
1241
|
+
rb_raise(rb_eTypeError, "`to_a' did not return Array");
|
1242
|
+
}
|
1243
|
+
return bit_cast_array(obj);
|
1244
|
+
}
|
1245
|
+
|
1246
|
+
rb_raise(nary_eCastError, "cannot cast to %s", rb_class2name(type));
|
1247
|
+
return Qnil;
|
1248
|
+
}
|
1249
|
+
|
1250
|
+
/*
|
1251
|
+
Multi-dimensional element reference.
|
1252
|
+
@overload [](dim0,...,dimL)
|
1253
|
+
@param [Numeric,Range,Array,Numo::Int32,Numo::Int64,Numo::Bit,TrueClass,FalseClass,Symbol] dim0,...,dimL multi-dimensional
|
1254
|
+
indices.
|
1255
|
+
@return [Numeric,Numo::Bit] an element or NArray view.
|
1256
|
+
@see Numo::NArray#[]
|
1257
|
+
@see #[]=
|
1258
|
+
|
1259
|
+
@example
|
1260
|
+
a = Numo::Int32.new(3,4).seq
|
1261
|
+
# => Numo::Int32#shape=[3,4]
|
1262
|
+
# [[0, 1, 2, 3],
|
1263
|
+
# [4, 5, 6, 7],
|
1264
|
+
# [8, 9, 10, 11]]
|
1265
|
+
|
1266
|
+
b = (a%2).eq(0)
|
1267
|
+
# => Numo::Bit#shape=[3,4]
|
1268
|
+
# [[1, 0, 1, 0],
|
1269
|
+
# [1, 0, 1, 0],
|
1270
|
+
# [1, 0, 1, 0]]
|
1271
|
+
|
1272
|
+
b[true,(0..-1)%2]
|
1273
|
+
# => Numo::Bit(view)#shape=[3,2]
|
1274
|
+
# [[1, 1],
|
1275
|
+
# [1, 1],
|
1276
|
+
# [1, 1]]
|
1277
|
+
|
1278
|
+
b[1,1]
|
1279
|
+
# => 0
|
1280
|
+
*/
|
1281
|
+
static VALUE bit_aref(int argc, VALUE* argv, VALUE self) {
|
1282
|
+
int nd;
|
1283
|
+
size_t pos;
|
1284
|
+
char* ptr;
|
1285
|
+
dtype x;
|
1286
|
+
|
1287
|
+
nd = na_get_result_dimension(self, argc, argv, 1, &pos);
|
1288
|
+
if (nd) {
|
1289
|
+
return na_aref_main(argc, argv, self, 0, nd);
|
1290
|
+
} else {
|
1291
|
+
ptr = na_get_pointer_for_read(self);
|
1292
|
+
LOAD_BIT(ptr, pos, x);
|
1293
|
+
return m_data_to_num(x);
|
1294
|
+
}
|
1295
|
+
}
|
1296
|
+
|
1297
|
+
/*
|
1298
|
+
Multi-dimensional element assignment.
|
1299
|
+
@overload []=(dim0,...,dimL,val)
|
1300
|
+
@param [Numeric,Range,Array,Numo::Int32,Numo::Int64,Numo::Bit,TrueClass,FalseClass,Symbol] dim0,...,dimL multi-dimensional
|
1301
|
+
indices.
|
1302
|
+
@param [Numeric,Numo::NArray,Array] val Value(s) to be set to self.
|
1303
|
+
@return [Numeric,Numo::NArray,Array] returns `val` (last argument).
|
1304
|
+
@see Numo::NArray#[]=
|
1305
|
+
@see #[]
|
1306
|
+
|
1307
|
+
@example
|
1308
|
+
a = Numo::Bit.new(4,5).fill(0)
|
1309
|
+
# => Numo::Bit#shape=[4,5]
|
1310
|
+
# [[0, 0, 0, 0, 0],
|
1311
|
+
# [0, 0, 0, 0, 0],
|
1312
|
+
# [0, 0, 0, 0, 0],
|
1313
|
+
# [0, 0, 0, 0, 0]]
|
1314
|
+
|
1315
|
+
a[(0..-1)%2,(1..-1)%2] = 1
|
1316
|
+
a
|
1317
|
+
# => Numo::Bit#shape=[4,5]
|
1318
|
+
# [[0, 1, 0, 1, 0],
|
1319
|
+
# [0, 0, 0, 0, 0],
|
1320
|
+
# [0, 1, 0, 1, 0],
|
1321
|
+
# [0, 0, 0, 0, 0]]
|
1322
|
+
*/
|
1323
|
+
static VALUE bit_aset(int argc, VALUE* argv, VALUE self) {
|
1324
|
+
int nd;
|
1325
|
+
size_t pos;
|
1326
|
+
char* ptr;
|
1327
|
+
VALUE a;
|
1328
|
+
dtype x;
|
1329
|
+
|
1330
|
+
argc--;
|
1331
|
+
if (argc == 0) {
|
1332
|
+
bit_store(self, argv[argc]);
|
1333
|
+
} else {
|
1334
|
+
nd = na_get_result_dimension(self, argc, argv, 1, &pos);
|
1335
|
+
if (nd) {
|
1336
|
+
a = na_aref_main(argc, argv, self, 0, nd);
|
1337
|
+
bit_store(a, argv[argc]);
|
1338
|
+
} else {
|
1339
|
+
x = bit_extract_data(argv[argc]);
|
1340
|
+
ptr = na_get_pointer_for_read_write(self);
|
1341
|
+
STORE_BIT(ptr, pos, x);
|
1342
|
+
}
|
1343
|
+
}
|
1344
|
+
return argv[argc];
|
1345
|
+
}
|
1346
|
+
|
1347
|
+
/*
|
1348
|
+
return NArray with cast to the type of self.
|
1349
|
+
@overload coerce_cast(type)
|
1350
|
+
@return [nil]
|
1351
|
+
*/
|
1352
|
+
static VALUE bit_coerce_cast(VALUE self, VALUE type) {
|
1353
|
+
return Qnil;
|
1354
|
+
}
|
1355
|
+
|
1356
|
+
static void iter_bit_to_a(na_loop_t* const lp) {
|
1357
|
+
size_t i;
|
1358
|
+
BIT_DIGIT* a1;
|
1359
|
+
size_t p1;
|
1360
|
+
ssize_t s1;
|
1361
|
+
size_t* idx1;
|
1362
|
+
BIT_DIGIT x = 0;
|
1363
|
+
VALUE a, y;
|
1364
|
+
|
1365
|
+
INIT_COUNTER(lp, i);
|
1366
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
1367
|
+
a = rb_ary_new2(i);
|
1368
|
+
rb_ary_push(lp->args[1].value, a);
|
1369
|
+
if (idx1) {
|
1370
|
+
for (; i--;) {
|
1371
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
1372
|
+
idx1++;
|
1373
|
+
y = m_data_to_num(x);
|
1374
|
+
rb_ary_push(a, y);
|
1375
|
+
}
|
1376
|
+
} else {
|
1377
|
+
for (; i--;) {
|
1378
|
+
LOAD_BIT(a1, p1, x);
|
1379
|
+
p1 += s1;
|
1380
|
+
y = m_data_to_num(x);
|
1381
|
+
rb_ary_push(a, y);
|
1382
|
+
}
|
1383
|
+
}
|
1384
|
+
}
|
1385
|
+
|
1386
|
+
/*
|
1387
|
+
Convert self to Array.
|
1388
|
+
@overload to_a
|
1389
|
+
@return [Array]
|
1390
|
+
*/
|
1391
|
+
static VALUE bit_to_a(VALUE self) {
|
1392
|
+
ndfunc_arg_in_t ain[3] = {{Qnil, 0}, {sym_loop_opt}, {sym_option}};
|
1393
|
+
ndfunc_arg_out_t aout[1] = {{rb_cArray, 0}}; // dummy?
|
1394
|
+
ndfunc_t ndf = {iter_bit_to_a, FULL_LOOP_NIP, 3, 1, ain, aout};
|
1395
|
+
return na_ndloop_cast_narray_to_rarray(&ndf, self, Qnil);
|
1396
|
+
}
|
1397
|
+
|
1398
|
+
static void iter_bit_fill(na_loop_t* const lp) {
|
1399
|
+
size_t n;
|
1400
|
+
size_t p3;
|
1401
|
+
ssize_t s3;
|
1402
|
+
size_t* idx3;
|
1403
|
+
int len;
|
1404
|
+
BIT_DIGIT* a3;
|
1405
|
+
BIT_DIGIT y;
|
1406
|
+
VALUE x = lp->option;
|
1407
|
+
|
1408
|
+
if (x == INT2FIX(0) || x == Qfalse) {
|
1409
|
+
y = 0;
|
1410
|
+
} else if (x == INT2FIX(1) || x == Qtrue) {
|
1411
|
+
y = ~(BIT_DIGIT)0;
|
1412
|
+
} else {
|
1413
|
+
rb_raise(rb_eArgError, "invalid value for Bit");
|
1414
|
+
}
|
1415
|
+
|
1416
|
+
INIT_COUNTER(lp, n);
|
1417
|
+
INIT_PTR_BIT_IDX(lp, 0, a3, p3, s3, idx3);
|
1418
|
+
if (idx3) {
|
1419
|
+
y = y & 1;
|
1420
|
+
for (; n--;) {
|
1421
|
+
STORE_BIT(a3, p3 + *idx3, y);
|
1422
|
+
idx3++;
|
1423
|
+
}
|
1424
|
+
} else if (s3 != 1) {
|
1425
|
+
y = y & 1;
|
1426
|
+
for (; n--;) {
|
1427
|
+
STORE_BIT(a3, p3, y);
|
1428
|
+
p3 += s3;
|
1429
|
+
}
|
1430
|
+
} else {
|
1431
|
+
if (p3 > 0 || n < NB) {
|
1432
|
+
len = (int)(NB - p3);
|
1433
|
+
if ((int)n < len) len = (int)n;
|
1434
|
+
*a3 = (y & (SLB(len) << p3)) | (*a3 & ~(SLB(len) << p3));
|
1435
|
+
a3++;
|
1436
|
+
n -= len;
|
1437
|
+
}
|
1438
|
+
for (; n >= NB; n -= NB) {
|
1439
|
+
*(a3++) = y;
|
1440
|
+
}
|
1441
|
+
if (n > 0) {
|
1442
|
+
*a3 = (y & SLB(n)) | (*a3 & BALL << n);
|
1443
|
+
}
|
1444
|
+
}
|
1445
|
+
}
|
1446
|
+
|
1447
|
+
/*
|
1448
|
+
Fill elements with other.
|
1449
|
+
@overload fill other
|
1450
|
+
@param [Numeric] other
|
1451
|
+
@return [Numo::Bit] self.
|
1452
|
+
*/
|
1453
|
+
static VALUE bit_fill(VALUE self, VALUE val) {
|
1454
|
+
ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {sym_option}};
|
1455
|
+
ndfunc_t ndf = {iter_bit_fill, FULL_LOOP, 2, 0, ain, 0};
|
1456
|
+
|
1457
|
+
na_ndloop(&ndf, 2, self, val);
|
1458
|
+
return self;
|
1459
|
+
}
|
1460
|
+
|
1461
|
+
static VALUE format_bit(VALUE fmt, dtype x) {
|
1462
|
+
if (NIL_P(fmt)) {
|
1463
|
+
char s[4];
|
1464
|
+
int n;
|
1465
|
+
n = m_sprintf(s, x);
|
1466
|
+
return rb_str_new(s, n);
|
1467
|
+
}
|
1468
|
+
return rb_funcall(fmt, '%', 1, m_data_to_num(x));
|
1469
|
+
}
|
1470
|
+
|
1471
|
+
static void iter_bit_format(na_loop_t* const lp) {
|
1472
|
+
size_t i;
|
1473
|
+
BIT_DIGIT *a1, x = 0;
|
1474
|
+
size_t p1;
|
1475
|
+
char* p2;
|
1476
|
+
ssize_t s1, s2;
|
1477
|
+
size_t* idx1;
|
1478
|
+
VALUE y;
|
1479
|
+
VALUE fmt = lp->option;
|
1480
|
+
|
1481
|
+
INIT_COUNTER(lp, i);
|
1482
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
1483
|
+
INIT_PTR(lp, 1, p2, s2);
|
1484
|
+
|
1485
|
+
if (idx1) {
|
1486
|
+
for (; i--;) {
|
1487
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
1488
|
+
idx1++;
|
1489
|
+
y = format_bit(fmt, x);
|
1490
|
+
SET_DATA_STRIDE(p2, s2, VALUE, y);
|
1491
|
+
}
|
1492
|
+
} else {
|
1493
|
+
for (; i--;) {
|
1494
|
+
LOAD_BIT(a1, p1, x);
|
1495
|
+
p1 += s1;
|
1496
|
+
y = format_bit(fmt, x);
|
1497
|
+
SET_DATA_STRIDE(p2, s2, VALUE, y);
|
1498
|
+
}
|
1499
|
+
}
|
1500
|
+
}
|
1501
|
+
|
1502
|
+
/*
|
1503
|
+
Format elements into strings.
|
1504
|
+
@overload format format
|
1505
|
+
@param [String] format
|
1506
|
+
@return [Numo::RObject] array of formatted strings.
|
1507
|
+
*/
|
1508
|
+
static VALUE bit_format(int argc, VALUE* argv, VALUE self) {
|
1509
|
+
VALUE fmt = Qnil;
|
1510
|
+
|
1511
|
+
ndfunc_arg_in_t ain[2] = {{Qnil, 0}, {sym_option}};
|
1512
|
+
ndfunc_arg_out_t aout[1] = {{numo_cRObject, 0}};
|
1513
|
+
ndfunc_t ndf = {iter_bit_format, FULL_LOOP_NIP, 2, 1, ain, aout};
|
1514
|
+
|
1515
|
+
rb_scan_args(argc, argv, "01", &fmt);
|
1516
|
+
return na_ndloop(&ndf, 2, self, fmt);
|
1517
|
+
}
|
1518
|
+
|
1519
|
+
static void iter_bit_format_to_a(na_loop_t* const lp) {
|
1520
|
+
size_t i;
|
1521
|
+
BIT_DIGIT *a1, x = 0;
|
1522
|
+
size_t p1;
|
1523
|
+
ssize_t s1;
|
1524
|
+
size_t* idx1;
|
1525
|
+
VALUE y;
|
1526
|
+
VALUE fmt = lp->option;
|
1527
|
+
volatile VALUE a;
|
1528
|
+
|
1529
|
+
INIT_COUNTER(lp, i);
|
1530
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
1531
|
+
a = rb_ary_new2(i);
|
1532
|
+
rb_ary_push(lp->args[1].value, a);
|
1533
|
+
if (idx1) {
|
1534
|
+
for (; i--;) {
|
1535
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
1536
|
+
idx1++;
|
1537
|
+
y = format_bit(fmt, x);
|
1538
|
+
rb_ary_push(a, y);
|
1539
|
+
}
|
1540
|
+
} else {
|
1541
|
+
for (; i--;) {
|
1542
|
+
LOAD_BIT(a1, p1, x);
|
1543
|
+
p1 += s1;
|
1544
|
+
y = format_bit(fmt, x);
|
1545
|
+
rb_ary_push(a, y);
|
1546
|
+
}
|
1547
|
+
}
|
1548
|
+
}
|
1549
|
+
|
1550
|
+
/*
|
1551
|
+
Format elements into strings.
|
1552
|
+
@overload format_to_a format
|
1553
|
+
@param [String] format
|
1554
|
+
@return [Array] array of formatted strings.
|
1555
|
+
*/
|
1556
|
+
static VALUE bit_format_to_a(int argc, VALUE* argv, VALUE self) {
|
1557
|
+
VALUE fmt = Qnil;
|
1558
|
+
ndfunc_arg_in_t ain[3] = {{Qnil, 0}, {sym_loop_opt}, {sym_option}};
|
1559
|
+
ndfunc_arg_out_t aout[1] = {{rb_cArray, 0}}; // dummy?
|
1560
|
+
ndfunc_t ndf = {iter_bit_format_to_a, FULL_LOOP_NIP, 3, 1, ain, aout};
|
1561
|
+
|
1562
|
+
rb_scan_args(argc, argv, "01", &fmt);
|
1563
|
+
return na_ndloop_cast_narray_to_rarray(&ndf, self, fmt);
|
1564
|
+
}
|
1565
|
+
|
1566
|
+
static VALUE iter_bit_inspect(char* ptr, size_t pos, VALUE fmt) {
|
1567
|
+
dtype x;
|
1568
|
+
LOAD_BIT(ptr, pos, x);
|
1569
|
+
return format_bit(fmt, x);
|
1570
|
+
}
|
1571
|
+
|
1572
|
+
/*
|
1573
|
+
Returns a string containing a human-readable representation of NArray.
|
1574
|
+
@overload inspect
|
1575
|
+
@return [String]
|
1576
|
+
*/
|
1577
|
+
static VALUE bit_inspect(VALUE ary) {
|
1578
|
+
return na_ndloop_inspect(ary, iter_bit_inspect, Qnil);
|
1579
|
+
}
|
1580
|
+
|
1581
|
+
static void iter_bit_each(na_loop_t* const lp) {
|
1582
|
+
size_t i;
|
1583
|
+
BIT_DIGIT *a1, x = 0;
|
1584
|
+
size_t p1;
|
1585
|
+
ssize_t s1;
|
1586
|
+
size_t* idx1;
|
1587
|
+
VALUE y;
|
1588
|
+
|
1589
|
+
INIT_COUNTER(lp, i);
|
1590
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
1591
|
+
if (idx1) {
|
1592
|
+
for (; i--;) {
|
1593
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
1594
|
+
idx1++;
|
1595
|
+
y = m_data_to_num(x);
|
1596
|
+
rb_yield(y);
|
1597
|
+
}
|
1598
|
+
} else {
|
1599
|
+
for (; i--;) {
|
1600
|
+
LOAD_BIT(a1, p1, x);
|
1601
|
+
p1 += s1;
|
1602
|
+
y = m_data_to_num(x);
|
1603
|
+
rb_yield(y);
|
1604
|
+
}
|
1605
|
+
}
|
1606
|
+
}
|
1607
|
+
|
1608
|
+
/*
|
1609
|
+
Calls the given block once for each element in self,
|
1610
|
+
passing that element as a parameter.
|
1611
|
+
@overload each
|
1612
|
+
@return [Numo::NArray] self
|
1613
|
+
For a block {|x| ... }
|
1614
|
+
@yield [x] x is element of NArray.
|
1615
|
+
*/
|
1616
|
+
static VALUE bit_each(VALUE self) {
|
1617
|
+
ndfunc_arg_in_t ain[1] = {{Qnil, 0}};
|
1618
|
+
ndfunc_t ndf = {iter_bit_each, FULL_LOOP_NIP, 1, 0, ain, 0};
|
1619
|
+
|
1620
|
+
na_ndloop(&ndf, 1, self);
|
1621
|
+
return self;
|
1622
|
+
}
|
1623
|
+
|
1624
|
+
static inline void yield_each_with_index(dtype x, size_t* c, VALUE* a, int nd, int md) {
|
1625
|
+
int j;
|
1626
|
+
|
1627
|
+
a[0] = m_data_to_num(x);
|
1628
|
+
for (j = 0; j <= nd; j++) {
|
1629
|
+
a[j + 1] = SIZET2NUM(c[j]);
|
1630
|
+
}
|
1631
|
+
rb_yield(rb_ary_new4(md, a));
|
1632
|
+
}
|
1633
|
+
|
1634
|
+
static void iter_bit_each_with_index(na_loop_t* const lp) {
|
1635
|
+
size_t i;
|
1636
|
+
BIT_DIGIT *a1, x = 0;
|
1637
|
+
size_t p1;
|
1638
|
+
ssize_t s1;
|
1639
|
+
size_t* idx1;
|
1640
|
+
|
1641
|
+
VALUE* a;
|
1642
|
+
size_t* c;
|
1643
|
+
int nd, md;
|
1644
|
+
|
1645
|
+
c = (size_t*)(lp->opt_ptr);
|
1646
|
+
nd = lp->ndim - 1;
|
1647
|
+
md = lp->ndim + 1;
|
1648
|
+
a = ALLOCA_N(VALUE, md);
|
1649
|
+
|
1650
|
+
INIT_COUNTER(lp, i);
|
1651
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
1652
|
+
c[nd] = 0;
|
1653
|
+
if (idx1) {
|
1654
|
+
for (; i--;) {
|
1655
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
1656
|
+
idx1++;
|
1657
|
+
yield_each_with_index(x, c, a, nd, md);
|
1658
|
+
c[nd]++;
|
1659
|
+
}
|
1660
|
+
} else {
|
1661
|
+
for (; i--;) {
|
1662
|
+
LOAD_BIT(a1, p1, x);
|
1663
|
+
p1 += s1;
|
1664
|
+
yield_each_with_index(x, c, a, nd, md);
|
1665
|
+
c[nd]++;
|
1666
|
+
}
|
1667
|
+
}
|
1668
|
+
}
|
1669
|
+
|
1670
|
+
/*
|
1671
|
+
Invokes the given block once for each element of self,
|
1672
|
+
passing that element and indices along each axis as parameters.
|
1673
|
+
@overload each_with_index
|
1674
|
+
@return [Numo::NArray] self
|
1675
|
+
For a block {|x,i,j,...| ... }
|
1676
|
+
@yield [x,i,j,...] x is an element, i,j,... are multidimensional indices.
|
1677
|
+
*/
|
1678
|
+
static VALUE bit_each_with_index(VALUE self) {
|
1679
|
+
ndfunc_arg_in_t ain[1] = {{Qnil, 0}};
|
1680
|
+
ndfunc_t ndf = {iter_bit_each_with_index, FULL_LOOP_NIP, 1, 0, ain, 0};
|
1681
|
+
|
1682
|
+
na_ndloop_with_index(&ndf, 1, self);
|
1683
|
+
return self;
|
1684
|
+
}
|
1685
|
+
|
1686
|
+
static void iter_bit_copy(na_loop_t* const lp) {
|
1687
|
+
size_t n;
|
1688
|
+
size_t p1, p3;
|
1689
|
+
ssize_t s1, s3;
|
1690
|
+
size_t *idx1, *idx3;
|
1691
|
+
int o1, l1, r1, len;
|
1692
|
+
BIT_DIGIT *a1, *a3;
|
1693
|
+
BIT_DIGIT x;
|
1694
|
+
BIT_DIGIT y;
|
1695
|
+
|
1696
|
+
INIT_COUNTER(lp, n);
|
1697
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
1698
|
+
INIT_PTR_BIT_IDX(lp, 1, a3, p3, s3, idx3);
|
1699
|
+
if (s1 != 1 || s3 != 1 || idx1 || idx3) {
|
1700
|
+
for (; n--;) {
|
1701
|
+
LOAD_BIT_STEP(a1, p1, s1, idx1, x);
|
1702
|
+
y = m_copy(x);
|
1703
|
+
STORE_BIT_STEP(a3, p3, s3, idx3, y);
|
1704
|
+
}
|
1705
|
+
} else {
|
1706
|
+
a1 += p1 / NB;
|
1707
|
+
p1 %= NB;
|
1708
|
+
a3 += p3 / NB;
|
1709
|
+
p3 %= NB;
|
1710
|
+
o1 = (int)(p1 - p3);
|
1711
|
+
l1 = NB + o1;
|
1712
|
+
r1 = NB - o1;
|
1713
|
+
if (p3 > 0 || n < NB) {
|
1714
|
+
len = (int)(NB - p3);
|
1715
|
+
if ((int)n < len) len = (int)n;
|
1716
|
+
if (o1 >= 0)
|
1717
|
+
x = *a1 >> o1;
|
1718
|
+
else
|
1719
|
+
x = *a1 << -o1;
|
1720
|
+
if (p1 + len > NB) x |= *(a1 + 1) << r1;
|
1721
|
+
a1++;
|
1722
|
+
y = m_copy(x);
|
1723
|
+
*a3 = (y & (SLB(len) << p3)) | (*a3 & ~(SLB(len) << p3));
|
1724
|
+
a3++;
|
1725
|
+
n -= len;
|
1726
|
+
}
|
1727
|
+
if (o1 == 0) {
|
1728
|
+
for (; n >= NB; n -= NB) {
|
1729
|
+
x = *(a1++);
|
1730
|
+
y = m_copy(x);
|
1731
|
+
*(a3++) = y;
|
1732
|
+
}
|
1733
|
+
} else {
|
1734
|
+
for (; n >= NB; n -= NB) {
|
1735
|
+
if (o1 == 0) {
|
1736
|
+
x = *a1;
|
1737
|
+
} else if (o1 > 0) {
|
1738
|
+
x = *a1 >> o1 | *(a1 + 1) << r1;
|
1739
|
+
} else {
|
1740
|
+
x = *a1 << -o1 | *(a1 - 1) >> l1;
|
1741
|
+
}
|
1742
|
+
a1++;
|
1743
|
+
y = m_copy(x);
|
1744
|
+
*(a3++) = y;
|
1745
|
+
}
|
1746
|
+
}
|
1747
|
+
if (n > 0) {
|
1748
|
+
if (o1 == 0) {
|
1749
|
+
x = *a1;
|
1750
|
+
} else if (o1 > 0) {
|
1751
|
+
x = *a1 >> o1;
|
1752
|
+
if ((int)n > r1) {
|
1753
|
+
x |= *(a1 + 1) << r1;
|
1754
|
+
}
|
1755
|
+
} else {
|
1756
|
+
x = *(a1 - 1) >> l1;
|
1757
|
+
if ((int)n > -o1) {
|
1758
|
+
x |= *a1 << -o1;
|
1759
|
+
}
|
1760
|
+
}
|
1761
|
+
y = m_copy(x);
|
1762
|
+
*a3 = (y & SLB(n)) | (*a3 & BALL << n);
|
1763
|
+
}
|
1764
|
+
}
|
1765
|
+
}
|
1766
|
+
|
1767
|
+
/*
|
1768
|
+
Unary copy.
|
1769
|
+
@overload copy
|
1770
|
+
@return [Numo::Bit] copy of self.
|
1771
|
+
*/
|
1772
|
+
static VALUE bit_copy(VALUE self) {
|
1773
|
+
ndfunc_arg_in_t ain[1] = {{cT, 0}};
|
1774
|
+
ndfunc_arg_out_t aout[1] = {{cT, 0}};
|
1775
|
+
ndfunc_t ndf = {iter_bit_copy, FULL_LOOP, 1, 1, ain, aout};
|
1776
|
+
|
1777
|
+
return na_ndloop(&ndf, 1, self);
|
1778
|
+
}
|
1779
|
+
|
1780
|
+
static void iter_bit_not(na_loop_t* const lp) {
|
1781
|
+
size_t n;
|
1782
|
+
size_t p1, p3;
|
1783
|
+
ssize_t s1, s3;
|
1784
|
+
size_t *idx1, *idx3;
|
1785
|
+
int o1, l1, r1, len;
|
1786
|
+
BIT_DIGIT *a1, *a3;
|
1787
|
+
BIT_DIGIT x;
|
1788
|
+
BIT_DIGIT y;
|
1789
|
+
|
1790
|
+
INIT_COUNTER(lp, n);
|
1791
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
1792
|
+
INIT_PTR_BIT_IDX(lp, 1, a3, p3, s3, idx3);
|
1793
|
+
if (s1 != 1 || s3 != 1 || idx1 || idx3) {
|
1794
|
+
for (; n--;) {
|
1795
|
+
LOAD_BIT_STEP(a1, p1, s1, idx1, x);
|
1796
|
+
y = m_not(x);
|
1797
|
+
STORE_BIT_STEP(a3, p3, s3, idx3, y);
|
1798
|
+
}
|
1799
|
+
} else {
|
1800
|
+
a1 += p1 / NB;
|
1801
|
+
p1 %= NB;
|
1802
|
+
a3 += p3 / NB;
|
1803
|
+
p3 %= NB;
|
1804
|
+
o1 = (int)(p1 - p3);
|
1805
|
+
l1 = NB + o1;
|
1806
|
+
r1 = NB - o1;
|
1807
|
+
if (p3 > 0 || n < NB) {
|
1808
|
+
len = (int)(NB - p3);
|
1809
|
+
if ((int)n < len) len = (int)n;
|
1810
|
+
if (o1 >= 0)
|
1811
|
+
x = *a1 >> o1;
|
1812
|
+
else
|
1813
|
+
x = *a1 << -o1;
|
1814
|
+
if (p1 + len > NB) x |= *(a1 + 1) << r1;
|
1815
|
+
a1++;
|
1816
|
+
y = m_not(x);
|
1817
|
+
*a3 = (y & (SLB(len) << p3)) | (*a3 & ~(SLB(len) << p3));
|
1818
|
+
a3++;
|
1819
|
+
n -= len;
|
1820
|
+
}
|
1821
|
+
if (o1 == 0) {
|
1822
|
+
for (; n >= NB; n -= NB) {
|
1823
|
+
x = *(a1++);
|
1824
|
+
y = m_not(x);
|
1825
|
+
*(a3++) = y;
|
1826
|
+
}
|
1827
|
+
} else {
|
1828
|
+
for (; n >= NB; n -= NB) {
|
1829
|
+
if (o1 == 0) {
|
1830
|
+
x = *a1;
|
1831
|
+
} else if (o1 > 0) {
|
1832
|
+
x = *a1 >> o1 | *(a1 + 1) << r1;
|
1833
|
+
} else {
|
1834
|
+
x = *a1 << -o1 | *(a1 - 1) >> l1;
|
1835
|
+
}
|
1836
|
+
a1++;
|
1837
|
+
y = m_not(x);
|
1838
|
+
*(a3++) = y;
|
1839
|
+
}
|
1840
|
+
}
|
1841
|
+
if (n > 0) {
|
1842
|
+
if (o1 == 0) {
|
1843
|
+
x = *a1;
|
1844
|
+
} else if (o1 > 0) {
|
1845
|
+
x = *a1 >> o1;
|
1846
|
+
if ((int)n > r1) {
|
1847
|
+
x |= *(a1 + 1) << r1;
|
1848
|
+
}
|
1849
|
+
} else {
|
1850
|
+
x = *(a1 - 1) >> l1;
|
1851
|
+
if ((int)n > -o1) {
|
1852
|
+
x |= *a1 << -o1;
|
1853
|
+
}
|
1854
|
+
}
|
1855
|
+
y = m_not(x);
|
1856
|
+
*a3 = (y & SLB(n)) | (*a3 & BALL << n);
|
1857
|
+
}
|
1858
|
+
}
|
1859
|
+
}
|
1860
|
+
|
1861
|
+
/*
|
1862
|
+
Unary not.
|
1863
|
+
@overload not
|
1864
|
+
@return [Numo::Bit] not of self.
|
1865
|
+
*/
|
1866
|
+
static VALUE bit_not(VALUE self) {
|
1867
|
+
ndfunc_arg_in_t ain[1] = {{cT, 0}};
|
1868
|
+
ndfunc_arg_out_t aout[1] = {{cT, 0}};
|
1869
|
+
ndfunc_t ndf = {iter_bit_not, FULL_LOOP, 1, 1, ain, aout};
|
1870
|
+
|
1871
|
+
return na_ndloop(&ndf, 1, self);
|
1872
|
+
}
|
1873
|
+
|
1874
|
+
static void iter_bit_and(na_loop_t* const lp) {
|
1875
|
+
size_t n;
|
1876
|
+
size_t p1, p2, p3;
|
1877
|
+
ssize_t s1, s2, s3;
|
1878
|
+
size_t *idx1, *idx2, *idx3;
|
1879
|
+
int o1, o2, l1, l2, r1, r2, len;
|
1880
|
+
BIT_DIGIT *a1, *a2, *a3;
|
1881
|
+
BIT_DIGIT x, y;
|
1882
|
+
|
1883
|
+
INIT_COUNTER(lp, n);
|
1884
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
1885
|
+
INIT_PTR_BIT_IDX(lp, 1, a2, p2, s2, idx2);
|
1886
|
+
INIT_PTR_BIT_IDX(lp, 2, a3, p3, s3, idx3);
|
1887
|
+
if (s1 != 1 || s2 != 1 || s3 != 1 || idx1 || idx2 || idx3) {
|
1888
|
+
for (; n--;) {
|
1889
|
+
LOAD_BIT_STEP(a1, p1, s1, idx1, x);
|
1890
|
+
LOAD_BIT_STEP(a2, p2, s2, idx2, y);
|
1891
|
+
x = m_and(x, y);
|
1892
|
+
STORE_BIT_STEP(a3, p3, s3, idx3, x);
|
1893
|
+
}
|
1894
|
+
} else {
|
1895
|
+
a1 += p1 / NB;
|
1896
|
+
p1 %= NB;
|
1897
|
+
a2 += p2 / NB;
|
1898
|
+
p2 %= NB;
|
1899
|
+
a3 += p3 / NB;
|
1900
|
+
p3 %= NB;
|
1901
|
+
o1 = (int)(p1 - p3);
|
1902
|
+
o2 = (int)(p2 - p3);
|
1903
|
+
l1 = NB + o1;
|
1904
|
+
r1 = NB - o1;
|
1905
|
+
l2 = NB + o2;
|
1906
|
+
r2 = NB - o2;
|
1907
|
+
if (p3 > 0 || n < NB) {
|
1908
|
+
len = (int)(NB - p3);
|
1909
|
+
if ((int)n < len) len = (int)n;
|
1910
|
+
if (o1 >= 0)
|
1911
|
+
x = *a1 >> o1;
|
1912
|
+
else
|
1913
|
+
x = *a1 << -o1;
|
1914
|
+
if (p1 + len > NB) x |= *(a1 + 1) << r1;
|
1915
|
+
a1++;
|
1916
|
+
if (o2 >= 0)
|
1917
|
+
y = *a2 >> o2;
|
1918
|
+
else
|
1919
|
+
y = *a2 << -o2;
|
1920
|
+
if (p2 + len > NB) y |= *(a2 + 1) << r2;
|
1921
|
+
a2++;
|
1922
|
+
x = m_and(x, y);
|
1923
|
+
*a3 = (x & (SLB(len) << p3)) | (*a3 & ~(SLB(len) << p3));
|
1924
|
+
a3++;
|
1925
|
+
n -= len;
|
1926
|
+
}
|
1927
|
+
if (o1 == 0 && o2 == 0) {
|
1928
|
+
for (; n >= NB; n -= NB) {
|
1929
|
+
x = *(a1++);
|
1930
|
+
y = *(a2++);
|
1931
|
+
x = m_and(x, y);
|
1932
|
+
*(a3++) = x;
|
1933
|
+
}
|
1934
|
+
} else {
|
1935
|
+
for (; n >= NB; n -= NB) {
|
1936
|
+
if (o1 == 0) {
|
1937
|
+
x = *a1;
|
1938
|
+
} else if (o1 > 0) {
|
1939
|
+
x = *a1 >> o1 | *(a1 + 1) << r1;
|
1940
|
+
} else {
|
1941
|
+
x = *a1 << -o1 | *(a1 - 1) >> l1;
|
1942
|
+
}
|
1943
|
+
a1++;
|
1944
|
+
if (o2 == 0) {
|
1945
|
+
y = *a2;
|
1946
|
+
} else if (o2 > 0) {
|
1947
|
+
y = *a2 >> o2 | *(a2 + 1) << r2;
|
1948
|
+
} else {
|
1949
|
+
y = *a2 << -o2 | *(a2 - 1) >> l2;
|
1950
|
+
}
|
1951
|
+
a2++;
|
1952
|
+
x = m_and(x, y);
|
1953
|
+
*(a3++) = x;
|
1954
|
+
}
|
1955
|
+
}
|
1956
|
+
if (n > 0) {
|
1957
|
+
if (o1 == 0) {
|
1958
|
+
x = *a1;
|
1959
|
+
} else if (o1 > 0) {
|
1960
|
+
x = *a1 >> o1;
|
1961
|
+
if ((int)n > r1) {
|
1962
|
+
x |= *(a1 + 1) << r1;
|
1963
|
+
}
|
1964
|
+
} else {
|
1965
|
+
x = *(a1 - 1) >> l1;
|
1966
|
+
if ((int)n > -o1) {
|
1967
|
+
x |= *a1 << -o1;
|
1968
|
+
}
|
1969
|
+
}
|
1970
|
+
if (o2 == 0) {
|
1971
|
+
y = *a2;
|
1972
|
+
} else if (o2 > 0) {
|
1973
|
+
y = *a2 >> o2;
|
1974
|
+
if ((int)n > r2) {
|
1975
|
+
y |= *(a2 + 1) << r2;
|
1976
|
+
}
|
1977
|
+
} else {
|
1978
|
+
y = *(a2 - 1) >> l2;
|
1979
|
+
if ((int)n > -o2) {
|
1980
|
+
y |= *a2 << -o2;
|
1981
|
+
}
|
1982
|
+
}
|
1983
|
+
x = m_and(x, y);
|
1984
|
+
*a3 = (x & SLB(n)) | (*a3 & BALL << n);
|
1985
|
+
}
|
1986
|
+
}
|
1987
|
+
}
|
1988
|
+
|
1989
|
+
/*
|
1990
|
+
Binary and.
|
1991
|
+
@overload & other
|
1992
|
+
@param [Numo::NArray,Numeric] other
|
1993
|
+
@return [Numo::NArray] and of self and other.
|
1994
|
+
*/
|
1995
|
+
static VALUE bit_and(VALUE self, VALUE other) {
|
1996
|
+
ndfunc_arg_in_t ain[2] = {{cT, 0}, {cT, 0}};
|
1997
|
+
ndfunc_arg_out_t aout[1] = {{cT, 0}};
|
1998
|
+
ndfunc_t ndf = {iter_bit_and, FULL_LOOP, 2, 1, ain, aout};
|
1999
|
+
|
2000
|
+
return na_ndloop(&ndf, 2, self, other);
|
2001
|
+
}
|
2002
|
+
|
2003
|
+
static void iter_bit_or(na_loop_t* const lp) {
|
2004
|
+
size_t n;
|
2005
|
+
size_t p1, p2, p3;
|
2006
|
+
ssize_t s1, s2, s3;
|
2007
|
+
size_t *idx1, *idx2, *idx3;
|
2008
|
+
int o1, o2, l1, l2, r1, r2, len;
|
2009
|
+
BIT_DIGIT *a1, *a2, *a3;
|
2010
|
+
BIT_DIGIT x, y;
|
2011
|
+
|
2012
|
+
INIT_COUNTER(lp, n);
|
2013
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
2014
|
+
INIT_PTR_BIT_IDX(lp, 1, a2, p2, s2, idx2);
|
2015
|
+
INIT_PTR_BIT_IDX(lp, 2, a3, p3, s3, idx3);
|
2016
|
+
if (s1 != 1 || s2 != 1 || s3 != 1 || idx1 || idx2 || idx3) {
|
2017
|
+
for (; n--;) {
|
2018
|
+
LOAD_BIT_STEP(a1, p1, s1, idx1, x);
|
2019
|
+
LOAD_BIT_STEP(a2, p2, s2, idx2, y);
|
2020
|
+
x = m_or(x, y);
|
2021
|
+
STORE_BIT_STEP(a3, p3, s3, idx3, x);
|
2022
|
+
}
|
2023
|
+
} else {
|
2024
|
+
a1 += p1 / NB;
|
2025
|
+
p1 %= NB;
|
2026
|
+
a2 += p2 / NB;
|
2027
|
+
p2 %= NB;
|
2028
|
+
a3 += p3 / NB;
|
2029
|
+
p3 %= NB;
|
2030
|
+
o1 = (int)(p1 - p3);
|
2031
|
+
o2 = (int)(p2 - p3);
|
2032
|
+
l1 = NB + o1;
|
2033
|
+
r1 = NB - o1;
|
2034
|
+
l2 = NB + o2;
|
2035
|
+
r2 = NB - o2;
|
2036
|
+
if (p3 > 0 || n < NB) {
|
2037
|
+
len = (int)(NB - p3);
|
2038
|
+
if ((int)n < len) len = (int)n;
|
2039
|
+
if (o1 >= 0)
|
2040
|
+
x = *a1 >> o1;
|
2041
|
+
else
|
2042
|
+
x = *a1 << -o1;
|
2043
|
+
if (p1 + len > NB) x |= *(a1 + 1) << r1;
|
2044
|
+
a1++;
|
2045
|
+
if (o2 >= 0)
|
2046
|
+
y = *a2 >> o2;
|
2047
|
+
else
|
2048
|
+
y = *a2 << -o2;
|
2049
|
+
if (p2 + len > NB) y |= *(a2 + 1) << r2;
|
2050
|
+
a2++;
|
2051
|
+
x = m_or(x, y);
|
2052
|
+
*a3 = (x & (SLB(len) << p3)) | (*a3 & ~(SLB(len) << p3));
|
2053
|
+
a3++;
|
2054
|
+
n -= len;
|
2055
|
+
}
|
2056
|
+
if (o1 == 0 && o2 == 0) {
|
2057
|
+
for (; n >= NB; n -= NB) {
|
2058
|
+
x = *(a1++);
|
2059
|
+
y = *(a2++);
|
2060
|
+
x = m_or(x, y);
|
2061
|
+
*(a3++) = x;
|
2062
|
+
}
|
2063
|
+
} else {
|
2064
|
+
for (; n >= NB; n -= NB) {
|
2065
|
+
if (o1 == 0) {
|
2066
|
+
x = *a1;
|
2067
|
+
} else if (o1 > 0) {
|
2068
|
+
x = *a1 >> o1 | *(a1 + 1) << r1;
|
2069
|
+
} else {
|
2070
|
+
x = *a1 << -o1 | *(a1 - 1) >> l1;
|
2071
|
+
}
|
2072
|
+
a1++;
|
2073
|
+
if (o2 == 0) {
|
2074
|
+
y = *a2;
|
2075
|
+
} else if (o2 > 0) {
|
2076
|
+
y = *a2 >> o2 | *(a2 + 1) << r2;
|
2077
|
+
} else {
|
2078
|
+
y = *a2 << -o2 | *(a2 - 1) >> l2;
|
2079
|
+
}
|
2080
|
+
a2++;
|
2081
|
+
x = m_or(x, y);
|
2082
|
+
*(a3++) = x;
|
2083
|
+
}
|
2084
|
+
}
|
2085
|
+
if (n > 0) {
|
2086
|
+
if (o1 == 0) {
|
2087
|
+
x = *a1;
|
2088
|
+
} else if (o1 > 0) {
|
2089
|
+
x = *a1 >> o1;
|
2090
|
+
if ((int)n > r1) {
|
2091
|
+
x |= *(a1 + 1) << r1;
|
2092
|
+
}
|
2093
|
+
} else {
|
2094
|
+
x = *(a1 - 1) >> l1;
|
2095
|
+
if ((int)n > -o1) {
|
2096
|
+
x |= *a1 << -o1;
|
2097
|
+
}
|
2098
|
+
}
|
2099
|
+
if (o2 == 0) {
|
2100
|
+
y = *a2;
|
2101
|
+
} else if (o2 > 0) {
|
2102
|
+
y = *a2 >> o2;
|
2103
|
+
if ((int)n > r2) {
|
2104
|
+
y |= *(a2 + 1) << r2;
|
2105
|
+
}
|
2106
|
+
} else {
|
2107
|
+
y = *(a2 - 1) >> l2;
|
2108
|
+
if ((int)n > -o2) {
|
2109
|
+
y |= *a2 << -o2;
|
2110
|
+
}
|
2111
|
+
}
|
2112
|
+
x = m_or(x, y);
|
2113
|
+
*a3 = (x & SLB(n)) | (*a3 & BALL << n);
|
2114
|
+
}
|
2115
|
+
}
|
2116
|
+
}
|
2117
|
+
|
2118
|
+
/*
|
2119
|
+
Binary or.
|
2120
|
+
@overload | other
|
2121
|
+
@param [Numo::NArray,Numeric] other
|
2122
|
+
@return [Numo::NArray] or of self and other.
|
2123
|
+
*/
|
2124
|
+
static VALUE bit_or(VALUE self, VALUE other) {
|
2125
|
+
ndfunc_arg_in_t ain[2] = {{cT, 0}, {cT, 0}};
|
2126
|
+
ndfunc_arg_out_t aout[1] = {{cT, 0}};
|
2127
|
+
ndfunc_t ndf = {iter_bit_or, FULL_LOOP, 2, 1, ain, aout};
|
2128
|
+
|
2129
|
+
return na_ndloop(&ndf, 2, self, other);
|
2130
|
+
}
|
2131
|
+
|
2132
|
+
static void iter_bit_xor(na_loop_t* const lp) {
|
2133
|
+
size_t n;
|
2134
|
+
size_t p1, p2, p3;
|
2135
|
+
ssize_t s1, s2, s3;
|
2136
|
+
size_t *idx1, *idx2, *idx3;
|
2137
|
+
int o1, o2, l1, l2, r1, r2, len;
|
2138
|
+
BIT_DIGIT *a1, *a2, *a3;
|
2139
|
+
BIT_DIGIT x, y;
|
2140
|
+
|
2141
|
+
INIT_COUNTER(lp, n);
|
2142
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
2143
|
+
INIT_PTR_BIT_IDX(lp, 1, a2, p2, s2, idx2);
|
2144
|
+
INIT_PTR_BIT_IDX(lp, 2, a3, p3, s3, idx3);
|
2145
|
+
if (s1 != 1 || s2 != 1 || s3 != 1 || idx1 || idx2 || idx3) {
|
2146
|
+
for (; n--;) {
|
2147
|
+
LOAD_BIT_STEP(a1, p1, s1, idx1, x);
|
2148
|
+
LOAD_BIT_STEP(a2, p2, s2, idx2, y);
|
2149
|
+
x = m_xor(x, y);
|
2150
|
+
STORE_BIT_STEP(a3, p3, s3, idx3, x);
|
2151
|
+
}
|
2152
|
+
} else {
|
2153
|
+
a1 += p1 / NB;
|
2154
|
+
p1 %= NB;
|
2155
|
+
a2 += p2 / NB;
|
2156
|
+
p2 %= NB;
|
2157
|
+
a3 += p3 / NB;
|
2158
|
+
p3 %= NB;
|
2159
|
+
o1 = (int)(p1 - p3);
|
2160
|
+
o2 = (int)(p2 - p3);
|
2161
|
+
l1 = NB + o1;
|
2162
|
+
r1 = NB - o1;
|
2163
|
+
l2 = NB + o2;
|
2164
|
+
r2 = NB - o2;
|
2165
|
+
if (p3 > 0 || n < NB) {
|
2166
|
+
len = (int)(NB - p3);
|
2167
|
+
if ((int)n < len) len = (int)n;
|
2168
|
+
if (o1 >= 0)
|
2169
|
+
x = *a1 >> o1;
|
2170
|
+
else
|
2171
|
+
x = *a1 << -o1;
|
2172
|
+
if (p1 + len > NB) x |= *(a1 + 1) << r1;
|
2173
|
+
a1++;
|
2174
|
+
if (o2 >= 0)
|
2175
|
+
y = *a2 >> o2;
|
2176
|
+
else
|
2177
|
+
y = *a2 << -o2;
|
2178
|
+
if (p2 + len > NB) y |= *(a2 + 1) << r2;
|
2179
|
+
a2++;
|
2180
|
+
x = m_xor(x, y);
|
2181
|
+
*a3 = (x & (SLB(len) << p3)) | (*a3 & ~(SLB(len) << p3));
|
2182
|
+
a3++;
|
2183
|
+
n -= len;
|
2184
|
+
}
|
2185
|
+
if (o1 == 0 && o2 == 0) {
|
2186
|
+
for (; n >= NB; n -= NB) {
|
2187
|
+
x = *(a1++);
|
2188
|
+
y = *(a2++);
|
2189
|
+
x = m_xor(x, y);
|
2190
|
+
*(a3++) = x;
|
2191
|
+
}
|
2192
|
+
} else {
|
2193
|
+
for (; n >= NB; n -= NB) {
|
2194
|
+
if (o1 == 0) {
|
2195
|
+
x = *a1;
|
2196
|
+
} else if (o1 > 0) {
|
2197
|
+
x = *a1 >> o1 | *(a1 + 1) << r1;
|
2198
|
+
} else {
|
2199
|
+
x = *a1 << -o1 | *(a1 - 1) >> l1;
|
2200
|
+
}
|
2201
|
+
a1++;
|
2202
|
+
if (o2 == 0) {
|
2203
|
+
y = *a2;
|
2204
|
+
} else if (o2 > 0) {
|
2205
|
+
y = *a2 >> o2 | *(a2 + 1) << r2;
|
2206
|
+
} else {
|
2207
|
+
y = *a2 << -o2 | *(a2 - 1) >> l2;
|
2208
|
+
}
|
2209
|
+
a2++;
|
2210
|
+
x = m_xor(x, y);
|
2211
|
+
*(a3++) = x;
|
2212
|
+
}
|
2213
|
+
}
|
2214
|
+
if (n > 0) {
|
2215
|
+
if (o1 == 0) {
|
2216
|
+
x = *a1;
|
2217
|
+
} else if (o1 > 0) {
|
2218
|
+
x = *a1 >> o1;
|
2219
|
+
if ((int)n > r1) {
|
2220
|
+
x |= *(a1 + 1) << r1;
|
2221
|
+
}
|
2222
|
+
} else {
|
2223
|
+
x = *(a1 - 1) >> l1;
|
2224
|
+
if ((int)n > -o1) {
|
2225
|
+
x |= *a1 << -o1;
|
2226
|
+
}
|
2227
|
+
}
|
2228
|
+
if (o2 == 0) {
|
2229
|
+
y = *a2;
|
2230
|
+
} else if (o2 > 0) {
|
2231
|
+
y = *a2 >> o2;
|
2232
|
+
if ((int)n > r2) {
|
2233
|
+
y |= *(a2 + 1) << r2;
|
2234
|
+
}
|
2235
|
+
} else {
|
2236
|
+
y = *(a2 - 1) >> l2;
|
2237
|
+
if ((int)n > -o2) {
|
2238
|
+
y |= *a2 << -o2;
|
2239
|
+
}
|
2240
|
+
}
|
2241
|
+
x = m_xor(x, y);
|
2242
|
+
*a3 = (x & SLB(n)) | (*a3 & BALL << n);
|
2243
|
+
}
|
2244
|
+
}
|
2245
|
+
}
|
2246
|
+
|
2247
|
+
/*
|
2248
|
+
Binary xor.
|
2249
|
+
@overload ^ other
|
2250
|
+
@param [Numo::NArray,Numeric] other
|
2251
|
+
@return [Numo::NArray] xor of self and other.
|
2252
|
+
*/
|
2253
|
+
static VALUE bit_xor(VALUE self, VALUE other) {
|
2254
|
+
ndfunc_arg_in_t ain[2] = {{cT, 0}, {cT, 0}};
|
2255
|
+
ndfunc_arg_out_t aout[1] = {{cT, 0}};
|
2256
|
+
ndfunc_t ndf = {iter_bit_xor, FULL_LOOP, 2, 1, ain, aout};
|
2257
|
+
|
2258
|
+
return na_ndloop(&ndf, 2, self, other);
|
2259
|
+
}
|
2260
|
+
|
2261
|
+
static void iter_bit_eq(na_loop_t* const lp) {
|
2262
|
+
size_t n;
|
2263
|
+
size_t p1, p2, p3;
|
2264
|
+
ssize_t s1, s2, s3;
|
2265
|
+
size_t *idx1, *idx2, *idx3;
|
2266
|
+
int o1, o2, l1, l2, r1, r2, len;
|
2267
|
+
BIT_DIGIT *a1, *a2, *a3;
|
2268
|
+
BIT_DIGIT x, y;
|
2269
|
+
|
2270
|
+
INIT_COUNTER(lp, n);
|
2271
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
2272
|
+
INIT_PTR_BIT_IDX(lp, 1, a2, p2, s2, idx2);
|
2273
|
+
INIT_PTR_BIT_IDX(lp, 2, a3, p3, s3, idx3);
|
2274
|
+
if (s1 != 1 || s2 != 1 || s3 != 1 || idx1 || idx2 || idx3) {
|
2275
|
+
for (; n--;) {
|
2276
|
+
LOAD_BIT_STEP(a1, p1, s1, idx1, x);
|
2277
|
+
LOAD_BIT_STEP(a2, p2, s2, idx2, y);
|
2278
|
+
x = m_eq(x, y);
|
2279
|
+
STORE_BIT_STEP(a3, p3, s3, idx3, x);
|
2280
|
+
}
|
2281
|
+
} else {
|
2282
|
+
a1 += p1 / NB;
|
2283
|
+
p1 %= NB;
|
2284
|
+
a2 += p2 / NB;
|
2285
|
+
p2 %= NB;
|
2286
|
+
a3 += p3 / NB;
|
2287
|
+
p3 %= NB;
|
2288
|
+
o1 = (int)(p1 - p3);
|
2289
|
+
o2 = (int)(p2 - p3);
|
2290
|
+
l1 = NB + o1;
|
2291
|
+
r1 = NB - o1;
|
2292
|
+
l2 = NB + o2;
|
2293
|
+
r2 = NB - o2;
|
2294
|
+
if (p3 > 0 || n < NB) {
|
2295
|
+
len = (int)(NB - p3);
|
2296
|
+
if ((int)n < len) len = (int)n;
|
2297
|
+
if (o1 >= 0)
|
2298
|
+
x = *a1 >> o1;
|
2299
|
+
else
|
2300
|
+
x = *a1 << -o1;
|
2301
|
+
if (p1 + len > NB) x |= *(a1 + 1) << r1;
|
2302
|
+
a1++;
|
2303
|
+
if (o2 >= 0)
|
2304
|
+
y = *a2 >> o2;
|
2305
|
+
else
|
2306
|
+
y = *a2 << -o2;
|
2307
|
+
if (p2 + len > NB) y |= *(a2 + 1) << r2;
|
2308
|
+
a2++;
|
2309
|
+
x = m_eq(x, y);
|
2310
|
+
*a3 = (x & (SLB(len) << p3)) | (*a3 & ~(SLB(len) << p3));
|
2311
|
+
a3++;
|
2312
|
+
n -= len;
|
2313
|
+
}
|
2314
|
+
if (o1 == 0 && o2 == 0) {
|
2315
|
+
for (; n >= NB; n -= NB) {
|
2316
|
+
x = *(a1++);
|
2317
|
+
y = *(a2++);
|
2318
|
+
x = m_eq(x, y);
|
2319
|
+
*(a3++) = x;
|
2320
|
+
}
|
2321
|
+
} else {
|
2322
|
+
for (; n >= NB; n -= NB) {
|
2323
|
+
if (o1 == 0) {
|
2324
|
+
x = *a1;
|
2325
|
+
} else if (o1 > 0) {
|
2326
|
+
x = *a1 >> o1 | *(a1 + 1) << r1;
|
2327
|
+
} else {
|
2328
|
+
x = *a1 << -o1 | *(a1 - 1) >> l1;
|
2329
|
+
}
|
2330
|
+
a1++;
|
2331
|
+
if (o2 == 0) {
|
2332
|
+
y = *a2;
|
2333
|
+
} else if (o2 > 0) {
|
2334
|
+
y = *a2 >> o2 | *(a2 + 1) << r2;
|
2335
|
+
} else {
|
2336
|
+
y = *a2 << -o2 | *(a2 - 1) >> l2;
|
2337
|
+
}
|
2338
|
+
a2++;
|
2339
|
+
x = m_eq(x, y);
|
2340
|
+
*(a3++) = x;
|
2341
|
+
}
|
2342
|
+
}
|
2343
|
+
if (n > 0) {
|
2344
|
+
if (o1 == 0) {
|
2345
|
+
x = *a1;
|
2346
|
+
} else if (o1 > 0) {
|
2347
|
+
x = *a1 >> o1;
|
2348
|
+
if ((int)n > r1) {
|
2349
|
+
x |= *(a1 + 1) << r1;
|
2350
|
+
}
|
2351
|
+
} else {
|
2352
|
+
x = *(a1 - 1) >> l1;
|
2353
|
+
if ((int)n > -o1) {
|
2354
|
+
x |= *a1 << -o1;
|
2355
|
+
}
|
2356
|
+
}
|
2357
|
+
if (o2 == 0) {
|
2358
|
+
y = *a2;
|
2359
|
+
} else if (o2 > 0) {
|
2360
|
+
y = *a2 >> o2;
|
2361
|
+
if ((int)n > r2) {
|
2362
|
+
y |= *(a2 + 1) << r2;
|
2363
|
+
}
|
2364
|
+
} else {
|
2365
|
+
y = *(a2 - 1) >> l2;
|
2366
|
+
if ((int)n > -o2) {
|
2367
|
+
y |= *a2 << -o2;
|
2368
|
+
}
|
2369
|
+
}
|
2370
|
+
x = m_eq(x, y);
|
2371
|
+
*a3 = (x & SLB(n)) | (*a3 & BALL << n);
|
2372
|
+
}
|
2373
|
+
}
|
2374
|
+
}
|
2375
|
+
|
2376
|
+
/*
|
2377
|
+
Binary eq.
|
2378
|
+
@overload eq other
|
2379
|
+
@param [Numo::NArray,Numeric] other
|
2380
|
+
@return [Numo::NArray] eq of self and other.
|
2381
|
+
*/
|
2382
|
+
static VALUE bit_eq(VALUE self, VALUE other) {
|
2383
|
+
ndfunc_arg_in_t ain[2] = {{cT, 0}, {cT, 0}};
|
2384
|
+
ndfunc_arg_out_t aout[1] = {{cT, 0}};
|
2385
|
+
ndfunc_t ndf = {iter_bit_eq, FULL_LOOP, 2, 1, ain, aout};
|
2386
|
+
|
2387
|
+
return na_ndloop(&ndf, 2, self, other);
|
2388
|
+
}
|
2389
|
+
|
2390
|
+
#undef int_t
|
2391
|
+
#define int_t int64_t
|
2392
|
+
|
2393
|
+
static void iter_bit_count_true(na_loop_t* const lp) {
|
2394
|
+
size_t i;
|
2395
|
+
BIT_DIGIT* a1;
|
2396
|
+
size_t p1;
|
2397
|
+
char* p2;
|
2398
|
+
ssize_t s1, s2;
|
2399
|
+
size_t* idx1;
|
2400
|
+
BIT_DIGIT x = 0;
|
2401
|
+
int_t y;
|
2402
|
+
|
2403
|
+
INIT_COUNTER(lp, i);
|
2404
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
2405
|
+
INIT_PTR(lp, 1, p2, s2);
|
2406
|
+
if (s2 == 0) {
|
2407
|
+
GET_DATA(p2, int_t, y);
|
2408
|
+
if (idx1) {
|
2409
|
+
for (; i--;) {
|
2410
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
2411
|
+
idx1++;
|
2412
|
+
if (m_count_true(x)) {
|
2413
|
+
y++;
|
2414
|
+
}
|
2415
|
+
}
|
2416
|
+
} else {
|
2417
|
+
for (; i--;) {
|
2418
|
+
LOAD_BIT(a1, p1, x);
|
2419
|
+
p1 += s1;
|
2420
|
+
if (m_count_true(x)) {
|
2421
|
+
y++;
|
2422
|
+
}
|
2423
|
+
}
|
2424
|
+
}
|
2425
|
+
*(int_t*)p2 = y;
|
2426
|
+
} else {
|
2427
|
+
if (idx1) {
|
2428
|
+
for (; i--;) {
|
2429
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
2430
|
+
idx1++;
|
2431
|
+
if (m_count_true(x)) {
|
2432
|
+
GET_DATA(p2, int_t, y);
|
2433
|
+
y++;
|
2434
|
+
SET_DATA(p2, int_t, y);
|
2435
|
+
}
|
2436
|
+
p2 += s2;
|
2437
|
+
}
|
2438
|
+
} else {
|
2439
|
+
for (; i--;) {
|
2440
|
+
LOAD_BIT(a1, p1, x);
|
2441
|
+
p1 += s1;
|
2442
|
+
if (m_count_true(x)) {
|
2443
|
+
GET_DATA(p2, int_t, y);
|
2444
|
+
y++;
|
2445
|
+
SET_DATA(p2, int_t, y);
|
2446
|
+
}
|
2447
|
+
p2 += s2;
|
2448
|
+
}
|
2449
|
+
}
|
2450
|
+
}
|
2451
|
+
}
|
2452
|
+
|
2453
|
+
/*
|
2454
|
+
Returns the number of bits.
|
2455
|
+
If argument is supplied, return Int-array counted along the axes.
|
2456
|
+
@overload count_true(axis:nil, keepdims:false)
|
2457
|
+
@param [Integer,Array,Range] axis (keyword) axes to be counted.
|
2458
|
+
@param [TrueClass] keepdims (keyword) If true, the reduced axes are left in the result array as dimensions with size one.
|
2459
|
+
@return [Numo::Int64]
|
2460
|
+
*/
|
2461
|
+
static VALUE bit_count_true(int argc, VALUE* argv, VALUE self) {
|
2462
|
+
VALUE v, reduce;
|
2463
|
+
narray_t* na;
|
2464
|
+
ndfunc_arg_in_t ain[3] = {{cT, 0}, {sym_reduce, 0}, {sym_init, 0}};
|
2465
|
+
ndfunc_arg_out_t aout[1] = {{numo_cInt64, 0}};
|
2466
|
+
ndfunc_t ndf = {iter_bit_count_true, FULL_LOOP_NIP, 3, 1, ain, aout};
|
2467
|
+
|
2468
|
+
GetNArray(self, na);
|
2469
|
+
if (NA_SIZE(na) == 0) {
|
2470
|
+
return INT2FIX(0);
|
2471
|
+
}
|
2472
|
+
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
|
2473
|
+
v = na_ndloop(&ndf, 3, self, reduce, INT2FIX(0));
|
2474
|
+
return rb_funcall(v, rb_intern("extract"), 0);
|
2475
|
+
}
|
2476
|
+
|
2477
|
+
#undef int_t
|
2478
|
+
#define int_t int64_t
|
2479
|
+
|
2480
|
+
static void iter_bit_count_false(na_loop_t* const lp) {
|
2481
|
+
size_t i;
|
2482
|
+
BIT_DIGIT* a1;
|
2483
|
+
size_t p1;
|
2484
|
+
char* p2;
|
2485
|
+
ssize_t s1, s2;
|
2486
|
+
size_t* idx1;
|
2487
|
+
BIT_DIGIT x = 0;
|
2488
|
+
int_t y;
|
2489
|
+
|
2490
|
+
INIT_COUNTER(lp, i);
|
2491
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
2492
|
+
INIT_PTR(lp, 1, p2, s2);
|
2493
|
+
if (s2 == 0) {
|
2494
|
+
GET_DATA(p2, int_t, y);
|
2495
|
+
if (idx1) {
|
2496
|
+
for (; i--;) {
|
2497
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
2498
|
+
idx1++;
|
2499
|
+
if (m_count_false(x)) {
|
2500
|
+
y++;
|
2501
|
+
}
|
2502
|
+
}
|
2503
|
+
} else {
|
2504
|
+
for (; i--;) {
|
2505
|
+
LOAD_BIT(a1, p1, x);
|
2506
|
+
p1 += s1;
|
2507
|
+
if (m_count_false(x)) {
|
2508
|
+
y++;
|
2509
|
+
}
|
2510
|
+
}
|
2511
|
+
}
|
2512
|
+
*(int_t*)p2 = y;
|
2513
|
+
} else {
|
2514
|
+
if (idx1) {
|
2515
|
+
for (; i--;) {
|
2516
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
2517
|
+
idx1++;
|
2518
|
+
if (m_count_false(x)) {
|
2519
|
+
GET_DATA(p2, int_t, y);
|
2520
|
+
y++;
|
2521
|
+
SET_DATA(p2, int_t, y);
|
2522
|
+
}
|
2523
|
+
p2 += s2;
|
2524
|
+
}
|
2525
|
+
} else {
|
2526
|
+
for (; i--;) {
|
2527
|
+
LOAD_BIT(a1, p1, x);
|
2528
|
+
p1 += s1;
|
2529
|
+
if (m_count_false(x)) {
|
2530
|
+
GET_DATA(p2, int_t, y);
|
2531
|
+
y++;
|
2532
|
+
SET_DATA(p2, int_t, y);
|
2533
|
+
}
|
2534
|
+
p2 += s2;
|
2535
|
+
}
|
2536
|
+
}
|
2537
|
+
}
|
2538
|
+
}
|
2539
|
+
|
2540
|
+
/*
|
2541
|
+
Returns the number of bits.
|
2542
|
+
If argument is supplied, return Int-array counted along the axes.
|
2543
|
+
@overload count_false(axis:nil, keepdims:false)
|
2544
|
+
@param [Integer,Array,Range] axis (keyword) axes to be counted.
|
2545
|
+
@param [TrueClass] keepdims (keyword) If true, the reduced axes are left in the result array as dimensions with size one.
|
2546
|
+
@return [Numo::Int64]
|
2547
|
+
*/
|
2548
|
+
static VALUE bit_count_false(int argc, VALUE* argv, VALUE self) {
|
2549
|
+
VALUE v, reduce;
|
2550
|
+
narray_t* na;
|
2551
|
+
ndfunc_arg_in_t ain[3] = {{cT, 0}, {sym_reduce, 0}, {sym_init, 0}};
|
2552
|
+
ndfunc_arg_out_t aout[1] = {{numo_cInt64, 0}};
|
2553
|
+
ndfunc_t ndf = {iter_bit_count_false, FULL_LOOP_NIP, 3, 1, ain, aout};
|
2554
|
+
|
2555
|
+
GetNArray(self, na);
|
2556
|
+
if (NA_SIZE(na) == 0) {
|
2557
|
+
return INT2FIX(0);
|
2558
|
+
}
|
2559
|
+
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
|
2560
|
+
v = na_ndloop(&ndf, 3, self, reduce, INT2FIX(0));
|
2561
|
+
return rb_funcall(v, rb_intern("extract"), 0);
|
2562
|
+
}
|
2563
|
+
|
2564
|
+
static void iter_bit_all_p(na_loop_t* const lp) {
|
2565
|
+
size_t i;
|
2566
|
+
BIT_DIGIT *a1, *a2;
|
2567
|
+
size_t p1, p2;
|
2568
|
+
ssize_t s1, s2;
|
2569
|
+
size_t *idx1, *idx2;
|
2570
|
+
BIT_DIGIT x = 0, y = 0;
|
2571
|
+
|
2572
|
+
INIT_COUNTER(lp, i);
|
2573
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
2574
|
+
INIT_PTR_BIT_IDX(lp, 1, a2, p2, s2, idx2);
|
2575
|
+
if (idx2) {
|
2576
|
+
if (idx1) {
|
2577
|
+
for (; i--;) {
|
2578
|
+
LOAD_BIT(a2, p2 + *idx2, y);
|
2579
|
+
if (y == 1) {
|
2580
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
2581
|
+
if (x != 1) {
|
2582
|
+
STORE_BIT(a2, p2 + *idx2, x);
|
2583
|
+
}
|
2584
|
+
}
|
2585
|
+
idx1++;
|
2586
|
+
idx2++;
|
2587
|
+
}
|
2588
|
+
} else {
|
2589
|
+
for (; i--;) {
|
2590
|
+
LOAD_BIT(a2, p2 + *idx2, y);
|
2591
|
+
if (y == 1) {
|
2592
|
+
LOAD_BIT(a1, p1, x);
|
2593
|
+
if (x != 1) {
|
2594
|
+
STORE_BIT(a2, p2 + *idx2, x);
|
2595
|
+
}
|
2596
|
+
}
|
2597
|
+
p1 += s1;
|
2598
|
+
idx2++;
|
2599
|
+
}
|
2600
|
+
}
|
2601
|
+
} else if (s2) {
|
2602
|
+
if (idx1) {
|
2603
|
+
for (; i--;) {
|
2604
|
+
LOAD_BIT(a2, p2, y);
|
2605
|
+
if (y == 1) {
|
2606
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
2607
|
+
if (x != 1) {
|
2608
|
+
STORE_BIT(a2, p2, x);
|
2609
|
+
}
|
2610
|
+
}
|
2611
|
+
idx1++;
|
2612
|
+
p2 += s2;
|
2613
|
+
}
|
2614
|
+
} else {
|
2615
|
+
for (; i--;) {
|
2616
|
+
LOAD_BIT(a2, p2, y);
|
2617
|
+
if (y == 1) {
|
2618
|
+
LOAD_BIT(a1, p1, x);
|
2619
|
+
if (x != 1) {
|
2620
|
+
STORE_BIT(a2, p2, x);
|
2621
|
+
}
|
2622
|
+
}
|
2623
|
+
p1 += s1;
|
2624
|
+
p2 += s2;
|
2625
|
+
}
|
2626
|
+
}
|
2627
|
+
} else {
|
2628
|
+
LOAD_BIT(a2, p2, x);
|
2629
|
+
if (x != 1) {
|
2630
|
+
return;
|
2631
|
+
}
|
2632
|
+
if (idx1) {
|
2633
|
+
for (; i--;) {
|
2634
|
+
LOAD_BIT(a1, p1 + *idx1, y);
|
2635
|
+
if (y != 1) {
|
2636
|
+
STORE_BIT(a2, p2, y);
|
2637
|
+
return;
|
2638
|
+
}
|
2639
|
+
idx1++;
|
2640
|
+
}
|
2641
|
+
} else {
|
2642
|
+
for (; i--;) {
|
2643
|
+
LOAD_BIT(a1, p1, y);
|
2644
|
+
if (y != 1) {
|
2645
|
+
STORE_BIT(a2, p2, y);
|
2646
|
+
return;
|
2647
|
+
}
|
2648
|
+
p1 += s1;
|
2649
|
+
}
|
2650
|
+
}
|
2651
|
+
}
|
2652
|
+
}
|
2653
|
+
|
2654
|
+
/*
|
2655
|
+
Return true if all of bits are one (true).
|
2656
|
+
If argument is supplied, return Bit-array reduced along the axes.
|
2657
|
+
@overload all?(axis:nil, keepdims:false)
|
2658
|
+
@param [Integer,Array,Range] axis (keyword) axes to be reduced.
|
2659
|
+
@param [TrueClass] keepdims (keyword) If true, the reduced axes are left in the result array as dimensions with size one.
|
2660
|
+
@return [Numo::Bit] .
|
2661
|
+
*/
|
2662
|
+
static VALUE bit_all_p(int argc, VALUE* argv, VALUE self) {
|
2663
|
+
VALUE v, reduce;
|
2664
|
+
narray_t* na;
|
2665
|
+
ndfunc_arg_in_t ain[3] = {{cT, 0}, {sym_reduce, 0}, {sym_init, 0}};
|
2666
|
+
ndfunc_arg_out_t aout[1] = {{numo_cBit, 0}};
|
2667
|
+
ndfunc_t ndf = {iter_bit_all_p, FULL_LOOP_NIP, 3, 1, ain, aout};
|
2668
|
+
|
2669
|
+
GetNArray(self, na);
|
2670
|
+
if (NA_SIZE(na) == 0) {
|
2671
|
+
return Qfalse;
|
2672
|
+
}
|
2673
|
+
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
|
2674
|
+
v = na_ndloop(&ndf, 3, self, reduce, INT2FIX(1));
|
2675
|
+
if (argc > 0) {
|
2676
|
+
return v;
|
2677
|
+
}
|
2678
|
+
v = bit_extract(v);
|
2679
|
+
switch (v) {
|
2680
|
+
case INT2FIX(0):
|
2681
|
+
return Qfalse;
|
2682
|
+
case INT2FIX(1):
|
2683
|
+
return Qtrue;
|
2684
|
+
default:
|
2685
|
+
rb_bug("unexpected result");
|
2686
|
+
return v;
|
2687
|
+
}
|
2688
|
+
}
|
2689
|
+
|
2690
|
+
static void iter_bit_any_p(na_loop_t* const lp) {
|
2691
|
+
size_t i;
|
2692
|
+
BIT_DIGIT *a1, *a2;
|
2693
|
+
size_t p1, p2;
|
2694
|
+
ssize_t s1, s2;
|
2695
|
+
size_t *idx1, *idx2;
|
2696
|
+
BIT_DIGIT x = 0, y = 0;
|
2697
|
+
|
2698
|
+
INIT_COUNTER(lp, i);
|
2699
|
+
INIT_PTR_BIT_IDX(lp, 0, a1, p1, s1, idx1);
|
2700
|
+
INIT_PTR_BIT_IDX(lp, 1, a2, p2, s2, idx2);
|
2701
|
+
if (idx2) {
|
2702
|
+
if (idx1) {
|
2703
|
+
for (; i--;) {
|
2704
|
+
LOAD_BIT(a2, p2 + *idx2, y);
|
2705
|
+
if (y == 0) {
|
2706
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
2707
|
+
if (x != 0) {
|
2708
|
+
STORE_BIT(a2, p2 + *idx2, x);
|
2709
|
+
}
|
2710
|
+
}
|
2711
|
+
idx1++;
|
2712
|
+
idx2++;
|
2713
|
+
}
|
2714
|
+
} else {
|
2715
|
+
for (; i--;) {
|
2716
|
+
LOAD_BIT(a2, p2 + *idx2, y);
|
2717
|
+
if (y == 0) {
|
2718
|
+
LOAD_BIT(a1, p1, x);
|
2719
|
+
if (x != 0) {
|
2720
|
+
STORE_BIT(a2, p2 + *idx2, x);
|
2721
|
+
}
|
2722
|
+
}
|
2723
|
+
p1 += s1;
|
2724
|
+
idx2++;
|
2725
|
+
}
|
2726
|
+
}
|
2727
|
+
} else if (s2) {
|
2728
|
+
if (idx1) {
|
2729
|
+
for (; i--;) {
|
2730
|
+
LOAD_BIT(a2, p2, y);
|
2731
|
+
if (y == 0) {
|
2732
|
+
LOAD_BIT(a1, p1 + *idx1, x);
|
2733
|
+
if (x != 0) {
|
2734
|
+
STORE_BIT(a2, p2, x);
|
2735
|
+
}
|
2736
|
+
}
|
2737
|
+
idx1++;
|
2738
|
+
p2 += s2;
|
2739
|
+
}
|
2740
|
+
} else {
|
2741
|
+
for (; i--;) {
|
2742
|
+
LOAD_BIT(a2, p2, y);
|
2743
|
+
if (y == 0) {
|
2744
|
+
LOAD_BIT(a1, p1, x);
|
2745
|
+
if (x != 0) {
|
2746
|
+
STORE_BIT(a2, p2, x);
|
2747
|
+
}
|
2748
|
+
}
|
2749
|
+
p1 += s1;
|
2750
|
+
p2 += s2;
|
2751
|
+
}
|
2752
|
+
}
|
2753
|
+
} else {
|
2754
|
+
LOAD_BIT(a2, p2, x);
|
2755
|
+
if (x != 0) {
|
2756
|
+
return;
|
2757
|
+
}
|
2758
|
+
if (idx1) {
|
2759
|
+
for (; i--;) {
|
2760
|
+
LOAD_BIT(a1, p1 + *idx1, y);
|
2761
|
+
if (y != 0) {
|
2762
|
+
STORE_BIT(a2, p2, y);
|
2763
|
+
return;
|
2764
|
+
}
|
2765
|
+
idx1++;
|
2766
|
+
}
|
2767
|
+
} else {
|
2768
|
+
for (; i--;) {
|
2769
|
+
LOAD_BIT(a1, p1, y);
|
2770
|
+
if (y != 0) {
|
2771
|
+
STORE_BIT(a2, p2, y);
|
2772
|
+
return;
|
2773
|
+
}
|
2774
|
+
p1 += s1;
|
2775
|
+
}
|
2776
|
+
}
|
2777
|
+
}
|
2778
|
+
}
|
2779
|
+
|
2780
|
+
/*
|
2781
|
+
|
2782
|
+
Return true if any of bits is one (true).
|
2783
|
+
If argument is supplied, return Bit-array reduced along the axes.
|
2784
|
+
@overload any?(axis:nil, keepdims:false)
|
2785
|
+
@param [Integer,Array,Range] axis (keyword) axes to be reduced.
|
2786
|
+
@param [TrueClass] keepdims (keyword) If true, the reduced axes are left in the result array as dimensions with size one.
|
2787
|
+
@return [Numo::Bit] .
|
2788
|
+
*/
|
2789
|
+
static VALUE bit_any_p(int argc, VALUE* argv, VALUE self) {
|
2790
|
+
VALUE v, reduce;
|
2791
|
+
narray_t* na;
|
2792
|
+
ndfunc_arg_in_t ain[3] = {{cT, 0}, {sym_reduce, 0}, {sym_init, 0}};
|
2793
|
+
ndfunc_arg_out_t aout[1] = {{numo_cBit, 0}};
|
2794
|
+
ndfunc_t ndf = {iter_bit_any_p, FULL_LOOP_NIP, 3, 1, ain, aout};
|
2795
|
+
|
2796
|
+
GetNArray(self, na);
|
2797
|
+
if (NA_SIZE(na) == 0) {
|
2798
|
+
return Qfalse;
|
2799
|
+
}
|
2800
|
+
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
|
2801
|
+
v = na_ndloop(&ndf, 3, self, reduce, INT2FIX(0));
|
2802
|
+
if (argc > 0) {
|
2803
|
+
return v;
|
2804
|
+
}
|
2805
|
+
v = bit_extract(v);
|
2806
|
+
switch (v) {
|
2807
|
+
case INT2FIX(0):
|
2808
|
+
return Qfalse;
|
2809
|
+
case INT2FIX(1):
|
2810
|
+
return Qtrue;
|
2811
|
+
default:
|
2812
|
+
rb_bug("unexpected result");
|
2813
|
+
return v;
|
2814
|
+
}
|
2815
|
+
}
|
2816
|
+
|
2817
|
+
static VALUE bit_none_p(int argc, VALUE* argv, VALUE self) {
|
2818
|
+
VALUE v;
|
2819
|
+
|
2820
|
+
v = bit_any_p(argc, argv, self);
|
2821
|
+
|
2822
|
+
if (v == Qtrue) {
|
2823
|
+
return Qfalse;
|
2824
|
+
} else if (v == Qfalse) {
|
2825
|
+
return Qtrue;
|
2826
|
+
}
|
2827
|
+
return bit_not(v);
|
2828
|
+
}
|
2829
|
+
|
2830
|
+
typedef struct {
|
2831
|
+
size_t count;
|
2832
|
+
char* idx0;
|
2833
|
+
char* idx1;
|
2834
|
+
size_t elmsz;
|
2835
|
+
} where_opt_t;
|
2836
|
+
|
2837
|
+
#define STORE_INT(ptr, esz, x) memcpy(ptr, &(x), esz)
|
2838
|
+
|
2839
|
+
static void iter_bit_where(na_loop_t* const lp) {
|
2840
|
+
size_t i;
|
2841
|
+
BIT_DIGIT* a;
|
2842
|
+
size_t p;
|
2843
|
+
ssize_t s;
|
2844
|
+
size_t* idx;
|
2845
|
+
BIT_DIGIT x = 0;
|
2846
|
+
char* idx1;
|
2847
|
+
size_t count;
|
2848
|
+
size_t e;
|
2849
|
+
where_opt_t* g;
|
2850
|
+
|
2851
|
+
g = (where_opt_t*)(lp->opt_ptr);
|
2852
|
+
count = g->count;
|
2853
|
+
idx1 = g->idx1;
|
2854
|
+
e = g->elmsz;
|
2855
|
+
INIT_COUNTER(lp, i);
|
2856
|
+
INIT_PTR_BIT_IDX(lp, 0, a, p, s, idx);
|
2857
|
+
if (idx) {
|
2858
|
+
for (; i--;) {
|
2859
|
+
LOAD_BIT(a, p + *idx, x);
|
2860
|
+
idx++;
|
2861
|
+
if (x != 0) {
|
2862
|
+
STORE_INT(idx1, e, count);
|
2863
|
+
idx1 += e;
|
2864
|
+
}
|
2865
|
+
count++;
|
2866
|
+
}
|
2867
|
+
} else {
|
2868
|
+
for (; i--;) {
|
2869
|
+
LOAD_BIT(a, p, x);
|
2870
|
+
p += s;
|
2871
|
+
if (x != 0) {
|
2872
|
+
STORE_INT(idx1, e, count);
|
2873
|
+
idx1 += e;
|
2874
|
+
}
|
2875
|
+
count++;
|
2876
|
+
}
|
2877
|
+
}
|
2878
|
+
g->count = count;
|
2879
|
+
g->idx1 = idx1;
|
2880
|
+
}
|
2881
|
+
|
2882
|
+
/*
|
2883
|
+
Returns the array of index where the bit is one (true).
|
2884
|
+
@overload where
|
2885
|
+
@return [Numo::Int32,Numo::Int64]
|
2886
|
+
*/
|
2887
|
+
static VALUE bit_where(VALUE self) {
|
2888
|
+
volatile VALUE idx_1;
|
2889
|
+
size_t size, n_1;
|
2890
|
+
where_opt_t* g;
|
2891
|
+
|
2892
|
+
ndfunc_arg_in_t ain[1] = {{cT, 0}};
|
2893
|
+
ndfunc_t ndf = {iter_bit_where, FULL_LOOP, 1, 0, ain, 0};
|
2894
|
+
|
2895
|
+
size = RNARRAY_SIZE(self);
|
2896
|
+
n_1 = NUM2SIZET(bit_count_true(0, NULL, self));
|
2897
|
+
g = ALLOCA_N(where_opt_t, 1);
|
2898
|
+
g->count = 0;
|
2899
|
+
if (size > 4294967295ul) {
|
2900
|
+
idx_1 = nary_new(numo_cInt64, 1, &n_1);
|
2901
|
+
g->elmsz = 8;
|
2902
|
+
} else {
|
2903
|
+
idx_1 = nary_new(numo_cInt32, 1, &n_1);
|
2904
|
+
g->elmsz = 4;
|
2905
|
+
}
|
2906
|
+
g->idx1 = na_get_pointer_for_write(idx_1);
|
2907
|
+
g->idx0 = NULL;
|
2908
|
+
na_ndloop3(&ndf, g, 1, self);
|
2909
|
+
na_release_lock(idx_1);
|
2910
|
+
return idx_1;
|
2911
|
+
}
|
2912
|
+
|
2913
|
+
static void iter_bit_where2(na_loop_t* const lp) {
|
2914
|
+
size_t i;
|
2915
|
+
BIT_DIGIT* a;
|
2916
|
+
size_t p;
|
2917
|
+
ssize_t s;
|
2918
|
+
size_t* idx;
|
2919
|
+
BIT_DIGIT x = 0;
|
2920
|
+
char *idx0, *idx1;
|
2921
|
+
size_t count;
|
2922
|
+
size_t e;
|
2923
|
+
where_opt_t* g;
|
2924
|
+
|
2925
|
+
g = (where_opt_t*)(lp->opt_ptr);
|
2926
|
+
count = g->count;
|
2927
|
+
idx0 = g->idx0;
|
2928
|
+
idx1 = g->idx1;
|
2929
|
+
e = g->elmsz;
|
2930
|
+
INIT_COUNTER(lp, i);
|
2931
|
+
INIT_PTR_BIT_IDX(lp, 0, a, p, s, idx);
|
2932
|
+
if (idx) {
|
2933
|
+
for (; i--;) {
|
2934
|
+
LOAD_BIT(a, p + *idx, x);
|
2935
|
+
idx++;
|
2936
|
+
if (x == 0) {
|
2937
|
+
STORE_INT(idx0, e, count);
|
2938
|
+
idx0 += e;
|
2939
|
+
} else {
|
2940
|
+
STORE_INT(idx1, e, count);
|
2941
|
+
idx1 += e;
|
2942
|
+
}
|
2943
|
+
count++;
|
2944
|
+
}
|
2945
|
+
} else {
|
2946
|
+
for (; i--;) {
|
2947
|
+
LOAD_BIT(a, p, x);
|
2948
|
+
p += s;
|
2949
|
+
if (x == 0) {
|
2950
|
+
STORE_INT(idx0, e, count);
|
2951
|
+
idx0 += e;
|
2952
|
+
} else {
|
2953
|
+
STORE_INT(idx1, e, count);
|
2954
|
+
idx1 += e;
|
2955
|
+
}
|
2956
|
+
count++;
|
2957
|
+
}
|
2958
|
+
}
|
2959
|
+
g->count = count;
|
2960
|
+
g->idx0 = idx0;
|
2961
|
+
g->idx1 = idx1;
|
2962
|
+
}
|
2963
|
+
|
2964
|
+
/*
|
2965
|
+
Returns two index arrays.
|
2966
|
+
The first array contains index where the bit is one (true).
|
2967
|
+
The second array contains index where the bit is zero (false).
|
2968
|
+
@overload where2
|
2969
|
+
@return [Numo::Int32,Numo::Int64]*2
|
2970
|
+
*/
|
2971
|
+
static VALUE bit_where2(VALUE self) {
|
2972
|
+
VALUE idx_1, idx_0;
|
2973
|
+
size_t size, n_1, n_0;
|
2974
|
+
where_opt_t* g;
|
2975
|
+
|
2976
|
+
ndfunc_arg_in_t ain[1] = {{cT, 0}};
|
2977
|
+
ndfunc_t ndf = {iter_bit_where2, FULL_LOOP, 1, 0, ain, 0};
|
2978
|
+
|
2979
|
+
size = RNARRAY_SIZE(self);
|
2980
|
+
n_1 = NUM2SIZET(bit_count_true(0, NULL, self));
|
2981
|
+
n_0 = size - n_1;
|
2982
|
+
g = ALLOCA_N(where_opt_t, 1);
|
2983
|
+
g->count = 0;
|
2984
|
+
if (size > 4294967295ul) {
|
2985
|
+
idx_1 = nary_new(numo_cInt64, 1, &n_1);
|
2986
|
+
idx_0 = nary_new(numo_cInt64, 1, &n_0);
|
2987
|
+
g->elmsz = 8;
|
2988
|
+
} else {
|
2989
|
+
idx_1 = nary_new(numo_cInt32, 1, &n_1);
|
2990
|
+
idx_0 = nary_new(numo_cInt32, 1, &n_0);
|
2991
|
+
g->elmsz = 4;
|
2992
|
+
}
|
2993
|
+
g->idx1 = na_get_pointer_for_write(idx_1);
|
2994
|
+
g->idx0 = na_get_pointer_for_write(idx_0);
|
2995
|
+
na_ndloop3(&ndf, g, 1, self);
|
2996
|
+
na_release_lock(idx_0);
|
2997
|
+
na_release_lock(idx_1);
|
2998
|
+
return rb_assoc_new(idx_1, idx_0);
|
2999
|
+
}
|
3000
|
+
|
3001
|
+
static void iter_bit_mask(na_loop_t* const lp) {
|
3002
|
+
size_t i;
|
3003
|
+
BIT_DIGIT* a;
|
3004
|
+
size_t p1, p2;
|
3005
|
+
ssize_t s1, s2;
|
3006
|
+
size_t *idx1, *idx2, *pidx;
|
3007
|
+
BIT_DIGIT x = 0;
|
3008
|
+
size_t count;
|
3009
|
+
where_opt_t* g;
|
3010
|
+
|
3011
|
+
g = (where_opt_t*)(lp->opt_ptr);
|
3012
|
+
count = g->count;
|
3013
|
+
pidx = (size_t*)(g->idx1);
|
3014
|
+
INIT_COUNTER(lp, i);
|
3015
|
+
INIT_PTR_BIT_IDX(lp, 0, a, p1, s1, idx1);
|
3016
|
+
// INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
3017
|
+
p2 = lp->args[1].iter[0].pos;
|
3018
|
+
s2 = lp->args[1].iter[0].step;
|
3019
|
+
idx2 = lp->args[1].iter[0].idx;
|
3020
|
+
|
3021
|
+
if (idx1) {
|
3022
|
+
if (idx2) {
|
3023
|
+
for (; i--;) {
|
3024
|
+
LOAD_BIT(a, p1 + *idx1, x);
|
3025
|
+
idx1++;
|
3026
|
+
if (x) {
|
3027
|
+
*(pidx++) = p2 + *idx2;
|
3028
|
+
count++;
|
3029
|
+
}
|
3030
|
+
idx2++;
|
3031
|
+
}
|
3032
|
+
} else {
|
3033
|
+
for (; i--;) {
|
3034
|
+
LOAD_BIT(a, p1 + *idx1, x);
|
3035
|
+
idx1++;
|
3036
|
+
if (x) {
|
3037
|
+
*(pidx++) = p2;
|
3038
|
+
count++;
|
3039
|
+
}
|
3040
|
+
p2 += s2;
|
3041
|
+
}
|
3042
|
+
}
|
3043
|
+
} else {
|
3044
|
+
if (idx2) {
|
3045
|
+
for (; i--;) {
|
3046
|
+
LOAD_BIT(a, p1, x);
|
3047
|
+
p1 += s1;
|
3048
|
+
if (x) {
|
3049
|
+
*(pidx++) = p2 + *idx2;
|
3050
|
+
count++;
|
3051
|
+
}
|
3052
|
+
idx2++;
|
3053
|
+
}
|
3054
|
+
} else {
|
3055
|
+
for (; i--;) {
|
3056
|
+
LOAD_BIT(a, p1, x);
|
3057
|
+
p1 += s1;
|
3058
|
+
if (x) {
|
3059
|
+
*(pidx++) = p2;
|
3060
|
+
count++;
|
3061
|
+
}
|
3062
|
+
p2 += s2;
|
3063
|
+
}
|
3064
|
+
}
|
3065
|
+
}
|
3066
|
+
g->count = count;
|
3067
|
+
g->idx1 = (char*)pidx;
|
3068
|
+
}
|
3069
|
+
|
3070
|
+
#if SIZEOF_VOIDP == 8
|
3071
|
+
#define cIndex numo_cInt64
|
3072
|
+
#elif SIZEOF_VOIDP == 4
|
3073
|
+
#define cIndex numo_cInt32
|
3074
|
+
#endif
|
3075
|
+
|
3076
|
+
static void shape_error(void) {
|
3077
|
+
rb_raise(nary_eShapeError, "mask and masked arrays must have the same shape");
|
3078
|
+
}
|
3079
|
+
|
3080
|
+
/*
|
3081
|
+
Return subarray of argument masked with self bit array.
|
3082
|
+
@overload mask(array)
|
3083
|
+
@param [Numo::NArray] array narray to be masked.
|
3084
|
+
@return [Numo::NArray] view of masked array.
|
3085
|
+
*/
|
3086
|
+
static VALUE bit_mask(VALUE mask, VALUE val) {
|
3087
|
+
int i;
|
3088
|
+
VALUE idx_1, view;
|
3089
|
+
narray_data_t* nidx;
|
3090
|
+
narray_view_t *nv, *nv_val;
|
3091
|
+
narray_t *na, *na_mask;
|
3092
|
+
stridx_t stridx0;
|
3093
|
+
size_t n_1;
|
3094
|
+
where_opt_t g;
|
3095
|
+
ndfunc_arg_in_t ain[2] = {{cT, 0}, {Qnil, 0}};
|
3096
|
+
ndfunc_t ndf = {iter_bit_mask, FULL_LOOP, 2, 0, ain, 0};
|
3097
|
+
|
3098
|
+
// cast val to NArray
|
3099
|
+
if (!rb_obj_is_kind_of(val, numo_cNArray)) {
|
3100
|
+
val = rb_funcall(numo_cNArray, id_cast, 1, val);
|
3101
|
+
}
|
3102
|
+
// shapes of mask and val must be same
|
3103
|
+
GetNArray(val, na);
|
3104
|
+
GetNArray(mask, na_mask);
|
3105
|
+
if (na_mask->ndim != na->ndim) {
|
3106
|
+
shape_error();
|
3107
|
+
}
|
3108
|
+
for (i = 0; i < na->ndim; i++) {
|
3109
|
+
if (na_mask->shape[i] != na->shape[i]) {
|
3110
|
+
shape_error();
|
3111
|
+
}
|
3112
|
+
}
|
3113
|
+
|
3114
|
+
n_1 = NUM2SIZET(bit_count_true(0, NULL, mask));
|
3115
|
+
idx_1 = nary_new(cIndex, 1, &n_1);
|
3116
|
+
g.count = 0;
|
3117
|
+
g.elmsz = SIZEOF_VOIDP;
|
3118
|
+
g.idx1 = na_get_pointer_for_write(idx_1);
|
3119
|
+
g.idx0 = NULL;
|
3120
|
+
na_ndloop3(&ndf, &g, 2, mask, val);
|
3121
|
+
|
3122
|
+
view = na_s_allocate_view(rb_obj_class(val));
|
3123
|
+
GetNArrayView(view, nv);
|
3124
|
+
na_setup_shape((narray_t*)nv, 1, &n_1);
|
3125
|
+
|
3126
|
+
GetNArrayData(idx_1, nidx);
|
3127
|
+
SDX_SET_INDEX(stridx0, (size_t*)nidx->ptr);
|
3128
|
+
nidx->ptr = NULL;
|
3129
|
+
RB_GC_GUARD(idx_1);
|
3130
|
+
|
3131
|
+
nv->stridx = ALLOC_N(stridx_t, 1);
|
3132
|
+
nv->stridx[0] = stridx0;
|
3133
|
+
nv->offset = 0;
|
3134
|
+
|
3135
|
+
switch (NA_TYPE(na)) {
|
3136
|
+
case NARRAY_DATA_T:
|
3137
|
+
nv->data = val;
|
3138
|
+
break;
|
3139
|
+
case NARRAY_VIEW_T:
|
3140
|
+
GetNArrayView(val, nv_val);
|
3141
|
+
nv->data = nv_val->data;
|
3142
|
+
break;
|
3143
|
+
default:
|
3144
|
+
rb_raise(rb_eRuntimeError, "invalid NA_TYPE: %d", NA_TYPE(na));
|
3145
|
+
}
|
3146
|
+
|
3147
|
+
return view;
|
3148
|
+
}
|
3149
|
+
|
3150
|
+
void Init_numo_bit(void) {
|
3151
|
+
VALUE hCast, mNumo;
|
3152
|
+
|
3153
|
+
mNumo = rb_define_module("Numo");
|
3154
|
+
|
3155
|
+
id_cast = rb_intern("cast");
|
3156
|
+
id_divmod = rb_intern("divmod");
|
3157
|
+
id_eq = rb_intern("eq");
|
3158
|
+
id_mulsum = rb_intern("mulsum");
|
3159
|
+
id_ne = rb_intern("ne");
|
3160
|
+
id_to_a = rb_intern("to_a");
|
3161
|
+
|
3162
|
+
/*
|
3163
|
+
Document-class: Numo::Bit
|
3164
|
+
|
3165
|
+
*/
|
3166
|
+
cT = rb_define_class_under(mNumo, "Bit", cNArray);
|
3167
|
+
|
3168
|
+
hCast = rb_hash_new();
|
3169
|
+
rb_define_const(cT, "UPCAST", hCast);
|
3170
|
+
rb_hash_aset(hCast, rb_cArray, cT);
|
3171
|
+
|
3172
|
+
#ifdef RUBY_INTEGER_UNIFICATION
|
3173
|
+
rb_hash_aset(hCast, rb_cInteger, cT);
|
3174
|
+
#else
|
3175
|
+
rb_hash_aset(hCast, rb_cFixnum, cT);
|
3176
|
+
rb_hash_aset(hCast, rb_cBignum, cT);
|
3177
|
+
#endif
|
3178
|
+
rb_hash_aset(hCast, rb_cFloat, numo_cDFloat);
|
3179
|
+
rb_hash_aset(hCast, rb_cComplex, numo_cDComplex);
|
3180
|
+
rb_hash_aset(hCast, numo_cRObject, numo_cRObject);
|
3181
|
+
rb_hash_aset(hCast, numo_cDComplex, numo_cDComplex);
|
3182
|
+
rb_hash_aset(hCast, numo_cSComplex, numo_cSComplex);
|
3183
|
+
rb_hash_aset(hCast, numo_cDFloat, numo_cDFloat);
|
3184
|
+
rb_hash_aset(hCast, numo_cSFloat, numo_cSFloat);
|
3185
|
+
rb_hash_aset(hCast, numo_cInt64, numo_cInt64);
|
3186
|
+
rb_hash_aset(hCast, numo_cInt32, numo_cInt32);
|
3187
|
+
rb_hash_aset(hCast, numo_cInt16, numo_cInt16);
|
3188
|
+
rb_hash_aset(hCast, numo_cInt8, numo_cInt8);
|
3189
|
+
rb_hash_aset(hCast, numo_cUInt64, numo_cUInt64);
|
3190
|
+
rb_hash_aset(hCast, numo_cUInt32, numo_cUInt32);
|
3191
|
+
rb_hash_aset(hCast, numo_cUInt16, numo_cUInt16);
|
3192
|
+
rb_hash_aset(hCast, numo_cUInt8, numo_cUInt8);
|
3193
|
+
rb_obj_freeze(hCast);
|
3194
|
+
|
3195
|
+
/**/
|
3196
|
+
rb_define_const(cT, "ELEMENT_BIT_SIZE", INT2FIX(1));
|
3197
|
+
/**/
|
3198
|
+
rb_define_const(cT, "ELEMENT_BYTE_SIZE", rb_float_new(1.0 / 8));
|
3199
|
+
/**/
|
3200
|
+
rb_define_const(cT, "CONTIGUOUS_STRIDE", INT2FIX(1));
|
3201
|
+
rb_define_alloc_func(cT, bit_s_alloc_func);
|
3202
|
+
rb_define_method(cT, "allocate", bit_allocate, 0);
|
3203
|
+
rb_define_method(cT, "extract", bit_extract, 0);
|
3204
|
+
|
3205
|
+
rb_define_method(cT, "store", bit_store, 1);
|
3206
|
+
|
3207
|
+
rb_define_singleton_method(cT, "cast", bit_s_cast, 1);
|
3208
|
+
rb_define_method(cT, "[]", bit_aref, -1);
|
3209
|
+
rb_define_method(cT, "[]=", bit_aset, -1);
|
3210
|
+
rb_define_method(cT, "coerce_cast", bit_coerce_cast, 1);
|
3211
|
+
rb_define_method(cT, "to_a", bit_to_a, 0);
|
3212
|
+
rb_define_method(cT, "fill", bit_fill, 1);
|
3213
|
+
rb_define_method(cT, "format", bit_format, -1);
|
3214
|
+
rb_define_method(cT, "format_to_a", bit_format_to_a, -1);
|
3215
|
+
rb_define_method(cT, "inspect", bit_inspect, 0);
|
3216
|
+
rb_define_method(cT, "each", bit_each, 0);
|
3217
|
+
rb_define_method(cT, "each_with_index", bit_each_with_index, 0);
|
3218
|
+
rb_define_method(cT, "copy", bit_copy, 0);
|
3219
|
+
rb_define_method(cT, "~", bit_not, 0);
|
3220
|
+
rb_define_method(cT, "&", bit_and, 1);
|
3221
|
+
rb_define_method(cT, "|", bit_or, 1);
|
3222
|
+
rb_define_method(cT, "^", bit_xor, 1);
|
3223
|
+
rb_define_method(cT, "eq", bit_eq, 1);
|
3224
|
+
rb_define_method(cT, "count_true", bit_count_true, -1);
|
3225
|
+
rb_define_alias(cT, "count_1", "count_true");
|
3226
|
+
rb_define_alias(cT, "count", "count_true");
|
3227
|
+
rb_define_method(cT, "count_false", bit_count_false, -1);
|
3228
|
+
rb_define_alias(cT, "count_0", "count_false");
|
3229
|
+
rb_define_method(cT, "all?", bit_all_p, -1);
|
3230
|
+
rb_define_method(cT, "any?", bit_any_p, -1);
|
3231
|
+
rb_define_method(cT, "none?", bit_none_p, -1);
|
3232
|
+
rb_define_method(cT, "where", bit_where, 0);
|
3233
|
+
rb_define_method(cT, "where2", bit_where2, 0);
|
3234
|
+
rb_define_method(cT, "mask", bit_mask, 1);
|
3235
|
+
rb_define_singleton_method(cT, "[]", bit_s_cast, -2);
|
3236
|
+
}
|