numo-narray-alt 0.9.11 → 0.9.12

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/README.md +7 -0
  4. data/ext/numo/narray/numo/narray.h +2 -2
  5. data/ext/numo/narray/numo/types/robj_macro.h +1 -1
  6. data/ext/numo/narray/src/mh/bincount.h +233 -0
  7. data/ext/numo/narray/src/mh/bit/and.h +225 -0
  8. data/ext/numo/narray/src/mh/bit/left_shift.h +225 -0
  9. data/ext/numo/narray/src/mh/bit/not.h +173 -0
  10. data/ext/numo/narray/src/mh/bit/or.h +225 -0
  11. data/ext/numo/narray/src/mh/bit/right_shift.h +225 -0
  12. data/ext/numo/narray/src/mh/bit/xor.h +225 -0
  13. data/ext/numo/narray/src/mh/coerce_cast.h +9 -0
  14. data/ext/numo/narray/src/mh/comp/binary_func.h +37 -0
  15. data/ext/numo/narray/src/mh/comp/eq.h +26 -0
  16. data/ext/numo/narray/src/mh/comp/ge.h +26 -0
  17. data/ext/numo/narray/src/mh/comp/gt.h +26 -0
  18. data/ext/numo/narray/src/mh/comp/le.h +26 -0
  19. data/ext/numo/narray/src/mh/comp/lt.h +26 -0
  20. data/ext/numo/narray/src/mh/comp/ne.h +26 -0
  21. data/ext/numo/narray/src/mh/comp/nearly_eq.h +26 -0
  22. data/ext/numo/narray/src/mh/divmod.h +142 -0
  23. data/ext/numo/narray/src/mh/eye.h +1 -1
  24. data/ext/numo/narray/src/mh/fill.h +94 -0
  25. data/ext/numo/narray/src/mh/format.h +108 -0
  26. data/ext/numo/narray/src/mh/format_to_a.h +89 -0
  27. data/ext/numo/narray/src/mh/inspect.h +33 -0
  28. data/ext/numo/narray/src/mh/isfinite.h +42 -0
  29. data/ext/numo/narray/src/mh/isinf.h +42 -0
  30. data/ext/numo/narray/src/mh/isnan.h +42 -0
  31. data/ext/numo/narray/src/mh/isneginf.h +42 -0
  32. data/ext/numo/narray/src/mh/isposinf.h +42 -0
  33. data/ext/numo/narray/src/mh/math/acos.h +2 -2
  34. data/ext/numo/narray/src/mh/math/acosh.h +2 -2
  35. data/ext/numo/narray/src/mh/math/asin.h +2 -2
  36. data/ext/numo/narray/src/mh/math/asinh.h +2 -2
  37. data/ext/numo/narray/src/mh/math/atan.h +2 -2
  38. data/ext/numo/narray/src/mh/math/atan2.h +3 -3
  39. data/ext/numo/narray/src/mh/math/atanh.h +2 -2
  40. data/ext/numo/narray/src/mh/math/cbrt.h +2 -2
  41. data/ext/numo/narray/src/mh/math/cos.h +2 -2
  42. data/ext/numo/narray/src/mh/math/cosh.h +2 -2
  43. data/ext/numo/narray/src/mh/math/erf.h +2 -2
  44. data/ext/numo/narray/src/mh/math/erfc.h +2 -2
  45. data/ext/numo/narray/src/mh/math/exp.h +2 -2
  46. data/ext/numo/narray/src/mh/math/exp10.h +2 -2
  47. data/ext/numo/narray/src/mh/math/exp2.h +2 -2
  48. data/ext/numo/narray/src/mh/math/expm1.h +2 -2
  49. data/ext/numo/narray/src/mh/math/frexp.h +3 -3
  50. data/ext/numo/narray/src/mh/math/hypot.h +3 -3
  51. data/ext/numo/narray/src/mh/math/ldexp.h +3 -3
  52. data/ext/numo/narray/src/mh/math/log.h +2 -2
  53. data/ext/numo/narray/src/mh/math/log10.h +2 -2
  54. data/ext/numo/narray/src/mh/math/log1p.h +2 -2
  55. data/ext/numo/narray/src/mh/math/log2.h +2 -2
  56. data/ext/numo/narray/src/mh/math/sin.h +2 -2
  57. data/ext/numo/narray/src/mh/math/sinc.h +2 -2
  58. data/ext/numo/narray/src/mh/math/sinh.h +2 -2
  59. data/ext/numo/narray/src/mh/math/sqrt.h +8 -8
  60. data/ext/numo/narray/src/mh/math/tan.h +2 -2
  61. data/ext/numo/narray/src/mh/math/tanh.h +2 -2
  62. data/ext/numo/narray/src/mh/math/unary_func.h +3 -3
  63. data/ext/numo/narray/src/mh/op/add.h +78 -0
  64. data/ext/numo/narray/src/mh/op/binary_func.h +423 -0
  65. data/ext/numo/narray/src/mh/op/div.h +118 -0
  66. data/ext/numo/narray/src/mh/op/mod.h +108 -0
  67. data/ext/numo/narray/src/mh/op/mul.h +78 -0
  68. data/ext/numo/narray/src/mh/op/sub.h +78 -0
  69. data/ext/numo/narray/src/mh/rand.h +2 -2
  70. data/ext/numo/narray/src/mh/round/ceil.h +11 -0
  71. data/ext/numo/narray/src/mh/round/floor.h +11 -0
  72. data/ext/numo/narray/src/mh/round/rint.h +9 -0
  73. data/ext/numo/narray/src/mh/round/round.h +11 -0
  74. data/ext/numo/narray/src/mh/round/trunc.h +11 -0
  75. data/ext/numo/narray/src/mh/round/unary_func.h +127 -0
  76. data/ext/numo/narray/src/mh/to_a.h +78 -0
  77. data/ext/numo/narray/src/t_bit.c +45 -234
  78. data/ext/numo/narray/src/t_dcomplex.c +584 -1809
  79. data/ext/numo/narray/src/t_dfloat.c +429 -2432
  80. data/ext/numo/narray/src/t_int16.c +481 -2283
  81. data/ext/numo/narray/src/t_int32.c +481 -2283
  82. data/ext/numo/narray/src/t_int64.c +481 -2283
  83. data/ext/numo/narray/src/t_int8.c +408 -1873
  84. data/ext/numo/narray/src/t_robject.c +448 -1977
  85. data/ext/numo/narray/src/t_scomplex.c +584 -1809
  86. data/ext/numo/narray/src/t_sfloat.c +429 -2434
  87. data/ext/numo/narray/src/t_uint16.c +480 -2278
  88. data/ext/numo/narray/src/t_uint32.c +480 -2278
  89. data/ext/numo/narray/src/t_uint64.c +480 -2278
  90. data/ext/numo/narray/src/t_uint8.c +407 -1868
  91. metadata +41 -2
@@ -43,6 +43,30 @@ static ID id_to_a;
43
43
  VALUE cT;
44
44
  extern VALUE cRT;
45
45
 
46
+ #include "mh/coerce_cast.h"
47
+ #include "mh/to_a.h"
48
+ #include "mh/fill.h"
49
+ #include "mh/format.h"
50
+ #include "mh/format_to_a.h"
51
+ #include "mh/inspect.h"
52
+ #include "mh/op/add.h"
53
+ #include "mh/op/sub.h"
54
+ #include "mh/op/mul.h"
55
+ #include "mh/op/div.h"
56
+ #include "mh/op/mod.h"
57
+ #include "mh/divmod.h"
58
+ #include "mh/comp/eq.h"
59
+ #include "mh/comp/ne.h"
60
+ #include "mh/comp/gt.h"
61
+ #include "mh/comp/ge.h"
62
+ #include "mh/comp/lt.h"
63
+ #include "mh/comp/le.h"
64
+ #include "mh/bit/and.h"
65
+ #include "mh/bit/or.h"
66
+ #include "mh/bit/xor.h"
67
+ #include "mh/bit/not.h"
68
+ #include "mh/bit/left_shift.h"
69
+ #include "mh/bit/right_shift.h"
46
70
  #include "mh/clip.h"
47
71
  #include "mh/sum.h"
48
72
  #include "mh/prod.h"
@@ -56,6 +80,7 @@ extern VALUE cRT;
56
80
  #include "mh/maximum.h"
57
81
  #include "mh/minimum.h"
58
82
  #include "mh/minmax.h"
83
+ #include "mh/bincount.h"
59
84
  #include "mh/cumsum.h"
60
85
  #include "mh/cumprod.h"
61
86
  #include "mh/mulsum.h"
@@ -70,6 +95,30 @@ extern VALUE cRT;
70
95
 
71
96
  typedef int32_t int32; // Type aliases for shorter notation
72
97
  // following the codebase naming convention.
98
+ DEF_NARRAY_COERCE_CAST_METHOD_FUNC(int32)
99
+ DEF_NARRAY_TO_A_METHOD_FUNC(int32)
100
+ DEF_NARRAY_FILL_METHOD_FUNC(int32)
101
+ DEF_NARRAY_FORMAT_METHOD_FUNC(int32)
102
+ DEF_NARRAY_FORMAT_TO_A_METHOD_FUNC(int32)
103
+ DEF_NARRAY_INSPECT_METHOD_FUNC(int32)
104
+ DEF_NARRAY_ADD_METHOD_FUNC(int32, numo_cInt32)
105
+ DEF_NARRAY_SUB_METHOD_FUNC(int32, numo_cInt32)
106
+ DEF_NARRAY_MUL_METHOD_FUNC(int32, numo_cInt32)
107
+ DEF_NARRAY_INT_DIV_METHOD_FUNC(int32, numo_cInt32)
108
+ DEF_NARRAY_INT_MOD_METHOD_FUNC(int32, numo_cInt32)
109
+ DEF_NARRAY_INT_DIVMOD_METHOD_FUNC(int32, numo_cInt32)
110
+ DEF_NARRAY_EQ_METHOD_FUNC(int32, numo_cInt32)
111
+ DEF_NARRAY_NE_METHOD_FUNC(int32, numo_cInt32)
112
+ DEF_NARRAY_GT_METHOD_FUNC(int32, numo_cInt32)
113
+ DEF_NARRAY_GE_METHOD_FUNC(int32, numo_cInt32)
114
+ DEF_NARRAY_LT_METHOD_FUNC(int32, numo_cInt32)
115
+ DEF_NARRAY_LE_METHOD_FUNC(int32, numo_cInt32)
116
+ DEF_NARRAY_INT_BIT_AND_METHOD_FUNC(int32, numo_cInt32)
117
+ DEF_NARRAY_INT_BIT_OR_METHOD_FUNC(int32, numo_cInt32)
118
+ DEF_NARRAY_INT_BIT_XOR_METHOD_FUNC(int32, numo_cInt32)
119
+ DEF_NARRAY_INT_BIT_NOT_METHOD_FUNC(int32, numo_cInt32)
120
+ DEF_NARRAY_INT_LEFT_SHIFT_METHOD_FUNC(int32, numo_cInt32)
121
+ DEF_NARRAY_INT_RIGHT_SHIFT_METHOD_FUNC(int32, numo_cInt32)
73
122
  DEF_NARRAY_CLIP_METHOD_FUNC(int32, numo_cInt32)
74
123
  DEF_NARRAY_INT_SUM_METHOD_FUNC(int32, numo_cInt32, int64_t, numo_cInt64)
75
124
  DEF_NARRAY_INT_PROD_METHOD_FUNC(int32, numo_cInt32, int64_t, numo_cInt64)
@@ -83,6 +132,7 @@ DEF_NARRAY_INT_ARGMIN_METHOD_FUNC(int32)
83
132
  DEF_NARRAY_INT_MAXIMUM_METHOD_FUNC(int32, numo_cInt32)
84
133
  DEF_NARRAY_INT_MINIMUM_METHOD_FUNC(int32, numo_cInt32)
85
134
  DEF_NARRAY_INT_MINMAX_METHOD_FUNC(int32, numo_cInt32)
135
+ DEF_NARRAY_INT_BINCOUNT_METHOD_FUNC(int32, numo_cInt32)
86
136
  DEF_NARRAY_INT_CUMSUM_METHOD_FUNC(int32, numo_cInt32)
87
137
  DEF_NARRAY_INT_CUMPROD_METHOD_FUNC(int32, numo_cInt32)
88
138
  DEF_NARRAY_INT_MULSUM_METHOD_FUNC(int32, numo_cInt32)
@@ -1253,204 +1303,6 @@ static VALUE int32_aset(int argc, VALUE* argv, VALUE self) {
1253
1303
  return argv[argc];
1254
1304
  }
1255
1305
 
1256
- /*
1257
- return NArray with cast to the type of self.
1258
- @overload coerce_cast(type)
1259
- @return [nil]
1260
- */
1261
- static VALUE int32_coerce_cast(VALUE self, VALUE type) {
1262
- return Qnil;
1263
- }
1264
-
1265
- static void iter_int32_to_a(na_loop_t* const lp) {
1266
- size_t i, s1;
1267
- char* p1;
1268
- size_t* idx1;
1269
- dtype x;
1270
- volatile VALUE a, y;
1271
-
1272
- INIT_COUNTER(lp, i);
1273
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1274
- a = rb_ary_new2(i);
1275
- rb_ary_push(lp->args[1].value, a);
1276
- if (idx1) {
1277
- for (; i--;) {
1278
- GET_DATA_INDEX(p1, idx1, dtype, x);
1279
- y = m_data_to_num(x);
1280
- rb_ary_push(a, y);
1281
- }
1282
- } else {
1283
- for (; i--;) {
1284
- GET_DATA_STRIDE(p1, s1, dtype, x);
1285
- y = m_data_to_num(x);
1286
- rb_ary_push(a, y);
1287
- }
1288
- }
1289
- }
1290
-
1291
- /*
1292
- Convert self to Array.
1293
- @overload to_a
1294
- @return [Array]
1295
- */
1296
- static VALUE int32_to_a(VALUE self) {
1297
- ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { sym_loop_opt }, { sym_option } };
1298
- ndfunc_arg_out_t aout[1] = { { rb_cArray, 0 } }; // dummy?
1299
- ndfunc_t ndf = { iter_int32_to_a, FULL_LOOP_NIP, 3, 1, ain, aout };
1300
- return na_ndloop_cast_narray_to_rarray(&ndf, self, Qnil);
1301
- }
1302
-
1303
- static void iter_int32_fill(na_loop_t* const lp) {
1304
- size_t i;
1305
- char* p1;
1306
- ssize_t s1;
1307
- size_t* idx1;
1308
- VALUE x = lp->option;
1309
- dtype y;
1310
- INIT_COUNTER(lp, i);
1311
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1312
- y = m_num_to_data(x);
1313
- if (idx1) {
1314
- for (; i--;) {
1315
- SET_DATA_INDEX(p1, idx1, dtype, y);
1316
- }
1317
- } else {
1318
- for (; i--;) {
1319
- SET_DATA_STRIDE(p1, s1, dtype, y);
1320
- }
1321
- }
1322
- }
1323
-
1324
- /*
1325
- Fill elements with other.
1326
- @overload fill other
1327
- @param [Numeric] other
1328
- @return [Numo::Int32] self.
1329
- */
1330
- static VALUE int32_fill(VALUE self, VALUE val) {
1331
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { sym_option } };
1332
- ndfunc_t ndf = { iter_int32_fill, FULL_LOOP, 2, 0, ain, 0 };
1333
-
1334
- na_ndloop(&ndf, 2, self, val);
1335
- return self;
1336
- }
1337
-
1338
- static VALUE format_int32(VALUE fmt, dtype* x) {
1339
- // fix-me
1340
- char s[48];
1341
- int n;
1342
-
1343
- if (NIL_P(fmt)) {
1344
- n = m_sprintf(s, *x);
1345
- return rb_str_new(s, n);
1346
- }
1347
- return rb_funcall(fmt, '%', 1, m_data_to_num(*x));
1348
- }
1349
-
1350
- static void iter_int32_format(na_loop_t* const lp) {
1351
- size_t i;
1352
- char *p1, *p2;
1353
- ssize_t s1, s2;
1354
- size_t* idx1;
1355
- dtype* x;
1356
- VALUE y;
1357
- VALUE fmt = lp->option;
1358
- INIT_COUNTER(lp, i);
1359
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1360
- INIT_PTR(lp, 1, p2, s2);
1361
- if (idx1) {
1362
- for (; i--;) {
1363
- x = (dtype*)(p1 + *idx1);
1364
- idx1++;
1365
- y = format_int32(fmt, x);
1366
- SET_DATA_STRIDE(p2, s2, VALUE, y);
1367
- }
1368
- } else {
1369
- for (; i--;) {
1370
- x = (dtype*)p1;
1371
- p1 += s1;
1372
- y = format_int32(fmt, x);
1373
- SET_DATA_STRIDE(p2, s2, VALUE, y);
1374
- }
1375
- }
1376
- }
1377
-
1378
- /*
1379
- Format elements into strings.
1380
- @overload format format
1381
- @param [String] format
1382
- @return [Numo::RObject] array of formatted strings.
1383
- */
1384
- static VALUE int32_format(int argc, VALUE* argv, VALUE self) {
1385
- VALUE fmt = Qnil;
1386
-
1387
- ndfunc_arg_in_t ain[2] = { { Qnil, 0 }, { sym_option } };
1388
- ndfunc_arg_out_t aout[1] = { { numo_cRObject, 0 } };
1389
- ndfunc_t ndf = { iter_int32_format, FULL_LOOP_NIP, 2, 1, ain, aout };
1390
-
1391
- rb_scan_args(argc, argv, "01", &fmt);
1392
- return na_ndloop(&ndf, 2, self, fmt);
1393
- }
1394
-
1395
- static void iter_int32_format_to_a(na_loop_t* const lp) {
1396
- size_t i;
1397
- char* p1;
1398
- ssize_t s1;
1399
- size_t* idx1;
1400
- dtype* x;
1401
- VALUE y;
1402
- volatile VALUE a;
1403
- VALUE fmt = lp->option;
1404
- INIT_COUNTER(lp, i);
1405
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1406
- a = rb_ary_new2(i);
1407
- rb_ary_push(lp->args[1].value, a);
1408
- if (idx1) {
1409
- for (; i--;) {
1410
- x = (dtype*)(p1 + *idx1);
1411
- idx1++;
1412
- y = format_int32(fmt, x);
1413
- rb_ary_push(a, y);
1414
- }
1415
- } else {
1416
- for (; i--;) {
1417
- x = (dtype*)p1;
1418
- p1 += s1;
1419
- y = format_int32(fmt, x);
1420
- rb_ary_push(a, y);
1421
- }
1422
- }
1423
- }
1424
-
1425
- /*
1426
- Format elements into strings.
1427
- @overload format_to_a format
1428
- @param [String] format
1429
- @return [Array] array of formatted strings.
1430
- */
1431
- static VALUE int32_format_to_a(int argc, VALUE* argv, VALUE self) {
1432
- VALUE fmt = Qnil;
1433
- ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { sym_loop_opt }, { sym_option } };
1434
- ndfunc_arg_out_t aout[1] = { { rb_cArray, 0 } }; // dummy?
1435
- ndfunc_t ndf = { iter_int32_format_to_a, FULL_LOOP_NIP, 3, 1, ain, aout };
1436
-
1437
- rb_scan_args(argc, argv, "01", &fmt);
1438
- return na_ndloop_cast_narray_to_rarray(&ndf, self, fmt);
1439
- }
1440
-
1441
- static VALUE iter_int32_inspect(char* ptr, size_t pos, VALUE fmt) {
1442
- return format_int32(fmt, (dtype*)(ptr + pos));
1443
- }
1444
-
1445
- /*
1446
- Returns a string containing a human-readable representation of NArray.
1447
- @overload inspect
1448
- @return [String]
1449
- */
1450
- static VALUE int32_inspect(VALUE ary) {
1451
- return na_ndloop_inspect(ary, iter_int32_inspect, Qnil);
1452
- }
1453
-
1454
1306
  static void iter_int32_each(na_loop_t* const lp) {
1455
1307
  size_t i, s1;
1456
1308
  char* p1;
@@ -1777,2199 +1629,374 @@ static VALUE int32_abs(VALUE self) {
1777
1629
  return na_ndloop(&ndf, 1, self);
1778
1630
  }
1779
1631
 
1780
- #define check_intdivzero(y) \
1781
- {}
1782
-
1783
- static void iter_int32_add(na_loop_t* const lp) {
1784
- size_t i = 0;
1785
- size_t n;
1632
+ static void iter_int32_pow(na_loop_t* const lp) {
1633
+ size_t i;
1786
1634
  char *p1, *p2, *p3;
1787
1635
  ssize_t s1, s2, s3;
1788
-
1789
- INIT_COUNTER(lp, n);
1636
+ dtype x, y;
1637
+ INIT_COUNTER(lp, i);
1790
1638
  INIT_PTR(lp, 0, p1, s1);
1791
1639
  INIT_PTR(lp, 1, p2, s2);
1792
1640
  INIT_PTR(lp, 2, p3, s3);
1793
-
1794
- //
1795
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
1796
- is_aligned(p3, sizeof(dtype))) {
1797
-
1798
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
1799
- if (p1 == p3) { // inplace case
1800
- for (; i < n; i++) {
1801
- check_intdivzero(((dtype*)p2)[i]);
1802
- ((dtype*)p1)[i] = m_add(((dtype*)p1)[i], ((dtype*)p2)[i]);
1803
- }
1804
- } else {
1805
- for (; i < n; i++) {
1806
- check_intdivzero(((dtype*)p2)[i]);
1807
- ((dtype*)p3)[i] = m_add(((dtype*)p1)[i], ((dtype*)p2)[i]);
1808
- }
1809
- }
1810
- return;
1811
- }
1812
-
1813
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
1814
- is_aligned_step(s3, sizeof(dtype))) {
1815
- //
1816
-
1817
- if (s2 == 0) { // Broadcasting from scalar value.
1818
- check_intdivzero(*(dtype*)p2);
1819
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
1820
- if (p1 == p3) { // inplace case
1821
- for (; i < n; i++) {
1822
- ((dtype*)p1)[i] = m_add(((dtype*)p1)[i], *(dtype*)p2);
1823
- }
1824
- } else {
1825
- for (; i < n; i++) {
1826
- ((dtype*)p3)[i] = m_add(((dtype*)p1)[i], *(dtype*)p2);
1827
- }
1828
- }
1829
- } else {
1830
- for (i = 0; i < n; i++) {
1831
- *(dtype*)p3 = m_add(*(dtype*)p1, *(dtype*)p2);
1832
- p1 += s1;
1833
- p3 += s3;
1834
- }
1835
- }
1836
- } else {
1837
- if (p1 == p3) { // inplace case
1838
- for (i = 0; i < n; i++) {
1839
- check_intdivzero(*(dtype*)p2);
1840
- *(dtype*)p1 = m_add(*(dtype*)p1, *(dtype*)p2);
1841
- p1 += s1;
1842
- p2 += s2;
1843
- }
1844
- } else {
1845
- for (i = 0; i < n; i++) {
1846
- check_intdivzero(*(dtype*)p2);
1847
- *(dtype*)p3 = m_add(*(dtype*)p1, *(dtype*)p2);
1848
- p1 += s1;
1849
- p2 += s2;
1850
- p3 += s3;
1851
- }
1852
- }
1853
- }
1854
-
1855
- return;
1856
- //
1857
- }
1858
- }
1859
- for (i = 0; i < n; i++) {
1860
- dtype x, y, z;
1641
+ for (; i--;) {
1861
1642
  GET_DATA_STRIDE(p1, s1, dtype, x);
1862
1643
  GET_DATA_STRIDE(p2, s2, dtype, y);
1863
- check_intdivzero(y);
1864
- z = m_add(x, y);
1865
- SET_DATA_STRIDE(p3, s3, dtype, z);
1644
+ x = m_pow(x, y);
1645
+ SET_DATA_STRIDE(p3, s3, dtype, x);
1646
+ }
1647
+ }
1648
+
1649
+ static void iter_int32_pow_int32(na_loop_t* const lp) {
1650
+ size_t i;
1651
+ char *p1, *p2, *p3;
1652
+ ssize_t s1, s2, s3;
1653
+ dtype x;
1654
+ int32_t y;
1655
+ INIT_COUNTER(lp, i);
1656
+ INIT_PTR(lp, 0, p1, s1);
1657
+ INIT_PTR(lp, 1, p2, s2);
1658
+ INIT_PTR(lp, 2, p3, s3);
1659
+ for (; i--;) {
1660
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1661
+ GET_DATA_STRIDE(p2, s2, int32_t, y);
1662
+ x = m_pow_int(x, y);
1663
+ SET_DATA_STRIDE(p3, s3, dtype, x);
1866
1664
  }
1867
- //
1868
1665
  }
1869
- #undef check_intdivzero
1870
1666
 
1871
- static VALUE int32_add_self(VALUE self, VALUE other) {
1667
+ static VALUE int32_pow_self(VALUE self, VALUE other) {
1872
1668
  ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
1669
+ ndfunc_arg_in_t ain_i[2] = { { cT, 0 }, { numo_cInt32, 0 } };
1873
1670
  ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1874
- ndfunc_t ndf = { iter_int32_add, STRIDE_LOOP, 2, 1, ain, aout };
1671
+ ndfunc_t ndf = { iter_int32_pow, STRIDE_LOOP, 2, 1, ain, aout };
1672
+ ndfunc_t ndf_i = { iter_int32_pow_int32, STRIDE_LOOP, 2, 1, ain_i, aout };
1875
1673
 
1876
- return na_ndloop(&ndf, 2, self, other);
1674
+ // fixme : use na.integer?
1675
+ if (FIXNUM_P(other) || rb_obj_is_kind_of(other, numo_cInt32)) {
1676
+ return na_ndloop(&ndf_i, 2, self, other);
1677
+ } else {
1678
+ return na_ndloop(&ndf, 2, self, other);
1679
+ }
1877
1680
  }
1878
1681
 
1879
1682
  /*
1880
- Binary add.
1881
- @overload + other
1683
+ Binary power.
1684
+ @overload ** other
1882
1685
  @param [Numo::NArray,Numeric] other
1883
- @return [Numo::NArray] self + other
1686
+ @return [Numo::NArray] self to the other-th power.
1884
1687
  */
1885
- static VALUE int32_add(VALUE self, VALUE other) {
1688
+ static VALUE int32_pow(VALUE self, VALUE other) {
1886
1689
 
1887
1690
  VALUE klass, v;
1888
-
1889
1691
  klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
1890
1692
  if (klass == cT) {
1891
- return int32_add_self(self, other);
1693
+ return int32_pow_self(self, other);
1892
1694
  } else {
1893
1695
  v = rb_funcall(klass, id_cast, 1, self);
1894
- return rb_funcall(v, '+', 1, other);
1696
+ return rb_funcall(v, id_pow, 1, other);
1895
1697
  }
1896
1698
  }
1897
1699
 
1898
- #define check_intdivzero(y) \
1899
- {}
1900
-
1901
- static void iter_int32_sub(na_loop_t* const lp) {
1902
- size_t i = 0;
1903
- size_t n;
1904
- char *p1, *p2, *p3;
1905
- ssize_t s1, s2, s3;
1700
+ static void iter_int32_minus(na_loop_t* const lp) {
1701
+ size_t i, n;
1702
+ char *p1, *p2;
1703
+ ssize_t s1, s2;
1704
+ size_t *idx1, *idx2;
1705
+ dtype x;
1906
1706
 
1907
1707
  INIT_COUNTER(lp, n);
1908
- INIT_PTR(lp, 0, p1, s1);
1909
- INIT_PTR(lp, 1, p2, s2);
1910
- INIT_PTR(lp, 2, p3, s3);
1911
-
1912
- //
1913
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
1914
- is_aligned(p3, sizeof(dtype))) {
1708
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1709
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
1915
1710
 
1916
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
1917
- if (p1 == p3) { // inplace case
1918
- for (; i < n; i++) {
1919
- check_intdivzero(((dtype*)p2)[i]);
1920
- ((dtype*)p1)[i] = m_sub(((dtype*)p1)[i], ((dtype*)p2)[i]);
1921
- }
1922
- } else {
1923
- for (; i < n; i++) {
1924
- check_intdivzero(((dtype*)p2)[i]);
1925
- ((dtype*)p3)[i] = m_sub(((dtype*)p1)[i], ((dtype*)p2)[i]);
1926
- }
1711
+ if (idx1) {
1712
+ if (idx2) {
1713
+ for (i = 0; i < n; i++) {
1714
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1715
+ x = m_minus(x);
1716
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1717
+ }
1718
+ } else {
1719
+ for (i = 0; i < n; i++) {
1720
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1721
+ x = m_minus(x);
1722
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1927
1723
  }
1928
- return;
1929
1724
  }
1930
-
1931
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
1932
- is_aligned_step(s3, sizeof(dtype))) {
1725
+ } else {
1726
+ if (idx2) {
1727
+ for (i = 0; i < n; i++) {
1728
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1729
+ x = m_minus(x);
1730
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1731
+ }
1732
+ } else {
1933
1733
  //
1934
-
1935
- if (s2 == 0) { // Broadcasting from scalar value.
1936
- check_intdivzero(*(dtype*)p2);
1937
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
1938
- if (p1 == p3) { // inplace case
1939
- for (; i < n; i++) {
1940
- ((dtype*)p1)[i] = m_sub(((dtype*)p1)[i], *(dtype*)p2);
1941
- }
1942
- } else {
1943
- for (; i < n; i++) {
1944
- ((dtype*)p3)[i] = m_sub(((dtype*)p1)[i], *(dtype*)p2);
1945
- }
1946
- }
1947
- } else {
1734
+ if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
1735
+ if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
1948
1736
  for (i = 0; i < n; i++) {
1949
- *(dtype*)p3 = m_sub(*(dtype*)p1, *(dtype*)p2);
1950
- p1 += s1;
1951
- p3 += s3;
1737
+ ((dtype*)p2)[i] = m_minus(((dtype*)p1)[i]);
1952
1738
  }
1739
+ return;
1953
1740
  }
1954
- } else {
1955
- if (p1 == p3) { // inplace case
1956
- for (i = 0; i < n; i++) {
1957
- check_intdivzero(*(dtype*)p2);
1958
- *(dtype*)p1 = m_sub(*(dtype*)p1, *(dtype*)p2);
1959
- p1 += s1;
1960
- p2 += s2;
1961
- }
1962
- } else {
1741
+ if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
1742
+ //
1963
1743
  for (i = 0; i < n; i++) {
1964
- check_intdivzero(*(dtype*)p2);
1965
- *(dtype*)p3 = m_sub(*(dtype*)p1, *(dtype*)p2);
1744
+ *(dtype*)p2 = m_minus(*(dtype*)p1);
1966
1745
  p1 += s1;
1967
1746
  p2 += s2;
1968
- p3 += s3;
1969
1747
  }
1748
+ return;
1749
+ //
1970
1750
  }
1971
1751
  }
1972
-
1973
- return;
1752
+ for (i = 0; i < n; i++) {
1753
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1754
+ x = m_minus(x);
1755
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1756
+ }
1974
1757
  //
1975
1758
  }
1976
1759
  }
1977
- for (i = 0; i < n; i++) {
1978
- dtype x, y, z;
1979
- GET_DATA_STRIDE(p1, s1, dtype, x);
1980
- GET_DATA_STRIDE(p2, s2, dtype, y);
1981
- check_intdivzero(y);
1982
- z = m_sub(x, y);
1983
- SET_DATA_STRIDE(p3, s3, dtype, z);
1984
- }
1985
- //
1986
1760
  }
1987
- #undef check_intdivzero
1988
1761
 
1989
- static VALUE int32_sub_self(VALUE self, VALUE other) {
1990
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
1762
+ /*
1763
+ Unary minus.
1764
+ @overload -@
1765
+ @return [Numo::Int32] minus of self.
1766
+ */
1767
+ static VALUE int32_minus(VALUE self) {
1768
+ ndfunc_arg_in_t ain[1] = { { cT, 0 } };
1991
1769
  ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1992
- ndfunc_t ndf = { iter_int32_sub, STRIDE_LOOP, 2, 1, ain, aout };
1770
+ ndfunc_t ndf = { iter_int32_minus, FULL_LOOP, 1, 1, ain, aout };
1993
1771
 
1994
- return na_ndloop(&ndf, 2, self, other);
1772
+ return na_ndloop(&ndf, 1, self);
1995
1773
  }
1996
1774
 
1997
- /*
1998
- Binary sub.
1999
- @overload - other
2000
- @param [Numo::NArray,Numeric] other
2001
- @return [Numo::NArray] self - other
2002
- */
2003
- static VALUE int32_sub(VALUE self, VALUE other) {
2004
-
2005
- VALUE klass, v;
2006
-
2007
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2008
- if (klass == cT) {
2009
- return int32_sub_self(self, other);
2010
- } else {
2011
- v = rb_funcall(klass, id_cast, 1, self);
2012
- return rb_funcall(v, '-', 1, other);
2013
- }
2014
- }
2015
-
2016
- #define check_intdivzero(y) \
2017
- {}
2018
-
2019
- static void iter_int32_mul(na_loop_t* const lp) {
2020
- size_t i = 0;
2021
- size_t n;
2022
- char *p1, *p2, *p3;
2023
- ssize_t s1, s2, s3;
1775
+ static void iter_int32_reciprocal(na_loop_t* const lp) {
1776
+ size_t i, n;
1777
+ char *p1, *p2;
1778
+ ssize_t s1, s2;
1779
+ size_t *idx1, *idx2;
1780
+ dtype x;
2024
1781
 
2025
1782
  INIT_COUNTER(lp, n);
2026
- INIT_PTR(lp, 0, p1, s1);
2027
- INIT_PTR(lp, 1, p2, s2);
2028
- INIT_PTR(lp, 2, p3, s3);
2029
-
2030
- //
2031
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2032
- is_aligned(p3, sizeof(dtype))) {
1783
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1784
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2033
1785
 
2034
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2035
- if (p1 == p3) { // inplace case
2036
- for (; i < n; i++) {
2037
- check_intdivzero(((dtype*)p2)[i]);
2038
- ((dtype*)p1)[i] = m_mul(((dtype*)p1)[i], ((dtype*)p2)[i]);
2039
- }
2040
- } else {
2041
- for (; i < n; i++) {
2042
- check_intdivzero(((dtype*)p2)[i]);
2043
- ((dtype*)p3)[i] = m_mul(((dtype*)p1)[i], ((dtype*)p2)[i]);
2044
- }
1786
+ if (idx1) {
1787
+ if (idx2) {
1788
+ for (i = 0; i < n; i++) {
1789
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1790
+ x = m_reciprocal(x);
1791
+ SET_DATA_INDEX(p2, idx2, dtype, x);
2045
1792
  }
2046
- return;
2047
- }
2048
-
2049
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2050
- is_aligned_step(s3, sizeof(dtype))) {
2051
- //
2052
-
2053
- if (s2 == 0) { // Broadcasting from scalar value.
2054
- check_intdivzero(*(dtype*)p2);
2055
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2056
- if (p1 == p3) { // inplace case
2057
- for (; i < n; i++) {
2058
- ((dtype*)p1)[i] = m_mul(((dtype*)p1)[i], *(dtype*)p2);
2059
- }
2060
- } else {
2061
- for (; i < n; i++) {
2062
- ((dtype*)p3)[i] = m_mul(((dtype*)p1)[i], *(dtype*)p2);
2063
- }
2064
- }
2065
- } else {
2066
- for (i = 0; i < n; i++) {
2067
- *(dtype*)p3 = m_mul(*(dtype*)p1, *(dtype*)p2);
2068
- p1 += s1;
2069
- p3 += s3;
2070
- }
2071
- }
2072
- } else {
2073
- if (p1 == p3) { // inplace case
2074
- for (i = 0; i < n; i++) {
2075
- check_intdivzero(*(dtype*)p2);
2076
- *(dtype*)p1 = m_mul(*(dtype*)p1, *(dtype*)p2);
2077
- p1 += s1;
2078
- p2 += s2;
2079
- }
2080
- } else {
2081
- for (i = 0; i < n; i++) {
2082
- check_intdivzero(*(dtype*)p2);
2083
- *(dtype*)p3 = m_mul(*(dtype*)p1, *(dtype*)p2);
2084
- p1 += s1;
2085
- p2 += s2;
2086
- p3 += s3;
2087
- }
2088
- }
1793
+ } else {
1794
+ for (i = 0; i < n; i++) {
1795
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1796
+ x = m_reciprocal(x);
1797
+ SET_DATA_STRIDE(p2, s2, dtype, x);
2089
1798
  }
2090
-
2091
- return;
2092
- //
2093
1799
  }
2094
- }
2095
- for (i = 0; i < n; i++) {
2096
- dtype x, y, z;
2097
- GET_DATA_STRIDE(p1, s1, dtype, x);
2098
- GET_DATA_STRIDE(p2, s2, dtype, y);
2099
- check_intdivzero(y);
2100
- z = m_mul(x, y);
2101
- SET_DATA_STRIDE(p3, s3, dtype, z);
2102
- }
2103
- //
2104
- }
2105
- #undef check_intdivzero
2106
-
2107
- static VALUE int32_mul_self(VALUE self, VALUE other) {
2108
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2109
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2110
- ndfunc_t ndf = { iter_int32_mul, STRIDE_LOOP, 2, 1, ain, aout };
2111
-
2112
- return na_ndloop(&ndf, 2, self, other);
2113
- }
2114
-
2115
- /*
2116
- Binary mul.
2117
- @overload * other
2118
- @param [Numo::NArray,Numeric] other
2119
- @return [Numo::NArray] self * other
2120
- */
2121
- static VALUE int32_mul(VALUE self, VALUE other) {
2122
-
2123
- VALUE klass, v;
2124
-
2125
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2126
- if (klass == cT) {
2127
- return int32_mul_self(self, other);
2128
1800
  } else {
2129
- v = rb_funcall(klass, id_cast, 1, self);
2130
- return rb_funcall(v, '*', 1, other);
2131
- }
2132
- }
2133
-
2134
- #define check_intdivzero(y) \
2135
- if ((y) == 0) { \
2136
- lp->err_type = rb_eZeroDivError; \
2137
- return; \
2138
- }
2139
-
2140
- static void iter_int32_div(na_loop_t* const lp) {
2141
- size_t i = 0;
2142
- size_t n;
2143
- char *p1, *p2, *p3;
2144
- ssize_t s1, s2, s3;
2145
-
2146
- INIT_COUNTER(lp, n);
2147
- INIT_PTR(lp, 0, p1, s1);
2148
- INIT_PTR(lp, 1, p2, s2);
2149
- INIT_PTR(lp, 2, p3, s3);
2150
-
2151
- //
2152
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2153
- is_aligned(p3, sizeof(dtype))) {
2154
-
2155
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2156
- if (p1 == p3) { // inplace case
2157
- for (; i < n; i++) {
2158
- check_intdivzero(((dtype*)p2)[i]);
2159
- ((dtype*)p1)[i] = m_div(((dtype*)p1)[i], ((dtype*)p2)[i]);
2160
- }
2161
- } else {
2162
- for (; i < n; i++) {
2163
- check_intdivzero(((dtype*)p2)[i]);
2164
- ((dtype*)p3)[i] = m_div(((dtype*)p1)[i], ((dtype*)p2)[i]);
2165
- }
1801
+ if (idx2) {
1802
+ for (i = 0; i < n; i++) {
1803
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1804
+ x = m_reciprocal(x);
1805
+ SET_DATA_INDEX(p2, idx2, dtype, x);
2166
1806
  }
2167
- return;
2168
- }
2169
-
2170
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2171
- is_aligned_step(s3, sizeof(dtype))) {
1807
+ } else {
2172
1808
  //
2173
-
2174
- if (s2 == 0) { // Broadcasting from scalar value.
2175
- check_intdivzero(*(dtype*)p2);
2176
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2177
- if (p1 == p3) { // inplace case
2178
- for (; i < n; i++) {
2179
- ((dtype*)p1)[i] = m_div(((dtype*)p1)[i], *(dtype*)p2);
2180
- }
2181
- } else {
2182
- for (; i < n; i++) {
2183
- ((dtype*)p3)[i] = m_div(((dtype*)p1)[i], *(dtype*)p2);
2184
- }
2185
- }
2186
- } else {
1809
+ if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
1810
+ if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2187
1811
  for (i = 0; i < n; i++) {
2188
- *(dtype*)p3 = m_div(*(dtype*)p1, *(dtype*)p2);
2189
- p1 += s1;
2190
- p3 += s3;
1812
+ ((dtype*)p2)[i] = m_reciprocal(((dtype*)p1)[i]);
2191
1813
  }
1814
+ return;
2192
1815
  }
2193
- } else {
2194
- if (p1 == p3) { // inplace case
2195
- for (i = 0; i < n; i++) {
2196
- check_intdivzero(*(dtype*)p2);
2197
- *(dtype*)p1 = m_div(*(dtype*)p1, *(dtype*)p2);
2198
- p1 += s1;
2199
- p2 += s2;
2200
- }
2201
- } else {
1816
+ if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
1817
+ //
2202
1818
  for (i = 0; i < n; i++) {
2203
- check_intdivzero(*(dtype*)p2);
2204
- *(dtype*)p3 = m_div(*(dtype*)p1, *(dtype*)p2);
1819
+ *(dtype*)p2 = m_reciprocal(*(dtype*)p1);
2205
1820
  p1 += s1;
2206
1821
  p2 += s2;
2207
- p3 += s3;
2208
1822
  }
1823
+ return;
1824
+ //
2209
1825
  }
2210
1826
  }
2211
-
2212
- return;
2213
- //
2214
- }
2215
- }
2216
- for (i = 0; i < n; i++) {
2217
- dtype x, y, z;
2218
- GET_DATA_STRIDE(p1, s1, dtype, x);
2219
- GET_DATA_STRIDE(p2, s2, dtype, y);
2220
- check_intdivzero(y);
2221
- z = m_div(x, y);
2222
- SET_DATA_STRIDE(p3, s3, dtype, z);
2223
- }
2224
- //
2225
- }
2226
- #undef check_intdivzero
2227
-
2228
- static VALUE int32_div_self(VALUE self, VALUE other) {
2229
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2230
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2231
- ndfunc_t ndf = { iter_int32_div, STRIDE_LOOP, 2, 1, ain, aout };
2232
-
2233
- return na_ndloop(&ndf, 2, self, other);
2234
- }
2235
-
2236
- /*
2237
- Binary div.
2238
- @overload / other
2239
- @param [Numo::NArray,Numeric] other
2240
- @return [Numo::NArray] self / other
2241
- */
2242
- static VALUE int32_div(VALUE self, VALUE other) {
2243
-
2244
- VALUE klass, v;
2245
-
2246
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2247
- if (klass == cT) {
2248
- return int32_div_self(self, other);
2249
- } else {
2250
- v = rb_funcall(klass, id_cast, 1, self);
2251
- return rb_funcall(v, '/', 1, other);
2252
- }
2253
- }
2254
-
2255
- #define check_intdivzero(y) \
2256
- if ((y) == 0) { \
2257
- lp->err_type = rb_eZeroDivError; \
2258
- return; \
2259
- }
2260
-
2261
- static void iter_int32_mod(na_loop_t* const lp) {
2262
- size_t i = 0;
2263
- size_t n;
2264
- char *p1, *p2, *p3;
2265
- ssize_t s1, s2, s3;
2266
-
2267
- INIT_COUNTER(lp, n);
2268
- INIT_PTR(lp, 0, p1, s1);
2269
- INIT_PTR(lp, 1, p2, s2);
2270
- INIT_PTR(lp, 2, p3, s3);
2271
-
2272
- //
2273
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2274
- is_aligned(p3, sizeof(dtype))) {
2275
-
2276
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2277
- if (p1 == p3) { // inplace case
2278
- for (; i < n; i++) {
2279
- check_intdivzero(((dtype*)p2)[i]);
2280
- ((dtype*)p1)[i] = m_mod(((dtype*)p1)[i], ((dtype*)p2)[i]);
2281
- }
2282
- } else {
2283
- for (; i < n; i++) {
2284
- check_intdivzero(((dtype*)p2)[i]);
2285
- ((dtype*)p3)[i] = m_mod(((dtype*)p1)[i], ((dtype*)p2)[i]);
2286
- }
2287
- }
2288
- return;
2289
- }
2290
-
2291
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2292
- is_aligned_step(s3, sizeof(dtype))) {
2293
- //
2294
-
2295
- if (s2 == 0) { // Broadcasting from scalar value.
2296
- check_intdivzero(*(dtype*)p2);
2297
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2298
- if (p1 == p3) { // inplace case
2299
- for (; i < n; i++) {
2300
- ((dtype*)p1)[i] = m_mod(((dtype*)p1)[i], *(dtype*)p2);
2301
- }
2302
- } else {
2303
- for (; i < n; i++) {
2304
- ((dtype*)p3)[i] = m_mod(((dtype*)p1)[i], *(dtype*)p2);
2305
- }
2306
- }
2307
- } else {
2308
- for (i = 0; i < n; i++) {
2309
- *(dtype*)p3 = m_mod(*(dtype*)p1, *(dtype*)p2);
2310
- p1 += s1;
2311
- p3 += s3;
2312
- }
2313
- }
2314
- } else {
2315
- if (p1 == p3) { // inplace case
2316
- for (i = 0; i < n; i++) {
2317
- check_intdivzero(*(dtype*)p2);
2318
- *(dtype*)p1 = m_mod(*(dtype*)p1, *(dtype*)p2);
2319
- p1 += s1;
2320
- p2 += s2;
2321
- }
2322
- } else {
2323
- for (i = 0; i < n; i++) {
2324
- check_intdivzero(*(dtype*)p2);
2325
- *(dtype*)p3 = m_mod(*(dtype*)p1, *(dtype*)p2);
2326
- p1 += s1;
2327
- p2 += s2;
2328
- p3 += s3;
2329
- }
2330
- }
1827
+ for (i = 0; i < n; i++) {
1828
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1829
+ x = m_reciprocal(x);
1830
+ SET_DATA_STRIDE(p2, s2, dtype, x);
2331
1831
  }
2332
-
2333
- return;
2334
1832
  //
2335
1833
  }
2336
1834
  }
2337
- for (i = 0; i < n; i++) {
2338
- dtype x, y, z;
2339
- GET_DATA_STRIDE(p1, s1, dtype, x);
2340
- GET_DATA_STRIDE(p2, s2, dtype, y);
2341
- check_intdivzero(y);
2342
- z = m_mod(x, y);
2343
- SET_DATA_STRIDE(p3, s3, dtype, z);
2344
- }
2345
- //
2346
- }
2347
- #undef check_intdivzero
2348
-
2349
- static VALUE int32_mod_self(VALUE self, VALUE other) {
2350
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2351
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2352
- ndfunc_t ndf = { iter_int32_mod, STRIDE_LOOP, 2, 1, ain, aout };
2353
-
2354
- return na_ndloop(&ndf, 2, self, other);
2355
- }
2356
-
2357
- /*
2358
- Binary mod.
2359
- @overload % other
2360
- @param [Numo::NArray,Numeric] other
2361
- @return [Numo::NArray] self % other
2362
- */
2363
- static VALUE int32_mod(VALUE self, VALUE other) {
2364
-
2365
- VALUE klass, v;
2366
-
2367
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2368
- if (klass == cT) {
2369
- return int32_mod_self(self, other);
2370
- } else {
2371
- v = rb_funcall(klass, id_cast, 1, self);
2372
- return rb_funcall(v, '%', 1, other);
2373
- }
2374
- }
2375
-
2376
- static void iter_int32_divmod(na_loop_t* const lp) {
2377
- size_t i, n;
2378
- char *p1, *p2, *p3, *p4;
2379
- ssize_t s1, s2, s3, s4;
2380
- dtype x, y, a, b;
2381
- INIT_COUNTER(lp, n);
2382
- INIT_PTR(lp, 0, p1, s1);
2383
- INIT_PTR(lp, 1, p2, s2);
2384
- INIT_PTR(lp, 2, p3, s3);
2385
- INIT_PTR(lp, 3, p4, s4);
2386
- for (i = n; i--;) {
2387
- GET_DATA_STRIDE(p1, s1, dtype, x);
2388
- GET_DATA_STRIDE(p2, s2, dtype, y);
2389
- if (y == 0) {
2390
- lp->err_type = rb_eZeroDivError;
2391
- return;
2392
- }
2393
- m_divmod(x, y, a, b);
2394
- SET_DATA_STRIDE(p3, s3, dtype, a);
2395
- SET_DATA_STRIDE(p4, s4, dtype, b);
2396
- }
2397
- }
2398
-
2399
- static VALUE int32_divmod_self(VALUE self, VALUE other) {
2400
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2401
- ndfunc_arg_out_t aout[2] = { { cT, 0 }, { cT, 0 } };
2402
- ndfunc_t ndf = { iter_int32_divmod, STRIDE_LOOP, 2, 2, ain, aout };
2403
-
2404
- return na_ndloop(&ndf, 2, self, other);
2405
1835
  }
2406
1836
 
2407
1837
  /*
2408
- Binary divmod.
2409
- @overload divmod other
2410
- @param [Numo::NArray,Numeric] other
2411
- @return [Numo::NArray] divmod of self and other.
2412
- */
2413
- static VALUE int32_divmod(VALUE self, VALUE other) {
2414
-
2415
- VALUE klass, v;
2416
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2417
- if (klass == cT) {
2418
- return int32_divmod_self(self, other);
2419
- } else {
2420
- v = rb_funcall(klass, id_cast, 1, self);
2421
- return rb_funcall(v, id_divmod, 1, other);
2422
- }
2423
- }
2424
-
2425
- static void iter_int32_pow(na_loop_t* const lp) {
2426
- size_t i;
2427
- char *p1, *p2, *p3;
2428
- ssize_t s1, s2, s3;
2429
- dtype x, y;
2430
- INIT_COUNTER(lp, i);
2431
- INIT_PTR(lp, 0, p1, s1);
2432
- INIT_PTR(lp, 1, p2, s2);
2433
- INIT_PTR(lp, 2, p3, s3);
2434
- for (; i--;) {
2435
- GET_DATA_STRIDE(p1, s1, dtype, x);
2436
- GET_DATA_STRIDE(p2, s2, dtype, y);
2437
- x = m_pow(x, y);
2438
- SET_DATA_STRIDE(p3, s3, dtype, x);
2439
- }
2440
- }
2441
-
2442
- static void iter_int32_pow_int32(na_loop_t* const lp) {
2443
- size_t i;
2444
- char *p1, *p2, *p3;
2445
- ssize_t s1, s2, s3;
2446
- dtype x;
2447
- int32_t y;
2448
- INIT_COUNTER(lp, i);
2449
- INIT_PTR(lp, 0, p1, s1);
2450
- INIT_PTR(lp, 1, p2, s2);
2451
- INIT_PTR(lp, 2, p3, s3);
2452
- for (; i--;) {
2453
- GET_DATA_STRIDE(p1, s1, dtype, x);
2454
- GET_DATA_STRIDE(p2, s2, int32_t, y);
2455
- x = m_pow_int(x, y);
2456
- SET_DATA_STRIDE(p3, s3, dtype, x);
2457
- }
2458
- }
2459
-
2460
- static VALUE int32_pow_self(VALUE self, VALUE other) {
2461
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2462
- ndfunc_arg_in_t ain_i[2] = { { cT, 0 }, { numo_cInt32, 0 } };
2463
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2464
- ndfunc_t ndf = { iter_int32_pow, STRIDE_LOOP, 2, 1, ain, aout };
2465
- ndfunc_t ndf_i = { iter_int32_pow_int32, STRIDE_LOOP, 2, 1, ain_i, aout };
2466
-
2467
- // fixme : use na.integer?
2468
- if (FIXNUM_P(other) || rb_obj_is_kind_of(other, numo_cInt32)) {
2469
- return na_ndloop(&ndf_i, 2, self, other);
2470
- } else {
2471
- return na_ndloop(&ndf, 2, self, other);
2472
- }
2473
- }
2474
-
2475
- /*
2476
- Binary power.
2477
- @overload ** other
2478
- @param [Numo::NArray,Numeric] other
2479
- @return [Numo::NArray] self to the other-th power.
2480
- */
2481
- static VALUE int32_pow(VALUE self, VALUE other) {
2482
-
2483
- VALUE klass, v;
2484
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2485
- if (klass == cT) {
2486
- return int32_pow_self(self, other);
2487
- } else {
2488
- v = rb_funcall(klass, id_cast, 1, self);
2489
- return rb_funcall(v, id_pow, 1, other);
2490
- }
2491
- }
2492
-
2493
- static void iter_int32_minus(na_loop_t* const lp) {
2494
- size_t i, n;
2495
- char *p1, *p2;
2496
- ssize_t s1, s2;
2497
- size_t *idx1, *idx2;
2498
- dtype x;
2499
-
2500
- INIT_COUNTER(lp, n);
2501
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2502
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2503
-
2504
- if (idx1) {
2505
- if (idx2) {
2506
- for (i = 0; i < n; i++) {
2507
- GET_DATA_INDEX(p1, idx1, dtype, x);
2508
- x = m_minus(x);
2509
- SET_DATA_INDEX(p2, idx2, dtype, x);
2510
- }
2511
- } else {
2512
- for (i = 0; i < n; i++) {
2513
- GET_DATA_INDEX(p1, idx1, dtype, x);
2514
- x = m_minus(x);
2515
- SET_DATA_STRIDE(p2, s2, dtype, x);
2516
- }
2517
- }
2518
- } else {
2519
- if (idx2) {
2520
- for (i = 0; i < n; i++) {
2521
- GET_DATA_STRIDE(p1, s1, dtype, x);
2522
- x = m_minus(x);
2523
- SET_DATA_INDEX(p2, idx2, dtype, x);
2524
- }
2525
- } else {
2526
- //
2527
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2528
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2529
- for (i = 0; i < n; i++) {
2530
- ((dtype*)p2)[i] = m_minus(((dtype*)p1)[i]);
2531
- }
2532
- return;
2533
- }
2534
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2535
- //
2536
- for (i = 0; i < n; i++) {
2537
- *(dtype*)p2 = m_minus(*(dtype*)p1);
2538
- p1 += s1;
2539
- p2 += s2;
2540
- }
2541
- return;
2542
- //
2543
- }
2544
- }
2545
- for (i = 0; i < n; i++) {
2546
- GET_DATA_STRIDE(p1, s1, dtype, x);
2547
- x = m_minus(x);
2548
- SET_DATA_STRIDE(p2, s2, dtype, x);
2549
- }
2550
- //
2551
- }
2552
- }
2553
- }
2554
-
2555
- /*
2556
- Unary minus.
2557
- @overload -@
2558
- @return [Numo::Int32] minus of self.
2559
- */
2560
- static VALUE int32_minus(VALUE self) {
2561
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2562
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2563
- ndfunc_t ndf = { iter_int32_minus, FULL_LOOP, 1, 1, ain, aout };
2564
-
2565
- return na_ndloop(&ndf, 1, self);
2566
- }
2567
-
2568
- static void iter_int32_reciprocal(na_loop_t* const lp) {
2569
- size_t i, n;
2570
- char *p1, *p2;
2571
- ssize_t s1, s2;
2572
- size_t *idx1, *idx2;
2573
- dtype x;
2574
-
2575
- INIT_COUNTER(lp, n);
2576
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2577
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2578
-
2579
- if (idx1) {
2580
- if (idx2) {
2581
- for (i = 0; i < n; i++) {
2582
- GET_DATA_INDEX(p1, idx1, dtype, x);
2583
- x = m_reciprocal(x);
2584
- SET_DATA_INDEX(p2, idx2, dtype, x);
2585
- }
2586
- } else {
2587
- for (i = 0; i < n; i++) {
2588
- GET_DATA_INDEX(p1, idx1, dtype, x);
2589
- x = m_reciprocal(x);
2590
- SET_DATA_STRIDE(p2, s2, dtype, x);
2591
- }
2592
- }
2593
- } else {
2594
- if (idx2) {
2595
- for (i = 0; i < n; i++) {
2596
- GET_DATA_STRIDE(p1, s1, dtype, x);
2597
- x = m_reciprocal(x);
2598
- SET_DATA_INDEX(p2, idx2, dtype, x);
2599
- }
2600
- } else {
2601
- //
2602
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2603
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2604
- for (i = 0; i < n; i++) {
2605
- ((dtype*)p2)[i] = m_reciprocal(((dtype*)p1)[i]);
2606
- }
2607
- return;
2608
- }
2609
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2610
- //
2611
- for (i = 0; i < n; i++) {
2612
- *(dtype*)p2 = m_reciprocal(*(dtype*)p1);
2613
- p1 += s1;
2614
- p2 += s2;
2615
- }
2616
- return;
2617
- //
2618
- }
2619
- }
2620
- for (i = 0; i < n; i++) {
2621
- GET_DATA_STRIDE(p1, s1, dtype, x);
2622
- x = m_reciprocal(x);
2623
- SET_DATA_STRIDE(p2, s2, dtype, x);
2624
- }
2625
- //
2626
- }
2627
- }
2628
- }
2629
-
2630
- /*
2631
- Unary reciprocal.
2632
- @overload reciprocal
2633
- @return [Numo::Int32] reciprocal of self.
1838
+ Unary reciprocal.
1839
+ @overload reciprocal
1840
+ @return [Numo::Int32] reciprocal of self.
2634
1841
  */
2635
1842
  static VALUE int32_reciprocal(VALUE self) {
2636
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2637
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2638
- ndfunc_t ndf = { iter_int32_reciprocal, FULL_LOOP, 1, 1, ain, aout };
2639
-
2640
- return na_ndloop(&ndf, 1, self);
2641
- }
2642
-
2643
- static void iter_int32_sign(na_loop_t* const lp) {
2644
- size_t i, n;
2645
- char *p1, *p2;
2646
- ssize_t s1, s2;
2647
- size_t *idx1, *idx2;
2648
- dtype x;
2649
-
2650
- INIT_COUNTER(lp, n);
2651
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2652
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2653
-
2654
- if (idx1) {
2655
- if (idx2) {
2656
- for (i = 0; i < n; i++) {
2657
- GET_DATA_INDEX(p1, idx1, dtype, x);
2658
- x = m_sign(x);
2659
- SET_DATA_INDEX(p2, idx2, dtype, x);
2660
- }
2661
- } else {
2662
- for (i = 0; i < n; i++) {
2663
- GET_DATA_INDEX(p1, idx1, dtype, x);
2664
- x = m_sign(x);
2665
- SET_DATA_STRIDE(p2, s2, dtype, x);
2666
- }
2667
- }
2668
- } else {
2669
- if (idx2) {
2670
- for (i = 0; i < n; i++) {
2671
- GET_DATA_STRIDE(p1, s1, dtype, x);
2672
- x = m_sign(x);
2673
- SET_DATA_INDEX(p2, idx2, dtype, x);
2674
- }
2675
- } else {
2676
- //
2677
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2678
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2679
- for (i = 0; i < n; i++) {
2680
- ((dtype*)p2)[i] = m_sign(((dtype*)p1)[i]);
2681
- }
2682
- return;
2683
- }
2684
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2685
- //
2686
- for (i = 0; i < n; i++) {
2687
- *(dtype*)p2 = m_sign(*(dtype*)p1);
2688
- p1 += s1;
2689
- p2 += s2;
2690
- }
2691
- return;
2692
- //
2693
- }
2694
- }
2695
- for (i = 0; i < n; i++) {
2696
- GET_DATA_STRIDE(p1, s1, dtype, x);
2697
- x = m_sign(x);
2698
- SET_DATA_STRIDE(p2, s2, dtype, x);
2699
- }
2700
- //
2701
- }
2702
- }
2703
- }
2704
-
2705
- /*
2706
- Unary sign.
2707
- @overload sign
2708
- @return [Numo::Int32] sign of self.
2709
- */
2710
- static VALUE int32_sign(VALUE self) {
2711
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2712
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2713
- ndfunc_t ndf = { iter_int32_sign, FULL_LOOP, 1, 1, ain, aout };
2714
-
2715
- return na_ndloop(&ndf, 1, self);
2716
- }
2717
-
2718
- static void iter_int32_square(na_loop_t* const lp) {
2719
- size_t i, n;
2720
- char *p1, *p2;
2721
- ssize_t s1, s2;
2722
- size_t *idx1, *idx2;
2723
- dtype x;
2724
-
2725
- INIT_COUNTER(lp, n);
2726
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2727
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2728
-
2729
- if (idx1) {
2730
- if (idx2) {
2731
- for (i = 0; i < n; i++) {
2732
- GET_DATA_INDEX(p1, idx1, dtype, x);
2733
- x = m_square(x);
2734
- SET_DATA_INDEX(p2, idx2, dtype, x);
2735
- }
2736
- } else {
2737
- for (i = 0; i < n; i++) {
2738
- GET_DATA_INDEX(p1, idx1, dtype, x);
2739
- x = m_square(x);
2740
- SET_DATA_STRIDE(p2, s2, dtype, x);
2741
- }
2742
- }
2743
- } else {
2744
- if (idx2) {
2745
- for (i = 0; i < n; i++) {
2746
- GET_DATA_STRIDE(p1, s1, dtype, x);
2747
- x = m_square(x);
2748
- SET_DATA_INDEX(p2, idx2, dtype, x);
2749
- }
2750
- } else {
2751
- //
2752
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2753
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2754
- for (i = 0; i < n; i++) {
2755
- ((dtype*)p2)[i] = m_square(((dtype*)p1)[i]);
2756
- }
2757
- return;
2758
- }
2759
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2760
- //
2761
- for (i = 0; i < n; i++) {
2762
- *(dtype*)p2 = m_square(*(dtype*)p1);
2763
- p1 += s1;
2764
- p2 += s2;
2765
- }
2766
- return;
2767
- //
2768
- }
2769
- }
2770
- for (i = 0; i < n; i++) {
2771
- GET_DATA_STRIDE(p1, s1, dtype, x);
2772
- x = m_square(x);
2773
- SET_DATA_STRIDE(p2, s2, dtype, x);
2774
- }
2775
- //
2776
- }
2777
- }
2778
- }
2779
-
2780
- /*
2781
- Unary square.
2782
- @overload square
2783
- @return [Numo::Int32] square of self.
2784
- */
2785
- static VALUE int32_square(VALUE self) {
2786
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2787
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2788
- ndfunc_t ndf = { iter_int32_square, FULL_LOOP, 1, 1, ain, aout };
2789
-
2790
- return na_ndloop(&ndf, 1, self);
2791
- }
2792
-
2793
- static void iter_int32_eq(na_loop_t* const lp) {
2794
- size_t i;
2795
- char *p1, *p2;
2796
- BIT_DIGIT* a3;
2797
- size_t p3;
2798
- ssize_t s1, s2, s3;
2799
- dtype x, y;
2800
- BIT_DIGIT b;
2801
- INIT_COUNTER(lp, i);
2802
- INIT_PTR(lp, 0, p1, s1);
2803
- INIT_PTR(lp, 1, p2, s2);
2804
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
2805
- for (; i--;) {
2806
- GET_DATA_STRIDE(p1, s1, dtype, x);
2807
- GET_DATA_STRIDE(p2, s2, dtype, y);
2808
- b = (m_eq(x, y)) ? 1 : 0;
2809
- STORE_BIT(a3, p3, b);
2810
- p3 += s3;
2811
- }
2812
- }
2813
-
2814
- static VALUE int32_eq_self(VALUE self, VALUE other) {
2815
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2816
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
2817
- ndfunc_t ndf = { iter_int32_eq, STRIDE_LOOP, 2, 1, ain, aout };
2818
-
2819
- return na_ndloop(&ndf, 2, self, other);
2820
- }
2821
-
2822
- /*
2823
- Comparison eq other.
2824
- @overload eq other
2825
- @param [Numo::NArray,Numeric] other
2826
- @return [Numo::Bit] result of self eq other.
2827
- */
2828
- static VALUE int32_eq(VALUE self, VALUE other) {
2829
-
2830
- VALUE klass, v;
2831
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2832
- if (klass == cT) {
2833
- return int32_eq_self(self, other);
2834
- } else {
2835
- v = rb_funcall(klass, id_cast, 1, self);
2836
- return rb_funcall(v, id_eq, 1, other);
2837
- }
2838
- }
2839
-
2840
- static void iter_int32_ne(na_loop_t* const lp) {
2841
- size_t i;
2842
- char *p1, *p2;
2843
- BIT_DIGIT* a3;
2844
- size_t p3;
2845
- ssize_t s1, s2, s3;
2846
- dtype x, y;
2847
- BIT_DIGIT b;
2848
- INIT_COUNTER(lp, i);
2849
- INIT_PTR(lp, 0, p1, s1);
2850
- INIT_PTR(lp, 1, p2, s2);
2851
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
2852
- for (; i--;) {
2853
- GET_DATA_STRIDE(p1, s1, dtype, x);
2854
- GET_DATA_STRIDE(p2, s2, dtype, y);
2855
- b = (m_ne(x, y)) ? 1 : 0;
2856
- STORE_BIT(a3, p3, b);
2857
- p3 += s3;
2858
- }
2859
- }
2860
-
2861
- static VALUE int32_ne_self(VALUE self, VALUE other) {
2862
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2863
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
2864
- ndfunc_t ndf = { iter_int32_ne, STRIDE_LOOP, 2, 1, ain, aout };
2865
-
2866
- return na_ndloop(&ndf, 2, self, other);
2867
- }
2868
-
2869
- /*
2870
- Comparison ne other.
2871
- @overload ne other
2872
- @param [Numo::NArray,Numeric] other
2873
- @return [Numo::Bit] result of self ne other.
2874
- */
2875
- static VALUE int32_ne(VALUE self, VALUE other) {
2876
-
2877
- VALUE klass, v;
2878
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2879
- if (klass == cT) {
2880
- return int32_ne_self(self, other);
2881
- } else {
2882
- v = rb_funcall(klass, id_cast, 1, self);
2883
- return rb_funcall(v, id_ne, 1, other);
2884
- }
2885
- }
2886
-
2887
- #define check_intdivzero(y) \
2888
- {}
2889
-
2890
- static void iter_int32_bit_and(na_loop_t* const lp) {
2891
- size_t i = 0;
2892
- size_t n;
2893
- char *p1, *p2, *p3;
2894
- ssize_t s1, s2, s3;
2895
-
2896
- INIT_COUNTER(lp, n);
2897
- INIT_PTR(lp, 0, p1, s1);
2898
- INIT_PTR(lp, 1, p2, s2);
2899
- INIT_PTR(lp, 2, p3, s3);
2900
-
2901
- //
2902
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2903
- is_aligned(p3, sizeof(dtype))) {
2904
-
2905
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2906
- if (p1 == p3) { // inplace case
2907
- for (; i < n; i++) {
2908
- check_intdivzero(((dtype*)p2)[i]);
2909
- ((dtype*)p1)[i] = m_bit_and(((dtype*)p1)[i], ((dtype*)p2)[i]);
2910
- }
2911
- } else {
2912
- for (; i < n; i++) {
2913
- check_intdivzero(((dtype*)p2)[i]);
2914
- ((dtype*)p3)[i] = m_bit_and(((dtype*)p1)[i], ((dtype*)p2)[i]);
2915
- }
2916
- }
2917
- return;
2918
- }
2919
-
2920
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2921
- is_aligned_step(s3, sizeof(dtype))) {
2922
- //
2923
-
2924
- if (s2 == 0) { // Broadcasting from scalar value.
2925
- check_intdivzero(*(dtype*)p2);
2926
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2927
- if (p1 == p3) { // inplace case
2928
- for (; i < n; i++) {
2929
- ((dtype*)p1)[i] = m_bit_and(((dtype*)p1)[i], *(dtype*)p2);
2930
- }
2931
- } else {
2932
- for (; i < n; i++) {
2933
- ((dtype*)p3)[i] = m_bit_and(((dtype*)p1)[i], *(dtype*)p2);
2934
- }
2935
- }
2936
- } else {
2937
- for (i = 0; i < n; i++) {
2938
- *(dtype*)p3 = m_bit_and(*(dtype*)p1, *(dtype*)p2);
2939
- p1 += s1;
2940
- p3 += s3;
2941
- }
2942
- }
2943
- } else {
2944
- if (p1 == p3) { // inplace case
2945
- for (i = 0; i < n; i++) {
2946
- check_intdivzero(*(dtype*)p2);
2947
- *(dtype*)p1 = m_bit_and(*(dtype*)p1, *(dtype*)p2);
2948
- p1 += s1;
2949
- p2 += s2;
2950
- }
2951
- } else {
2952
- for (i = 0; i < n; i++) {
2953
- check_intdivzero(*(dtype*)p2);
2954
- *(dtype*)p3 = m_bit_and(*(dtype*)p1, *(dtype*)p2);
2955
- p1 += s1;
2956
- p2 += s2;
2957
- p3 += s3;
2958
- }
2959
- }
2960
- }
2961
-
2962
- return;
2963
- //
2964
- }
2965
- }
2966
- for (i = 0; i < n; i++) {
2967
- dtype x, y, z;
2968
- GET_DATA_STRIDE(p1, s1, dtype, x);
2969
- GET_DATA_STRIDE(p2, s2, dtype, y);
2970
- check_intdivzero(y);
2971
- z = m_bit_and(x, y);
2972
- SET_DATA_STRIDE(p3, s3, dtype, z);
2973
- }
2974
- //
2975
- }
2976
- #undef check_intdivzero
2977
-
2978
- static VALUE int32_bit_and_self(VALUE self, VALUE other) {
2979
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2980
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2981
- ndfunc_t ndf = { iter_int32_bit_and, STRIDE_LOOP, 2, 1, ain, aout };
2982
-
2983
- return na_ndloop(&ndf, 2, self, other);
2984
- }
2985
-
2986
- /*
2987
- Binary bit_and.
2988
- @overload & other
2989
- @param [Numo::NArray,Numeric] other
2990
- @return [Numo::NArray] self & other
2991
- */
2992
- static VALUE int32_bit_and(VALUE self, VALUE other) {
2993
-
2994
- VALUE klass, v;
2995
-
2996
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2997
- if (klass == cT) {
2998
- return int32_bit_and_self(self, other);
2999
- } else {
3000
- v = rb_funcall(klass, id_cast, 1, self);
3001
- return rb_funcall(v, '&', 1, other);
3002
- }
3003
- }
3004
-
3005
- #define check_intdivzero(y) \
3006
- {}
3007
-
3008
- static void iter_int32_bit_or(na_loop_t* const lp) {
3009
- size_t i = 0;
3010
- size_t n;
3011
- char *p1, *p2, *p3;
3012
- ssize_t s1, s2, s3;
3013
-
3014
- INIT_COUNTER(lp, n);
3015
- INIT_PTR(lp, 0, p1, s1);
3016
- INIT_PTR(lp, 1, p2, s2);
3017
- INIT_PTR(lp, 2, p3, s3);
3018
-
3019
- //
3020
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
3021
- is_aligned(p3, sizeof(dtype))) {
3022
-
3023
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
3024
- if (p1 == p3) { // inplace case
3025
- for (; i < n; i++) {
3026
- check_intdivzero(((dtype*)p2)[i]);
3027
- ((dtype*)p1)[i] = m_bit_or(((dtype*)p1)[i], ((dtype*)p2)[i]);
3028
- }
3029
- } else {
3030
- for (; i < n; i++) {
3031
- check_intdivzero(((dtype*)p2)[i]);
3032
- ((dtype*)p3)[i] = m_bit_or(((dtype*)p1)[i], ((dtype*)p2)[i]);
3033
- }
3034
- }
3035
- return;
3036
- }
3037
-
3038
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
3039
- is_aligned_step(s3, sizeof(dtype))) {
3040
- //
3041
-
3042
- if (s2 == 0) { // Broadcasting from scalar value.
3043
- check_intdivzero(*(dtype*)p2);
3044
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
3045
- if (p1 == p3) { // inplace case
3046
- for (; i < n; i++) {
3047
- ((dtype*)p1)[i] = m_bit_or(((dtype*)p1)[i], *(dtype*)p2);
3048
- }
3049
- } else {
3050
- for (; i < n; i++) {
3051
- ((dtype*)p3)[i] = m_bit_or(((dtype*)p1)[i], *(dtype*)p2);
3052
- }
3053
- }
3054
- } else {
3055
- for (i = 0; i < n; i++) {
3056
- *(dtype*)p3 = m_bit_or(*(dtype*)p1, *(dtype*)p2);
3057
- p1 += s1;
3058
- p3 += s3;
3059
- }
3060
- }
3061
- } else {
3062
- if (p1 == p3) { // inplace case
3063
- for (i = 0; i < n; i++) {
3064
- check_intdivzero(*(dtype*)p2);
3065
- *(dtype*)p1 = m_bit_or(*(dtype*)p1, *(dtype*)p2);
3066
- p1 += s1;
3067
- p2 += s2;
3068
- }
3069
- } else {
3070
- for (i = 0; i < n; i++) {
3071
- check_intdivzero(*(dtype*)p2);
3072
- *(dtype*)p3 = m_bit_or(*(dtype*)p1, *(dtype*)p2);
3073
- p1 += s1;
3074
- p2 += s2;
3075
- p3 += s3;
3076
- }
3077
- }
3078
- }
3079
-
3080
- return;
3081
- //
3082
- }
3083
- }
3084
- for (i = 0; i < n; i++) {
3085
- dtype x, y, z;
3086
- GET_DATA_STRIDE(p1, s1, dtype, x);
3087
- GET_DATA_STRIDE(p2, s2, dtype, y);
3088
- check_intdivzero(y);
3089
- z = m_bit_or(x, y);
3090
- SET_DATA_STRIDE(p3, s3, dtype, z);
3091
- }
3092
- //
3093
- }
3094
- #undef check_intdivzero
3095
-
3096
- static VALUE int32_bit_or_self(VALUE self, VALUE other) {
3097
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3098
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3099
- ndfunc_t ndf = { iter_int32_bit_or, STRIDE_LOOP, 2, 1, ain, aout };
3100
-
3101
- return na_ndloop(&ndf, 2, self, other);
3102
- }
3103
-
3104
- /*
3105
- Binary bit_or.
3106
- @overload | other
3107
- @param [Numo::NArray,Numeric] other
3108
- @return [Numo::NArray] self | other
3109
- */
3110
- static VALUE int32_bit_or(VALUE self, VALUE other) {
3111
-
3112
- VALUE klass, v;
3113
-
3114
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3115
- if (klass == cT) {
3116
- return int32_bit_or_self(self, other);
3117
- } else {
3118
- v = rb_funcall(klass, id_cast, 1, self);
3119
- return rb_funcall(v, '|', 1, other);
3120
- }
3121
- }
3122
-
3123
- #define check_intdivzero(y) \
3124
- {}
3125
-
3126
- static void iter_int32_bit_xor(na_loop_t* const lp) {
3127
- size_t i = 0;
3128
- size_t n;
3129
- char *p1, *p2, *p3;
3130
- ssize_t s1, s2, s3;
3131
-
3132
- INIT_COUNTER(lp, n);
3133
- INIT_PTR(lp, 0, p1, s1);
3134
- INIT_PTR(lp, 1, p2, s2);
3135
- INIT_PTR(lp, 2, p3, s3);
3136
-
3137
- //
3138
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
3139
- is_aligned(p3, sizeof(dtype))) {
3140
-
3141
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
3142
- if (p1 == p3) { // inplace case
3143
- for (; i < n; i++) {
3144
- check_intdivzero(((dtype*)p2)[i]);
3145
- ((dtype*)p1)[i] = m_bit_xor(((dtype*)p1)[i], ((dtype*)p2)[i]);
3146
- }
3147
- } else {
3148
- for (; i < n; i++) {
3149
- check_intdivzero(((dtype*)p2)[i]);
3150
- ((dtype*)p3)[i] = m_bit_xor(((dtype*)p1)[i], ((dtype*)p2)[i]);
3151
- }
3152
- }
3153
- return;
3154
- }
3155
-
3156
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
3157
- is_aligned_step(s3, sizeof(dtype))) {
3158
- //
3159
-
3160
- if (s2 == 0) { // Broadcasting from scalar value.
3161
- check_intdivzero(*(dtype*)p2);
3162
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
3163
- if (p1 == p3) { // inplace case
3164
- for (; i < n; i++) {
3165
- ((dtype*)p1)[i] = m_bit_xor(((dtype*)p1)[i], *(dtype*)p2);
3166
- }
3167
- } else {
3168
- for (; i < n; i++) {
3169
- ((dtype*)p3)[i] = m_bit_xor(((dtype*)p1)[i], *(dtype*)p2);
3170
- }
3171
- }
3172
- } else {
3173
- for (i = 0; i < n; i++) {
3174
- *(dtype*)p3 = m_bit_xor(*(dtype*)p1, *(dtype*)p2);
3175
- p1 += s1;
3176
- p3 += s3;
3177
- }
3178
- }
3179
- } else {
3180
- if (p1 == p3) { // inplace case
3181
- for (i = 0; i < n; i++) {
3182
- check_intdivzero(*(dtype*)p2);
3183
- *(dtype*)p1 = m_bit_xor(*(dtype*)p1, *(dtype*)p2);
3184
- p1 += s1;
3185
- p2 += s2;
3186
- }
3187
- } else {
3188
- for (i = 0; i < n; i++) {
3189
- check_intdivzero(*(dtype*)p2);
3190
- *(dtype*)p3 = m_bit_xor(*(dtype*)p1, *(dtype*)p2);
3191
- p1 += s1;
3192
- p2 += s2;
3193
- p3 += s3;
3194
- }
3195
- }
3196
- }
3197
-
3198
- return;
3199
- //
3200
- }
3201
- }
3202
- for (i = 0; i < n; i++) {
3203
- dtype x, y, z;
3204
- GET_DATA_STRIDE(p1, s1, dtype, x);
3205
- GET_DATA_STRIDE(p2, s2, dtype, y);
3206
- check_intdivzero(y);
3207
- z = m_bit_xor(x, y);
3208
- SET_DATA_STRIDE(p3, s3, dtype, z);
3209
- }
3210
- //
3211
- }
3212
- #undef check_intdivzero
3213
-
3214
- static VALUE int32_bit_xor_self(VALUE self, VALUE other) {
3215
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3216
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3217
- ndfunc_t ndf = { iter_int32_bit_xor, STRIDE_LOOP, 2, 1, ain, aout };
3218
-
3219
- return na_ndloop(&ndf, 2, self, other);
3220
- }
3221
-
3222
- /*
3223
- Binary bit_xor.
3224
- @overload ^ other
3225
- @param [Numo::NArray,Numeric] other
3226
- @return [Numo::NArray] self ^ other
3227
- */
3228
- static VALUE int32_bit_xor(VALUE self, VALUE other) {
3229
-
3230
- VALUE klass, v;
3231
-
3232
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3233
- if (klass == cT) {
3234
- return int32_bit_xor_self(self, other);
3235
- } else {
3236
- v = rb_funcall(klass, id_cast, 1, self);
3237
- return rb_funcall(v, '^', 1, other);
3238
- }
3239
- }
3240
-
3241
- static void iter_int32_bit_not(na_loop_t* const lp) {
3242
- size_t i, n;
3243
- char *p1, *p2;
3244
- ssize_t s1, s2;
3245
- size_t *idx1, *idx2;
3246
- dtype x;
3247
-
3248
- INIT_COUNTER(lp, n);
3249
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3250
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
3251
-
3252
- if (idx1) {
3253
- if (idx2) {
3254
- for (i = 0; i < n; i++) {
3255
- GET_DATA_INDEX(p1, idx1, dtype, x);
3256
- x = m_bit_not(x);
3257
- SET_DATA_INDEX(p2, idx2, dtype, x);
3258
- }
3259
- } else {
3260
- for (i = 0; i < n; i++) {
3261
- GET_DATA_INDEX(p1, idx1, dtype, x);
3262
- x = m_bit_not(x);
3263
- SET_DATA_STRIDE(p2, s2, dtype, x);
3264
- }
3265
- }
3266
- } else {
3267
- if (idx2) {
3268
- for (i = 0; i < n; i++) {
3269
- GET_DATA_STRIDE(p1, s1, dtype, x);
3270
- x = m_bit_not(x);
3271
- SET_DATA_INDEX(p2, idx2, dtype, x);
3272
- }
3273
- } else {
3274
- //
3275
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
3276
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
3277
- for (i = 0; i < n; i++) {
3278
- ((dtype*)p2)[i] = m_bit_not(((dtype*)p1)[i]);
3279
- }
3280
- return;
3281
- }
3282
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
3283
- //
3284
- for (i = 0; i < n; i++) {
3285
- *(dtype*)p2 = m_bit_not(*(dtype*)p1);
3286
- p1 += s1;
3287
- p2 += s2;
3288
- }
3289
- return;
3290
- //
3291
- }
3292
- }
3293
- for (i = 0; i < n; i++) {
3294
- GET_DATA_STRIDE(p1, s1, dtype, x);
3295
- x = m_bit_not(x);
3296
- SET_DATA_STRIDE(p2, s2, dtype, x);
3297
- }
3298
- //
3299
- }
3300
- }
3301
- }
3302
-
3303
- /*
3304
- Unary bit_not.
3305
- @overload ~
3306
- @return [Numo::Int32] bit_not of self.
3307
- */
3308
- static VALUE int32_bit_not(VALUE self) {
3309
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3310
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3311
- ndfunc_t ndf = { iter_int32_bit_not, FULL_LOOP, 1, 1, ain, aout };
3312
-
3313
- return na_ndloop(&ndf, 1, self);
3314
- }
3315
-
3316
- #define check_intdivzero(y) \
3317
- {}
3318
-
3319
- static void iter_int32_left_shift(na_loop_t* const lp) {
3320
- size_t i = 0;
3321
- size_t n;
3322
- char *p1, *p2, *p3;
3323
- ssize_t s1, s2, s3;
3324
-
3325
- INIT_COUNTER(lp, n);
3326
- INIT_PTR(lp, 0, p1, s1);
3327
- INIT_PTR(lp, 1, p2, s2);
3328
- INIT_PTR(lp, 2, p3, s3);
3329
-
3330
- //
3331
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
3332
- is_aligned(p3, sizeof(dtype))) {
3333
-
3334
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
3335
- if (p1 == p3) { // inplace case
3336
- for (; i < n; i++) {
3337
- check_intdivzero(((dtype*)p2)[i]);
3338
- ((dtype*)p1)[i] = m_left_shift(((dtype*)p1)[i], ((dtype*)p2)[i]);
3339
- }
3340
- } else {
3341
- for (; i < n; i++) {
3342
- check_intdivzero(((dtype*)p2)[i]);
3343
- ((dtype*)p3)[i] = m_left_shift(((dtype*)p1)[i], ((dtype*)p2)[i]);
3344
- }
3345
- }
3346
- return;
3347
- }
3348
-
3349
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
3350
- is_aligned_step(s3, sizeof(dtype))) {
3351
- //
3352
-
3353
- if (s2 == 0) { // Broadcasting from scalar value.
3354
- check_intdivzero(*(dtype*)p2);
3355
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
3356
- if (p1 == p3) { // inplace case
3357
- for (; i < n; i++) {
3358
- ((dtype*)p1)[i] = m_left_shift(((dtype*)p1)[i], *(dtype*)p2);
3359
- }
3360
- } else {
3361
- for (; i < n; i++) {
3362
- ((dtype*)p3)[i] = m_left_shift(((dtype*)p1)[i], *(dtype*)p2);
3363
- }
3364
- }
3365
- } else {
3366
- for (i = 0; i < n; i++) {
3367
- *(dtype*)p3 = m_left_shift(*(dtype*)p1, *(dtype*)p2);
3368
- p1 += s1;
3369
- p3 += s3;
3370
- }
3371
- }
3372
- } else {
3373
- if (p1 == p3) { // inplace case
3374
- for (i = 0; i < n; i++) {
3375
- check_intdivzero(*(dtype*)p2);
3376
- *(dtype*)p1 = m_left_shift(*(dtype*)p1, *(dtype*)p2);
3377
- p1 += s1;
3378
- p2 += s2;
3379
- }
3380
- } else {
3381
- for (i = 0; i < n; i++) {
3382
- check_intdivzero(*(dtype*)p2);
3383
- *(dtype*)p3 = m_left_shift(*(dtype*)p1, *(dtype*)p2);
3384
- p1 += s1;
3385
- p2 += s2;
3386
- p3 += s3;
3387
- }
3388
- }
3389
- }
3390
-
3391
- return;
3392
- //
3393
- }
3394
- }
3395
- for (i = 0; i < n; i++) {
3396
- dtype x, y, z;
3397
- GET_DATA_STRIDE(p1, s1, dtype, x);
3398
- GET_DATA_STRIDE(p2, s2, dtype, y);
3399
- check_intdivzero(y);
3400
- z = m_left_shift(x, y);
3401
- SET_DATA_STRIDE(p3, s3, dtype, z);
3402
- }
3403
- //
3404
- }
3405
- #undef check_intdivzero
3406
-
3407
- static VALUE int32_left_shift_self(VALUE self, VALUE other) {
3408
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3409
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3410
- ndfunc_t ndf = { iter_int32_left_shift, STRIDE_LOOP, 2, 1, ain, aout };
3411
-
3412
- return na_ndloop(&ndf, 2, self, other);
3413
- }
3414
-
3415
- /*
3416
- Binary left_shift.
3417
- @overload << other
3418
- @param [Numo::NArray,Numeric] other
3419
- @return [Numo::NArray] self << other
3420
- */
3421
- static VALUE int32_left_shift(VALUE self, VALUE other) {
3422
-
3423
- VALUE klass, v;
3424
-
3425
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3426
- if (klass == cT) {
3427
- return int32_left_shift_self(self, other);
3428
- } else {
3429
- v = rb_funcall(klass, id_cast, 1, self);
3430
- return rb_funcall(v, id_left_shift, 1, other);
3431
- }
3432
- }
3433
-
3434
- #define check_intdivzero(y) \
3435
- {}
3436
-
3437
- static void iter_int32_right_shift(na_loop_t* const lp) {
3438
- size_t i = 0;
3439
- size_t n;
3440
- char *p1, *p2, *p3;
3441
- ssize_t s1, s2, s3;
3442
-
3443
- INIT_COUNTER(lp, n);
3444
- INIT_PTR(lp, 0, p1, s1);
3445
- INIT_PTR(lp, 1, p2, s2);
3446
- INIT_PTR(lp, 2, p3, s3);
3447
-
3448
- //
3449
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
3450
- is_aligned(p3, sizeof(dtype))) {
3451
-
3452
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
3453
- if (p1 == p3) { // inplace case
3454
- for (; i < n; i++) {
3455
- check_intdivzero(((dtype*)p2)[i]);
3456
- ((dtype*)p1)[i] = m_right_shift(((dtype*)p1)[i], ((dtype*)p2)[i]);
3457
- }
3458
- } else {
3459
- for (; i < n; i++) {
3460
- check_intdivzero(((dtype*)p2)[i]);
3461
- ((dtype*)p3)[i] = m_right_shift(((dtype*)p1)[i], ((dtype*)p2)[i]);
3462
- }
3463
- }
3464
- return;
3465
- }
3466
-
3467
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
3468
- is_aligned_step(s3, sizeof(dtype))) {
3469
- //
3470
-
3471
- if (s2 == 0) { // Broadcasting from scalar value.
3472
- check_intdivzero(*(dtype*)p2);
3473
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
3474
- if (p1 == p3) { // inplace case
3475
- for (; i < n; i++) {
3476
- ((dtype*)p1)[i] = m_right_shift(((dtype*)p1)[i], *(dtype*)p2);
3477
- }
3478
- } else {
3479
- for (; i < n; i++) {
3480
- ((dtype*)p3)[i] = m_right_shift(((dtype*)p1)[i], *(dtype*)p2);
3481
- }
3482
- }
3483
- } else {
3484
- for (i = 0; i < n; i++) {
3485
- *(dtype*)p3 = m_right_shift(*(dtype*)p1, *(dtype*)p2);
3486
- p1 += s1;
3487
- p3 += s3;
3488
- }
3489
- }
3490
- } else {
3491
- if (p1 == p3) { // inplace case
3492
- for (i = 0; i < n; i++) {
3493
- check_intdivzero(*(dtype*)p2);
3494
- *(dtype*)p1 = m_right_shift(*(dtype*)p1, *(dtype*)p2);
3495
- p1 += s1;
3496
- p2 += s2;
3497
- }
3498
- } else {
3499
- for (i = 0; i < n; i++) {
3500
- check_intdivzero(*(dtype*)p2);
3501
- *(dtype*)p3 = m_right_shift(*(dtype*)p1, *(dtype*)p2);
3502
- p1 += s1;
3503
- p2 += s2;
3504
- p3 += s3;
3505
- }
3506
- }
3507
- }
3508
-
3509
- return;
3510
- //
3511
- }
3512
- }
3513
- for (i = 0; i < n; i++) {
3514
- dtype x, y, z;
3515
- GET_DATA_STRIDE(p1, s1, dtype, x);
3516
- GET_DATA_STRIDE(p2, s2, dtype, y);
3517
- check_intdivzero(y);
3518
- z = m_right_shift(x, y);
3519
- SET_DATA_STRIDE(p3, s3, dtype, z);
3520
- }
3521
- //
3522
- }
3523
- #undef check_intdivzero
3524
-
3525
- static VALUE int32_right_shift_self(VALUE self, VALUE other) {
3526
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3527
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3528
- ndfunc_t ndf = { iter_int32_right_shift, STRIDE_LOOP, 2, 1, ain, aout };
3529
-
3530
- return na_ndloop(&ndf, 2, self, other);
3531
- }
3532
-
3533
- /*
3534
- Binary right_shift.
3535
- @overload >> other
3536
- @param [Numo::NArray,Numeric] other
3537
- @return [Numo::NArray] self >> other
3538
- */
3539
- static VALUE int32_right_shift(VALUE self, VALUE other) {
3540
-
3541
- VALUE klass, v;
3542
-
3543
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3544
- if (klass == cT) {
3545
- return int32_right_shift_self(self, other);
3546
- } else {
3547
- v = rb_funcall(klass, id_cast, 1, self);
3548
- return rb_funcall(v, id_right_shift, 1, other);
3549
- }
3550
- }
3551
-
3552
- static void iter_int32_gt(na_loop_t* const lp) {
3553
- size_t i;
3554
- char *p1, *p2;
3555
- BIT_DIGIT* a3;
3556
- size_t p3;
3557
- ssize_t s1, s2, s3;
3558
- dtype x, y;
3559
- BIT_DIGIT b;
3560
- INIT_COUNTER(lp, i);
3561
- INIT_PTR(lp, 0, p1, s1);
3562
- INIT_PTR(lp, 1, p2, s2);
3563
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
3564
- for (; i--;) {
3565
- GET_DATA_STRIDE(p1, s1, dtype, x);
3566
- GET_DATA_STRIDE(p2, s2, dtype, y);
3567
- b = (m_gt(x, y)) ? 1 : 0;
3568
- STORE_BIT(a3, p3, b);
3569
- p3 += s3;
3570
- }
3571
- }
3572
-
3573
- static VALUE int32_gt_self(VALUE self, VALUE other) {
3574
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3575
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3576
- ndfunc_t ndf = { iter_int32_gt, STRIDE_LOOP, 2, 1, ain, aout };
3577
-
3578
- return na_ndloop(&ndf, 2, self, other);
3579
- }
3580
-
3581
- /*
3582
- Comparison gt other.
3583
- @overload gt other
3584
- @param [Numo::NArray,Numeric] other
3585
- @return [Numo::Bit] result of self gt other.
3586
- */
3587
- static VALUE int32_gt(VALUE self, VALUE other) {
3588
-
3589
- VALUE klass, v;
3590
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3591
- if (klass == cT) {
3592
- return int32_gt_self(self, other);
3593
- } else {
3594
- v = rb_funcall(klass, id_cast, 1, self);
3595
- return rb_funcall(v, id_gt, 1, other);
3596
- }
3597
- }
3598
-
3599
- static void iter_int32_ge(na_loop_t* const lp) {
3600
- size_t i;
3601
- char *p1, *p2;
3602
- BIT_DIGIT* a3;
3603
- size_t p3;
3604
- ssize_t s1, s2, s3;
3605
- dtype x, y;
3606
- BIT_DIGIT b;
3607
- INIT_COUNTER(lp, i);
3608
- INIT_PTR(lp, 0, p1, s1);
3609
- INIT_PTR(lp, 1, p2, s2);
3610
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
3611
- for (; i--;) {
3612
- GET_DATA_STRIDE(p1, s1, dtype, x);
3613
- GET_DATA_STRIDE(p2, s2, dtype, y);
3614
- b = (m_ge(x, y)) ? 1 : 0;
3615
- STORE_BIT(a3, p3, b);
3616
- p3 += s3;
3617
- }
3618
- }
3619
-
3620
- static VALUE int32_ge_self(VALUE self, VALUE other) {
3621
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3622
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3623
- ndfunc_t ndf = { iter_int32_ge, STRIDE_LOOP, 2, 1, ain, aout };
3624
-
3625
- return na_ndloop(&ndf, 2, self, other);
3626
- }
3627
-
3628
- /*
3629
- Comparison ge other.
3630
- @overload ge other
3631
- @param [Numo::NArray,Numeric] other
3632
- @return [Numo::Bit] result of self ge other.
3633
- */
3634
- static VALUE int32_ge(VALUE self, VALUE other) {
3635
-
3636
- VALUE klass, v;
3637
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3638
- if (klass == cT) {
3639
- return int32_ge_self(self, other);
3640
- } else {
3641
- v = rb_funcall(klass, id_cast, 1, self);
3642
- return rb_funcall(v, id_ge, 1, other);
3643
- }
3644
- }
3645
-
3646
- static void iter_int32_lt(na_loop_t* const lp) {
3647
- size_t i;
3648
- char *p1, *p2;
3649
- BIT_DIGIT* a3;
3650
- size_t p3;
3651
- ssize_t s1, s2, s3;
3652
- dtype x, y;
3653
- BIT_DIGIT b;
3654
- INIT_COUNTER(lp, i);
3655
- INIT_PTR(lp, 0, p1, s1);
3656
- INIT_PTR(lp, 1, p2, s2);
3657
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
3658
- for (; i--;) {
3659
- GET_DATA_STRIDE(p1, s1, dtype, x);
3660
- GET_DATA_STRIDE(p2, s2, dtype, y);
3661
- b = (m_lt(x, y)) ? 1 : 0;
3662
- STORE_BIT(a3, p3, b);
3663
- p3 += s3;
3664
- }
3665
- }
3666
-
3667
- static VALUE int32_lt_self(VALUE self, VALUE other) {
3668
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3669
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3670
- ndfunc_t ndf = { iter_int32_lt, STRIDE_LOOP, 2, 1, ain, aout };
3671
-
3672
- return na_ndloop(&ndf, 2, self, other);
3673
- }
3674
-
3675
- /*
3676
- Comparison lt other.
3677
- @overload lt other
3678
- @param [Numo::NArray,Numeric] other
3679
- @return [Numo::Bit] result of self lt other.
3680
- */
3681
- static VALUE int32_lt(VALUE self, VALUE other) {
3682
-
3683
- VALUE klass, v;
3684
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3685
- if (klass == cT) {
3686
- return int32_lt_self(self, other);
3687
- } else {
3688
- v = rb_funcall(klass, id_cast, 1, self);
3689
- return rb_funcall(v, id_lt, 1, other);
3690
- }
3691
- }
3692
-
3693
- static void iter_int32_le(na_loop_t* const lp) {
3694
- size_t i;
3695
- char *p1, *p2;
3696
- BIT_DIGIT* a3;
3697
- size_t p3;
3698
- ssize_t s1, s2, s3;
3699
- dtype x, y;
3700
- BIT_DIGIT b;
3701
- INIT_COUNTER(lp, i);
3702
- INIT_PTR(lp, 0, p1, s1);
3703
- INIT_PTR(lp, 1, p2, s2);
3704
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
3705
- for (; i--;) {
3706
- GET_DATA_STRIDE(p1, s1, dtype, x);
3707
- GET_DATA_STRIDE(p2, s2, dtype, y);
3708
- b = (m_le(x, y)) ? 1 : 0;
3709
- STORE_BIT(a3, p3, b);
3710
- p3 += s3;
3711
- }
3712
- }
3713
-
3714
- static VALUE int32_le_self(VALUE self, VALUE other) {
3715
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3716
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3717
- ndfunc_t ndf = { iter_int32_le, STRIDE_LOOP, 2, 1, ain, aout };
3718
-
3719
- return na_ndloop(&ndf, 2, self, other);
3720
- }
3721
-
3722
- /*
3723
- Comparison le other.
3724
- @overload le other
3725
- @param [Numo::NArray,Numeric] other
3726
- @return [Numo::Bit] result of self le other.
3727
- */
3728
- static VALUE int32_le(VALUE self, VALUE other) {
3729
-
3730
- VALUE klass, v;
3731
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3732
- if (klass == cT) {
3733
- return int32_le_self(self, other);
3734
- } else {
3735
- v = rb_funcall(klass, id_cast, 1, self);
3736
- return rb_funcall(v, id_le, 1, other);
3737
- }
3738
- }
3739
-
3740
- // ------- Integer count without weights -------
3741
-
3742
- static void iter_int32_bincount_32(na_loop_t* const lp) {
3743
- size_t i, x, n;
3744
- char *p1, *p2;
3745
- ssize_t s1, s2;
3746
- size_t* idx1;
3747
-
3748
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3749
- INIT_PTR(lp, 1, p2, s2);
3750
- i = lp->args[0].shape[0];
3751
- n = lp->args[1].shape[0];
3752
-
3753
- // initialize
3754
- for (x = 0; x < n; x++) {
3755
- *(u_int32_t*)(p2 + s2 * x) = 0;
3756
- }
3757
-
3758
- if (idx1) {
3759
- for (; i--;) {
3760
- GET_DATA_INDEX(p1, idx1, dtype, x);
3761
- (*(u_int32_t*)(p2 + s2 * x))++;
3762
- }
3763
- } else {
3764
- for (; i--;) {
3765
- GET_DATA_STRIDE(p1, s1, dtype, x);
3766
- (*(u_int32_t*)(p2 + s2 * x))++;
3767
- }
3768
- }
3769
- }
3770
-
3771
- static VALUE int32_bincount_32(VALUE self, size_t length) {
3772
- size_t shape_out[1] = { length };
3773
- ndfunc_arg_in_t ain[1] = { { cT, 1 } };
3774
- ndfunc_arg_out_t aout[1] = { { numo_cUInt32, 1, shape_out } };
3775
- ndfunc_t ndf = {
3776
- iter_int32_bincount_32, NO_LOOP | NDF_STRIDE_LOOP | NDF_INDEX_LOOP, 1, 1, ain, aout
3777
- };
1843
+ ndfunc_arg_in_t ain[1] = { { cT, 0 } };
1844
+ ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1845
+ ndfunc_t ndf = { iter_int32_reciprocal, FULL_LOOP, 1, 1, ain, aout };
3778
1846
 
3779
1847
  return na_ndloop(&ndf, 1, self);
3780
1848
  }
3781
1849
 
3782
- static void iter_int32_bincount_64(na_loop_t* const lp) {
3783
- size_t i, x, n;
1850
+ static void iter_int32_sign(na_loop_t* const lp) {
1851
+ size_t i, n;
3784
1852
  char *p1, *p2;
3785
1853
  ssize_t s1, s2;
3786
- size_t* idx1;
1854
+ size_t *idx1, *idx2;
1855
+ dtype x;
3787
1856
 
1857
+ INIT_COUNTER(lp, n);
3788
1858
  INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3789
- INIT_PTR(lp, 1, p2, s2);
3790
- i = lp->args[0].shape[0];
3791
- n = lp->args[1].shape[0];
3792
-
3793
- // initialize
3794
- for (x = 0; x < n; x++) {
3795
- *(u_int64_t*)(p2 + s2 * x) = 0;
3796
- }
1859
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
3797
1860
 
3798
1861
  if (idx1) {
3799
- for (; i--;) {
3800
- GET_DATA_INDEX(p1, idx1, dtype, x);
3801
- (*(u_int64_t*)(p2 + s2 * x))++;
1862
+ if (idx2) {
1863
+ for (i = 0; i < n; i++) {
1864
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1865
+ x = m_sign(x);
1866
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1867
+ }
1868
+ } else {
1869
+ for (i = 0; i < n; i++) {
1870
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1871
+ x = m_sign(x);
1872
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1873
+ }
3802
1874
  }
3803
1875
  } else {
3804
- for (; i--;) {
3805
- GET_DATA_STRIDE(p1, s1, dtype, x);
3806
- (*(u_int64_t*)(p2 + s2 * x))++;
1876
+ if (idx2) {
1877
+ for (i = 0; i < n; i++) {
1878
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1879
+ x = m_sign(x);
1880
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1881
+ }
1882
+ } else {
1883
+ //
1884
+ if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
1885
+ if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
1886
+ for (i = 0; i < n; i++) {
1887
+ ((dtype*)p2)[i] = m_sign(((dtype*)p1)[i]);
1888
+ }
1889
+ return;
1890
+ }
1891
+ if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
1892
+ //
1893
+ for (i = 0; i < n; i++) {
1894
+ *(dtype*)p2 = m_sign(*(dtype*)p1);
1895
+ p1 += s1;
1896
+ p2 += s2;
1897
+ }
1898
+ return;
1899
+ //
1900
+ }
1901
+ }
1902
+ for (i = 0; i < n; i++) {
1903
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1904
+ x = m_sign(x);
1905
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1906
+ }
1907
+ //
3807
1908
  }
3808
1909
  }
3809
1910
  }
3810
1911
 
3811
- static VALUE int32_bincount_64(VALUE self, size_t length) {
3812
- size_t shape_out[1] = { length };
3813
- ndfunc_arg_in_t ain[1] = { { cT, 1 } };
3814
- ndfunc_arg_out_t aout[1] = { { numo_cUInt64, 1, shape_out } };
3815
- ndfunc_t ndf = {
3816
- iter_int32_bincount_64, NO_LOOP | NDF_STRIDE_LOOP | NDF_INDEX_LOOP, 1, 1, ain, aout
3817
- };
1912
+ /*
1913
+ Unary sign.
1914
+ @overload sign
1915
+ @return [Numo::Int32] sign of self.
1916
+ */
1917
+ static VALUE int32_sign(VALUE self) {
1918
+ ndfunc_arg_in_t ain[1] = { { cT, 0 } };
1919
+ ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1920
+ ndfunc_t ndf = { iter_int32_sign, FULL_LOOP, 1, 1, ain, aout };
3818
1921
 
3819
1922
  return na_ndloop(&ndf, 1, self);
3820
1923
  }
3821
- // ------- end of Integer count without weights -------
3822
-
3823
- // ------- Float count with weights -------
3824
-
3825
- static void iter_int32_bincount_sf(na_loop_t* const lp) {
3826
- float w;
3827
- size_t i, x, n, m;
3828
- char *p1, *p2, *p3;
3829
- ssize_t s1, s2, s3;
3830
-
3831
- INIT_PTR(lp, 0, p1, s1);
3832
- INIT_PTR(lp, 1, p2, s2);
3833
- INIT_PTR(lp, 2, p3, s3);
3834
- i = lp->args[0].shape[0];
3835
- m = lp->args[1].shape[0];
3836
- n = lp->args[2].shape[0];
3837
-
3838
- if (i != m) {
3839
- rb_raise(nary_eShapeError, "size mismatch along last axis between self and weight");
3840
- }
3841
-
3842
- // initialize
3843
- for (x = 0; x < n; x++) {
3844
- *(float*)(p3 + s3 * x) = 0;
3845
- }
3846
- for (; i--;) {
3847
- GET_DATA_STRIDE(p1, s1, dtype, x);
3848
- GET_DATA_STRIDE(p2, s2, float, w);
3849
- (*(float*)(p3 + s3 * x)) += w;
3850
- }
3851
- }
3852
-
3853
- static VALUE int32_bincount_sf(VALUE self, VALUE weight, size_t length) {
3854
- size_t shape_out[1] = { length };
3855
- ndfunc_arg_in_t ain[2] = { { cT, 1 }, { numo_cSFloat, 1 } };
3856
- ndfunc_arg_out_t aout[1] = { { numo_cSFloat, 1, shape_out } };
3857
- ndfunc_t ndf = { iter_int32_bincount_sf, NO_LOOP | NDF_STRIDE_LOOP, 2, 1, ain, aout };
3858
-
3859
- return na_ndloop(&ndf, 2, self, weight);
3860
- }
3861
-
3862
- static void iter_int32_bincount_df(na_loop_t* const lp) {
3863
- double w;
3864
- size_t i, x, n, m;
3865
- char *p1, *p2, *p3;
3866
- ssize_t s1, s2, s3;
3867
-
3868
- INIT_PTR(lp, 0, p1, s1);
3869
- INIT_PTR(lp, 1, p2, s2);
3870
- INIT_PTR(lp, 2, p3, s3);
3871
- i = lp->args[0].shape[0];
3872
- m = lp->args[1].shape[0];
3873
- n = lp->args[2].shape[0];
3874
-
3875
- if (i != m) {
3876
- rb_raise(nary_eShapeError, "size mismatch along last axis between self and weight");
3877
- }
3878
-
3879
- // initialize
3880
- for (x = 0; x < n; x++) {
3881
- *(double*)(p3 + s3 * x) = 0;
3882
- }
3883
- for (; i--;) {
3884
- GET_DATA_STRIDE(p1, s1, dtype, x);
3885
- GET_DATA_STRIDE(p2, s2, double, w);
3886
- (*(double*)(p3 + s3 * x)) += w;
3887
- }
3888
- }
3889
-
3890
- static VALUE int32_bincount_df(VALUE self, VALUE weight, size_t length) {
3891
- size_t shape_out[1] = { length };
3892
- ndfunc_arg_in_t ain[2] = { { cT, 1 }, { numo_cDFloat, 1 } };
3893
- ndfunc_arg_out_t aout[1] = { { numo_cDFloat, 1, shape_out } };
3894
- ndfunc_t ndf = { iter_int32_bincount_df, NO_LOOP | NDF_STRIDE_LOOP, 2, 1, ain, aout };
3895
-
3896
- return na_ndloop(&ndf, 2, self, weight);
3897
- }
3898
- // ------- end of Float count with weights -------
3899
-
3900
- /*
3901
- Count the number of occurrences of each non-negative integer value.
3902
- Only Integer-types has this method.
3903
-
3904
- @overload bincount([weight], minlength:nil)
3905
- @param [SFloat or DFloat or Array] weight (optional) Array of
3906
- float values. Its size along last axis should be same as that of self.
3907
- @param [Integer] minlength (keyword, optional) Minimum size along
3908
- last axis for the output array.
3909
- @return [UInt32 or UInt64 or SFloat or DFloat]
3910
- Returns Float NArray if weight array is supplied,
3911
- otherwise returns UInt32 or UInt64 depending on the size along last axis.
3912
- @example
3913
- Numo::Int32[0..4].bincount
3914
- # => Numo::UInt32#shape=[5]
3915
- # [1, 1, 1, 1, 1]
3916
-
3917
- Numo::Int32[0, 1, 1, 3, 2, 1, 7].bincount
3918
- # => Numo::UInt32#shape=[8]
3919
- # [1, 3, 1, 1, 0, 0, 0, 1]
3920
-
3921
- x = Numo::Int32[0, 1, 1, 3, 2, 1, 7, 23]
3922
- x.bincount.size == x.max+1
3923
- # => true
3924
1924
 
3925
- w = Numo::DFloat[0.3, 0.5, 0.2, 0.7, 1.0, -0.6]
3926
- x = Numo::Int32[0, 1, 1, 2, 2, 2]
3927
- x.bincount(w)
3928
- # => Numo::DFloat#shape=[3]
3929
- # [0.3, 0.7, 1.1]
3930
-
3931
- */
3932
- static VALUE int32_bincount(int argc, VALUE* argv, VALUE self) {
3933
- VALUE weight = Qnil, kw = Qnil;
3934
- VALUE opts[1] = { Qundef };
3935
- VALUE v, wclass;
3936
- ID table[1] = { id_minlength };
3937
- size_t length, minlength;
3938
-
3939
- rb_scan_args(argc, argv, "01:", &weight, &kw);
3940
- rb_get_kwargs(kw, table, 0, 1, opts);
3941
-
3942
- v = int32_minmax(0, 0, self);
3943
- if (m_num_to_data(RARRAY_AREF(v, 0)) < 0) {
3944
- rb_raise(rb_eArgError, "array items must be non-netagive");
3945
- }
3946
- v = RARRAY_AREF(v, 1);
3947
-
3948
- length = NUM2SIZET(v) + 1;
1925
+ static void iter_int32_square(na_loop_t* const lp) {
1926
+ size_t i, n;
1927
+ char *p1, *p2;
1928
+ ssize_t s1, s2;
1929
+ size_t *idx1, *idx2;
1930
+ dtype x;
3949
1931
 
3950
- if (opts[0] != Qundef) {
3951
- minlength = NUM2SIZET(opts[0]);
3952
- if (minlength > length) {
3953
- length = minlength;
3954
- }
3955
- }
1932
+ INIT_COUNTER(lp, n);
1933
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1934
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
3956
1935
 
3957
- if (NIL_P(weight)) {
3958
- if (length > 4294967295ul) {
3959
- return int32_bincount_64(self, length);
1936
+ if (idx1) {
1937
+ if (idx2) {
1938
+ for (i = 0; i < n; i++) {
1939
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1940
+ x = m_square(x);
1941
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1942
+ }
3960
1943
  } else {
3961
- return int32_bincount_32(self, length);
1944
+ for (i = 0; i < n; i++) {
1945
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1946
+ x = m_square(x);
1947
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1948
+ }
3962
1949
  }
3963
1950
  } else {
3964
- wclass = rb_obj_class(weight);
3965
- if (wclass == numo_cSFloat) {
3966
- return int32_bincount_sf(self, weight, length);
1951
+ if (idx2) {
1952
+ for (i = 0; i < n; i++) {
1953
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1954
+ x = m_square(x);
1955
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1956
+ }
3967
1957
  } else {
3968
- return int32_bincount_df(self, weight, length);
1958
+ //
1959
+ if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
1960
+ if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
1961
+ for (i = 0; i < n; i++) {
1962
+ ((dtype*)p2)[i] = m_square(((dtype*)p1)[i]);
1963
+ }
1964
+ return;
1965
+ }
1966
+ if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
1967
+ //
1968
+ for (i = 0; i < n; i++) {
1969
+ *(dtype*)p2 = m_square(*(dtype*)p1);
1970
+ p1 += s1;
1971
+ p2 += s2;
1972
+ }
1973
+ return;
1974
+ //
1975
+ }
1976
+ }
1977
+ for (i = 0; i < n; i++) {
1978
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1979
+ x = m_square(x);
1980
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1981
+ }
1982
+ //
3969
1983
  }
3970
1984
  }
3971
1985
  }
3972
1986
 
1987
+ /*
1988
+ Unary square.
1989
+ @overload square
1990
+ @return [Numo::Int32] square of self.
1991
+ */
1992
+ static VALUE int32_square(VALUE self) {
1993
+ ndfunc_arg_in_t ain[1] = { { cT, 0 } };
1994
+ ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1995
+ ndfunc_t ndf = { iter_int32_square, FULL_LOOP, 1, 1, ain, aout };
1996
+
1997
+ return na_ndloop(&ndf, 1, self);
1998
+ }
1999
+
3973
2000
  static void iter_int32_poly(na_loop_t* const lp) {
3974
2001
  size_t i;
3975
2002
  dtype x, y, a;
@@ -4593,22 +2620,91 @@ void Init_numo_int32(void) {
4593
2620
  rb_define_singleton_method(cT, "cast", int32_s_cast, 1);
4594
2621
  rb_define_method(cT, "[]", int32_aref, -1);
4595
2622
  rb_define_method(cT, "[]=", int32_aset, -1);
2623
+ /**
2624
+ * return NArray with cast to the type of self.
2625
+ * @overload coerce_cast(type)
2626
+ * @return [nil]
2627
+ */
4596
2628
  rb_define_method(cT, "coerce_cast", int32_coerce_cast, 1);
2629
+ /**
2630
+ * Convert self to Array.
2631
+ * @overload to_a
2632
+ * @return [Array]
2633
+ */
4597
2634
  rb_define_method(cT, "to_a", int32_to_a, 0);
2635
+ /**
2636
+ * Fill elements with other.
2637
+ * @overload fill other
2638
+ * @param [Numeric] other
2639
+ * @return [Numo::Int32] self.
2640
+ */
4598
2641
  rb_define_method(cT, "fill", int32_fill, 1);
2642
+ /**
2643
+ * Format elements into strings.
2644
+ * @overload format format
2645
+ * @param [String] format
2646
+ * @return [Numo::RObject] array of formatted strings.
2647
+ */
4599
2648
  rb_define_method(cT, "format", int32_format, -1);
2649
+ /**
2650
+ * Format elements into strings.
2651
+ * @overload format_to_a format
2652
+ * @param [String] format
2653
+ * @return [Array] array of formatted strings.
2654
+ */
4600
2655
  rb_define_method(cT, "format_to_a", int32_format_to_a, -1);
2656
+ /**
2657
+ * Returns a string containing a human-readable representation of NArray.
2658
+ * @overload inspect
2659
+ * @return [String]
2660
+ */
4601
2661
  rb_define_method(cT, "inspect", int32_inspect, 0);
4602
2662
  rb_define_method(cT, "each", int32_each, 0);
4603
2663
  rb_define_method(cT, "map", int32_map, 0);
4604
2664
  rb_define_method(cT, "each_with_index", int32_each_with_index, 0);
4605
2665
  rb_define_method(cT, "map_with_index", int32_map_with_index, 0);
4606
2666
  rb_define_method(cT, "abs", int32_abs, 0);
2667
+ /**
2668
+ * Binary add.
2669
+ * @overload + other
2670
+ * @param [Numo::NArray,Numeric] other
2671
+ * @return [Numo::NArray] self + other
2672
+ */
4607
2673
  rb_define_method(cT, "+", int32_add, 1);
2674
+ /**
2675
+ * Binary sub.
2676
+ * @overload - other
2677
+ * @param [Numo::NArray,Numeric] other
2678
+ * @return [Numo::NArray] self - other
2679
+ */
4608
2680
  rb_define_method(cT, "-", int32_sub, 1);
2681
+ /**
2682
+ * Binary mul.
2683
+ * @overload * other
2684
+ * @param [Numo::NArray,Numeric] other
2685
+ * @return [Numo::NArray] self * other
2686
+ */
4609
2687
  rb_define_method(cT, "*", int32_mul, 1);
2688
+ /**
2689
+ * Binary div.
2690
+ * @overload / other
2691
+ * @param [Numo::NArray,Numeric] other
2692
+ * @return [Numo::NArray] self / other
2693
+ */
4610
2694
  rb_define_method(cT, "/", int32_div, 1);
2695
+ /**
2696
+ * Binary mod.
2697
+ * @overload % other
2698
+ * @param [Numo::NArray,Numeric] other
2699
+ * @return [Numo::NArray] self % other
2700
+ */
4611
2701
  rb_define_method(cT, "%", int32_mod, 1);
2702
+ /**
2703
+ * Binary divmod.
2704
+ * @overload divmod other
2705
+ * @param [Numo::NArray,Numeric] other
2706
+ * @return [Numo::NArray] divmod of self and other.
2707
+ */
4612
2708
  rb_define_method(cT, "divmod", int32_divmod, 1);
4613
2709
  rb_define_method(cT, "**", int32_pow, 1);
4614
2710
  rb_define_alias(cT, "pow", "**");
@@ -4619,24 +2715,95 @@ void Init_numo_int32(void) {
4619
2715
  rb_define_alias(cT, "conj", "view");
4620
2716
  rb_define_alias(cT, "im", "view");
4621
2717
  rb_define_alias(cT, "conjugate", "conj");
2718
+ /**
2719
+ * Comparison eq other.
2720
+ * @overload eq other
2721
+ * @param [Numo::NArray,Numeric] other
2722
+ * @return [Numo::Bit] result of self eq other.
2723
+ */
4622
2724
  rb_define_method(cT, "eq", int32_eq, 1);
2725
+ /**
2726
+ * Comparison ne other.
2727
+ * @overload ne other
2728
+ * @param [Numo::NArray,Numeric] other
2729
+ * @return [Numo::Bit] result of self ne other.
2730
+ */
4623
2731
  rb_define_method(cT, "ne", int32_ne, 1);
4624
2732
  rb_define_alias(cT, "nearly_eq", "eq");
4625
2733
  rb_define_alias(cT, "close_to", "nearly_eq");
2734
+ /**
2735
+ * Binary bit_and.
2736
+ * @overload & other
2737
+ * @param [Numo::NArray,Numeric] other
2738
+ * @return [Numo::NArray] self & other
2739
+ */
4626
2740
  rb_define_method(cT, "&", int32_bit_and, 1);
2741
+ /**
2742
+ * Binary bit_or.
2743
+ * @overload | other
2744
+ * @param [Numo::NArray,Numeric] other
2745
+ * @return [Numo::NArray] self | other
2746
+ */
4627
2747
  rb_define_method(cT, "|", int32_bit_or, 1);
2748
+ /**
2749
+ * Binary bit_xor.
2750
+ * @overload ^ other
2751
+ * @param [Numo::NArray,Numeric] other
2752
+ * @return [Numo::NArray] self ^ other
2753
+ */
4628
2754
  rb_define_method(cT, "^", int32_bit_xor, 1);
2755
+ /**
2756
+ * Unary bit_not.
2757
+ * @overload ~
2758
+ * @return [Numo::Int32] bit_not of self.
2759
+ */
4629
2760
  rb_define_method(cT, "~", int32_bit_not, 0);
2761
+ /**
2762
+ * Binary left_shift.
2763
+ * @overload << other
2764
+ * @param [Numo::NArray,Numeric] other
2765
+ * @return [Numo::NArray] self << other
2766
+ */
4630
2767
  rb_define_method(cT, "<<", int32_left_shift, 1);
2768
+ /**
2769
+ * Binary right_shift.
2770
+ * @overload >> other
2771
+ * @param [Numo::NArray,Numeric] other
2772
+ * @return [Numo::NArray] self >> other
2773
+ */
4631
2774
  rb_define_method(cT, ">>", int32_right_shift, 1);
4632
2775
  rb_define_alias(cT, "floor", "view");
4633
2776
  rb_define_alias(cT, "round", "view");
4634
2777
  rb_define_alias(cT, "ceil", "view");
4635
2778
  rb_define_alias(cT, "trunc", "view");
4636
2779
  rb_define_alias(cT, "rint", "view");
2780
+ /**
2781
+ * Comparison gt other.
2782
+ * @overload gt other
2783
+ * @param [Numo::NArray,Numeric] other
2784
+ * @return [Numo::Bit] result of self gt other.
2785
+ */
4637
2786
  rb_define_method(cT, "gt", int32_gt, 1);
2787
+ /**
2788
+ * Comparison ge other.
2789
+ * @overload ge other
2790
+ * @param [Numo::NArray,Numeric] other
2791
+ * @return [Numo::Bit] result of self ge other.
2792
+ */
4638
2793
  rb_define_method(cT, "ge", int32_ge, 1);
2794
+ /**
2795
+ * Comparison lt other.
2796
+ * @overload lt other
2797
+ * @param [Numo::NArray,Numeric] other
2798
+ * @return [Numo::Bit] result of self lt other.
2799
+ */
4639
2800
  rb_define_method(cT, "lt", int32_lt, 1);
2801
+ /**
2802
+ * Comparison le other.
2803
+ * @overload le other
2804
+ * @param [Numo::NArray,Numeric] other
2805
+ * @return [Numo::Bit] result of self le other.
2806
+ */
4640
2807
  rb_define_method(cT, "le", int32_le, 1);
4641
2808
  rb_define_alias(cT, ">", "gt");
4642
2809
  rb_define_alias(cT, ">=", "ge");
@@ -4821,6 +2988,37 @@ void Init_numo_int32(void) {
4821
2988
  * @return [Numo::Int32]
4822
2989
  */
4823
2990
  rb_define_module_function(cT, "minimum", int32_s_minimum, -1);
2991
+ /**
2992
+ * Count the number of occurrences of each non-negative integer value.
2993
+ * Only Integer-types has this method.
2994
+ *
2995
+ * @overload bincount([weight], minlength:nil)
2996
+ * @param [SFloat or DFloat or Array] weight (optional) Array of
2997
+ * float values. Its size along last axis should be same as that of self.
2998
+ * @param [Integer] minlength (keyword, optional) Minimum size along
2999
+ * last axis for the output array.
3000
+ * @return [UInt32 or UInt64 or SFloat or DFloat]
3001
+ * Returns Float NArray if weight array is supplied,
3002
+ * otherwise returns UInt32 or UInt64 depending on the size along last axis.
3003
+ * @example
3004
+ * Numo::Int32[0..4].bincount
3005
+ * # => Numo::UInt32#shape=[5]
3006
+ * # [1, 1, 1, 1, 1]
3007
+ *
3008
+ * Numo::Int32[0, 1, 1, 3, 2, 1, 7].bincount
3009
+ * # => Numo::UInt32#shape=[8]
3010
+ * # [1, 3, 1, 1, 0, 0, 0, 1]
3011
+ *
3012
+ * x = Numo::Int32[0, 1, 1, 3, 2, 1, 7, 23]
3013
+ * x.bincount.size == x.max+1
3014
+ * # => true
3015
+ *
3016
+ * w = Numo::DFloat[0.3, 0.5, 0.2, 0.7, 1.0, -0.6]
3017
+ * x = Numo::Int32[0, 1, 1, 2, 2, 2]
3018
+ * x.bincount(w)
3019
+ * # => Numo::DFloat#shape=[3]
3020
+ * # [0.3, 0.7, 1.1]
3021
+ */
4824
3022
  rb_define_method(cT, "bincount", int32_bincount, -1);
4825
3023
  /**
4826
3024
  * cumsum of self.