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.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +14 -0
  3. data/LICENSE +30 -0
  4. data/README.md +71 -0
  5. data/Rakefile +24 -0
  6. data/ext/numo/narray/SFMT-params.h +97 -0
  7. data/ext/numo/narray/SFMT-params19937.h +48 -0
  8. data/ext/numo/narray/SFMT.c +602 -0
  9. data/ext/numo/narray/SFMT.h +147 -0
  10. data/ext/numo/narray/array.c +575 -0
  11. data/ext/numo/narray/data.c +958 -0
  12. data/ext/numo/narray/extconf.rb +84 -0
  13. data/ext/numo/narray/index.c +1092 -0
  14. data/ext/numo/narray/kwargs.c +142 -0
  15. data/ext/numo/narray/math.c +133 -0
  16. data/ext/numo/narray/narray.c +1976 -0
  17. data/ext/numo/narray/narray.def +28 -0
  18. data/ext/numo/narray/ndloop.c +1840 -0
  19. data/ext/numo/narray/numo/compat.h +23 -0
  20. data/ext/numo/narray/numo/intern.h +115 -0
  21. data/ext/numo/narray/numo/narray.h +480 -0
  22. data/ext/numo/narray/numo/ndloop.h +93 -0
  23. data/ext/numo/narray/numo/template.h +149 -0
  24. data/ext/numo/narray/numo/types/bit.h +38 -0
  25. data/ext/numo/narray/numo/types/complex.h +404 -0
  26. data/ext/numo/narray/numo/types/complex_macro.h +384 -0
  27. data/ext/numo/narray/numo/types/dcomplex.h +42 -0
  28. data/ext/numo/narray/numo/types/dfloat.h +44 -0
  29. data/ext/numo/narray/numo/types/float_def.h +34 -0
  30. data/ext/numo/narray/numo/types/float_macro.h +202 -0
  31. data/ext/numo/narray/numo/types/int16.h +27 -0
  32. data/ext/numo/narray/numo/types/int32.h +23 -0
  33. data/ext/numo/narray/numo/types/int64.h +23 -0
  34. data/ext/numo/narray/numo/types/int8.h +23 -0
  35. data/ext/numo/narray/numo/types/int_macro.h +66 -0
  36. data/ext/numo/narray/numo/types/real_accum.h +481 -0
  37. data/ext/numo/narray/numo/types/robj_macro.h +78 -0
  38. data/ext/numo/narray/numo/types/robject.h +25 -0
  39. data/ext/numo/narray/numo/types/scomplex.h +42 -0
  40. data/ext/numo/narray/numo/types/sfloat.h +45 -0
  41. data/ext/numo/narray/numo/types/uint16.h +24 -0
  42. data/ext/numo/narray/numo/types/uint32.h +20 -0
  43. data/ext/numo/narray/numo/types/uint64.h +20 -0
  44. data/ext/numo/narray/numo/types/uint8.h +20 -0
  45. data/ext/numo/narray/numo/types/uint_macro.h +57 -0
  46. data/ext/numo/narray/numo/types/xint_macro.h +166 -0
  47. data/ext/numo/narray/rand.c +40 -0
  48. data/ext/numo/narray/src/t_bit.c +3236 -0
  49. data/ext/numo/narray/src/t_dcomplex.c +6776 -0
  50. data/ext/numo/narray/src/t_dfloat.c +9417 -0
  51. data/ext/numo/narray/src/t_int16.c +5757 -0
  52. data/ext/numo/narray/src/t_int32.c +5757 -0
  53. data/ext/numo/narray/src/t_int64.c +5759 -0
  54. data/ext/numo/narray/src/t_int8.c +5355 -0
  55. data/ext/numo/narray/src/t_robject.c +5567 -0
  56. data/ext/numo/narray/src/t_scomplex.c +6731 -0
  57. data/ext/numo/narray/src/t_sfloat.c +9374 -0
  58. data/ext/numo/narray/src/t_uint16.c +5753 -0
  59. data/ext/numo/narray/src/t_uint32.c +5753 -0
  60. data/ext/numo/narray/src/t_uint64.c +5755 -0
  61. data/ext/numo/narray/src/t_uint8.c +5351 -0
  62. data/ext/numo/narray/step.c +266 -0
  63. data/ext/numo/narray/struct.c +814 -0
  64. data/lib/numo/narray/extra.rb +1266 -0
  65. data/lib/numo/narray.rb +4 -0
  66. 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
+ }