numo-narray-alt 0.9.11 → 0.9.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) 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/minus.h +125 -0
  64. data/ext/numo/narray/src/mh/op/add.h +78 -0
  65. data/ext/numo/narray/src/mh/op/binary_func.h +423 -0
  66. data/ext/numo/narray/src/mh/op/div.h +118 -0
  67. data/ext/numo/narray/src/mh/op/mod.h +108 -0
  68. data/ext/numo/narray/src/mh/op/mul.h +78 -0
  69. data/ext/numo/narray/src/mh/op/sub.h +78 -0
  70. data/ext/numo/narray/src/mh/pow.h +197 -0
  71. data/ext/numo/narray/src/mh/rand.h +2 -2
  72. data/ext/numo/narray/src/mh/rand_norm.h +125 -0
  73. data/ext/numo/narray/src/mh/reciprocal.h +125 -0
  74. data/ext/numo/narray/src/mh/round/ceil.h +11 -0
  75. data/ext/numo/narray/src/mh/round/floor.h +11 -0
  76. data/ext/numo/narray/src/mh/round/rint.h +9 -0
  77. data/ext/numo/narray/src/mh/round/round.h +11 -0
  78. data/ext/numo/narray/src/mh/round/trunc.h +11 -0
  79. data/ext/numo/narray/src/mh/round/unary_func.h +127 -0
  80. data/ext/numo/narray/src/mh/sign.h +125 -0
  81. data/ext/numo/narray/src/mh/square.h +125 -0
  82. data/ext/numo/narray/src/mh/to_a.h +78 -0
  83. data/ext/numo/narray/src/t_bit.c +45 -234
  84. data/ext/numo/narray/src/t_dcomplex.c +457 -2075
  85. data/ext/numo/narray/src/t_dfloat.c +154 -2560
  86. data/ext/numo/narray/src/t_int16.c +408 -2542
  87. data/ext/numo/narray/src/t_int32.c +408 -2542
  88. data/ext/numo/narray/src/t_int64.c +408 -2542
  89. data/ext/numo/narray/src/t_int8.c +409 -2138
  90. data/ext/numo/narray/src/t_robject.c +376 -2161
  91. data/ext/numo/narray/src/t_scomplex.c +435 -2053
  92. data/ext/numo/narray/src/t_sfloat.c +149 -2557
  93. data/ext/numo/narray/src/t_uint16.c +407 -2537
  94. data/ext/numo/narray/src/t_uint32.c +407 -2537
  95. data/ext/numo/narray/src/t_uint64.c +407 -2537
  96. data/ext/numo/narray/src/t_uint8.c +407 -2132
  97. metadata +47 -2
@@ -43,6 +43,35 @@ 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/pow.h"
59
+ #include "mh/minus.h"
60
+ #include "mh/reciprocal.h"
61
+ #include "mh/sign.h"
62
+ #include "mh/square.h"
63
+ #include "mh/comp/eq.h"
64
+ #include "mh/comp/ne.h"
65
+ #include "mh/comp/gt.h"
66
+ #include "mh/comp/ge.h"
67
+ #include "mh/comp/lt.h"
68
+ #include "mh/comp/le.h"
69
+ #include "mh/bit/and.h"
70
+ #include "mh/bit/or.h"
71
+ #include "mh/bit/xor.h"
72
+ #include "mh/bit/not.h"
73
+ #include "mh/bit/left_shift.h"
74
+ #include "mh/bit/right_shift.h"
46
75
  #include "mh/clip.h"
47
76
  #include "mh/sum.h"
48
77
  #include "mh/prod.h"
@@ -56,6 +85,7 @@ extern VALUE cRT;
56
85
  #include "mh/maximum.h"
57
86
  #include "mh/minimum.h"
58
87
  #include "mh/minmax.h"
88
+ #include "mh/bincount.h"
59
89
  #include "mh/cumsum.h"
60
90
  #include "mh/cumprod.h"
61
91
  #include "mh/mulsum.h"
@@ -70,6 +100,35 @@ extern VALUE cRT;
70
100
 
71
101
  typedef int32_t int32; // Type aliases for shorter notation
72
102
  // following the codebase naming convention.
103
+ DEF_NARRAY_COERCE_CAST_METHOD_FUNC(int32)
104
+ DEF_NARRAY_TO_A_METHOD_FUNC(int32)
105
+ DEF_NARRAY_FILL_METHOD_FUNC(int32)
106
+ DEF_NARRAY_FORMAT_METHOD_FUNC(int32)
107
+ DEF_NARRAY_FORMAT_TO_A_METHOD_FUNC(int32)
108
+ DEF_NARRAY_INSPECT_METHOD_FUNC(int32)
109
+ DEF_NARRAY_ADD_METHOD_FUNC(int32, numo_cInt32)
110
+ DEF_NARRAY_SUB_METHOD_FUNC(int32, numo_cInt32)
111
+ DEF_NARRAY_MUL_METHOD_FUNC(int32, numo_cInt32)
112
+ DEF_NARRAY_INT_DIV_METHOD_FUNC(int32, numo_cInt32)
113
+ DEF_NARRAY_INT_MOD_METHOD_FUNC(int32, numo_cInt32)
114
+ DEF_NARRAY_INT_DIVMOD_METHOD_FUNC(int32, numo_cInt32)
115
+ DEF_NARRAY_POW_METHOD_FUNC(int32, numo_cInt32)
116
+ DEF_NARRAY_MINUS_METHOD_FUNC(int32, numo_cInt32)
117
+ DEF_NARRAY_RECIPROCAL_METHOD_FUNC(int32, numo_cInt32)
118
+ DEF_NARRAY_SIGN_METHOD_FUNC(int32, numo_cInt32)
119
+ DEF_NARRAY_SQUARE_METHOD_FUNC(int32, numo_cInt32)
120
+ DEF_NARRAY_EQ_METHOD_FUNC(int32, numo_cInt32)
121
+ DEF_NARRAY_NE_METHOD_FUNC(int32, numo_cInt32)
122
+ DEF_NARRAY_GT_METHOD_FUNC(int32, numo_cInt32)
123
+ DEF_NARRAY_GE_METHOD_FUNC(int32, numo_cInt32)
124
+ DEF_NARRAY_LT_METHOD_FUNC(int32, numo_cInt32)
125
+ DEF_NARRAY_LE_METHOD_FUNC(int32, numo_cInt32)
126
+ DEF_NARRAY_INT_BIT_AND_METHOD_FUNC(int32, numo_cInt32)
127
+ DEF_NARRAY_INT_BIT_OR_METHOD_FUNC(int32, numo_cInt32)
128
+ DEF_NARRAY_INT_BIT_XOR_METHOD_FUNC(int32, numo_cInt32)
129
+ DEF_NARRAY_INT_BIT_NOT_METHOD_FUNC(int32, numo_cInt32)
130
+ DEF_NARRAY_INT_LEFT_SHIFT_METHOD_FUNC(int32, numo_cInt32)
131
+ DEF_NARRAY_INT_RIGHT_SHIFT_METHOD_FUNC(int32, numo_cInt32)
73
132
  DEF_NARRAY_CLIP_METHOD_FUNC(int32, numo_cInt32)
74
133
  DEF_NARRAY_INT_SUM_METHOD_FUNC(int32, numo_cInt32, int64_t, numo_cInt64)
75
134
  DEF_NARRAY_INT_PROD_METHOD_FUNC(int32, numo_cInt32, int64_t, numo_cInt64)
@@ -83,6 +142,7 @@ DEF_NARRAY_INT_ARGMIN_METHOD_FUNC(int32)
83
142
  DEF_NARRAY_INT_MAXIMUM_METHOD_FUNC(int32, numo_cInt32)
84
143
  DEF_NARRAY_INT_MINIMUM_METHOD_FUNC(int32, numo_cInt32)
85
144
  DEF_NARRAY_INT_MINMAX_METHOD_FUNC(int32, numo_cInt32)
145
+ DEF_NARRAY_INT_BINCOUNT_METHOD_FUNC(int32, numo_cInt32)
86
146
  DEF_NARRAY_INT_CUMSUM_METHOD_FUNC(int32, numo_cInt32)
87
147
  DEF_NARRAY_INT_CUMPROD_METHOD_FUNC(int32, numo_cInt32)
88
148
  DEF_NARRAY_INT_MULSUM_METHOD_FUNC(int32, numo_cInt32)
@@ -1253,204 +1313,6 @@ static VALUE int32_aset(int argc, VALUE* argv, VALUE self) {
1253
1313
  return argv[argc];
1254
1314
  }
1255
1315
 
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
1316
  static void iter_int32_each(na_loop_t* const lp) {
1455
1317
  size_t i, s1;
1456
1318
  char* p1;
@@ -1588,2388 +1450,195 @@ static void iter_int32_each_with_index(na_loop_t* const lp) {
1588
1450
  int nd, md;
1589
1451
 
1590
1452
  c = (size_t*)(lp->opt_ptr);
1591
- nd = lp->ndim;
1592
- if (nd > 0) {
1593
- nd--;
1594
- }
1595
- md = nd + 2;
1596
- a = ALLOCA_N(VALUE, md);
1597
-
1598
- INIT_COUNTER(lp, i);
1599
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1600
- c[nd] = 0;
1601
- if (idx1) {
1602
- for (; i--;) {
1603
- GET_DATA_INDEX(p1, idx1, dtype, x);
1604
- yield_each_with_index(x, c, a, nd, md);
1605
- c[nd]++;
1606
- }
1607
- } else {
1608
- for (; i--;) {
1609
- GET_DATA_STRIDE(p1, s1, dtype, x);
1610
- yield_each_with_index(x, c, a, nd, md);
1611
- c[nd]++;
1612
- }
1613
- }
1614
- }
1615
-
1616
- /*
1617
- Invokes the given block once for each element of self,
1618
- passing that element and indices along each axis as parameters.
1619
- @overload each_with_index
1620
- For a block `{|x,i,j,...| ... }`,
1621
- @yieldparam [Numeric] x an element
1622
- @yieldparam [Integer] i,j,... multitimensional indices
1623
- @return [Numo::NArray] self
1624
- @see #each
1625
- @see #map_with_index
1626
- */
1627
- static VALUE int32_each_with_index(VALUE self) {
1628
- ndfunc_arg_in_t ain[1] = { { Qnil, 0 } };
1629
- ndfunc_t ndf = { iter_int32_each_with_index, FULL_LOOP_NIP, 1, 0, ain, 0 };
1630
-
1631
- na_ndloop_with_index(&ndf, 1, self);
1632
- return self;
1633
- }
1634
-
1635
- static inline dtype yield_map_with_index(dtype x, size_t* c, VALUE* a, int nd, int md) {
1636
- int j;
1637
- VALUE y;
1638
-
1639
- a[0] = m_data_to_num(x);
1640
- for (j = 0; j <= nd; j++) {
1641
- a[j + 1] = SIZET2NUM(c[j]);
1642
- }
1643
- y = rb_yield(rb_ary_new4(md, a));
1644
- return m_num_to_data(y);
1645
- }
1646
-
1647
- static void iter_int32_map_with_index(na_loop_t* const lp) {
1648
- size_t i;
1649
- char *p1, *p2;
1650
- ssize_t s1, s2;
1651
- size_t *idx1, *idx2;
1652
- dtype x;
1653
- VALUE* a;
1654
- size_t* c;
1655
- int nd, md;
1656
-
1657
- c = (size_t*)(lp->opt_ptr);
1658
- nd = lp->ndim;
1659
- if (nd > 0) {
1660
- nd--;
1661
- }
1662
- md = nd + 2;
1663
- a = ALLOCA_N(VALUE, md);
1664
-
1665
- INIT_COUNTER(lp, i);
1666
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1667
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
1668
-
1669
- c[nd] = 0;
1670
- if (idx1) {
1671
- if (idx2) {
1672
- for (; i--;) {
1673
- GET_DATA_INDEX(p1, idx1, dtype, x);
1674
- x = yield_map_with_index(x, c, a, nd, md);
1675
- SET_DATA_INDEX(p2, idx2, dtype, x);
1676
- c[nd]++;
1677
- }
1678
- } else {
1679
- for (; i--;) {
1680
- GET_DATA_INDEX(p1, idx1, dtype, x);
1681
- x = yield_map_with_index(x, c, a, nd, md);
1682
- SET_DATA_STRIDE(p2, s2, dtype, x);
1683
- c[nd]++;
1684
- }
1685
- }
1686
- } else {
1687
- if (idx2) {
1688
- for (; i--;) {
1689
- GET_DATA_STRIDE(p1, s1, dtype, x);
1690
- x = yield_map_with_index(x, c, a, nd, md);
1691
- SET_DATA_INDEX(p2, idx2, dtype, x);
1692
- c[nd]++;
1693
- }
1694
- } else {
1695
- for (; i--;) {
1696
- GET_DATA_STRIDE(p1, s1, dtype, x);
1697
- x = yield_map_with_index(x, c, a, nd, md);
1698
- SET_DATA_STRIDE(p2, s2, dtype, x);
1699
- c[nd]++;
1700
- }
1701
- }
1702
- }
1703
- }
1704
-
1705
- /*
1706
- Invokes the given block once for each element of self,
1707
- passing that element and indices along each axis as parameters.
1708
- Creates a new NArray containing the values returned by the block.
1709
- Inplace option is allowed, i.e., `nary.inplace.map` overwrites `nary`.
1710
- @overload map_with_index
1711
- For a block `{|x,i,j,...| ... }`,
1712
- @yieldparam [Numeric] x an element
1713
- @yieldparam [Integer] i,j,... multitimensional indices
1714
- @return [Numo::NArray] mapped array
1715
- @see #map
1716
- @see #each_with_index
1717
- */
1718
- static VALUE int32_map_with_index(VALUE self) {
1719
- ndfunc_arg_in_t ain[1] = { { Qnil, 0 } };
1720
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1721
- ndfunc_t ndf = { iter_int32_map_with_index, FULL_LOOP, 1, 1, ain, aout };
1722
-
1723
- return na_ndloop_with_index(&ndf, 1, self);
1724
- }
1725
-
1726
- static void iter_int32_abs(na_loop_t* const lp) {
1727
- size_t i;
1728
- char *p1, *p2;
1729
- ssize_t s1, s2;
1730
- size_t *idx1, *idx2;
1731
- dtype x;
1732
- rtype y;
1733
- INIT_COUNTER(lp, i);
1734
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1735
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
1736
- if (idx1) {
1737
- if (idx2) {
1738
- for (; i--;) {
1739
- GET_DATA_INDEX(p1, idx1, dtype, x);
1740
- y = m_abs(x);
1741
- SET_DATA_INDEX(p2, idx2, rtype, y);
1742
- }
1743
- } else {
1744
- for (; i--;) {
1745
- GET_DATA_INDEX(p1, idx1, dtype, x);
1746
- y = m_abs(x);
1747
- SET_DATA_STRIDE(p2, s2, rtype, y);
1748
- }
1749
- }
1750
- } else {
1751
- if (idx2) {
1752
- for (; i--;) {
1753
- GET_DATA_STRIDE(p1, s1, dtype, x);
1754
- y = m_abs(x);
1755
- SET_DATA_INDEX(p2, idx2, rtype, y);
1756
- }
1757
- } else {
1758
- for (; i--;) {
1759
- GET_DATA_STRIDE(p1, s1, dtype, x);
1760
- y = m_abs(x);
1761
- SET_DATA_STRIDE(p2, s2, rtype, y);
1762
- }
1763
- }
1764
- }
1765
- }
1766
-
1767
- /*
1768
- abs of self.
1769
- @overload abs
1770
- @return [Numo::Int32] abs of self.
1771
- */
1772
- static VALUE int32_abs(VALUE self) {
1773
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
1774
- ndfunc_arg_out_t aout[1] = { { cRT, 0 } };
1775
- ndfunc_t ndf = { iter_int32_abs, FULL_LOOP, 1, 1, ain, aout };
1776
-
1777
- return na_ndloop(&ndf, 1, self);
1778
- }
1779
-
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;
1786
- char *p1, *p2, *p3;
1787
- ssize_t s1, s2, s3;
1788
-
1789
- INIT_COUNTER(lp, n);
1790
- INIT_PTR(lp, 0, p1, s1);
1791
- INIT_PTR(lp, 1, p2, s2);
1792
- 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;
1861
- GET_DATA_STRIDE(p1, s1, dtype, x);
1862
- 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);
1866
- }
1867
- //
1868
- }
1869
- #undef check_intdivzero
1870
-
1871
- static VALUE int32_add_self(VALUE self, VALUE other) {
1872
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
1873
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1874
- ndfunc_t ndf = { iter_int32_add, STRIDE_LOOP, 2, 1, ain, aout };
1875
-
1876
- return na_ndloop(&ndf, 2, self, other);
1877
- }
1878
-
1879
- /*
1880
- Binary add.
1881
- @overload + other
1882
- @param [Numo::NArray,Numeric] other
1883
- @return [Numo::NArray] self + other
1884
- */
1885
- static VALUE int32_add(VALUE self, VALUE other) {
1886
-
1887
- VALUE klass, v;
1888
-
1889
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
1890
- if (klass == cT) {
1891
- return int32_add_self(self, other);
1892
- } else {
1893
- v = rb_funcall(klass, id_cast, 1, self);
1894
- return rb_funcall(v, '+', 1, other);
1895
- }
1896
- }
1897
-
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;
1906
-
1907
- 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))) {
1915
-
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
- }
1927
- }
1928
- return;
1929
- }
1930
-
1931
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
1932
- is_aligned_step(s3, sizeof(dtype))) {
1933
- //
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 {
1948
- for (i = 0; i < n; i++) {
1949
- *(dtype*)p3 = m_sub(*(dtype*)p1, *(dtype*)p2);
1950
- p1 += s1;
1951
- p3 += s3;
1952
- }
1953
- }
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 {
1963
- for (i = 0; i < n; i++) {
1964
- check_intdivzero(*(dtype*)p2);
1965
- *(dtype*)p3 = m_sub(*(dtype*)p1, *(dtype*)p2);
1966
- p1 += s1;
1967
- p2 += s2;
1968
- p3 += s3;
1969
- }
1970
- }
1971
- }
1972
-
1973
- return;
1974
- //
1975
- }
1976
- }
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
- }
1987
- #undef check_intdivzero
1988
-
1989
- static VALUE int32_sub_self(VALUE self, VALUE other) {
1990
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
1991
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1992
- ndfunc_t ndf = { iter_int32_sub, STRIDE_LOOP, 2, 1, ain, aout };
1993
-
1994
- return na_ndloop(&ndf, 2, self, other);
1995
- }
1996
-
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;
2024
-
2025
- 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))) {
2033
-
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
- }
2045
- }
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
- }
2089
- }
2090
-
2091
- return;
2092
- //
2093
- }
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
- } 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
- }
2166
- }
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))) {
2172
- //
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 {
2187
- for (i = 0; i < n; i++) {
2188
- *(dtype*)p3 = m_div(*(dtype*)p1, *(dtype*)p2);
2189
- p1 += s1;
2190
- p3 += s3;
2191
- }
2192
- }
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 {
2202
- for (i = 0; i < n; i++) {
2203
- check_intdivzero(*(dtype*)p2);
2204
- *(dtype*)p3 = m_div(*(dtype*)p1, *(dtype*)p2);
2205
- p1 += s1;
2206
- p2 += s2;
2207
- p3 += s3;
2208
- }
2209
- }
2210
- }
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
- }
2331
- }
2332
-
2333
- return;
2334
- //
2335
- }
2336
- }
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
- }
2406
-
2407
- /*
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.
2634
- */
2635
- 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
- };
3778
-
3779
- return na_ndloop(&ndf, 1, self);
3780
- }
3781
-
3782
- static void iter_int32_bincount_64(na_loop_t* const lp) {
3783
- size_t i, x, n;
3784
- char *p1, *p2;
3785
- ssize_t s1, s2;
3786
- size_t* idx1;
3787
-
3788
- 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;
1453
+ nd = lp->ndim;
1454
+ if (nd > 0) {
1455
+ nd--;
3796
1456
  }
1457
+ md = nd + 2;
1458
+ a = ALLOCA_N(VALUE, md);
3797
1459
 
1460
+ INIT_COUNTER(lp, i);
1461
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1462
+ c[nd] = 0;
3798
1463
  if (idx1) {
3799
1464
  for (; i--;) {
3800
1465
  GET_DATA_INDEX(p1, idx1, dtype, x);
3801
- (*(u_int64_t*)(p2 + s2 * x))++;
1466
+ yield_each_with_index(x, c, a, nd, md);
1467
+ c[nd]++;
3802
1468
  }
3803
1469
  } else {
3804
1470
  for (; i--;) {
3805
1471
  GET_DATA_STRIDE(p1, s1, dtype, x);
3806
- (*(u_int64_t*)(p2 + s2 * x))++;
1472
+ yield_each_with_index(x, c, a, nd, md);
1473
+ c[nd]++;
3807
1474
  }
3808
1475
  }
3809
1476
  }
3810
1477
 
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
- };
1478
+ /*
1479
+ Invokes the given block once for each element of self,
1480
+ passing that element and indices along each axis as parameters.
1481
+ @overload each_with_index
1482
+ For a block `{|x,i,j,...| ... }`,
1483
+ @yieldparam [Numeric] x an element
1484
+ @yieldparam [Integer] i,j,... multitimensional indices
1485
+ @return [Numo::NArray] self
1486
+ @see #each
1487
+ @see #map_with_index
1488
+ */
1489
+ static VALUE int32_each_with_index(VALUE self) {
1490
+ ndfunc_arg_in_t ain[1] = { { Qnil, 0 } };
1491
+ ndfunc_t ndf = { iter_int32_each_with_index, FULL_LOOP_NIP, 1, 0, ain, 0 };
3818
1492
 
3819
- return na_ndloop(&ndf, 1, self);
1493
+ na_ndloop_with_index(&ndf, 1, self);
1494
+ return self;
3820
1495
  }
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
1496
 
3838
- if (i != m) {
3839
- rb_raise(nary_eShapeError, "size mismatch along last axis between self and weight");
3840
- }
1497
+ static inline dtype yield_map_with_index(dtype x, size_t* c, VALUE* a, int nd, int md) {
1498
+ int j;
1499
+ VALUE y;
3841
1500
 
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;
1501
+ a[0] = m_data_to_num(x);
1502
+ for (j = 0; j <= nd; j++) {
1503
+ a[j + 1] = SIZET2NUM(c[j]);
3850
1504
  }
1505
+ y = rb_yield(rb_ary_new4(md, a));
1506
+ return m_num_to_data(y);
3851
1507
  }
3852
1508
 
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
- }
1509
+ static void iter_int32_map_with_index(na_loop_t* const lp) {
1510
+ size_t i;
1511
+ char *p1, *p2;
1512
+ ssize_t s1, s2;
1513
+ size_t *idx1, *idx2;
1514
+ dtype x;
1515
+ VALUE* a;
1516
+ size_t* c;
1517
+ int nd, md;
3878
1518
 
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;
1519
+ c = (size_t*)(lp->opt_ptr);
1520
+ nd = lp->ndim;
1521
+ if (nd > 0) {
1522
+ nd--;
3887
1523
  }
3888
- }
1524
+ md = nd + 2;
1525
+ a = ALLOCA_N(VALUE, md);
3889
1526
 
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 };
1527
+ INIT_COUNTER(lp, i);
1528
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1529
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
3895
1530
 
3896
- return na_ndloop(&ndf, 2, self, weight);
1531
+ c[nd] = 0;
1532
+ if (idx1) {
1533
+ if (idx2) {
1534
+ for (; i--;) {
1535
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1536
+ x = yield_map_with_index(x, c, a, nd, md);
1537
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1538
+ c[nd]++;
1539
+ }
1540
+ } else {
1541
+ for (; i--;) {
1542
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1543
+ x = yield_map_with_index(x, c, a, nd, md);
1544
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1545
+ c[nd]++;
1546
+ }
1547
+ }
1548
+ } else {
1549
+ if (idx2) {
1550
+ for (; i--;) {
1551
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1552
+ x = yield_map_with_index(x, c, a, nd, md);
1553
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1554
+ c[nd]++;
1555
+ }
1556
+ } else {
1557
+ for (; i--;) {
1558
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1559
+ x = yield_map_with_index(x, c, a, nd, md);
1560
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1561
+ c[nd]++;
1562
+ }
1563
+ }
1564
+ }
3897
1565
  }
3898
- // ------- end of Float count with weights -------
3899
1566
 
3900
1567
  /*
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
-
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
-
1568
+ Invokes the given block once for each element of self,
1569
+ passing that element and indices along each axis as parameters.
1570
+ Creates a new NArray containing the values returned by the block.
1571
+ Inplace option is allowed, i.e., `nary.inplace.map` overwrites `nary`.
1572
+ @overload map_with_index
1573
+ For a block `{|x,i,j,...| ... }`,
1574
+ @yieldparam [Numeric] x an element
1575
+ @yieldparam [Integer] i,j,... multitimensional indices
1576
+ @return [Numo::NArray] mapped array
1577
+ @see #map
1578
+ @see #each_with_index
3931
1579
  */
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;
1580
+ static VALUE int32_map_with_index(VALUE self) {
1581
+ ndfunc_arg_in_t ain[1] = { { Qnil, 0 } };
1582
+ ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1583
+ ndfunc_t ndf = { iter_int32_map_with_index, FULL_LOOP, 1, 1, ain, aout };
3949
1584
 
3950
- if (opts[0] != Qundef) {
3951
- minlength = NUM2SIZET(opts[0]);
3952
- if (minlength > length) {
3953
- length = minlength;
3954
- }
3955
- }
1585
+ return na_ndloop_with_index(&ndf, 1, self);
1586
+ }
3956
1587
 
3957
- if (NIL_P(weight)) {
3958
- if (length > 4294967295ul) {
3959
- return int32_bincount_64(self, length);
1588
+ static void iter_int32_abs(na_loop_t* const lp) {
1589
+ size_t i;
1590
+ char *p1, *p2;
1591
+ ssize_t s1, s2;
1592
+ size_t *idx1, *idx2;
1593
+ dtype x;
1594
+ rtype y;
1595
+ INIT_COUNTER(lp, i);
1596
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1597
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
1598
+ if (idx1) {
1599
+ if (idx2) {
1600
+ for (; i--;) {
1601
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1602
+ y = m_abs(x);
1603
+ SET_DATA_INDEX(p2, idx2, rtype, y);
1604
+ }
3960
1605
  } else {
3961
- return int32_bincount_32(self, length);
1606
+ for (; i--;) {
1607
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1608
+ y = m_abs(x);
1609
+ SET_DATA_STRIDE(p2, s2, rtype, y);
1610
+ }
3962
1611
  }
3963
1612
  } else {
3964
- wclass = rb_obj_class(weight);
3965
- if (wclass == numo_cSFloat) {
3966
- return int32_bincount_sf(self, weight, length);
1613
+ if (idx2) {
1614
+ for (; i--;) {
1615
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1616
+ y = m_abs(x);
1617
+ SET_DATA_INDEX(p2, idx2, rtype, y);
1618
+ }
3967
1619
  } else {
3968
- return int32_bincount_df(self, weight, length);
1620
+ for (; i--;) {
1621
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1622
+ y = m_abs(x);
1623
+ SET_DATA_STRIDE(p2, s2, rtype, y);
1624
+ }
3969
1625
  }
3970
1626
  }
3971
1627
  }
3972
1628
 
1629
+ /*
1630
+ abs of self.
1631
+ @overload abs
1632
+ @return [Numo::Int32] abs of self.
1633
+ */
1634
+ static VALUE int32_abs(VALUE self) {
1635
+ ndfunc_arg_in_t ain[1] = { { cT, 0 } };
1636
+ ndfunc_arg_out_t aout[1] = { { cRT, 0 } };
1637
+ ndfunc_t ndf = { iter_int32_abs, FULL_LOOP, 1, 1, ain, aout };
1638
+
1639
+ return na_ndloop(&ndf, 1, self);
1640
+ }
1641
+
3973
1642
  static void iter_int32_poly(na_loop_t* const lp) {
3974
1643
  size_t i;
3975
1644
  dtype x, y, a;
@@ -4593,50 +2262,216 @@ void Init_numo_int32(void) {
4593
2262
  rb_define_singleton_method(cT, "cast", int32_s_cast, 1);
4594
2263
  rb_define_method(cT, "[]", int32_aref, -1);
4595
2264
  rb_define_method(cT, "[]=", int32_aset, -1);
2265
+ /**
2266
+ * return NArray with cast to the type of self.
2267
+ * @overload coerce_cast(type)
2268
+ * @return [nil]
2269
+ */
4596
2270
  rb_define_method(cT, "coerce_cast", int32_coerce_cast, 1);
2271
+ /**
2272
+ * Convert self to Array.
2273
+ * @overload to_a
2274
+ * @return [Array]
2275
+ */
4597
2276
  rb_define_method(cT, "to_a", int32_to_a, 0);
2277
+ /**
2278
+ * Fill elements with other.
2279
+ * @overload fill other
2280
+ * @param [Numeric] other
2281
+ * @return [Numo::Int32] self.
2282
+ */
4598
2283
  rb_define_method(cT, "fill", int32_fill, 1);
2284
+ /**
2285
+ * Format elements into strings.
2286
+ * @overload format format
2287
+ * @param [String] format
2288
+ * @return [Numo::RObject] array of formatted strings.
2289
+ */
4599
2290
  rb_define_method(cT, "format", int32_format, -1);
2291
+ /**
2292
+ * Format elements into strings.
2293
+ * @overload format_to_a format
2294
+ * @param [String] format
2295
+ * @return [Array] array of formatted strings.
2296
+ */
4600
2297
  rb_define_method(cT, "format_to_a", int32_format_to_a, -1);
2298
+ /**
2299
+ * Returns a string containing a human-readable representation of NArray.
2300
+ * @overload inspect
2301
+ * @return [String]
2302
+ */
4601
2303
  rb_define_method(cT, "inspect", int32_inspect, 0);
4602
2304
  rb_define_method(cT, "each", int32_each, 0);
4603
2305
  rb_define_method(cT, "map", int32_map, 0);
4604
2306
  rb_define_method(cT, "each_with_index", int32_each_with_index, 0);
4605
2307
  rb_define_method(cT, "map_with_index", int32_map_with_index, 0);
4606
2308
  rb_define_method(cT, "abs", int32_abs, 0);
2309
+ /**
2310
+ * Binary add.
2311
+ * @overload + other
2312
+ * @param [Numo::NArray,Numeric] other
2313
+ * @return [Numo::NArray] self + other
2314
+ */
4607
2315
  rb_define_method(cT, "+", int32_add, 1);
2316
+ /**
2317
+ * Binary sub.
2318
+ * @overload - other
2319
+ * @param [Numo::NArray,Numeric] other
2320
+ * @return [Numo::NArray] self - other
2321
+ */
4608
2322
  rb_define_method(cT, "-", int32_sub, 1);
2323
+ /**
2324
+ * Binary mul.
2325
+ * @overload * other
2326
+ * @param [Numo::NArray,Numeric] other
2327
+ * @return [Numo::NArray] self * other
2328
+ */
4609
2329
  rb_define_method(cT, "*", int32_mul, 1);
2330
+ /**
2331
+ * Binary div.
2332
+ * @overload / other
2333
+ * @param [Numo::NArray,Numeric] other
2334
+ * @return [Numo::NArray] self / other
2335
+ */
4610
2336
  rb_define_method(cT, "/", int32_div, 1);
2337
+ /**
2338
+ * Binary mod.
2339
+ * @overload % other
2340
+ * @param [Numo::NArray,Numeric] other
2341
+ * @return [Numo::NArray] self % other
2342
+ */
4611
2343
  rb_define_method(cT, "%", int32_mod, 1);
2344
+ /**
2345
+ * Binary divmod.
2346
+ * @overload divmod other
2347
+ * @param [Numo::NArray,Numeric] other
2348
+ * @return [Numo::NArray] divmod of self and other.
2349
+ */
4612
2350
  rb_define_method(cT, "divmod", int32_divmod, 1);
2351
+ /**
2352
+ * Binary power.
2353
+ * @overload ** other
2354
+ * @param [Numo::NArray,Numeric] other
2355
+ * @return [Numo::NArray] self to the other-th power.
2356
+ */
4613
2357
  rb_define_method(cT, "**", int32_pow, 1);
4614
2358
  rb_define_alias(cT, "pow", "**");
2359
+ /**
2360
+ * Unary minus.
2361
+ * @overload -@
2362
+ * @return [Numo::Int32] minus of self.
2363
+ */
4615
2364
  rb_define_method(cT, "-@", int32_minus, 0);
2365
+ /**
2366
+ * Unary reciprocal.
2367
+ * @overload reciprocal
2368
+ * @return [Numo::Int32] reciprocal of self.
2369
+ */
4616
2370
  rb_define_method(cT, "reciprocal", int32_reciprocal, 0);
2371
+ /**
2372
+ * Unary sign.
2373
+ * @overload sign
2374
+ * @return [Numo::Int32] sign of self.
2375
+ */
4617
2376
  rb_define_method(cT, "sign", int32_sign, 0);
2377
+ /**
2378
+ * Unary square.
2379
+ * @overload square
2380
+ * @return [Numo::Int32] square of self.
2381
+ */
4618
2382
  rb_define_method(cT, "square", int32_square, 0);
4619
2383
  rb_define_alias(cT, "conj", "view");
4620
2384
  rb_define_alias(cT, "im", "view");
4621
2385
  rb_define_alias(cT, "conjugate", "conj");
2386
+ /**
2387
+ * Comparison eq other.
2388
+ * @overload eq other
2389
+ * @param [Numo::NArray,Numeric] other
2390
+ * @return [Numo::Bit] result of self eq other.
2391
+ */
4622
2392
  rb_define_method(cT, "eq", int32_eq, 1);
2393
+ /**
2394
+ * Comparison ne other.
2395
+ * @overload ne other
2396
+ * @param [Numo::NArray,Numeric] other
2397
+ * @return [Numo::Bit] result of self ne other.
2398
+ */
4623
2399
  rb_define_method(cT, "ne", int32_ne, 1);
4624
2400
  rb_define_alias(cT, "nearly_eq", "eq");
4625
2401
  rb_define_alias(cT, "close_to", "nearly_eq");
2402
+ /**
2403
+ * Binary bit_and.
2404
+ * @overload & other
2405
+ * @param [Numo::NArray,Numeric] other
2406
+ * @return [Numo::NArray] self & other
2407
+ */
4626
2408
  rb_define_method(cT, "&", int32_bit_and, 1);
2409
+ /**
2410
+ * Binary bit_or.
2411
+ * @overload | other
2412
+ * @param [Numo::NArray,Numeric] other
2413
+ * @return [Numo::NArray] self | other
2414
+ */
4627
2415
  rb_define_method(cT, "|", int32_bit_or, 1);
2416
+ /**
2417
+ * Binary bit_xor.
2418
+ * @overload ^ other
2419
+ * @param [Numo::NArray,Numeric] other
2420
+ * @return [Numo::NArray] self ^ other
2421
+ */
4628
2422
  rb_define_method(cT, "^", int32_bit_xor, 1);
2423
+ /**
2424
+ * Unary bit_not.
2425
+ * @overload ~
2426
+ * @return [Numo::Int32] bit_not of self.
2427
+ */
4629
2428
  rb_define_method(cT, "~", int32_bit_not, 0);
2429
+ /**
2430
+ * Binary left_shift.
2431
+ * @overload << other
2432
+ * @param [Numo::NArray,Numeric] other
2433
+ * @return [Numo::NArray] self << other
2434
+ */
4630
2435
  rb_define_method(cT, "<<", int32_left_shift, 1);
2436
+ /**
2437
+ * Binary right_shift.
2438
+ * @overload >> other
2439
+ * @param [Numo::NArray,Numeric] other
2440
+ * @return [Numo::NArray] self >> other
2441
+ */
4631
2442
  rb_define_method(cT, ">>", int32_right_shift, 1);
4632
2443
  rb_define_alias(cT, "floor", "view");
4633
2444
  rb_define_alias(cT, "round", "view");
4634
2445
  rb_define_alias(cT, "ceil", "view");
4635
2446
  rb_define_alias(cT, "trunc", "view");
4636
2447
  rb_define_alias(cT, "rint", "view");
2448
+ /**
2449
+ * Comparison gt other.
2450
+ * @overload gt other
2451
+ * @param [Numo::NArray,Numeric] other
2452
+ * @return [Numo::Bit] result of self gt other.
2453
+ */
4637
2454
  rb_define_method(cT, "gt", int32_gt, 1);
2455
+ /**
2456
+ * Comparison ge other.
2457
+ * @overload ge other
2458
+ * @param [Numo::NArray,Numeric] other
2459
+ * @return [Numo::Bit] result of self ge other.
2460
+ */
4638
2461
  rb_define_method(cT, "ge", int32_ge, 1);
2462
+ /**
2463
+ * Comparison lt other.
2464
+ * @overload lt other
2465
+ * @param [Numo::NArray,Numeric] other
2466
+ * @return [Numo::Bit] result of self lt other.
2467
+ */
4639
2468
  rb_define_method(cT, "lt", int32_lt, 1);
2469
+ /**
2470
+ * Comparison le other.
2471
+ * @overload le other
2472
+ * @param [Numo::NArray,Numeric] other
2473
+ * @return [Numo::Bit] result of self le other.
2474
+ */
4640
2475
  rb_define_method(cT, "le", int32_le, 1);
4641
2476
  rb_define_alias(cT, ">", "gt");
4642
2477
  rb_define_alias(cT, ">=", "ge");
@@ -4821,6 +2656,37 @@ void Init_numo_int32(void) {
4821
2656
  * @return [Numo::Int32]
4822
2657
  */
4823
2658
  rb_define_module_function(cT, "minimum", int32_s_minimum, -1);
2659
+ /**
2660
+ * Count the number of occurrences of each non-negative integer value.
2661
+ * Only Integer-types has this method.
2662
+ *
2663
+ * @overload bincount([weight], minlength:nil)
2664
+ * @param [SFloat or DFloat or Array] weight (optional) Array of
2665
+ * float values. Its size along last axis should be same as that of self.
2666
+ * @param [Integer] minlength (keyword, optional) Minimum size along
2667
+ * last axis for the output array.
2668
+ * @return [UInt32 or UInt64 or SFloat or DFloat]
2669
+ * Returns Float NArray if weight array is supplied,
2670
+ * otherwise returns UInt32 or UInt64 depending on the size along last axis.
2671
+ * @example
2672
+ * Numo::Int32[0..4].bincount
2673
+ * # => Numo::UInt32#shape=[5]
2674
+ * # [1, 1, 1, 1, 1]
2675
+ *
2676
+ * Numo::Int32[0, 1, 1, 3, 2, 1, 7].bincount
2677
+ * # => Numo::UInt32#shape=[8]
2678
+ * # [1, 3, 1, 1, 0, 0, 0, 1]
2679
+ *
2680
+ * x = Numo::Int32[0, 1, 1, 3, 2, 1, 7, 23]
2681
+ * x.bincount.size == x.max+1
2682
+ * # => true
2683
+ *
2684
+ * w = Numo::DFloat[0.3, 0.5, 0.2, 0.7, 1.0, -0.6]
2685
+ * x = Numo::Int32[0, 1, 1, 2, 2, 2]
2686
+ * x.bincount(w)
2687
+ * # => Numo::DFloat#shape=[3]
2688
+ * # [0.3, 0.7, 1.1]
2689
+ */
4824
2690
  rb_define_method(cT, "bincount", int32_bincount, -1);
4825
2691
  /**
4826
2692
  * cumsum of self.