numo-narray-alt 0.9.10 → 0.9.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/LICENSE +1 -1
  4. data/README.md +7 -0
  5. data/ext/numo/narray/numo/narray.h +2 -2
  6. data/ext/numo/narray/numo/types/robj_macro.h +1 -1
  7. data/ext/numo/narray/numo/types/robject.h +1 -1
  8. data/ext/numo/narray/src/mh/argmax.h +154 -0
  9. data/ext/numo/narray/src/mh/argmin.h +154 -0
  10. data/ext/numo/narray/src/mh/bincount.h +233 -0
  11. data/ext/numo/narray/src/mh/bit/and.h +225 -0
  12. data/ext/numo/narray/src/mh/bit/left_shift.h +225 -0
  13. data/ext/numo/narray/src/mh/bit/not.h +173 -0
  14. data/ext/numo/narray/src/mh/bit/or.h +225 -0
  15. data/ext/numo/narray/src/mh/bit/right_shift.h +225 -0
  16. data/ext/numo/narray/src/mh/bit/xor.h +225 -0
  17. data/ext/numo/narray/src/mh/clip.h +115 -0
  18. data/ext/numo/narray/src/mh/coerce_cast.h +9 -0
  19. data/ext/numo/narray/src/mh/comp/binary_func.h +37 -0
  20. data/ext/numo/narray/src/mh/comp/eq.h +26 -0
  21. data/ext/numo/narray/src/mh/comp/ge.h +26 -0
  22. data/ext/numo/narray/src/mh/comp/gt.h +26 -0
  23. data/ext/numo/narray/src/mh/comp/le.h +26 -0
  24. data/ext/numo/narray/src/mh/comp/lt.h +26 -0
  25. data/ext/numo/narray/src/mh/comp/ne.h +26 -0
  26. data/ext/numo/narray/src/mh/comp/nearly_eq.h +26 -0
  27. data/ext/numo/narray/src/mh/cumprod.h +98 -0
  28. data/ext/numo/narray/src/mh/cumsum.h +98 -0
  29. data/ext/numo/narray/src/mh/divmod.h +142 -0
  30. data/ext/numo/narray/src/mh/eye.h +82 -0
  31. data/ext/numo/narray/src/mh/fill.h +94 -0
  32. data/ext/numo/narray/src/mh/format.h +108 -0
  33. data/ext/numo/narray/src/mh/format_to_a.h +89 -0
  34. data/ext/numo/narray/src/mh/inspect.h +33 -0
  35. data/ext/numo/narray/src/mh/isfinite.h +42 -0
  36. data/ext/numo/narray/src/mh/isinf.h +42 -0
  37. data/ext/numo/narray/src/mh/isnan.h +42 -0
  38. data/ext/numo/narray/src/mh/isneginf.h +42 -0
  39. data/ext/numo/narray/src/mh/isposinf.h +42 -0
  40. data/ext/numo/narray/src/mh/logseq.h +69 -0
  41. data/ext/numo/narray/src/mh/math/acos.h +2 -2
  42. data/ext/numo/narray/src/mh/math/acosh.h +2 -2
  43. data/ext/numo/narray/src/mh/math/asin.h +2 -2
  44. data/ext/numo/narray/src/mh/math/asinh.h +2 -2
  45. data/ext/numo/narray/src/mh/math/atan.h +2 -2
  46. data/ext/numo/narray/src/mh/math/atan2.h +3 -3
  47. data/ext/numo/narray/src/mh/math/atanh.h +2 -2
  48. data/ext/numo/narray/src/mh/math/cbrt.h +2 -2
  49. data/ext/numo/narray/src/mh/math/cos.h +2 -2
  50. data/ext/numo/narray/src/mh/math/cosh.h +2 -2
  51. data/ext/numo/narray/src/mh/math/erf.h +2 -2
  52. data/ext/numo/narray/src/mh/math/erfc.h +2 -2
  53. data/ext/numo/narray/src/mh/math/exp.h +2 -2
  54. data/ext/numo/narray/src/mh/math/exp10.h +2 -2
  55. data/ext/numo/narray/src/mh/math/exp2.h +2 -2
  56. data/ext/numo/narray/src/mh/math/expm1.h +2 -2
  57. data/ext/numo/narray/src/mh/math/frexp.h +3 -3
  58. data/ext/numo/narray/src/mh/math/hypot.h +3 -3
  59. data/ext/numo/narray/src/mh/math/ldexp.h +3 -3
  60. data/ext/numo/narray/src/mh/math/log.h +2 -2
  61. data/ext/numo/narray/src/mh/math/log10.h +2 -2
  62. data/ext/numo/narray/src/mh/math/log1p.h +2 -2
  63. data/ext/numo/narray/src/mh/math/log2.h +2 -2
  64. data/ext/numo/narray/src/mh/math/sin.h +2 -2
  65. data/ext/numo/narray/src/mh/math/sinc.h +2 -2
  66. data/ext/numo/narray/src/mh/math/sinh.h +2 -2
  67. data/ext/numo/narray/src/mh/math/sqrt.h +8 -8
  68. data/ext/numo/narray/src/mh/math/tan.h +2 -2
  69. data/ext/numo/narray/src/mh/math/tanh.h +2 -2
  70. data/ext/numo/narray/src/mh/math/unary_func.h +3 -3
  71. data/ext/numo/narray/src/mh/max.h +69 -0
  72. data/ext/numo/narray/src/mh/max_index.h +184 -0
  73. data/ext/numo/narray/src/mh/maximum.h +116 -0
  74. data/ext/numo/narray/src/mh/min.h +69 -0
  75. data/ext/numo/narray/src/mh/min_index.h +184 -0
  76. data/ext/numo/narray/src/mh/minimum.h +116 -0
  77. data/ext/numo/narray/src/mh/minmax.h +77 -0
  78. data/ext/numo/narray/src/mh/mulsum.h +185 -0
  79. data/ext/numo/narray/src/mh/op/add.h +78 -0
  80. data/ext/numo/narray/src/mh/op/binary_func.h +423 -0
  81. data/ext/numo/narray/src/mh/op/div.h +118 -0
  82. data/ext/numo/narray/src/mh/op/mod.h +108 -0
  83. data/ext/numo/narray/src/mh/op/mul.h +78 -0
  84. data/ext/numo/narray/src/mh/op/sub.h +78 -0
  85. data/ext/numo/narray/src/mh/prod.h +69 -0
  86. data/ext/numo/narray/src/mh/ptp.h +69 -0
  87. data/ext/numo/narray/src/mh/rand.h +315 -0
  88. data/ext/numo/narray/src/mh/round/ceil.h +11 -0
  89. data/ext/numo/narray/src/mh/round/floor.h +11 -0
  90. data/ext/numo/narray/src/mh/round/rint.h +9 -0
  91. data/ext/numo/narray/src/mh/round/round.h +11 -0
  92. data/ext/numo/narray/src/mh/round/trunc.h +11 -0
  93. data/ext/numo/narray/src/mh/round/unary_func.h +127 -0
  94. data/ext/numo/narray/src/mh/seq.h +130 -0
  95. data/ext/numo/narray/src/mh/sum.h +69 -0
  96. data/ext/numo/narray/src/mh/to_a.h +78 -0
  97. data/ext/numo/narray/src/t_bit.c +45 -234
  98. data/ext/numo/narray/src/t_dcomplex.c +608 -2369
  99. data/ext/numo/narray/src/t_dfloat.c +485 -3736
  100. data/ext/numo/narray/src/t_int16.c +743 -3444
  101. data/ext/numo/narray/src/t_int32.c +745 -3445
  102. data/ext/numo/narray/src/t_int64.c +743 -3446
  103. data/ext/numo/narray/src/t_int8.c +678 -3040
  104. data/ext/numo/narray/src/t_robject.c +771 -3548
  105. data/ext/numo/narray/src/t_scomplex.c +607 -2368
  106. data/ext/numo/narray/src/t_sfloat.c +440 -3693
  107. data/ext/numo/narray/src/t_uint16.c +743 -3440
  108. data/ext/numo/narray/src/t_uint32.c +743 -3440
  109. data/ext/numo/narray/src/t_uint64.c +743 -3442
  110. data/ext/numo/narray/src/t_uint8.c +678 -3038
  111. data/lib/numo/narray.rb +2 -3
  112. metadata +62 -3
@@ -43,6 +43,51 @@ static ID id_to_a;
43
43
  VALUE cT;
44
44
  extern VALUE cRT;
45
45
 
46
+ #include "mh/coerce_cast.h"
47
+ #include "mh/to_a.h"
48
+ #include "mh/fill.h"
49
+ #include "mh/format.h"
50
+ #include "mh/format_to_a.h"
51
+ #include "mh/inspect.h"
52
+ #include "mh/op/add.h"
53
+ #include "mh/op/sub.h"
54
+ #include "mh/op/mul.h"
55
+ #include "mh/op/div.h"
56
+ #include "mh/op/mod.h"
57
+ #include "mh/divmod.h"
58
+ #include "mh/comp/eq.h"
59
+ #include "mh/comp/ne.h"
60
+ #include "mh/comp/gt.h"
61
+ #include "mh/comp/ge.h"
62
+ #include "mh/comp/lt.h"
63
+ #include "mh/comp/le.h"
64
+ #include "mh/bit/and.h"
65
+ #include "mh/bit/or.h"
66
+ #include "mh/bit/xor.h"
67
+ #include "mh/bit/not.h"
68
+ #include "mh/bit/left_shift.h"
69
+ #include "mh/bit/right_shift.h"
70
+ #include "mh/clip.h"
71
+ #include "mh/sum.h"
72
+ #include "mh/prod.h"
73
+ #include "mh/min.h"
74
+ #include "mh/max.h"
75
+ #include "mh/ptp.h"
76
+ #include "mh/max_index.h"
77
+ #include "mh/min_index.h"
78
+ #include "mh/argmax.h"
79
+ #include "mh/argmin.h"
80
+ #include "mh/maximum.h"
81
+ #include "mh/minimum.h"
82
+ #include "mh/minmax.h"
83
+ #include "mh/bincount.h"
84
+ #include "mh/cumsum.h"
85
+ #include "mh/cumprod.h"
86
+ #include "mh/mulsum.h"
87
+ #include "mh/seq.h"
88
+ #include "mh/eye.h"
89
+ #include "mh/rand.h"
90
+ #include "mh/cumprod.h"
46
91
  #include "mh/mean.h"
47
92
  #include "mh/var.h"
48
93
  #include "mh/stddev.h"
@@ -50,6 +95,50 @@ extern VALUE cRT;
50
95
 
51
96
  typedef int32_t int32; // Type aliases for shorter notation
52
97
  // following the codebase naming convention.
98
+ DEF_NARRAY_COERCE_CAST_METHOD_FUNC(int32)
99
+ DEF_NARRAY_TO_A_METHOD_FUNC(int32)
100
+ DEF_NARRAY_FILL_METHOD_FUNC(int32)
101
+ DEF_NARRAY_FORMAT_METHOD_FUNC(int32)
102
+ DEF_NARRAY_FORMAT_TO_A_METHOD_FUNC(int32)
103
+ DEF_NARRAY_INSPECT_METHOD_FUNC(int32)
104
+ DEF_NARRAY_ADD_METHOD_FUNC(int32, numo_cInt32)
105
+ DEF_NARRAY_SUB_METHOD_FUNC(int32, numo_cInt32)
106
+ DEF_NARRAY_MUL_METHOD_FUNC(int32, numo_cInt32)
107
+ DEF_NARRAY_INT_DIV_METHOD_FUNC(int32, numo_cInt32)
108
+ DEF_NARRAY_INT_MOD_METHOD_FUNC(int32, numo_cInt32)
109
+ DEF_NARRAY_INT_DIVMOD_METHOD_FUNC(int32, numo_cInt32)
110
+ DEF_NARRAY_EQ_METHOD_FUNC(int32, numo_cInt32)
111
+ DEF_NARRAY_NE_METHOD_FUNC(int32, numo_cInt32)
112
+ DEF_NARRAY_GT_METHOD_FUNC(int32, numo_cInt32)
113
+ DEF_NARRAY_GE_METHOD_FUNC(int32, numo_cInt32)
114
+ DEF_NARRAY_LT_METHOD_FUNC(int32, numo_cInt32)
115
+ DEF_NARRAY_LE_METHOD_FUNC(int32, numo_cInt32)
116
+ DEF_NARRAY_INT_BIT_AND_METHOD_FUNC(int32, numo_cInt32)
117
+ DEF_NARRAY_INT_BIT_OR_METHOD_FUNC(int32, numo_cInt32)
118
+ DEF_NARRAY_INT_BIT_XOR_METHOD_FUNC(int32, numo_cInt32)
119
+ DEF_NARRAY_INT_BIT_NOT_METHOD_FUNC(int32, numo_cInt32)
120
+ DEF_NARRAY_INT_LEFT_SHIFT_METHOD_FUNC(int32, numo_cInt32)
121
+ DEF_NARRAY_INT_RIGHT_SHIFT_METHOD_FUNC(int32, numo_cInt32)
122
+ DEF_NARRAY_CLIP_METHOD_FUNC(int32, numo_cInt32)
123
+ DEF_NARRAY_INT_SUM_METHOD_FUNC(int32, numo_cInt32, int64_t, numo_cInt64)
124
+ DEF_NARRAY_INT_PROD_METHOD_FUNC(int32, numo_cInt32, int64_t, numo_cInt64)
125
+ DEF_NARRAY_INT_MIN_METHOD_FUNC(int32, numo_cInt32)
126
+ DEF_NARRAY_INT_MAX_METHOD_FUNC(int32, numo_cInt32)
127
+ DEF_NARRAY_INT_PTP_METHOD_FUNC(int32, numo_cInt32)
128
+ DEF_NARRAY_INT_MAX_INDEX_METHOD_FUNC(int32)
129
+ DEF_NARRAY_INT_MIN_INDEX_METHOD_FUNC(int32)
130
+ DEF_NARRAY_INT_ARGMAX_METHOD_FUNC(int32)
131
+ DEF_NARRAY_INT_ARGMIN_METHOD_FUNC(int32)
132
+ DEF_NARRAY_INT_MAXIMUM_METHOD_FUNC(int32, numo_cInt32)
133
+ DEF_NARRAY_INT_MINIMUM_METHOD_FUNC(int32, numo_cInt32)
134
+ DEF_NARRAY_INT_MINMAX_METHOD_FUNC(int32, numo_cInt32)
135
+ DEF_NARRAY_INT_BINCOUNT_METHOD_FUNC(int32, numo_cInt32)
136
+ DEF_NARRAY_INT_CUMSUM_METHOD_FUNC(int32, numo_cInt32)
137
+ DEF_NARRAY_INT_CUMPROD_METHOD_FUNC(int32, numo_cInt32)
138
+ DEF_NARRAY_INT_MULSUM_METHOD_FUNC(int32, numo_cInt32)
139
+ DEF_NARRAY_INT_SEQ_METHOD_FUNC(int32)
140
+ DEF_NARRAY_EYE_METHOD_FUNC(int32)
141
+ DEF_NARRAY_INT_RAND_METHOD_FUNC(int32)
53
142
  DEF_NARRAY_INT_MEAN_METHOD_FUNC(int32, numo_cInt32)
54
143
  DEF_NARRAY_INT_VAR_METHOD_FUNC(int32, numo_cInt32)
55
144
  DEF_NARRAY_INT_STDDEV_METHOD_FUNC(int32, numo_cInt32)
@@ -1214,204 +1303,6 @@ static VALUE int32_aset(int argc, VALUE* argv, VALUE self) {
1214
1303
  return argv[argc];
1215
1304
  }
1216
1305
 
1217
- /*
1218
- return NArray with cast to the type of self.
1219
- @overload coerce_cast(type)
1220
- @return [nil]
1221
- */
1222
- static VALUE int32_coerce_cast(VALUE self, VALUE type) {
1223
- return Qnil;
1224
- }
1225
-
1226
- static void iter_int32_to_a(na_loop_t* const lp) {
1227
- size_t i, s1;
1228
- char* p1;
1229
- size_t* idx1;
1230
- dtype x;
1231
- volatile VALUE a, y;
1232
-
1233
- INIT_COUNTER(lp, i);
1234
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1235
- a = rb_ary_new2(i);
1236
- rb_ary_push(lp->args[1].value, a);
1237
- if (idx1) {
1238
- for (; i--;) {
1239
- GET_DATA_INDEX(p1, idx1, dtype, x);
1240
- y = m_data_to_num(x);
1241
- rb_ary_push(a, y);
1242
- }
1243
- } else {
1244
- for (; i--;) {
1245
- GET_DATA_STRIDE(p1, s1, dtype, x);
1246
- y = m_data_to_num(x);
1247
- rb_ary_push(a, y);
1248
- }
1249
- }
1250
- }
1251
-
1252
- /*
1253
- Convert self to Array.
1254
- @overload to_a
1255
- @return [Array]
1256
- */
1257
- static VALUE int32_to_a(VALUE self) {
1258
- ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { sym_loop_opt }, { sym_option } };
1259
- ndfunc_arg_out_t aout[1] = { { rb_cArray, 0 } }; // dummy?
1260
- ndfunc_t ndf = { iter_int32_to_a, FULL_LOOP_NIP, 3, 1, ain, aout };
1261
- return na_ndloop_cast_narray_to_rarray(&ndf, self, Qnil);
1262
- }
1263
-
1264
- static void iter_int32_fill(na_loop_t* const lp) {
1265
- size_t i;
1266
- char* p1;
1267
- ssize_t s1;
1268
- size_t* idx1;
1269
- VALUE x = lp->option;
1270
- dtype y;
1271
- INIT_COUNTER(lp, i);
1272
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1273
- y = m_num_to_data(x);
1274
- if (idx1) {
1275
- for (; i--;) {
1276
- SET_DATA_INDEX(p1, idx1, dtype, y);
1277
- }
1278
- } else {
1279
- for (; i--;) {
1280
- SET_DATA_STRIDE(p1, s1, dtype, y);
1281
- }
1282
- }
1283
- }
1284
-
1285
- /*
1286
- Fill elements with other.
1287
- @overload fill other
1288
- @param [Numeric] other
1289
- @return [Numo::Int32] self.
1290
- */
1291
- static VALUE int32_fill(VALUE self, VALUE val) {
1292
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { sym_option } };
1293
- ndfunc_t ndf = { iter_int32_fill, FULL_LOOP, 2, 0, ain, 0 };
1294
-
1295
- na_ndloop(&ndf, 2, self, val);
1296
- return self;
1297
- }
1298
-
1299
- static VALUE format_int32(VALUE fmt, dtype* x) {
1300
- // fix-me
1301
- char s[48];
1302
- int n;
1303
-
1304
- if (NIL_P(fmt)) {
1305
- n = m_sprintf(s, *x);
1306
- return rb_str_new(s, n);
1307
- }
1308
- return rb_funcall(fmt, '%', 1, m_data_to_num(*x));
1309
- }
1310
-
1311
- static void iter_int32_format(na_loop_t* const lp) {
1312
- size_t i;
1313
- char *p1, *p2;
1314
- ssize_t s1, s2;
1315
- size_t* idx1;
1316
- dtype* x;
1317
- VALUE y;
1318
- VALUE fmt = lp->option;
1319
- INIT_COUNTER(lp, i);
1320
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1321
- INIT_PTR(lp, 1, p2, s2);
1322
- if (idx1) {
1323
- for (; i--;) {
1324
- x = (dtype*)(p1 + *idx1);
1325
- idx1++;
1326
- y = format_int32(fmt, x);
1327
- SET_DATA_STRIDE(p2, s2, VALUE, y);
1328
- }
1329
- } else {
1330
- for (; i--;) {
1331
- x = (dtype*)p1;
1332
- p1 += s1;
1333
- y = format_int32(fmt, x);
1334
- SET_DATA_STRIDE(p2, s2, VALUE, y);
1335
- }
1336
- }
1337
- }
1338
-
1339
- /*
1340
- Format elements into strings.
1341
- @overload format format
1342
- @param [String] format
1343
- @return [Numo::RObject] array of formatted strings.
1344
- */
1345
- static VALUE int32_format(int argc, VALUE* argv, VALUE self) {
1346
- VALUE fmt = Qnil;
1347
-
1348
- ndfunc_arg_in_t ain[2] = { { Qnil, 0 }, { sym_option } };
1349
- ndfunc_arg_out_t aout[1] = { { numo_cRObject, 0 } };
1350
- ndfunc_t ndf = { iter_int32_format, FULL_LOOP_NIP, 2, 1, ain, aout };
1351
-
1352
- rb_scan_args(argc, argv, "01", &fmt);
1353
- return na_ndloop(&ndf, 2, self, fmt);
1354
- }
1355
-
1356
- static void iter_int32_format_to_a(na_loop_t* const lp) {
1357
- size_t i;
1358
- char* p1;
1359
- ssize_t s1;
1360
- size_t* idx1;
1361
- dtype* x;
1362
- VALUE y;
1363
- volatile VALUE a;
1364
- VALUE fmt = lp->option;
1365
- INIT_COUNTER(lp, i);
1366
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1367
- a = rb_ary_new2(i);
1368
- rb_ary_push(lp->args[1].value, a);
1369
- if (idx1) {
1370
- for (; i--;) {
1371
- x = (dtype*)(p1 + *idx1);
1372
- idx1++;
1373
- y = format_int32(fmt, x);
1374
- rb_ary_push(a, y);
1375
- }
1376
- } else {
1377
- for (; i--;) {
1378
- x = (dtype*)p1;
1379
- p1 += s1;
1380
- y = format_int32(fmt, x);
1381
- rb_ary_push(a, y);
1382
- }
1383
- }
1384
- }
1385
-
1386
- /*
1387
- Format elements into strings.
1388
- @overload format_to_a format
1389
- @param [String] format
1390
- @return [Array] array of formatted strings.
1391
- */
1392
- static VALUE int32_format_to_a(int argc, VALUE* argv, VALUE self) {
1393
- VALUE fmt = Qnil;
1394
- ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { sym_loop_opt }, { sym_option } };
1395
- ndfunc_arg_out_t aout[1] = { { rb_cArray, 0 } }; // dummy?
1396
- ndfunc_t ndf = { iter_int32_format_to_a, FULL_LOOP_NIP, 3, 1, ain, aout };
1397
-
1398
- rb_scan_args(argc, argv, "01", &fmt);
1399
- return na_ndloop_cast_narray_to_rarray(&ndf, self, fmt);
1400
- }
1401
-
1402
- static VALUE iter_int32_inspect(char* ptr, size_t pos, VALUE fmt) {
1403
- return format_int32(fmt, (dtype*)(ptr + pos));
1404
- }
1405
-
1406
- /*
1407
- Returns a string containing a human-readable representation of NArray.
1408
- @overload inspect
1409
- @return [String]
1410
- */
1411
- static VALUE int32_inspect(VALUE ary) {
1412
- return na_ndloop_inspect(ary, iter_int32_inspect, Qnil);
1413
- }
1414
-
1415
1306
  static void iter_int32_each(na_loop_t* const lp) {
1416
1307
  size_t i, s1;
1417
1308
  char* p1;
@@ -1738,3358 +1629,372 @@ static VALUE int32_abs(VALUE self) {
1738
1629
  return na_ndloop(&ndf, 1, self);
1739
1630
  }
1740
1631
 
1741
- #define check_intdivzero(y) \
1742
- {}
1743
-
1744
- static void iter_int32_add(na_loop_t* const lp) {
1745
- size_t i = 0;
1746
- size_t n;
1632
+ static void iter_int32_pow(na_loop_t* const lp) {
1633
+ size_t i;
1747
1634
  char *p1, *p2, *p3;
1748
1635
  ssize_t s1, s2, s3;
1749
-
1750
- INIT_COUNTER(lp, n);
1636
+ dtype x, y;
1637
+ INIT_COUNTER(lp, i);
1751
1638
  INIT_PTR(lp, 0, p1, s1);
1752
1639
  INIT_PTR(lp, 1, p2, s2);
1753
1640
  INIT_PTR(lp, 2, p3, s3);
1754
-
1755
- //
1756
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
1757
- is_aligned(p3, sizeof(dtype))) {
1758
-
1759
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
1760
- if (p1 == p3) { // inplace case
1761
- for (; i < n; i++) {
1762
- check_intdivzero(((dtype*)p2)[i]);
1763
- ((dtype*)p1)[i] = m_add(((dtype*)p1)[i], ((dtype*)p2)[i]);
1764
- }
1765
- } else {
1766
- for (; i < n; i++) {
1767
- check_intdivzero(((dtype*)p2)[i]);
1768
- ((dtype*)p3)[i] = m_add(((dtype*)p1)[i], ((dtype*)p2)[i]);
1769
- }
1770
- }
1771
- return;
1772
- }
1773
-
1774
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
1775
- is_aligned_step(s3, sizeof(dtype))) {
1776
- //
1777
-
1778
- if (s2 == 0) { // Broadcasting from scalar value.
1779
- check_intdivzero(*(dtype*)p2);
1780
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
1781
- if (p1 == p3) { // inplace case
1782
- for (; i < n; i++) {
1783
- ((dtype*)p1)[i] = m_add(((dtype*)p1)[i], *(dtype*)p2);
1784
- }
1785
- } else {
1786
- for (; i < n; i++) {
1787
- ((dtype*)p3)[i] = m_add(((dtype*)p1)[i], *(dtype*)p2);
1788
- }
1789
- }
1790
- } else {
1791
- for (i = 0; i < n; i++) {
1792
- *(dtype*)p3 = m_add(*(dtype*)p1, *(dtype*)p2);
1793
- p1 += s1;
1794
- p3 += s3;
1795
- }
1796
- }
1797
- } else {
1798
- if (p1 == p3) { // inplace case
1799
- for (i = 0; i < n; i++) {
1800
- check_intdivzero(*(dtype*)p2);
1801
- *(dtype*)p1 = m_add(*(dtype*)p1, *(dtype*)p2);
1802
- p1 += s1;
1803
- p2 += s2;
1804
- }
1805
- } else {
1806
- for (i = 0; i < n; i++) {
1807
- check_intdivzero(*(dtype*)p2);
1808
- *(dtype*)p3 = m_add(*(dtype*)p1, *(dtype*)p2);
1809
- p1 += s1;
1810
- p2 += s2;
1811
- p3 += s3;
1812
- }
1813
- }
1814
- }
1815
-
1816
- return;
1817
- //
1818
- }
1819
- }
1820
- for (i = 0; i < n; i++) {
1821
- dtype x, y, z;
1641
+ for (; i--;) {
1822
1642
  GET_DATA_STRIDE(p1, s1, dtype, x);
1823
1643
  GET_DATA_STRIDE(p2, s2, dtype, y);
1824
- check_intdivzero(y);
1825
- z = m_add(x, y);
1826
- SET_DATA_STRIDE(p3, s3, dtype, z);
1644
+ x = m_pow(x, y);
1645
+ SET_DATA_STRIDE(p3, s3, dtype, x);
1646
+ }
1647
+ }
1648
+
1649
+ static void iter_int32_pow_int32(na_loop_t* const lp) {
1650
+ size_t i;
1651
+ char *p1, *p2, *p3;
1652
+ ssize_t s1, s2, s3;
1653
+ dtype x;
1654
+ int32_t y;
1655
+ INIT_COUNTER(lp, i);
1656
+ INIT_PTR(lp, 0, p1, s1);
1657
+ INIT_PTR(lp, 1, p2, s2);
1658
+ INIT_PTR(lp, 2, p3, s3);
1659
+ for (; i--;) {
1660
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1661
+ GET_DATA_STRIDE(p2, s2, int32_t, y);
1662
+ x = m_pow_int(x, y);
1663
+ SET_DATA_STRIDE(p3, s3, dtype, x);
1827
1664
  }
1828
- //
1829
1665
  }
1830
- #undef check_intdivzero
1831
1666
 
1832
- static VALUE int32_add_self(VALUE self, VALUE other) {
1667
+ static VALUE int32_pow_self(VALUE self, VALUE other) {
1833
1668
  ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
1669
+ ndfunc_arg_in_t ain_i[2] = { { cT, 0 }, { numo_cInt32, 0 } };
1834
1670
  ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1835
- ndfunc_t ndf = { iter_int32_add, STRIDE_LOOP, 2, 1, ain, aout };
1671
+ ndfunc_t ndf = { iter_int32_pow, STRIDE_LOOP, 2, 1, ain, aout };
1672
+ ndfunc_t ndf_i = { iter_int32_pow_int32, STRIDE_LOOP, 2, 1, ain_i, aout };
1836
1673
 
1837
- return na_ndloop(&ndf, 2, self, other);
1674
+ // fixme : use na.integer?
1675
+ if (FIXNUM_P(other) || rb_obj_is_kind_of(other, numo_cInt32)) {
1676
+ return na_ndloop(&ndf_i, 2, self, other);
1677
+ } else {
1678
+ return na_ndloop(&ndf, 2, self, other);
1679
+ }
1838
1680
  }
1839
1681
 
1840
1682
  /*
1841
- Binary add.
1842
- @overload + other
1683
+ Binary power.
1684
+ @overload ** other
1843
1685
  @param [Numo::NArray,Numeric] other
1844
- @return [Numo::NArray] self + other
1686
+ @return [Numo::NArray] self to the other-th power.
1845
1687
  */
1846
- static VALUE int32_add(VALUE self, VALUE other) {
1688
+ static VALUE int32_pow(VALUE self, VALUE other) {
1847
1689
 
1848
1690
  VALUE klass, v;
1849
-
1850
1691
  klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
1851
1692
  if (klass == cT) {
1852
- return int32_add_self(self, other);
1693
+ return int32_pow_self(self, other);
1853
1694
  } else {
1854
1695
  v = rb_funcall(klass, id_cast, 1, self);
1855
- return rb_funcall(v, '+', 1, other);
1696
+ return rb_funcall(v, id_pow, 1, other);
1856
1697
  }
1857
1698
  }
1858
1699
 
1859
- #define check_intdivzero(y) \
1860
- {}
1861
-
1862
- static void iter_int32_sub(na_loop_t* const lp) {
1863
- size_t i = 0;
1864
- size_t n;
1865
- char *p1, *p2, *p3;
1866
- ssize_t s1, s2, s3;
1700
+ static void iter_int32_minus(na_loop_t* const lp) {
1701
+ size_t i, n;
1702
+ char *p1, *p2;
1703
+ ssize_t s1, s2;
1704
+ size_t *idx1, *idx2;
1705
+ dtype x;
1867
1706
 
1868
1707
  INIT_COUNTER(lp, n);
1869
- INIT_PTR(lp, 0, p1, s1);
1870
- INIT_PTR(lp, 1, p2, s2);
1871
- INIT_PTR(lp, 2, p3, s3);
1872
-
1873
- //
1874
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
1875
- is_aligned(p3, sizeof(dtype))) {
1708
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1709
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
1876
1710
 
1877
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
1878
- if (p1 == p3) { // inplace case
1879
- for (; i < n; i++) {
1880
- check_intdivzero(((dtype*)p2)[i]);
1881
- ((dtype*)p1)[i] = m_sub(((dtype*)p1)[i], ((dtype*)p2)[i]);
1882
- }
1883
- } else {
1884
- for (; i < n; i++) {
1885
- check_intdivzero(((dtype*)p2)[i]);
1886
- ((dtype*)p3)[i] = m_sub(((dtype*)p1)[i], ((dtype*)p2)[i]);
1887
- }
1711
+ if (idx1) {
1712
+ if (idx2) {
1713
+ for (i = 0; i < n; i++) {
1714
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1715
+ x = m_minus(x);
1716
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1717
+ }
1718
+ } else {
1719
+ for (i = 0; i < n; i++) {
1720
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1721
+ x = m_minus(x);
1722
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1888
1723
  }
1889
- return;
1890
1724
  }
1891
-
1892
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
1893
- is_aligned_step(s3, sizeof(dtype))) {
1725
+ } else {
1726
+ if (idx2) {
1727
+ for (i = 0; i < n; i++) {
1728
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1729
+ x = m_minus(x);
1730
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1731
+ }
1732
+ } else {
1894
1733
  //
1895
-
1896
- if (s2 == 0) { // Broadcasting from scalar value.
1897
- check_intdivzero(*(dtype*)p2);
1898
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
1899
- if (p1 == p3) { // inplace case
1900
- for (; i < n; i++) {
1901
- ((dtype*)p1)[i] = m_sub(((dtype*)p1)[i], *(dtype*)p2);
1902
- }
1903
- } else {
1904
- for (; i < n; i++) {
1905
- ((dtype*)p3)[i] = m_sub(((dtype*)p1)[i], *(dtype*)p2);
1906
- }
1907
- }
1908
- } else {
1734
+ if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
1735
+ if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
1909
1736
  for (i = 0; i < n; i++) {
1910
- *(dtype*)p3 = m_sub(*(dtype*)p1, *(dtype*)p2);
1911
- p1 += s1;
1912
- p3 += s3;
1737
+ ((dtype*)p2)[i] = m_minus(((dtype*)p1)[i]);
1913
1738
  }
1739
+ return;
1914
1740
  }
1915
- } else {
1916
- if (p1 == p3) { // inplace case
1917
- for (i = 0; i < n; i++) {
1918
- check_intdivzero(*(dtype*)p2);
1919
- *(dtype*)p1 = m_sub(*(dtype*)p1, *(dtype*)p2);
1920
- p1 += s1;
1921
- p2 += s2;
1922
- }
1923
- } else {
1741
+ if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
1742
+ //
1924
1743
  for (i = 0; i < n; i++) {
1925
- check_intdivzero(*(dtype*)p2);
1926
- *(dtype*)p3 = m_sub(*(dtype*)p1, *(dtype*)p2);
1744
+ *(dtype*)p2 = m_minus(*(dtype*)p1);
1927
1745
  p1 += s1;
1928
1746
  p2 += s2;
1929
- p3 += s3;
1930
1747
  }
1748
+ return;
1749
+ //
1931
1750
  }
1932
1751
  }
1933
-
1934
- return;
1752
+ for (i = 0; i < n; i++) {
1753
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1754
+ x = m_minus(x);
1755
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1756
+ }
1935
1757
  //
1936
1758
  }
1937
1759
  }
1938
- for (i = 0; i < n; i++) {
1939
- dtype x, y, z;
1940
- GET_DATA_STRIDE(p1, s1, dtype, x);
1941
- GET_DATA_STRIDE(p2, s2, dtype, y);
1942
- check_intdivzero(y);
1943
- z = m_sub(x, y);
1944
- SET_DATA_STRIDE(p3, s3, dtype, z);
1945
- }
1946
- //
1947
1760
  }
1948
- #undef check_intdivzero
1949
1761
 
1950
- static VALUE int32_sub_self(VALUE self, VALUE other) {
1951
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
1762
+ /*
1763
+ Unary minus.
1764
+ @overload -@
1765
+ @return [Numo::Int32] minus of self.
1766
+ */
1767
+ static VALUE int32_minus(VALUE self) {
1768
+ ndfunc_arg_in_t ain[1] = { { cT, 0 } };
1952
1769
  ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1953
- ndfunc_t ndf = { iter_int32_sub, STRIDE_LOOP, 2, 1, ain, aout };
1770
+ ndfunc_t ndf = { iter_int32_minus, FULL_LOOP, 1, 1, ain, aout };
1954
1771
 
1955
- return na_ndloop(&ndf, 2, self, other);
1772
+ return na_ndloop(&ndf, 1, self);
1956
1773
  }
1957
1774
 
1958
- /*
1959
- Binary sub.
1960
- @overload - other
1961
- @param [Numo::NArray,Numeric] other
1962
- @return [Numo::NArray] self - other
1963
- */
1964
- static VALUE int32_sub(VALUE self, VALUE other) {
1965
-
1966
- VALUE klass, v;
1967
-
1968
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
1969
- if (klass == cT) {
1970
- return int32_sub_self(self, other);
1971
- } else {
1972
- v = rb_funcall(klass, id_cast, 1, self);
1973
- return rb_funcall(v, '-', 1, other);
1974
- }
1975
- }
1976
-
1977
- #define check_intdivzero(y) \
1978
- {}
1979
-
1980
- static void iter_int32_mul(na_loop_t* const lp) {
1981
- size_t i = 0;
1982
- size_t n;
1983
- char *p1, *p2, *p3;
1984
- ssize_t s1, s2, s3;
1775
+ static void iter_int32_reciprocal(na_loop_t* const lp) {
1776
+ size_t i, n;
1777
+ char *p1, *p2;
1778
+ ssize_t s1, s2;
1779
+ size_t *idx1, *idx2;
1780
+ dtype x;
1985
1781
 
1986
1782
  INIT_COUNTER(lp, n);
1987
- INIT_PTR(lp, 0, p1, s1);
1988
- INIT_PTR(lp, 1, p2, s2);
1989
- INIT_PTR(lp, 2, p3, s3);
1990
-
1991
- //
1992
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
1993
- is_aligned(p3, sizeof(dtype))) {
1783
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1784
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
1994
1785
 
1995
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
1996
- if (p1 == p3) { // inplace case
1997
- for (; i < n; i++) {
1998
- check_intdivzero(((dtype*)p2)[i]);
1999
- ((dtype*)p1)[i] = m_mul(((dtype*)p1)[i], ((dtype*)p2)[i]);
2000
- }
2001
- } else {
2002
- for (; i < n; i++) {
2003
- check_intdivzero(((dtype*)p2)[i]);
2004
- ((dtype*)p3)[i] = m_mul(((dtype*)p1)[i], ((dtype*)p2)[i]);
2005
- }
1786
+ if (idx1) {
1787
+ if (idx2) {
1788
+ for (i = 0; i < n; i++) {
1789
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1790
+ x = m_reciprocal(x);
1791
+ SET_DATA_INDEX(p2, idx2, dtype, x);
2006
1792
  }
2007
- return;
2008
- }
2009
-
2010
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2011
- is_aligned_step(s3, sizeof(dtype))) {
2012
- //
2013
-
2014
- if (s2 == 0) { // Broadcasting from scalar value.
2015
- check_intdivzero(*(dtype*)p2);
2016
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2017
- if (p1 == p3) { // inplace case
2018
- for (; i < n; i++) {
2019
- ((dtype*)p1)[i] = m_mul(((dtype*)p1)[i], *(dtype*)p2);
2020
- }
2021
- } else {
2022
- for (; i < n; i++) {
2023
- ((dtype*)p3)[i] = m_mul(((dtype*)p1)[i], *(dtype*)p2);
2024
- }
2025
- }
2026
- } else {
2027
- for (i = 0; i < n; i++) {
2028
- *(dtype*)p3 = m_mul(*(dtype*)p1, *(dtype*)p2);
2029
- p1 += s1;
2030
- p3 += s3;
2031
- }
2032
- }
2033
- } else {
2034
- if (p1 == p3) { // inplace case
2035
- for (i = 0; i < n; i++) {
2036
- check_intdivzero(*(dtype*)p2);
2037
- *(dtype*)p1 = m_mul(*(dtype*)p1, *(dtype*)p2);
2038
- p1 += s1;
2039
- p2 += s2;
2040
- }
2041
- } else {
2042
- for (i = 0; i < n; i++) {
2043
- check_intdivzero(*(dtype*)p2);
2044
- *(dtype*)p3 = m_mul(*(dtype*)p1, *(dtype*)p2);
2045
- p1 += s1;
2046
- p2 += s2;
2047
- p3 += s3;
2048
- }
2049
- }
1793
+ } else {
1794
+ for (i = 0; i < n; i++) {
1795
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1796
+ x = m_reciprocal(x);
1797
+ SET_DATA_STRIDE(p2, s2, dtype, x);
2050
1798
  }
2051
-
2052
- return;
2053
- //
2054
1799
  }
2055
- }
2056
- for (i = 0; i < n; i++) {
2057
- dtype x, y, z;
2058
- GET_DATA_STRIDE(p1, s1, dtype, x);
2059
- GET_DATA_STRIDE(p2, s2, dtype, y);
2060
- check_intdivzero(y);
2061
- z = m_mul(x, y);
2062
- SET_DATA_STRIDE(p3, s3, dtype, z);
2063
- }
2064
- //
2065
- }
2066
- #undef check_intdivzero
2067
-
2068
- static VALUE int32_mul_self(VALUE self, VALUE other) {
2069
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2070
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2071
- ndfunc_t ndf = { iter_int32_mul, STRIDE_LOOP, 2, 1, ain, aout };
2072
-
2073
- return na_ndloop(&ndf, 2, self, other);
2074
- }
2075
-
2076
- /*
2077
- Binary mul.
2078
- @overload * other
2079
- @param [Numo::NArray,Numeric] other
2080
- @return [Numo::NArray] self * other
2081
- */
2082
- static VALUE int32_mul(VALUE self, VALUE other) {
2083
-
2084
- VALUE klass, v;
2085
-
2086
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2087
- if (klass == cT) {
2088
- return int32_mul_self(self, other);
2089
1800
  } else {
2090
- v = rb_funcall(klass, id_cast, 1, self);
2091
- return rb_funcall(v, '*', 1, other);
2092
- }
2093
- }
2094
-
2095
- #define check_intdivzero(y) \
2096
- if ((y) == 0) { \
2097
- lp->err_type = rb_eZeroDivError; \
2098
- return; \
2099
- }
2100
-
2101
- static void iter_int32_div(na_loop_t* const lp) {
2102
- size_t i = 0;
2103
- size_t n;
2104
- char *p1, *p2, *p3;
2105
- ssize_t s1, s2, s3;
2106
-
2107
- INIT_COUNTER(lp, n);
2108
- INIT_PTR(lp, 0, p1, s1);
2109
- INIT_PTR(lp, 1, p2, s2);
2110
- INIT_PTR(lp, 2, p3, s3);
2111
-
2112
- //
2113
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2114
- is_aligned(p3, sizeof(dtype))) {
2115
-
2116
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2117
- if (p1 == p3) { // inplace case
2118
- for (; i < n; i++) {
2119
- check_intdivzero(((dtype*)p2)[i]);
2120
- ((dtype*)p1)[i] = m_div(((dtype*)p1)[i], ((dtype*)p2)[i]);
2121
- }
2122
- } else {
2123
- for (; i < n; i++) {
2124
- check_intdivzero(((dtype*)p2)[i]);
2125
- ((dtype*)p3)[i] = m_div(((dtype*)p1)[i], ((dtype*)p2)[i]);
2126
- }
1801
+ if (idx2) {
1802
+ for (i = 0; i < n; i++) {
1803
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1804
+ x = m_reciprocal(x);
1805
+ SET_DATA_INDEX(p2, idx2, dtype, x);
2127
1806
  }
2128
- return;
2129
- }
2130
-
2131
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2132
- is_aligned_step(s3, sizeof(dtype))) {
1807
+ } else {
2133
1808
  //
2134
-
2135
- if (s2 == 0) { // Broadcasting from scalar value.
2136
- check_intdivzero(*(dtype*)p2);
2137
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2138
- if (p1 == p3) { // inplace case
2139
- for (; i < n; i++) {
2140
- ((dtype*)p1)[i] = m_div(((dtype*)p1)[i], *(dtype*)p2);
2141
- }
2142
- } else {
2143
- for (; i < n; i++) {
2144
- ((dtype*)p3)[i] = m_div(((dtype*)p1)[i], *(dtype*)p2);
2145
- }
2146
- }
2147
- } else {
1809
+ if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
1810
+ if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2148
1811
  for (i = 0; i < n; i++) {
2149
- *(dtype*)p3 = m_div(*(dtype*)p1, *(dtype*)p2);
2150
- p1 += s1;
2151
- p3 += s3;
1812
+ ((dtype*)p2)[i] = m_reciprocal(((dtype*)p1)[i]);
2152
1813
  }
1814
+ return;
2153
1815
  }
2154
- } else {
2155
- if (p1 == p3) { // inplace case
2156
- for (i = 0; i < n; i++) {
2157
- check_intdivzero(*(dtype*)p2);
2158
- *(dtype*)p1 = m_div(*(dtype*)p1, *(dtype*)p2);
2159
- p1 += s1;
2160
- p2 += s2;
2161
- }
2162
- } else {
1816
+ if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
1817
+ //
2163
1818
  for (i = 0; i < n; i++) {
2164
- check_intdivzero(*(dtype*)p2);
2165
- *(dtype*)p3 = m_div(*(dtype*)p1, *(dtype*)p2);
1819
+ *(dtype*)p2 = m_reciprocal(*(dtype*)p1);
2166
1820
  p1 += s1;
2167
1821
  p2 += s2;
2168
- p3 += s3;
2169
1822
  }
1823
+ return;
1824
+ //
2170
1825
  }
2171
1826
  }
2172
-
2173
- return;
2174
- //
2175
- }
2176
- }
2177
- for (i = 0; i < n; i++) {
2178
- dtype x, y, z;
2179
- GET_DATA_STRIDE(p1, s1, dtype, x);
2180
- GET_DATA_STRIDE(p2, s2, dtype, y);
2181
- check_intdivzero(y);
2182
- z = m_div(x, y);
2183
- SET_DATA_STRIDE(p3, s3, dtype, z);
2184
- }
2185
- //
2186
- }
2187
- #undef check_intdivzero
2188
-
2189
- static VALUE int32_div_self(VALUE self, VALUE other) {
2190
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2191
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2192
- ndfunc_t ndf = { iter_int32_div, STRIDE_LOOP, 2, 1, ain, aout };
2193
-
2194
- return na_ndloop(&ndf, 2, self, other);
2195
- }
2196
-
2197
- /*
2198
- Binary div.
2199
- @overload / other
2200
- @param [Numo::NArray,Numeric] other
2201
- @return [Numo::NArray] self / other
2202
- */
2203
- static VALUE int32_div(VALUE self, VALUE other) {
2204
-
2205
- VALUE klass, v;
2206
-
2207
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2208
- if (klass == cT) {
2209
- return int32_div_self(self, other);
2210
- } else {
2211
- v = rb_funcall(klass, id_cast, 1, self);
2212
- return rb_funcall(v, '/', 1, other);
2213
- }
2214
- }
2215
-
2216
- #define check_intdivzero(y) \
2217
- if ((y) == 0) { \
2218
- lp->err_type = rb_eZeroDivError; \
2219
- return; \
2220
- }
2221
-
2222
- static void iter_int32_mod(na_loop_t* const lp) {
2223
- size_t i = 0;
2224
- size_t n;
2225
- char *p1, *p2, *p3;
2226
- ssize_t s1, s2, s3;
2227
-
2228
- INIT_COUNTER(lp, n);
2229
- INIT_PTR(lp, 0, p1, s1);
2230
- INIT_PTR(lp, 1, p2, s2);
2231
- INIT_PTR(lp, 2, p3, s3);
2232
-
2233
- //
2234
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2235
- is_aligned(p3, sizeof(dtype))) {
2236
-
2237
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2238
- if (p1 == p3) { // inplace case
2239
- for (; i < n; i++) {
2240
- check_intdivzero(((dtype*)p2)[i]);
2241
- ((dtype*)p1)[i] = m_mod(((dtype*)p1)[i], ((dtype*)p2)[i]);
2242
- }
2243
- } else {
2244
- for (; i < n; i++) {
2245
- check_intdivzero(((dtype*)p2)[i]);
2246
- ((dtype*)p3)[i] = m_mod(((dtype*)p1)[i], ((dtype*)p2)[i]);
2247
- }
2248
- }
2249
- return;
2250
- }
2251
-
2252
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2253
- is_aligned_step(s3, sizeof(dtype))) {
2254
- //
2255
-
2256
- if (s2 == 0) { // Broadcasting from scalar value.
2257
- check_intdivzero(*(dtype*)p2);
2258
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2259
- if (p1 == p3) { // inplace case
2260
- for (; i < n; i++) {
2261
- ((dtype*)p1)[i] = m_mod(((dtype*)p1)[i], *(dtype*)p2);
2262
- }
2263
- } else {
2264
- for (; i < n; i++) {
2265
- ((dtype*)p3)[i] = m_mod(((dtype*)p1)[i], *(dtype*)p2);
2266
- }
2267
- }
2268
- } else {
2269
- for (i = 0; i < n; i++) {
2270
- *(dtype*)p3 = m_mod(*(dtype*)p1, *(dtype*)p2);
2271
- p1 += s1;
2272
- p3 += s3;
2273
- }
2274
- }
2275
- } else {
2276
- if (p1 == p3) { // inplace case
2277
- for (i = 0; i < n; i++) {
2278
- check_intdivzero(*(dtype*)p2);
2279
- *(dtype*)p1 = m_mod(*(dtype*)p1, *(dtype*)p2);
2280
- p1 += s1;
2281
- p2 += s2;
2282
- }
2283
- } else {
2284
- for (i = 0; i < n; i++) {
2285
- check_intdivzero(*(dtype*)p2);
2286
- *(dtype*)p3 = m_mod(*(dtype*)p1, *(dtype*)p2);
2287
- p1 += s1;
2288
- p2 += s2;
2289
- p3 += s3;
2290
- }
2291
- }
1827
+ for (i = 0; i < n; i++) {
1828
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1829
+ x = m_reciprocal(x);
1830
+ SET_DATA_STRIDE(p2, s2, dtype, x);
2292
1831
  }
2293
-
2294
- return;
2295
1832
  //
2296
1833
  }
2297
1834
  }
2298
- for (i = 0; i < n; i++) {
2299
- dtype x, y, z;
2300
- GET_DATA_STRIDE(p1, s1, dtype, x);
2301
- GET_DATA_STRIDE(p2, s2, dtype, y);
2302
- check_intdivzero(y);
2303
- z = m_mod(x, y);
2304
- SET_DATA_STRIDE(p3, s3, dtype, z);
2305
- }
2306
- //
2307
- }
2308
- #undef check_intdivzero
2309
-
2310
- static VALUE int32_mod_self(VALUE self, VALUE other) {
2311
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2312
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2313
- ndfunc_t ndf = { iter_int32_mod, STRIDE_LOOP, 2, 1, ain, aout };
2314
-
2315
- return na_ndloop(&ndf, 2, self, other);
2316
- }
2317
-
2318
- /*
2319
- Binary mod.
2320
- @overload % other
2321
- @param [Numo::NArray,Numeric] other
2322
- @return [Numo::NArray] self % other
2323
- */
2324
- static VALUE int32_mod(VALUE self, VALUE other) {
2325
-
2326
- VALUE klass, v;
2327
-
2328
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2329
- if (klass == cT) {
2330
- return int32_mod_self(self, other);
2331
- } else {
2332
- v = rb_funcall(klass, id_cast, 1, self);
2333
- return rb_funcall(v, '%', 1, other);
2334
- }
2335
- }
2336
-
2337
- static void iter_int32_divmod(na_loop_t* const lp) {
2338
- size_t i, n;
2339
- char *p1, *p2, *p3, *p4;
2340
- ssize_t s1, s2, s3, s4;
2341
- dtype x, y, a, b;
2342
- INIT_COUNTER(lp, n);
2343
- INIT_PTR(lp, 0, p1, s1);
2344
- INIT_PTR(lp, 1, p2, s2);
2345
- INIT_PTR(lp, 2, p3, s3);
2346
- INIT_PTR(lp, 3, p4, s4);
2347
- for (i = n; i--;) {
2348
- GET_DATA_STRIDE(p1, s1, dtype, x);
2349
- GET_DATA_STRIDE(p2, s2, dtype, y);
2350
- if (y == 0) {
2351
- lp->err_type = rb_eZeroDivError;
2352
- return;
2353
- }
2354
- m_divmod(x, y, a, b);
2355
- SET_DATA_STRIDE(p3, s3, dtype, a);
2356
- SET_DATA_STRIDE(p4, s4, dtype, b);
2357
- }
2358
- }
2359
-
2360
- static VALUE int32_divmod_self(VALUE self, VALUE other) {
2361
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2362
- ndfunc_arg_out_t aout[2] = { { cT, 0 }, { cT, 0 } };
2363
- ndfunc_t ndf = { iter_int32_divmod, STRIDE_LOOP, 2, 2, ain, aout };
2364
-
2365
- return na_ndloop(&ndf, 2, self, other);
2366
1835
  }
2367
1836
 
2368
1837
  /*
2369
- Binary divmod.
2370
- @overload divmod other
2371
- @param [Numo::NArray,Numeric] other
2372
- @return [Numo::NArray] divmod of self and other.
2373
- */
2374
- static VALUE int32_divmod(VALUE self, VALUE other) {
2375
-
2376
- VALUE klass, v;
2377
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2378
- if (klass == cT) {
2379
- return int32_divmod_self(self, other);
2380
- } else {
2381
- v = rb_funcall(klass, id_cast, 1, self);
2382
- return rb_funcall(v, id_divmod, 1, other);
2383
- }
2384
- }
2385
-
2386
- static void iter_int32_pow(na_loop_t* const lp) {
2387
- size_t i;
2388
- char *p1, *p2, *p3;
2389
- ssize_t s1, s2, s3;
2390
- dtype x, y;
2391
- INIT_COUNTER(lp, i);
2392
- INIT_PTR(lp, 0, p1, s1);
2393
- INIT_PTR(lp, 1, p2, s2);
2394
- INIT_PTR(lp, 2, p3, s3);
2395
- for (; i--;) {
2396
- GET_DATA_STRIDE(p1, s1, dtype, x);
2397
- GET_DATA_STRIDE(p2, s2, dtype, y);
2398
- x = m_pow(x, y);
2399
- SET_DATA_STRIDE(p3, s3, dtype, x);
2400
- }
2401
- }
2402
-
2403
- static void iter_int32_pow_int32(na_loop_t* const lp) {
2404
- size_t i;
2405
- char *p1, *p2, *p3;
2406
- ssize_t s1, s2, s3;
2407
- dtype x;
2408
- int32_t y;
2409
- INIT_COUNTER(lp, i);
2410
- INIT_PTR(lp, 0, p1, s1);
2411
- INIT_PTR(lp, 1, p2, s2);
2412
- INIT_PTR(lp, 2, p3, s3);
2413
- for (; i--;) {
2414
- GET_DATA_STRIDE(p1, s1, dtype, x);
2415
- GET_DATA_STRIDE(p2, s2, int32_t, y);
2416
- x = m_pow_int(x, y);
2417
- SET_DATA_STRIDE(p3, s3, dtype, x);
2418
- }
2419
- }
2420
-
2421
- static VALUE int32_pow_self(VALUE self, VALUE other) {
2422
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2423
- ndfunc_arg_in_t ain_i[2] = { { cT, 0 }, { numo_cInt32, 0 } };
2424
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2425
- ndfunc_t ndf = { iter_int32_pow, STRIDE_LOOP, 2, 1, ain, aout };
2426
- ndfunc_t ndf_i = { iter_int32_pow_int32, STRIDE_LOOP, 2, 1, ain_i, aout };
2427
-
2428
- // fixme : use na.integer?
2429
- if (FIXNUM_P(other) || rb_obj_is_kind_of(other, numo_cInt32)) {
2430
- return na_ndloop(&ndf_i, 2, self, other);
2431
- } else {
2432
- return na_ndloop(&ndf, 2, self, other);
2433
- }
2434
- }
2435
-
2436
- /*
2437
- Binary power.
2438
- @overload ** other
2439
- @param [Numo::NArray,Numeric] other
2440
- @return [Numo::NArray] self to the other-th power.
2441
- */
2442
- static VALUE int32_pow(VALUE self, VALUE other) {
2443
-
2444
- VALUE klass, v;
2445
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2446
- if (klass == cT) {
2447
- return int32_pow_self(self, other);
2448
- } else {
2449
- v = rb_funcall(klass, id_cast, 1, self);
2450
- return rb_funcall(v, id_pow, 1, other);
2451
- }
2452
- }
2453
-
2454
- static void iter_int32_minus(na_loop_t* const lp) {
2455
- size_t i, n;
2456
- char *p1, *p2;
2457
- ssize_t s1, s2;
2458
- size_t *idx1, *idx2;
2459
- dtype x;
2460
-
2461
- INIT_COUNTER(lp, n);
2462
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2463
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2464
-
2465
- if (idx1) {
2466
- if (idx2) {
2467
- for (i = 0; i < n; i++) {
2468
- GET_DATA_INDEX(p1, idx1, dtype, x);
2469
- x = m_minus(x);
2470
- SET_DATA_INDEX(p2, idx2, dtype, x);
2471
- }
2472
- } else {
2473
- for (i = 0; i < n; i++) {
2474
- GET_DATA_INDEX(p1, idx1, dtype, x);
2475
- x = m_minus(x);
2476
- SET_DATA_STRIDE(p2, s2, dtype, x);
2477
- }
2478
- }
2479
- } else {
2480
- if (idx2) {
2481
- for (i = 0; i < n; i++) {
2482
- GET_DATA_STRIDE(p1, s1, dtype, x);
2483
- x = m_minus(x);
2484
- SET_DATA_INDEX(p2, idx2, dtype, x);
2485
- }
2486
- } else {
2487
- //
2488
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2489
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2490
- for (i = 0; i < n; i++) {
2491
- ((dtype*)p2)[i] = m_minus(((dtype*)p1)[i]);
2492
- }
2493
- return;
2494
- }
2495
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2496
- //
2497
- for (i = 0; i < n; i++) {
2498
- *(dtype*)p2 = m_minus(*(dtype*)p1);
2499
- p1 += s1;
2500
- p2 += s2;
2501
- }
2502
- return;
2503
- //
2504
- }
2505
- }
2506
- for (i = 0; i < n; i++) {
2507
- GET_DATA_STRIDE(p1, s1, dtype, x);
2508
- x = m_minus(x);
2509
- SET_DATA_STRIDE(p2, s2, dtype, x);
2510
- }
2511
- //
2512
- }
2513
- }
2514
- }
2515
-
2516
- /*
2517
- Unary minus.
2518
- @overload -@
2519
- @return [Numo::Int32] minus of self.
2520
- */
2521
- static VALUE int32_minus(VALUE self) {
2522
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2523
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2524
- ndfunc_t ndf = { iter_int32_minus, FULL_LOOP, 1, 1, ain, aout };
2525
-
2526
- return na_ndloop(&ndf, 1, self);
2527
- }
2528
-
2529
- static void iter_int32_reciprocal(na_loop_t* const lp) {
2530
- size_t i, n;
2531
- char *p1, *p2;
2532
- ssize_t s1, s2;
2533
- size_t *idx1, *idx2;
2534
- dtype x;
2535
-
2536
- INIT_COUNTER(lp, n);
2537
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2538
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2539
-
2540
- if (idx1) {
2541
- if (idx2) {
2542
- for (i = 0; i < n; i++) {
2543
- GET_DATA_INDEX(p1, idx1, dtype, x);
2544
- x = m_reciprocal(x);
2545
- SET_DATA_INDEX(p2, idx2, dtype, x);
2546
- }
2547
- } else {
2548
- for (i = 0; i < n; i++) {
2549
- GET_DATA_INDEX(p1, idx1, dtype, x);
2550
- x = m_reciprocal(x);
2551
- SET_DATA_STRIDE(p2, s2, dtype, x);
2552
- }
2553
- }
2554
- } else {
2555
- if (idx2) {
2556
- for (i = 0; i < n; i++) {
2557
- GET_DATA_STRIDE(p1, s1, dtype, x);
2558
- x = m_reciprocal(x);
2559
- SET_DATA_INDEX(p2, idx2, dtype, x);
2560
- }
2561
- } else {
2562
- //
2563
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2564
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2565
- for (i = 0; i < n; i++) {
2566
- ((dtype*)p2)[i] = m_reciprocal(((dtype*)p1)[i]);
2567
- }
2568
- return;
2569
- }
2570
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2571
- //
2572
- for (i = 0; i < n; i++) {
2573
- *(dtype*)p2 = m_reciprocal(*(dtype*)p1);
2574
- p1 += s1;
2575
- p2 += s2;
2576
- }
2577
- return;
2578
- //
2579
- }
2580
- }
2581
- for (i = 0; i < n; i++) {
2582
- GET_DATA_STRIDE(p1, s1, dtype, x);
2583
- x = m_reciprocal(x);
2584
- SET_DATA_STRIDE(p2, s2, dtype, x);
2585
- }
2586
- //
2587
- }
2588
- }
2589
- }
2590
-
2591
- /*
2592
- Unary reciprocal.
2593
- @overload reciprocal
2594
- @return [Numo::Int32] reciprocal of self.
1838
+ Unary reciprocal.
1839
+ @overload reciprocal
1840
+ @return [Numo::Int32] reciprocal of self.
2595
1841
  */
2596
1842
  static VALUE int32_reciprocal(VALUE self) {
2597
1843
  ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2598
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2599
- ndfunc_t ndf = { iter_int32_reciprocal, FULL_LOOP, 1, 1, ain, aout };
2600
-
2601
- return na_ndloop(&ndf, 1, self);
2602
- }
2603
-
2604
- static void iter_int32_sign(na_loop_t* const lp) {
2605
- size_t i, n;
2606
- char *p1, *p2;
2607
- ssize_t s1, s2;
2608
- size_t *idx1, *idx2;
2609
- dtype x;
2610
-
2611
- INIT_COUNTER(lp, n);
2612
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2613
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2614
-
2615
- if (idx1) {
2616
- if (idx2) {
2617
- for (i = 0; i < n; i++) {
2618
- GET_DATA_INDEX(p1, idx1, dtype, x);
2619
- x = m_sign(x);
2620
- SET_DATA_INDEX(p2, idx2, dtype, x);
2621
- }
2622
- } else {
2623
- for (i = 0; i < n; i++) {
2624
- GET_DATA_INDEX(p1, idx1, dtype, x);
2625
- x = m_sign(x);
2626
- SET_DATA_STRIDE(p2, s2, dtype, x);
2627
- }
2628
- }
2629
- } else {
2630
- if (idx2) {
2631
- for (i = 0; i < n; i++) {
2632
- GET_DATA_STRIDE(p1, s1, dtype, x);
2633
- x = m_sign(x);
2634
- SET_DATA_INDEX(p2, idx2, dtype, x);
2635
- }
2636
- } else {
2637
- //
2638
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2639
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2640
- for (i = 0; i < n; i++) {
2641
- ((dtype*)p2)[i] = m_sign(((dtype*)p1)[i]);
2642
- }
2643
- return;
2644
- }
2645
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2646
- //
2647
- for (i = 0; i < n; i++) {
2648
- *(dtype*)p2 = m_sign(*(dtype*)p1);
2649
- p1 += s1;
2650
- p2 += s2;
2651
- }
2652
- return;
2653
- //
2654
- }
2655
- }
2656
- for (i = 0; i < n; i++) {
2657
- GET_DATA_STRIDE(p1, s1, dtype, x);
2658
- x = m_sign(x);
2659
- SET_DATA_STRIDE(p2, s2, dtype, x);
2660
- }
2661
- //
2662
- }
2663
- }
2664
- }
2665
-
2666
- /*
2667
- Unary sign.
2668
- @overload sign
2669
- @return [Numo::Int32] sign of self.
2670
- */
2671
- static VALUE int32_sign(VALUE self) {
2672
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2673
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2674
- ndfunc_t ndf = { iter_int32_sign, FULL_LOOP, 1, 1, ain, aout };
2675
-
2676
- return na_ndloop(&ndf, 1, self);
2677
- }
2678
-
2679
- static void iter_int32_square(na_loop_t* const lp) {
2680
- size_t i, n;
2681
- char *p1, *p2;
2682
- ssize_t s1, s2;
2683
- size_t *idx1, *idx2;
2684
- dtype x;
2685
-
2686
- INIT_COUNTER(lp, n);
2687
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2688
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2689
-
2690
- if (idx1) {
2691
- if (idx2) {
2692
- for (i = 0; i < n; i++) {
2693
- GET_DATA_INDEX(p1, idx1, dtype, x);
2694
- x = m_square(x);
2695
- SET_DATA_INDEX(p2, idx2, dtype, x);
2696
- }
2697
- } else {
2698
- for (i = 0; i < n; i++) {
2699
- GET_DATA_INDEX(p1, idx1, dtype, x);
2700
- x = m_square(x);
2701
- SET_DATA_STRIDE(p2, s2, dtype, x);
2702
- }
2703
- }
2704
- } else {
2705
- if (idx2) {
2706
- for (i = 0; i < n; i++) {
2707
- GET_DATA_STRIDE(p1, s1, dtype, x);
2708
- x = m_square(x);
2709
- SET_DATA_INDEX(p2, idx2, dtype, x);
2710
- }
2711
- } else {
2712
- //
2713
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2714
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2715
- for (i = 0; i < n; i++) {
2716
- ((dtype*)p2)[i] = m_square(((dtype*)p1)[i]);
2717
- }
2718
- return;
2719
- }
2720
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2721
- //
2722
- for (i = 0; i < n; i++) {
2723
- *(dtype*)p2 = m_square(*(dtype*)p1);
2724
- p1 += s1;
2725
- p2 += s2;
2726
- }
2727
- return;
2728
- //
2729
- }
2730
- }
2731
- for (i = 0; i < n; i++) {
2732
- GET_DATA_STRIDE(p1, s1, dtype, x);
2733
- x = m_square(x);
2734
- SET_DATA_STRIDE(p2, s2, dtype, x);
2735
- }
2736
- //
2737
- }
2738
- }
2739
- }
2740
-
2741
- /*
2742
- Unary square.
2743
- @overload square
2744
- @return [Numo::Int32] square of self.
2745
- */
2746
- static VALUE int32_square(VALUE self) {
2747
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2748
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2749
- ndfunc_t ndf = { iter_int32_square, FULL_LOOP, 1, 1, ain, aout };
2750
-
2751
- return na_ndloop(&ndf, 1, self);
2752
- }
2753
-
2754
- static void iter_int32_eq(na_loop_t* const lp) {
2755
- size_t i;
2756
- char *p1, *p2;
2757
- BIT_DIGIT* a3;
2758
- size_t p3;
2759
- ssize_t s1, s2, s3;
2760
- dtype x, y;
2761
- BIT_DIGIT b;
2762
- INIT_COUNTER(lp, i);
2763
- INIT_PTR(lp, 0, p1, s1);
2764
- INIT_PTR(lp, 1, p2, s2);
2765
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
2766
- for (; i--;) {
2767
- GET_DATA_STRIDE(p1, s1, dtype, x);
2768
- GET_DATA_STRIDE(p2, s2, dtype, y);
2769
- b = (m_eq(x, y)) ? 1 : 0;
2770
- STORE_BIT(a3, p3, b);
2771
- p3 += s3;
2772
- }
2773
- }
2774
-
2775
- static VALUE int32_eq_self(VALUE self, VALUE other) {
2776
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2777
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
2778
- ndfunc_t ndf = { iter_int32_eq, STRIDE_LOOP, 2, 1, ain, aout };
2779
-
2780
- return na_ndloop(&ndf, 2, self, other);
2781
- }
2782
-
2783
- /*
2784
- Comparison eq other.
2785
- @overload eq other
2786
- @param [Numo::NArray,Numeric] other
2787
- @return [Numo::Bit] result of self eq other.
2788
- */
2789
- static VALUE int32_eq(VALUE self, VALUE other) {
2790
-
2791
- VALUE klass, v;
2792
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2793
- if (klass == cT) {
2794
- return int32_eq_self(self, other);
2795
- } else {
2796
- v = rb_funcall(klass, id_cast, 1, self);
2797
- return rb_funcall(v, id_eq, 1, other);
2798
- }
2799
- }
2800
-
2801
- static void iter_int32_ne(na_loop_t* const lp) {
2802
- size_t i;
2803
- char *p1, *p2;
2804
- BIT_DIGIT* a3;
2805
- size_t p3;
2806
- ssize_t s1, s2, s3;
2807
- dtype x, y;
2808
- BIT_DIGIT b;
2809
- INIT_COUNTER(lp, i);
2810
- INIT_PTR(lp, 0, p1, s1);
2811
- INIT_PTR(lp, 1, p2, s2);
2812
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
2813
- for (; i--;) {
2814
- GET_DATA_STRIDE(p1, s1, dtype, x);
2815
- GET_DATA_STRIDE(p2, s2, dtype, y);
2816
- b = (m_ne(x, y)) ? 1 : 0;
2817
- STORE_BIT(a3, p3, b);
2818
- p3 += s3;
2819
- }
2820
- }
2821
-
2822
- static VALUE int32_ne_self(VALUE self, VALUE other) {
2823
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2824
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
2825
- ndfunc_t ndf = { iter_int32_ne, STRIDE_LOOP, 2, 1, ain, aout };
2826
-
2827
- return na_ndloop(&ndf, 2, self, other);
2828
- }
2829
-
2830
- /*
2831
- Comparison ne other.
2832
- @overload ne other
2833
- @param [Numo::NArray,Numeric] other
2834
- @return [Numo::Bit] result of self ne other.
2835
- */
2836
- static VALUE int32_ne(VALUE self, VALUE other) {
2837
-
2838
- VALUE klass, v;
2839
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2840
- if (klass == cT) {
2841
- return int32_ne_self(self, other);
2842
- } else {
2843
- v = rb_funcall(klass, id_cast, 1, self);
2844
- return rb_funcall(v, id_ne, 1, other);
2845
- }
2846
- }
2847
-
2848
- #define check_intdivzero(y) \
2849
- {}
2850
-
2851
- static void iter_int32_bit_and(na_loop_t* const lp) {
2852
- size_t i = 0;
2853
- size_t n;
2854
- char *p1, *p2, *p3;
2855
- ssize_t s1, s2, s3;
2856
-
2857
- INIT_COUNTER(lp, n);
2858
- INIT_PTR(lp, 0, p1, s1);
2859
- INIT_PTR(lp, 1, p2, s2);
2860
- INIT_PTR(lp, 2, p3, s3);
2861
-
2862
- //
2863
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2864
- is_aligned(p3, sizeof(dtype))) {
2865
-
2866
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2867
- if (p1 == p3) { // inplace case
2868
- for (; i < n; i++) {
2869
- check_intdivzero(((dtype*)p2)[i]);
2870
- ((dtype*)p1)[i] = m_bit_and(((dtype*)p1)[i], ((dtype*)p2)[i]);
2871
- }
2872
- } else {
2873
- for (; i < n; i++) {
2874
- check_intdivzero(((dtype*)p2)[i]);
2875
- ((dtype*)p3)[i] = m_bit_and(((dtype*)p1)[i], ((dtype*)p2)[i]);
2876
- }
2877
- }
2878
- return;
2879
- }
2880
-
2881
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2882
- is_aligned_step(s3, sizeof(dtype))) {
2883
- //
2884
-
2885
- if (s2 == 0) { // Broadcasting from scalar value.
2886
- check_intdivzero(*(dtype*)p2);
2887
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2888
- if (p1 == p3) { // inplace case
2889
- for (; i < n; i++) {
2890
- ((dtype*)p1)[i] = m_bit_and(((dtype*)p1)[i], *(dtype*)p2);
2891
- }
2892
- } else {
2893
- for (; i < n; i++) {
2894
- ((dtype*)p3)[i] = m_bit_and(((dtype*)p1)[i], *(dtype*)p2);
2895
- }
2896
- }
2897
- } else {
2898
- for (i = 0; i < n; i++) {
2899
- *(dtype*)p3 = m_bit_and(*(dtype*)p1, *(dtype*)p2);
2900
- p1 += s1;
2901
- p3 += s3;
2902
- }
2903
- }
2904
- } else {
2905
- if (p1 == p3) { // inplace case
2906
- for (i = 0; i < n; i++) {
2907
- check_intdivzero(*(dtype*)p2);
2908
- *(dtype*)p1 = m_bit_and(*(dtype*)p1, *(dtype*)p2);
2909
- p1 += s1;
2910
- p2 += s2;
2911
- }
2912
- } else {
2913
- for (i = 0; i < n; i++) {
2914
- check_intdivzero(*(dtype*)p2);
2915
- *(dtype*)p3 = m_bit_and(*(dtype*)p1, *(dtype*)p2);
2916
- p1 += s1;
2917
- p2 += s2;
2918
- p3 += s3;
2919
- }
2920
- }
2921
- }
2922
-
2923
- return;
2924
- //
2925
- }
2926
- }
2927
- for (i = 0; i < n; i++) {
2928
- dtype x, y, z;
2929
- GET_DATA_STRIDE(p1, s1, dtype, x);
2930
- GET_DATA_STRIDE(p2, s2, dtype, y);
2931
- check_intdivzero(y);
2932
- z = m_bit_and(x, y);
2933
- SET_DATA_STRIDE(p3, s3, dtype, z);
2934
- }
2935
- //
2936
- }
2937
- #undef check_intdivzero
2938
-
2939
- static VALUE int32_bit_and_self(VALUE self, VALUE other) {
2940
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2941
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2942
- ndfunc_t ndf = { iter_int32_bit_and, STRIDE_LOOP, 2, 1, ain, aout };
2943
-
2944
- return na_ndloop(&ndf, 2, self, other);
2945
- }
2946
-
2947
- /*
2948
- Binary bit_and.
2949
- @overload & other
2950
- @param [Numo::NArray,Numeric] other
2951
- @return [Numo::NArray] self & other
2952
- */
2953
- static VALUE int32_bit_and(VALUE self, VALUE other) {
2954
-
2955
- VALUE klass, v;
2956
-
2957
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2958
- if (klass == cT) {
2959
- return int32_bit_and_self(self, other);
2960
- } else {
2961
- v = rb_funcall(klass, id_cast, 1, self);
2962
- return rb_funcall(v, '&', 1, other);
2963
- }
2964
- }
2965
-
2966
- #define check_intdivzero(y) \
2967
- {}
2968
-
2969
- static void iter_int32_bit_or(na_loop_t* const lp) {
2970
- size_t i = 0;
2971
- size_t n;
2972
- char *p1, *p2, *p3;
2973
- ssize_t s1, s2, s3;
2974
-
2975
- INIT_COUNTER(lp, n);
2976
- INIT_PTR(lp, 0, p1, s1);
2977
- INIT_PTR(lp, 1, p2, s2);
2978
- INIT_PTR(lp, 2, p3, s3);
2979
-
2980
- //
2981
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2982
- is_aligned(p3, sizeof(dtype))) {
2983
-
2984
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2985
- if (p1 == p3) { // inplace case
2986
- for (; i < n; i++) {
2987
- check_intdivzero(((dtype*)p2)[i]);
2988
- ((dtype*)p1)[i] = m_bit_or(((dtype*)p1)[i], ((dtype*)p2)[i]);
2989
- }
2990
- } else {
2991
- for (; i < n; i++) {
2992
- check_intdivzero(((dtype*)p2)[i]);
2993
- ((dtype*)p3)[i] = m_bit_or(((dtype*)p1)[i], ((dtype*)p2)[i]);
2994
- }
2995
- }
2996
- return;
2997
- }
2998
-
2999
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
3000
- is_aligned_step(s3, sizeof(dtype))) {
3001
- //
3002
-
3003
- if (s2 == 0) { // Broadcasting from scalar value.
3004
- check_intdivzero(*(dtype*)p2);
3005
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
3006
- if (p1 == p3) { // inplace case
3007
- for (; i < n; i++) {
3008
- ((dtype*)p1)[i] = m_bit_or(((dtype*)p1)[i], *(dtype*)p2);
3009
- }
3010
- } else {
3011
- for (; i < n; i++) {
3012
- ((dtype*)p3)[i] = m_bit_or(((dtype*)p1)[i], *(dtype*)p2);
3013
- }
3014
- }
3015
- } else {
3016
- for (i = 0; i < n; i++) {
3017
- *(dtype*)p3 = m_bit_or(*(dtype*)p1, *(dtype*)p2);
3018
- p1 += s1;
3019
- p3 += s3;
3020
- }
3021
- }
3022
- } else {
3023
- if (p1 == p3) { // inplace case
3024
- for (i = 0; i < n; i++) {
3025
- check_intdivzero(*(dtype*)p2);
3026
- *(dtype*)p1 = m_bit_or(*(dtype*)p1, *(dtype*)p2);
3027
- p1 += s1;
3028
- p2 += s2;
3029
- }
3030
- } else {
3031
- for (i = 0; i < n; i++) {
3032
- check_intdivzero(*(dtype*)p2);
3033
- *(dtype*)p3 = m_bit_or(*(dtype*)p1, *(dtype*)p2);
3034
- p1 += s1;
3035
- p2 += s2;
3036
- p3 += s3;
3037
- }
3038
- }
3039
- }
3040
-
3041
- return;
3042
- //
3043
- }
3044
- }
3045
- for (i = 0; i < n; i++) {
3046
- dtype x, y, z;
3047
- GET_DATA_STRIDE(p1, s1, dtype, x);
3048
- GET_DATA_STRIDE(p2, s2, dtype, y);
3049
- check_intdivzero(y);
3050
- z = m_bit_or(x, y);
3051
- SET_DATA_STRIDE(p3, s3, dtype, z);
3052
- }
3053
- //
3054
- }
3055
- #undef check_intdivzero
3056
-
3057
- static VALUE int32_bit_or_self(VALUE self, VALUE other) {
3058
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3059
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3060
- ndfunc_t ndf = { iter_int32_bit_or, STRIDE_LOOP, 2, 1, ain, aout };
3061
-
3062
- return na_ndloop(&ndf, 2, self, other);
3063
- }
3064
-
3065
- /*
3066
- Binary bit_or.
3067
- @overload | other
3068
- @param [Numo::NArray,Numeric] other
3069
- @return [Numo::NArray] self | other
3070
- */
3071
- static VALUE int32_bit_or(VALUE self, VALUE other) {
3072
-
3073
- VALUE klass, v;
3074
-
3075
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3076
- if (klass == cT) {
3077
- return int32_bit_or_self(self, other);
3078
- } else {
3079
- v = rb_funcall(klass, id_cast, 1, self);
3080
- return rb_funcall(v, '|', 1, other);
3081
- }
3082
- }
3083
-
3084
- #define check_intdivzero(y) \
3085
- {}
3086
-
3087
- static void iter_int32_bit_xor(na_loop_t* const lp) {
3088
- size_t i = 0;
3089
- size_t n;
3090
- char *p1, *p2, *p3;
3091
- ssize_t s1, s2, s3;
3092
-
3093
- INIT_COUNTER(lp, n);
3094
- INIT_PTR(lp, 0, p1, s1);
3095
- INIT_PTR(lp, 1, p2, s2);
3096
- INIT_PTR(lp, 2, p3, s3);
3097
-
3098
- //
3099
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
3100
- is_aligned(p3, sizeof(dtype))) {
3101
-
3102
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
3103
- if (p1 == p3) { // inplace case
3104
- for (; i < n; i++) {
3105
- check_intdivzero(((dtype*)p2)[i]);
3106
- ((dtype*)p1)[i] = m_bit_xor(((dtype*)p1)[i], ((dtype*)p2)[i]);
3107
- }
3108
- } else {
3109
- for (; i < n; i++) {
3110
- check_intdivzero(((dtype*)p2)[i]);
3111
- ((dtype*)p3)[i] = m_bit_xor(((dtype*)p1)[i], ((dtype*)p2)[i]);
3112
- }
3113
- }
3114
- return;
3115
- }
3116
-
3117
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
3118
- is_aligned_step(s3, sizeof(dtype))) {
3119
- //
3120
-
3121
- if (s2 == 0) { // Broadcasting from scalar value.
3122
- check_intdivzero(*(dtype*)p2);
3123
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
3124
- if (p1 == p3) { // inplace case
3125
- for (; i < n; i++) {
3126
- ((dtype*)p1)[i] = m_bit_xor(((dtype*)p1)[i], *(dtype*)p2);
3127
- }
3128
- } else {
3129
- for (; i < n; i++) {
3130
- ((dtype*)p3)[i] = m_bit_xor(((dtype*)p1)[i], *(dtype*)p2);
3131
- }
3132
- }
3133
- } else {
3134
- for (i = 0; i < n; i++) {
3135
- *(dtype*)p3 = m_bit_xor(*(dtype*)p1, *(dtype*)p2);
3136
- p1 += s1;
3137
- p3 += s3;
3138
- }
3139
- }
3140
- } else {
3141
- if (p1 == p3) { // inplace case
3142
- for (i = 0; i < n; i++) {
3143
- check_intdivzero(*(dtype*)p2);
3144
- *(dtype*)p1 = m_bit_xor(*(dtype*)p1, *(dtype*)p2);
3145
- p1 += s1;
3146
- p2 += s2;
3147
- }
3148
- } else {
3149
- for (i = 0; i < n; i++) {
3150
- check_intdivzero(*(dtype*)p2);
3151
- *(dtype*)p3 = m_bit_xor(*(dtype*)p1, *(dtype*)p2);
3152
- p1 += s1;
3153
- p2 += s2;
3154
- p3 += s3;
3155
- }
3156
- }
3157
- }
3158
-
3159
- return;
3160
- //
3161
- }
3162
- }
3163
- for (i = 0; i < n; i++) {
3164
- dtype x, y, z;
3165
- GET_DATA_STRIDE(p1, s1, dtype, x);
3166
- GET_DATA_STRIDE(p2, s2, dtype, y);
3167
- check_intdivzero(y);
3168
- z = m_bit_xor(x, y);
3169
- SET_DATA_STRIDE(p3, s3, dtype, z);
3170
- }
3171
- //
3172
- }
3173
- #undef check_intdivzero
3174
-
3175
- static VALUE int32_bit_xor_self(VALUE self, VALUE other) {
3176
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3177
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3178
- ndfunc_t ndf = { iter_int32_bit_xor, STRIDE_LOOP, 2, 1, ain, aout };
3179
-
3180
- return na_ndloop(&ndf, 2, self, other);
3181
- }
3182
-
3183
- /*
3184
- Binary bit_xor.
3185
- @overload ^ other
3186
- @param [Numo::NArray,Numeric] other
3187
- @return [Numo::NArray] self ^ other
3188
- */
3189
- static VALUE int32_bit_xor(VALUE self, VALUE other) {
3190
-
3191
- VALUE klass, v;
3192
-
3193
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3194
- if (klass == cT) {
3195
- return int32_bit_xor_self(self, other);
3196
- } else {
3197
- v = rb_funcall(klass, id_cast, 1, self);
3198
- return rb_funcall(v, '^', 1, other);
3199
- }
3200
- }
3201
-
3202
- static void iter_int32_bit_not(na_loop_t* const lp) {
3203
- size_t i, n;
3204
- char *p1, *p2;
3205
- ssize_t s1, s2;
3206
- size_t *idx1, *idx2;
3207
- dtype x;
3208
-
3209
- INIT_COUNTER(lp, n);
3210
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3211
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
3212
-
3213
- if (idx1) {
3214
- if (idx2) {
3215
- for (i = 0; i < n; i++) {
3216
- GET_DATA_INDEX(p1, idx1, dtype, x);
3217
- x = m_bit_not(x);
3218
- SET_DATA_INDEX(p2, idx2, dtype, x);
3219
- }
3220
- } else {
3221
- for (i = 0; i < n; i++) {
3222
- GET_DATA_INDEX(p1, idx1, dtype, x);
3223
- x = m_bit_not(x);
3224
- SET_DATA_STRIDE(p2, s2, dtype, x);
3225
- }
3226
- }
3227
- } else {
3228
- if (idx2) {
3229
- for (i = 0; i < n; i++) {
3230
- GET_DATA_STRIDE(p1, s1, dtype, x);
3231
- x = m_bit_not(x);
3232
- SET_DATA_INDEX(p2, idx2, dtype, x);
3233
- }
3234
- } else {
3235
- //
3236
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
3237
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
3238
- for (i = 0; i < n; i++) {
3239
- ((dtype*)p2)[i] = m_bit_not(((dtype*)p1)[i]);
3240
- }
3241
- return;
3242
- }
3243
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
3244
- //
3245
- for (i = 0; i < n; i++) {
3246
- *(dtype*)p2 = m_bit_not(*(dtype*)p1);
3247
- p1 += s1;
3248
- p2 += s2;
3249
- }
3250
- return;
3251
- //
3252
- }
3253
- }
3254
- for (i = 0; i < n; i++) {
3255
- GET_DATA_STRIDE(p1, s1, dtype, x);
3256
- x = m_bit_not(x);
3257
- SET_DATA_STRIDE(p2, s2, dtype, x);
3258
- }
3259
- //
3260
- }
3261
- }
3262
- }
3263
-
3264
- /*
3265
- Unary bit_not.
3266
- @overload ~
3267
- @return [Numo::Int32] bit_not of self.
3268
- */
3269
- static VALUE int32_bit_not(VALUE self) {
3270
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3271
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3272
- ndfunc_t ndf = { iter_int32_bit_not, FULL_LOOP, 1, 1, ain, aout };
3273
-
3274
- return na_ndloop(&ndf, 1, self);
3275
- }
3276
-
3277
- #define check_intdivzero(y) \
3278
- {}
3279
-
3280
- static void iter_int32_left_shift(na_loop_t* const lp) {
3281
- size_t i = 0;
3282
- size_t n;
3283
- char *p1, *p2, *p3;
3284
- ssize_t s1, s2, s3;
3285
-
3286
- INIT_COUNTER(lp, n);
3287
- INIT_PTR(lp, 0, p1, s1);
3288
- INIT_PTR(lp, 1, p2, s2);
3289
- INIT_PTR(lp, 2, p3, s3);
3290
-
3291
- //
3292
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
3293
- is_aligned(p3, sizeof(dtype))) {
3294
-
3295
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
3296
- if (p1 == p3) { // inplace case
3297
- for (; i < n; i++) {
3298
- check_intdivzero(((dtype*)p2)[i]);
3299
- ((dtype*)p1)[i] = m_left_shift(((dtype*)p1)[i], ((dtype*)p2)[i]);
3300
- }
3301
- } else {
3302
- for (; i < n; i++) {
3303
- check_intdivzero(((dtype*)p2)[i]);
3304
- ((dtype*)p3)[i] = m_left_shift(((dtype*)p1)[i], ((dtype*)p2)[i]);
3305
- }
3306
- }
3307
- return;
3308
- }
3309
-
3310
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
3311
- is_aligned_step(s3, sizeof(dtype))) {
3312
- //
3313
-
3314
- if (s2 == 0) { // Broadcasting from scalar value.
3315
- check_intdivzero(*(dtype*)p2);
3316
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
3317
- if (p1 == p3) { // inplace case
3318
- for (; i < n; i++) {
3319
- ((dtype*)p1)[i] = m_left_shift(((dtype*)p1)[i], *(dtype*)p2);
3320
- }
3321
- } else {
3322
- for (; i < n; i++) {
3323
- ((dtype*)p3)[i] = m_left_shift(((dtype*)p1)[i], *(dtype*)p2);
3324
- }
3325
- }
3326
- } else {
3327
- for (i = 0; i < n; i++) {
3328
- *(dtype*)p3 = m_left_shift(*(dtype*)p1, *(dtype*)p2);
3329
- p1 += s1;
3330
- p3 += s3;
3331
- }
3332
- }
3333
- } else {
3334
- if (p1 == p3) { // inplace case
3335
- for (i = 0; i < n; i++) {
3336
- check_intdivzero(*(dtype*)p2);
3337
- *(dtype*)p1 = m_left_shift(*(dtype*)p1, *(dtype*)p2);
3338
- p1 += s1;
3339
- p2 += s2;
3340
- }
3341
- } else {
3342
- for (i = 0; i < n; i++) {
3343
- check_intdivzero(*(dtype*)p2);
3344
- *(dtype*)p3 = m_left_shift(*(dtype*)p1, *(dtype*)p2);
3345
- p1 += s1;
3346
- p2 += s2;
3347
- p3 += s3;
3348
- }
3349
- }
3350
- }
3351
-
3352
- return;
3353
- //
3354
- }
3355
- }
3356
- for (i = 0; i < n; i++) {
3357
- dtype x, y, z;
3358
- GET_DATA_STRIDE(p1, s1, dtype, x);
3359
- GET_DATA_STRIDE(p2, s2, dtype, y);
3360
- check_intdivzero(y);
3361
- z = m_left_shift(x, y);
3362
- SET_DATA_STRIDE(p3, s3, dtype, z);
3363
- }
3364
- //
3365
- }
3366
- #undef check_intdivzero
3367
-
3368
- static VALUE int32_left_shift_self(VALUE self, VALUE other) {
3369
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3370
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3371
- ndfunc_t ndf = { iter_int32_left_shift, STRIDE_LOOP, 2, 1, ain, aout };
3372
-
3373
- return na_ndloop(&ndf, 2, self, other);
3374
- }
3375
-
3376
- /*
3377
- Binary left_shift.
3378
- @overload << other
3379
- @param [Numo::NArray,Numeric] other
3380
- @return [Numo::NArray] self << other
3381
- */
3382
- static VALUE int32_left_shift(VALUE self, VALUE other) {
3383
-
3384
- VALUE klass, v;
3385
-
3386
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3387
- if (klass == cT) {
3388
- return int32_left_shift_self(self, other);
3389
- } else {
3390
- v = rb_funcall(klass, id_cast, 1, self);
3391
- return rb_funcall(v, id_left_shift, 1, other);
3392
- }
3393
- }
3394
-
3395
- #define check_intdivzero(y) \
3396
- {}
3397
-
3398
- static void iter_int32_right_shift(na_loop_t* const lp) {
3399
- size_t i = 0;
3400
- size_t n;
3401
- char *p1, *p2, *p3;
3402
- ssize_t s1, s2, s3;
3403
-
3404
- INIT_COUNTER(lp, n);
3405
- INIT_PTR(lp, 0, p1, s1);
3406
- INIT_PTR(lp, 1, p2, s2);
3407
- INIT_PTR(lp, 2, p3, s3);
3408
-
3409
- //
3410
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
3411
- is_aligned(p3, sizeof(dtype))) {
3412
-
3413
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
3414
- if (p1 == p3) { // inplace case
3415
- for (; i < n; i++) {
3416
- check_intdivzero(((dtype*)p2)[i]);
3417
- ((dtype*)p1)[i] = m_right_shift(((dtype*)p1)[i], ((dtype*)p2)[i]);
3418
- }
3419
- } else {
3420
- for (; i < n; i++) {
3421
- check_intdivzero(((dtype*)p2)[i]);
3422
- ((dtype*)p3)[i] = m_right_shift(((dtype*)p1)[i], ((dtype*)p2)[i]);
3423
- }
3424
- }
3425
- return;
3426
- }
3427
-
3428
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
3429
- is_aligned_step(s3, sizeof(dtype))) {
3430
- //
3431
-
3432
- if (s2 == 0) { // Broadcasting from scalar value.
3433
- check_intdivzero(*(dtype*)p2);
3434
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
3435
- if (p1 == p3) { // inplace case
3436
- for (; i < n; i++) {
3437
- ((dtype*)p1)[i] = m_right_shift(((dtype*)p1)[i], *(dtype*)p2);
3438
- }
3439
- } else {
3440
- for (; i < n; i++) {
3441
- ((dtype*)p3)[i] = m_right_shift(((dtype*)p1)[i], *(dtype*)p2);
3442
- }
3443
- }
3444
- } else {
3445
- for (i = 0; i < n; i++) {
3446
- *(dtype*)p3 = m_right_shift(*(dtype*)p1, *(dtype*)p2);
3447
- p1 += s1;
3448
- p3 += s3;
3449
- }
3450
- }
3451
- } else {
3452
- if (p1 == p3) { // inplace case
3453
- for (i = 0; i < n; i++) {
3454
- check_intdivzero(*(dtype*)p2);
3455
- *(dtype*)p1 = m_right_shift(*(dtype*)p1, *(dtype*)p2);
3456
- p1 += s1;
3457
- p2 += s2;
3458
- }
3459
- } else {
3460
- for (i = 0; i < n; i++) {
3461
- check_intdivzero(*(dtype*)p2);
3462
- *(dtype*)p3 = m_right_shift(*(dtype*)p1, *(dtype*)p2);
3463
- p1 += s1;
3464
- p2 += s2;
3465
- p3 += s3;
3466
- }
3467
- }
3468
- }
3469
-
3470
- return;
3471
- //
3472
- }
3473
- }
3474
- for (i = 0; i < n; i++) {
3475
- dtype x, y, z;
3476
- GET_DATA_STRIDE(p1, s1, dtype, x);
3477
- GET_DATA_STRIDE(p2, s2, dtype, y);
3478
- check_intdivzero(y);
3479
- z = m_right_shift(x, y);
3480
- SET_DATA_STRIDE(p3, s3, dtype, z);
3481
- }
3482
- //
3483
- }
3484
- #undef check_intdivzero
3485
-
3486
- static VALUE int32_right_shift_self(VALUE self, VALUE other) {
3487
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3488
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3489
- ndfunc_t ndf = { iter_int32_right_shift, STRIDE_LOOP, 2, 1, ain, aout };
3490
-
3491
- return na_ndloop(&ndf, 2, self, other);
3492
- }
3493
-
3494
- /*
3495
- Binary right_shift.
3496
- @overload >> other
3497
- @param [Numo::NArray,Numeric] other
3498
- @return [Numo::NArray] self >> other
3499
- */
3500
- static VALUE int32_right_shift(VALUE self, VALUE other) {
3501
-
3502
- VALUE klass, v;
3503
-
3504
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3505
- if (klass == cT) {
3506
- return int32_right_shift_self(self, other);
3507
- } else {
3508
- v = rb_funcall(klass, id_cast, 1, self);
3509
- return rb_funcall(v, id_right_shift, 1, other);
3510
- }
3511
- }
3512
-
3513
- static void iter_int32_gt(na_loop_t* const lp) {
3514
- size_t i;
3515
- char *p1, *p2;
3516
- BIT_DIGIT* a3;
3517
- size_t p3;
3518
- ssize_t s1, s2, s3;
3519
- dtype x, y;
3520
- BIT_DIGIT b;
3521
- INIT_COUNTER(lp, i);
3522
- INIT_PTR(lp, 0, p1, s1);
3523
- INIT_PTR(lp, 1, p2, s2);
3524
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
3525
- for (; i--;) {
3526
- GET_DATA_STRIDE(p1, s1, dtype, x);
3527
- GET_DATA_STRIDE(p2, s2, dtype, y);
3528
- b = (m_gt(x, y)) ? 1 : 0;
3529
- STORE_BIT(a3, p3, b);
3530
- p3 += s3;
3531
- }
3532
- }
3533
-
3534
- static VALUE int32_gt_self(VALUE self, VALUE other) {
3535
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3536
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3537
- ndfunc_t ndf = { iter_int32_gt, STRIDE_LOOP, 2, 1, ain, aout };
3538
-
3539
- return na_ndloop(&ndf, 2, self, other);
3540
- }
3541
-
3542
- /*
3543
- Comparison gt other.
3544
- @overload gt other
3545
- @param [Numo::NArray,Numeric] other
3546
- @return [Numo::Bit] result of self gt other.
3547
- */
3548
- static VALUE int32_gt(VALUE self, VALUE other) {
3549
-
3550
- VALUE klass, v;
3551
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3552
- if (klass == cT) {
3553
- return int32_gt_self(self, other);
3554
- } else {
3555
- v = rb_funcall(klass, id_cast, 1, self);
3556
- return rb_funcall(v, id_gt, 1, other);
3557
- }
3558
- }
3559
-
3560
- static void iter_int32_ge(na_loop_t* const lp) {
3561
- size_t i;
3562
- char *p1, *p2;
3563
- BIT_DIGIT* a3;
3564
- size_t p3;
3565
- ssize_t s1, s2, s3;
3566
- dtype x, y;
3567
- BIT_DIGIT b;
3568
- INIT_COUNTER(lp, i);
3569
- INIT_PTR(lp, 0, p1, s1);
3570
- INIT_PTR(lp, 1, p2, s2);
3571
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
3572
- for (; i--;) {
3573
- GET_DATA_STRIDE(p1, s1, dtype, x);
3574
- GET_DATA_STRIDE(p2, s2, dtype, y);
3575
- b = (m_ge(x, y)) ? 1 : 0;
3576
- STORE_BIT(a3, p3, b);
3577
- p3 += s3;
3578
- }
3579
- }
3580
-
3581
- static VALUE int32_ge_self(VALUE self, VALUE other) {
3582
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3583
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3584
- ndfunc_t ndf = { iter_int32_ge, STRIDE_LOOP, 2, 1, ain, aout };
3585
-
3586
- return na_ndloop(&ndf, 2, self, other);
3587
- }
3588
-
3589
- /*
3590
- Comparison ge other.
3591
- @overload ge other
3592
- @param [Numo::NArray,Numeric] other
3593
- @return [Numo::Bit] result of self ge other.
3594
- */
3595
- static VALUE int32_ge(VALUE self, VALUE other) {
3596
-
3597
- VALUE klass, v;
3598
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3599
- if (klass == cT) {
3600
- return int32_ge_self(self, other);
3601
- } else {
3602
- v = rb_funcall(klass, id_cast, 1, self);
3603
- return rb_funcall(v, id_ge, 1, other);
3604
- }
3605
- }
3606
-
3607
- static void iter_int32_lt(na_loop_t* const lp) {
3608
- size_t i;
3609
- char *p1, *p2;
3610
- BIT_DIGIT* a3;
3611
- size_t p3;
3612
- ssize_t s1, s2, s3;
3613
- dtype x, y;
3614
- BIT_DIGIT b;
3615
- INIT_COUNTER(lp, i);
3616
- INIT_PTR(lp, 0, p1, s1);
3617
- INIT_PTR(lp, 1, p2, s2);
3618
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
3619
- for (; i--;) {
3620
- GET_DATA_STRIDE(p1, s1, dtype, x);
3621
- GET_DATA_STRIDE(p2, s2, dtype, y);
3622
- b = (m_lt(x, y)) ? 1 : 0;
3623
- STORE_BIT(a3, p3, b);
3624
- p3 += s3;
3625
- }
3626
- }
3627
-
3628
- static VALUE int32_lt_self(VALUE self, VALUE other) {
3629
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3630
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3631
- ndfunc_t ndf = { iter_int32_lt, STRIDE_LOOP, 2, 1, ain, aout };
3632
-
3633
- return na_ndloop(&ndf, 2, self, other);
3634
- }
3635
-
3636
- /*
3637
- Comparison lt other.
3638
- @overload lt other
3639
- @param [Numo::NArray,Numeric] other
3640
- @return [Numo::Bit] result of self lt other.
3641
- */
3642
- static VALUE int32_lt(VALUE self, VALUE other) {
3643
-
3644
- VALUE klass, v;
3645
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3646
- if (klass == cT) {
3647
- return int32_lt_self(self, other);
3648
- } else {
3649
- v = rb_funcall(klass, id_cast, 1, self);
3650
- return rb_funcall(v, id_lt, 1, other);
3651
- }
3652
- }
3653
-
3654
- static void iter_int32_le(na_loop_t* const lp) {
3655
- size_t i;
3656
- char *p1, *p2;
3657
- BIT_DIGIT* a3;
3658
- size_t p3;
3659
- ssize_t s1, s2, s3;
3660
- dtype x, y;
3661
- BIT_DIGIT b;
3662
- INIT_COUNTER(lp, i);
3663
- INIT_PTR(lp, 0, p1, s1);
3664
- INIT_PTR(lp, 1, p2, s2);
3665
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
3666
- for (; i--;) {
3667
- GET_DATA_STRIDE(p1, s1, dtype, x);
3668
- GET_DATA_STRIDE(p2, s2, dtype, y);
3669
- b = (m_le(x, y)) ? 1 : 0;
3670
- STORE_BIT(a3, p3, b);
3671
- p3 += s3;
3672
- }
3673
- }
3674
-
3675
- static VALUE int32_le_self(VALUE self, VALUE other) {
3676
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3677
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3678
- ndfunc_t ndf = { iter_int32_le, STRIDE_LOOP, 2, 1, ain, aout };
3679
-
3680
- return na_ndloop(&ndf, 2, self, other);
3681
- }
3682
-
3683
- /*
3684
- Comparison le other.
3685
- @overload le other
3686
- @param [Numo::NArray,Numeric] other
3687
- @return [Numo::Bit] result of self le other.
3688
- */
3689
- static VALUE int32_le(VALUE self, VALUE other) {
3690
-
3691
- VALUE klass, v;
3692
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3693
- if (klass == cT) {
3694
- return int32_le_self(self, other);
3695
- } else {
3696
- v = rb_funcall(klass, id_cast, 1, self);
3697
- return rb_funcall(v, id_le, 1, other);
3698
- }
3699
- }
3700
-
3701
- static void iter_int32_clip(na_loop_t* const lp) {
3702
- size_t i;
3703
- char *p1, *p2, *p3, *p4;
3704
- ssize_t s1, s2, s3, s4;
3705
- dtype x, min, max;
3706
- INIT_COUNTER(lp, i);
3707
- INIT_PTR(lp, 0, p1, s1);
3708
- INIT_PTR(lp, 1, p2, s2);
3709
- INIT_PTR(lp, 2, p3, s3);
3710
- INIT_PTR(lp, 3, p4, s4);
3711
- for (; i--;) {
3712
- GET_DATA_STRIDE(p1, s1, dtype, x);
3713
- GET_DATA_STRIDE(p2, s2, dtype, min);
3714
- GET_DATA_STRIDE(p3, s3, dtype, max);
3715
- if (m_gt(min, max)) {
3716
- rb_raise(nary_eOperationError, "min is greater than max");
3717
- }
3718
- if (m_lt(x, min)) {
3719
- x = min;
3720
- }
3721
- if (m_gt(x, max)) {
3722
- x = max;
3723
- }
3724
- SET_DATA_STRIDE(p4, s4, dtype, x);
3725
- }
3726
- }
3727
-
3728
- static void iter_int32_clip_min(na_loop_t* const lp) {
3729
- size_t i;
3730
- char *p1, *p2, *p3;
3731
- ssize_t s1, s2, s3;
3732
- dtype x, min;
3733
- INIT_COUNTER(lp, i);
3734
- INIT_PTR(lp, 0, p1, s1);
3735
- INIT_PTR(lp, 1, p2, s2);
3736
- INIT_PTR(lp, 2, p3, s3);
3737
- for (; i--;) {
3738
- GET_DATA_STRIDE(p1, s1, dtype, x);
3739
- GET_DATA_STRIDE(p2, s2, dtype, min);
3740
- if (m_lt(x, min)) {
3741
- x = min;
3742
- }
3743
- SET_DATA_STRIDE(p3, s3, dtype, x);
3744
- }
3745
- }
3746
-
3747
- static void iter_int32_clip_max(na_loop_t* const lp) {
3748
- size_t i;
3749
- char *p1, *p2, *p3;
3750
- ssize_t s1, s2, s3;
3751
- dtype x, max;
3752
- INIT_COUNTER(lp, i);
3753
- INIT_PTR(lp, 0, p1, s1);
3754
- INIT_PTR(lp, 1, p2, s2);
3755
- INIT_PTR(lp, 2, p3, s3);
3756
- for (; i--;) {
3757
- GET_DATA_STRIDE(p1, s1, dtype, x);
3758
- GET_DATA_STRIDE(p2, s2, dtype, max);
3759
- if (m_gt(x, max)) {
3760
- x = max;
3761
- }
3762
- SET_DATA_STRIDE(p3, s3, dtype, x);
3763
- }
3764
- }
3765
-
3766
- /*
3767
- Clip array elements by [min,max].
3768
- If either of min or max is nil, one side is clipped.
3769
- @overload clip(min,max)
3770
- @param [Numo::NArray,Numeric] min
3771
- @param [Numo::NArray,Numeric] max
3772
- @return [Numo::NArray] result of clip.
3773
-
3774
- @example
3775
- a = Numo::Int32.new(10).seq
3776
- # => Numo::Int32#shape=[10]
3777
- # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3778
-
3779
- a.clip(1,8)
3780
- # => Numo::Int32#shape=[10]
3781
- # [1, 1, 2, 3, 4, 5, 6, 7, 8, 8]
3782
-
3783
- a.inplace.clip(3,6)
3784
- a
3785
- # => Numo::Int32#shape=[10]
3786
- # [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]
3787
-
3788
- b = Numo::Int32.new(10).seq
3789
- # => Numo::Int32#shape=[10]
3790
- # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3791
-
3792
- b.clip([3,4,1,1,1,4,4,4,4,4], 8)
3793
- # => Numo::Int32#shape=[10]
3794
- # [3, 4, 2, 3, 4, 5, 6, 7, 8, 8]
3795
- */
3796
- static VALUE int32_clip(VALUE self, VALUE min, VALUE max) {
3797
- ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { cT, 0 }, { cT, 0 } };
3798
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3799
- ndfunc_t ndf_min = { iter_int32_clip_min, STRIDE_LOOP, 2, 1, ain, aout };
3800
- ndfunc_t ndf_max = { iter_int32_clip_max, STRIDE_LOOP, 2, 1, ain, aout };
3801
- ndfunc_t ndf_both = { iter_int32_clip, STRIDE_LOOP, 3, 1, ain, aout };
3802
-
3803
- if (RTEST(min)) {
3804
- if (RTEST(max)) {
3805
- return na_ndloop(&ndf_both, 3, self, min, max);
3806
- } else {
3807
- return na_ndloop(&ndf_min, 2, self, min);
3808
- }
3809
- } else {
3810
- if (RTEST(max)) {
3811
- return na_ndloop(&ndf_max, 2, self, max);
3812
- }
3813
- }
3814
- rb_raise(rb_eArgError, "min and max are not given");
3815
- return Qnil;
3816
- }
3817
-
3818
- static void iter_int32_sum(na_loop_t* const lp) {
3819
- size_t n;
3820
- char *p1, *p2;
3821
- ssize_t s1;
3822
-
3823
- INIT_COUNTER(lp, n);
3824
- INIT_PTR(lp, 0, p1, s1);
3825
- p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
3826
-
3827
- *(int64_t*)p2 = f_sum(n, p1, s1);
3828
- }
3829
-
3830
- /*
3831
- sum of self.
3832
- @overload sum(axis:nil, keepdims:false)
3833
- @param [Numeric,Array,Range] axis Performs sum along the axis.
3834
- @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
3835
- dimensions with size one.
3836
- @return [Numo::Int32] returns result of sum.
3837
- */
3838
- static VALUE int32_sum(int argc, VALUE* argv, VALUE self) {
3839
- VALUE v, reduce;
3840
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
3841
- ndfunc_arg_out_t aout[1] = { { numo_cInt64, 0 } };
3842
- ndfunc_t ndf = { iter_int32_sum, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout };
3843
-
3844
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
3845
-
3846
- v = na_ndloop(&ndf, 2, self, reduce);
3847
-
3848
- return rb_funcall(v, rb_intern("extract"), 0);
3849
- }
3850
-
3851
- static void iter_int32_prod(na_loop_t* const lp) {
3852
- size_t n;
3853
- char *p1, *p2;
3854
- ssize_t s1;
3855
-
3856
- INIT_COUNTER(lp, n);
3857
- INIT_PTR(lp, 0, p1, s1);
3858
- p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
3859
-
3860
- *(int64_t*)p2 = f_prod(n, p1, s1);
3861
- }
3862
-
3863
- /*
3864
- prod of self.
3865
- @overload prod(axis:nil, keepdims:false)
3866
- @param [Numeric,Array,Range] axis Performs prod along the axis.
3867
- @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
3868
- dimensions with size one.
3869
- @return [Numo::Int32] returns result of prod.
3870
- */
3871
- static VALUE int32_prod(int argc, VALUE* argv, VALUE self) {
3872
- VALUE v, reduce;
3873
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
3874
- ndfunc_arg_out_t aout[1] = { { numo_cInt64, 0 } };
3875
- ndfunc_t ndf = { iter_int32_prod, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout };
3876
-
3877
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
3878
-
3879
- v = na_ndloop(&ndf, 2, self, reduce);
3880
-
3881
- return rb_funcall(v, rb_intern("extract"), 0);
3882
- }
3883
-
3884
- static void iter_int32_min(na_loop_t* const lp) {
3885
- size_t n;
3886
- char *p1, *p2;
3887
- ssize_t s1;
3888
-
3889
- INIT_COUNTER(lp, n);
3890
- INIT_PTR(lp, 0, p1, s1);
3891
- p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
3892
-
3893
- *(dtype*)p2 = f_min(n, p1, s1);
3894
- }
3895
-
3896
- /*
3897
- min of self.
3898
- @overload min(axis:nil, keepdims:false)
3899
- @param [Numeric,Array,Range] axis Performs min along the axis.
3900
- @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
3901
- dimensions with size one.
3902
- @return [Numo::Int32] returns result of min.
3903
- */
3904
- static VALUE int32_min(int argc, VALUE* argv, VALUE self) {
3905
- VALUE v, reduce;
3906
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
3907
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3908
- ndfunc_t ndf = { iter_int32_min, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout };
3909
-
3910
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
3911
-
3912
- v = na_ndloop(&ndf, 2, self, reduce);
3913
-
3914
- return int32_extract(v);
3915
- }
3916
-
3917
- static void iter_int32_max(na_loop_t* const lp) {
3918
- size_t n;
3919
- char *p1, *p2;
3920
- ssize_t s1;
3921
-
3922
- INIT_COUNTER(lp, n);
3923
- INIT_PTR(lp, 0, p1, s1);
3924
- p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
3925
-
3926
- *(dtype*)p2 = f_max(n, p1, s1);
3927
- }
3928
-
3929
- /*
3930
- max of self.
3931
- @overload max(axis:nil, keepdims:false)
3932
- @param [Numeric,Array,Range] axis Performs max along the axis.
3933
- @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
3934
- dimensions with size one.
3935
- @return [Numo::Int32] returns result of max.
3936
- */
3937
- static VALUE int32_max(int argc, VALUE* argv, VALUE self) {
3938
- VALUE v, reduce;
3939
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
3940
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3941
- ndfunc_t ndf = { iter_int32_max, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout };
3942
-
3943
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
3944
-
3945
- v = na_ndloop(&ndf, 2, self, reduce);
3946
-
3947
- return int32_extract(v);
3948
- }
3949
-
3950
- static void iter_int32_ptp(na_loop_t* const lp) {
3951
- size_t n;
3952
- char *p1, *p2;
3953
- ssize_t s1;
3954
-
3955
- INIT_COUNTER(lp, n);
3956
- INIT_PTR(lp, 0, p1, s1);
3957
- p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
3958
-
3959
- *(dtype*)p2 = f_ptp(n, p1, s1);
3960
- }
3961
-
3962
- /*
3963
- ptp of self.
3964
- @overload ptp(axis:nil, keepdims:false)
3965
- @param [Numeric,Array,Range] axis Performs ptp along the axis.
3966
- @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
3967
- dimensions with size one.
3968
- @return [Numo::Int32] returns result of ptp.
3969
- */
3970
- static VALUE int32_ptp(int argc, VALUE* argv, VALUE self) {
3971
- VALUE v, reduce;
3972
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
3973
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3974
- ndfunc_t ndf = { iter_int32_ptp, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout };
3975
-
3976
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
3977
-
3978
- v = na_ndloop(&ndf, 2, self, reduce);
3979
-
3980
- return int32_extract(v);
3981
- }
3982
-
3983
- #define idx_t int64_t
3984
- static void iter_int32_max_index_index64(na_loop_t* const lp) {
3985
- size_t n, idx;
3986
- char *d_ptr, *i_ptr, *o_ptr;
3987
- ssize_t d_step, i_step;
3988
-
3989
- INIT_COUNTER(lp, n);
3990
- INIT_PTR(lp, 0, d_ptr, d_step);
3991
-
3992
- idx = f_max_index(n, d_ptr, d_step);
3993
-
3994
- INIT_PTR(lp, 1, i_ptr, i_step);
3995
- o_ptr = NDL_PTR(lp, 2);
3996
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
3997
- }
3998
- #undef idx_t
3999
-
4000
- #define idx_t int32_t
4001
- static void iter_int32_max_index_index32(na_loop_t* const lp) {
4002
- size_t n, idx;
4003
- char *d_ptr, *i_ptr, *o_ptr;
4004
- ssize_t d_step, i_step;
4005
-
4006
- INIT_COUNTER(lp, n);
4007
- INIT_PTR(lp, 0, d_ptr, d_step);
4008
-
4009
- idx = f_max_index(n, d_ptr, d_step);
4010
-
4011
- INIT_PTR(lp, 1, i_ptr, i_step);
4012
- o_ptr = NDL_PTR(lp, 2);
4013
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
4014
- }
4015
- #undef idx_t
4016
-
4017
- /*
4018
- Index of the maximum value.
4019
- @overload max_index(axis:nil)
4020
- @param [Numeric,Array,Range] axis Finds maximum values along the axis and returns **flat
4021
- 1-d indices**.
4022
- @return [Integer,Numo::Int] returns result indices.
4023
- @see #argmax
4024
- @see #max
4025
-
4026
- @example
4027
- a = Numo::NArray[3,4,1,2]
4028
- a.max_index #=> 1
4029
-
4030
- b = Numo::NArray[[3,4,1],[2,0,5]]
4031
- b.max_index #=> 5
4032
- b.max_index(axis:1) #=> [1, 5]
4033
- b.max_index(axis:0) #=> [0, 1, 5]
4034
- b[b.max_index(axis:0)] #=> [3, 4, 5]
4035
- */
4036
- static VALUE int32_max_index(int argc, VALUE* argv, VALUE self) {
4037
- narray_t* na;
4038
- VALUE idx, reduce;
4039
- ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { Qnil, 0 }, { sym_reduce, 0 } };
4040
- ndfunc_arg_out_t aout[1] = { { 0, 0, 0 } };
4041
- ndfunc_t ndf = { 0, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE | NDF_EXTRACT, 3, 1, ain, aout };
4042
-
4043
- GetNArray(self, na);
4044
- if (na->ndim == 0) {
4045
- return INT2FIX(0);
4046
- }
4047
- if (na->size > (~(u_int32_t)0)) {
4048
- aout[0].type = numo_cInt64;
4049
- idx = nary_new(numo_cInt64, na->ndim, na->shape);
4050
- ndf.func = iter_int32_max_index_index64;
4051
-
4052
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
4053
-
4054
- } else {
4055
- aout[0].type = numo_cInt32;
4056
- idx = nary_new(numo_cInt32, na->ndim, na->shape);
4057
- ndf.func = iter_int32_max_index_index32;
4058
-
4059
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
4060
- }
4061
- rb_funcall(idx, rb_intern("seq"), 0);
4062
-
4063
- return na_ndloop(&ndf, 3, self, idx, reduce);
4064
- }
4065
-
4066
- #define idx_t int64_t
4067
- static void iter_int32_min_index_index64(na_loop_t* const lp) {
4068
- size_t n, idx;
4069
- char *d_ptr, *i_ptr, *o_ptr;
4070
- ssize_t d_step, i_step;
4071
-
4072
- INIT_COUNTER(lp, n);
4073
- INIT_PTR(lp, 0, d_ptr, d_step);
4074
-
4075
- idx = f_min_index(n, d_ptr, d_step);
4076
-
4077
- INIT_PTR(lp, 1, i_ptr, i_step);
4078
- o_ptr = NDL_PTR(lp, 2);
4079
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
4080
- }
4081
- #undef idx_t
4082
-
4083
- #define idx_t int32_t
4084
- static void iter_int32_min_index_index32(na_loop_t* const lp) {
4085
- size_t n, idx;
4086
- char *d_ptr, *i_ptr, *o_ptr;
4087
- ssize_t d_step, i_step;
4088
-
4089
- INIT_COUNTER(lp, n);
4090
- INIT_PTR(lp, 0, d_ptr, d_step);
4091
-
4092
- idx = f_min_index(n, d_ptr, d_step);
4093
-
4094
- INIT_PTR(lp, 1, i_ptr, i_step);
4095
- o_ptr = NDL_PTR(lp, 2);
4096
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
4097
- }
4098
- #undef idx_t
4099
-
4100
- /*
4101
- Index of the minimum value.
4102
- @overload min_index(axis:nil)
4103
- @param [Numeric,Array,Range] axis Finds minimum values along the axis and returns **flat
4104
- 1-d indices**.
4105
- @return [Integer,Numo::Int] returns result indices.
4106
- @see #argmin
4107
- @see #min
4108
-
4109
- @example
4110
- a = Numo::NArray[3,4,1,2]
4111
- a.min_index #=> 2
4112
-
4113
- b = Numo::NArray[[3,4,1],[2,0,5]]
4114
- b.min_index #=> 4
4115
- b.min_index(axis:1) #=> [2, 4]
4116
- b.min_index(axis:0) #=> [3, 4, 2]
4117
- b[b.min_index(axis:0)] #=> [2, 0, 1]
4118
- */
4119
- static VALUE int32_min_index(int argc, VALUE* argv, VALUE self) {
4120
- narray_t* na;
4121
- VALUE idx, reduce;
4122
- ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { Qnil, 0 }, { sym_reduce, 0 } };
4123
- ndfunc_arg_out_t aout[1] = { { 0, 0, 0 } };
4124
- ndfunc_t ndf = { 0, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE | NDF_EXTRACT, 3, 1, ain, aout };
4125
-
4126
- GetNArray(self, na);
4127
- if (na->ndim == 0) {
4128
- return INT2FIX(0);
4129
- }
4130
- if (na->size > (~(u_int32_t)0)) {
4131
- aout[0].type = numo_cInt64;
4132
- idx = nary_new(numo_cInt64, na->ndim, na->shape);
4133
- ndf.func = iter_int32_min_index_index64;
4134
-
4135
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
4136
-
4137
- } else {
4138
- aout[0].type = numo_cInt32;
4139
- idx = nary_new(numo_cInt32, na->ndim, na->shape);
4140
- ndf.func = iter_int32_min_index_index32;
4141
-
4142
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
4143
- }
4144
- rb_funcall(idx, rb_intern("seq"), 0);
4145
-
4146
- return na_ndloop(&ndf, 3, self, idx, reduce);
4147
- }
4148
-
4149
- #define idx_t int64_t
4150
- static void iter_int32_argmax_arg64(na_loop_t* const lp) {
4151
- size_t n, idx;
4152
- char *d_ptr, *o_ptr;
4153
- ssize_t d_step;
4154
-
4155
- INIT_COUNTER(lp, n);
4156
- INIT_PTR(lp, 0, d_ptr, d_step);
4157
-
4158
- idx = f_max_index(n, d_ptr, d_step);
4159
-
4160
- o_ptr = NDL_PTR(lp, 1);
4161
- *(idx_t*)o_ptr = (idx_t)idx;
4162
- }
4163
- #undef idx_t
4164
-
4165
- #define idx_t int32_t
4166
- static void iter_int32_argmax_arg32(na_loop_t* const lp) {
4167
- size_t n, idx;
4168
- char *d_ptr, *o_ptr;
4169
- ssize_t d_step;
4170
-
4171
- INIT_COUNTER(lp, n);
4172
- INIT_PTR(lp, 0, d_ptr, d_step);
4173
-
4174
- idx = f_max_index(n, d_ptr, d_step);
4175
-
4176
- o_ptr = NDL_PTR(lp, 1);
4177
- *(idx_t*)o_ptr = (idx_t)idx;
4178
- }
4179
- #undef idx_t
4180
-
4181
- /*
4182
- Index of the maximum value.
4183
- @overload argmax(axis:nil)
4184
- @param [Numeric,Array,Range] axis Finds maximum values along the axis and returns **indices
4185
- along the axis**.
4186
- @return [Integer,Numo::Int] returns the result indices.
4187
- @see #max_index
4188
- @see #max
4189
-
4190
- @example
4191
- a = Numo::NArray[3,4,1,2]
4192
- a.argmax #=> 1
4193
-
4194
- b = Numo::NArray[[3,4,1],[2,0,5]]
4195
- b.argmax #=> 5
4196
- b.argmax(axis:1) #=> [1, 2]
4197
- b.argmax(axis:0) #=> [0, 0, 1]
4198
- b.at(b.argmax(axis:0), 0..-1) #=> [3, 4, 5]
4199
- */
4200
- static VALUE int32_argmax(int argc, VALUE* argv, VALUE self) {
4201
- narray_t* na;
4202
- VALUE reduce;
4203
- ndfunc_arg_in_t ain[2] = { { Qnil, 0 }, { sym_reduce, 0 } };
4204
- ndfunc_arg_out_t aout[1] = { { 0, 0, 0 } };
4205
- ndfunc_t ndf = { 0, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE | NDF_EXTRACT, 2, 1, ain, aout };
4206
-
4207
- GetNArray(self, na);
4208
- if (na->ndim == 0) {
4209
- return INT2FIX(0);
4210
- }
4211
- if (na->size > (~(u_int32_t)0)) {
4212
- aout[0].type = numo_cInt64;
4213
- ndf.func = iter_int32_argmax_arg64;
4214
-
4215
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
4216
-
4217
- } else {
4218
- aout[0].type = numo_cInt32;
4219
- ndf.func = iter_int32_argmax_arg32;
4220
-
4221
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
4222
- }
4223
-
4224
- return na_ndloop(&ndf, 2, self, reduce);
4225
- }
4226
-
4227
- #define idx_t int64_t
4228
- static void iter_int32_argmin_arg64(na_loop_t* const lp) {
4229
- size_t n, idx;
4230
- char *d_ptr, *o_ptr;
4231
- ssize_t d_step;
4232
-
4233
- INIT_COUNTER(lp, n);
4234
- INIT_PTR(lp, 0, d_ptr, d_step);
4235
-
4236
- idx = f_min_index(n, d_ptr, d_step);
4237
-
4238
- o_ptr = NDL_PTR(lp, 1);
4239
- *(idx_t*)o_ptr = (idx_t)idx;
4240
- }
4241
- #undef idx_t
4242
-
4243
- #define idx_t int32_t
4244
- static void iter_int32_argmin_arg32(na_loop_t* const lp) {
4245
- size_t n, idx;
4246
- char *d_ptr, *o_ptr;
4247
- ssize_t d_step;
4248
-
4249
- INIT_COUNTER(lp, n);
4250
- INIT_PTR(lp, 0, d_ptr, d_step);
4251
-
4252
- idx = f_min_index(n, d_ptr, d_step);
4253
-
4254
- o_ptr = NDL_PTR(lp, 1);
4255
- *(idx_t*)o_ptr = (idx_t)idx;
4256
- }
4257
- #undef idx_t
4258
-
4259
- /*
4260
- Index of the minimum value.
4261
- @overload argmin(axis:nil)
4262
- @param [Numeric,Array,Range] axis Finds minimum values along the axis and returns **indices
4263
- along the axis**.
4264
- @return [Integer,Numo::Int] returns the result indices.
4265
- @see #min_index
4266
- @see #min
4267
-
4268
- @example
4269
- a = Numo::NArray[3,4,1,2]
4270
- a.argmin #=> 2
4271
-
4272
- b = Numo::NArray[[3,4,1],[2,0,5]]
4273
- b.argmin #=> 4
4274
- b.argmin(axis:1) #=> [2, 1]
4275
- b.argmin(axis:0) #=> [1, 1, 0]
4276
- b.at(b.argmin(axis:0), 0..-1) #=> [2, 0, 1]
4277
- */
4278
- static VALUE int32_argmin(int argc, VALUE* argv, VALUE self) {
4279
- narray_t* na;
4280
- VALUE reduce;
4281
- ndfunc_arg_in_t ain[2] = { { Qnil, 0 }, { sym_reduce, 0 } };
4282
- ndfunc_arg_out_t aout[1] = { { 0, 0, 0 } };
4283
- ndfunc_t ndf = { 0, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE | NDF_EXTRACT, 2, 1, ain, aout };
4284
-
4285
- GetNArray(self, na);
4286
- if (na->ndim == 0) {
4287
- return INT2FIX(0);
4288
- }
4289
- if (na->size > (~(u_int32_t)0)) {
4290
- aout[0].type = numo_cInt64;
4291
- ndf.func = iter_int32_argmin_arg64;
4292
-
4293
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
4294
-
4295
- } else {
4296
- aout[0].type = numo_cInt32;
4297
- ndf.func = iter_int32_argmin_arg32;
4298
-
4299
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
4300
- }
4301
-
4302
- return na_ndloop(&ndf, 2, self, reduce);
4303
- }
4304
-
4305
- static void iter_int32_minmax(na_loop_t* const lp) {
4306
- size_t n;
4307
- char* p1;
4308
- ssize_t s1;
4309
- dtype xmin, xmax;
4310
-
4311
- INIT_COUNTER(lp, n);
4312
- INIT_PTR(lp, 0, p1, s1);
4313
-
4314
- f_minmax(n, p1, s1, &xmin, &xmax);
4315
-
4316
- *(dtype*)(lp->args[1].ptr + lp->args[1].iter[0].pos) = xmin;
4317
- *(dtype*)(lp->args[2].ptr + lp->args[2].iter[0].pos) = xmax;
4318
- }
4319
-
4320
- /*
4321
- minmax of self.
4322
- @overload minmax(axis:nil, keepdims:false)
4323
- @param [Numeric,Array,Range] axis Finds min-max along the axis.
4324
- @param [TrueClass] keepdims (keyword) If true, the reduced axes are left in the result array
4325
- as dimensions with size one.
4326
- @return [Numo::Int32,Numo::Int32] min and max of self.
4327
- */
4328
- static VALUE int32_minmax(int argc, VALUE* argv, VALUE self) {
4329
- VALUE reduce;
4330
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
4331
- ndfunc_arg_out_t aout[2] = { { cT, 0 }, { cT, 0 } };
4332
- ndfunc_t ndf = {
4333
- iter_int32_minmax, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE | NDF_EXTRACT, 2, 2, ain, aout
4334
- };
4335
-
4336
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
4337
-
4338
- return na_ndloop(&ndf, 2, self, reduce);
4339
- }
4340
-
4341
- static void iter_int32_s_maximum(na_loop_t* const lp) {
4342
- size_t i, n;
4343
- char *p1, *p2, *p3;
4344
- ssize_t s1, s2, s3;
4345
-
4346
- INIT_COUNTER(lp, n);
4347
- INIT_PTR(lp, 0, p1, s1);
4348
- INIT_PTR(lp, 1, p2, s2);
4349
- INIT_PTR(lp, 2, p3, s3);
4350
-
4351
- for (i = 0; i < n; i++) {
4352
- dtype x, y, z;
4353
- GET_DATA_STRIDE(p1, s1, dtype, x);
4354
- GET_DATA_STRIDE(p2, s2, dtype, y);
4355
- GET_DATA(p3, dtype, z);
4356
- z = f_maximum(x, y);
4357
- SET_DATA_STRIDE(p3, s3, dtype, z);
4358
- }
4359
- }
4360
-
4361
- static VALUE int32_s_maximum(int argc, VALUE* argv, VALUE mod) {
4362
- VALUE a1 = Qnil;
4363
- VALUE a2 = Qnil;
4364
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
4365
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
4366
- ndfunc_t ndf = { iter_int32_s_maximum, STRIDE_LOOP_NIP, 2, 1, ain, aout };
4367
-
4368
- rb_scan_args(argc, argv, "20", &a1, &a2);
4369
-
4370
- return na_ndloop(&ndf, 2, a1, a2);
4371
- }
4372
-
4373
- static void iter_int32_s_minimum(na_loop_t* const lp) {
4374
- size_t i, n;
4375
- char *p1, *p2, *p3;
4376
- ssize_t s1, s2, s3;
4377
-
4378
- INIT_COUNTER(lp, n);
4379
- INIT_PTR(lp, 0, p1, s1);
4380
- INIT_PTR(lp, 1, p2, s2);
4381
- INIT_PTR(lp, 2, p3, s3);
4382
-
4383
- for (i = 0; i < n; i++) {
4384
- dtype x, y, z;
4385
- GET_DATA_STRIDE(p1, s1, dtype, x);
4386
- GET_DATA_STRIDE(p2, s2, dtype, y);
4387
- GET_DATA(p3, dtype, z);
4388
- z = f_minimum(x, y);
4389
- SET_DATA_STRIDE(p3, s3, dtype, z);
4390
- }
4391
- }
4392
-
4393
- static VALUE int32_s_minimum(int argc, VALUE* argv, VALUE mod) {
4394
- VALUE a1 = Qnil;
4395
- VALUE a2 = Qnil;
4396
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
4397
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
4398
- ndfunc_t ndf = { iter_int32_s_minimum, STRIDE_LOOP_NIP, 2, 1, ain, aout };
4399
-
4400
- rb_scan_args(argc, argv, "20", &a1, &a2);
4401
-
4402
- return na_ndloop(&ndf, 2, a1, a2);
4403
- }
4404
-
4405
- // ------- Integer count without weights -------
4406
-
4407
- static void iter_int32_bincount_32(na_loop_t* const lp) {
4408
- size_t i, x, n;
4409
- char *p1, *p2;
4410
- ssize_t s1, s2;
4411
- size_t* idx1;
4412
-
4413
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
4414
- INIT_PTR(lp, 1, p2, s2);
4415
- i = lp->args[0].shape[0];
4416
- n = lp->args[1].shape[0];
4417
-
4418
- // initialize
4419
- for (x = 0; x < n; x++) {
4420
- *(u_int32_t*)(p2 + s2 * x) = 0;
4421
- }
4422
-
4423
- if (idx1) {
4424
- for (; i--;) {
4425
- GET_DATA_INDEX(p1, idx1, dtype, x);
4426
- (*(u_int32_t*)(p2 + s2 * x))++;
4427
- }
4428
- } else {
4429
- for (; i--;) {
4430
- GET_DATA_STRIDE(p1, s1, dtype, x);
4431
- (*(u_int32_t*)(p2 + s2 * x))++;
4432
- }
4433
- }
4434
- }
4435
-
4436
- static VALUE int32_bincount_32(VALUE self, size_t length) {
4437
- size_t shape_out[1] = { length };
4438
- ndfunc_arg_in_t ain[1] = { { cT, 1 } };
4439
- ndfunc_arg_out_t aout[1] = { { numo_cUInt32, 1, shape_out } };
4440
- ndfunc_t ndf = {
4441
- iter_int32_bincount_32, NO_LOOP | NDF_STRIDE_LOOP | NDF_INDEX_LOOP, 1, 1, ain, aout
4442
- };
4443
-
4444
- return na_ndloop(&ndf, 1, self);
4445
- }
4446
-
4447
- static void iter_int32_bincount_64(na_loop_t* const lp) {
4448
- size_t i, x, n;
4449
- char *p1, *p2;
4450
- ssize_t s1, s2;
4451
- size_t* idx1;
4452
-
4453
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
4454
- INIT_PTR(lp, 1, p2, s2);
4455
- i = lp->args[0].shape[0];
4456
- n = lp->args[1].shape[0];
4457
-
4458
- // initialize
4459
- for (x = 0; x < n; x++) {
4460
- *(u_int64_t*)(p2 + s2 * x) = 0;
4461
- }
4462
-
4463
- if (idx1) {
4464
- for (; i--;) {
4465
- GET_DATA_INDEX(p1, idx1, dtype, x);
4466
- (*(u_int64_t*)(p2 + s2 * x))++;
4467
- }
4468
- } else {
4469
- for (; i--;) {
4470
- GET_DATA_STRIDE(p1, s1, dtype, x);
4471
- (*(u_int64_t*)(p2 + s2 * x))++;
4472
- }
4473
- }
4474
- }
4475
-
4476
- static VALUE int32_bincount_64(VALUE self, size_t length) {
4477
- size_t shape_out[1] = { length };
4478
- ndfunc_arg_in_t ain[1] = { { cT, 1 } };
4479
- ndfunc_arg_out_t aout[1] = { { numo_cUInt64, 1, shape_out } };
4480
- ndfunc_t ndf = {
4481
- iter_int32_bincount_64, NO_LOOP | NDF_STRIDE_LOOP | NDF_INDEX_LOOP, 1, 1, ain, aout
4482
- };
4483
-
4484
- return na_ndloop(&ndf, 1, self);
4485
- }
4486
- // ------- end of Integer count without weights -------
4487
-
4488
- // ------- Float count with weights -------
4489
-
4490
- static void iter_int32_bincount_sf(na_loop_t* const lp) {
4491
- float w;
4492
- size_t i, x, n, m;
4493
- char *p1, *p2, *p3;
4494
- ssize_t s1, s2, s3;
4495
-
4496
- INIT_PTR(lp, 0, p1, s1);
4497
- INIT_PTR(lp, 1, p2, s2);
4498
- INIT_PTR(lp, 2, p3, s3);
4499
- i = lp->args[0].shape[0];
4500
- m = lp->args[1].shape[0];
4501
- n = lp->args[2].shape[0];
4502
-
4503
- if (i != m) {
4504
- rb_raise(nary_eShapeError, "size mismatch along last axis between self and weight");
4505
- }
4506
-
4507
- // initialize
4508
- for (x = 0; x < n; x++) {
4509
- *(float*)(p3 + s3 * x) = 0;
4510
- }
4511
- for (; i--;) {
4512
- GET_DATA_STRIDE(p1, s1, dtype, x);
4513
- GET_DATA_STRIDE(p2, s2, float, w);
4514
- (*(float*)(p3 + s3 * x)) += w;
4515
- }
4516
- }
4517
-
4518
- static VALUE int32_bincount_sf(VALUE self, VALUE weight, size_t length) {
4519
- size_t shape_out[1] = { length };
4520
- ndfunc_arg_in_t ain[2] = { { cT, 1 }, { numo_cSFloat, 1 } };
4521
- ndfunc_arg_out_t aout[1] = { { numo_cSFloat, 1, shape_out } };
4522
- ndfunc_t ndf = { iter_int32_bincount_sf, NO_LOOP | NDF_STRIDE_LOOP, 2, 1, ain, aout };
4523
-
4524
- return na_ndloop(&ndf, 2, self, weight);
4525
- }
4526
-
4527
- static void iter_int32_bincount_df(na_loop_t* const lp) {
4528
- double w;
4529
- size_t i, x, n, m;
4530
- char *p1, *p2, *p3;
4531
- ssize_t s1, s2, s3;
4532
-
4533
- INIT_PTR(lp, 0, p1, s1);
4534
- INIT_PTR(lp, 1, p2, s2);
4535
- INIT_PTR(lp, 2, p3, s3);
4536
- i = lp->args[0].shape[0];
4537
- m = lp->args[1].shape[0];
4538
- n = lp->args[2].shape[0];
4539
-
4540
- if (i != m) {
4541
- rb_raise(nary_eShapeError, "size mismatch along last axis between self and weight");
4542
- }
4543
-
4544
- // initialize
4545
- for (x = 0; x < n; x++) {
4546
- *(double*)(p3 + s3 * x) = 0;
4547
- }
4548
- for (; i--;) {
4549
- GET_DATA_STRIDE(p1, s1, dtype, x);
4550
- GET_DATA_STRIDE(p2, s2, double, w);
4551
- (*(double*)(p3 + s3 * x)) += w;
4552
- }
4553
- }
4554
-
4555
- static VALUE int32_bincount_df(VALUE self, VALUE weight, size_t length) {
4556
- size_t shape_out[1] = { length };
4557
- ndfunc_arg_in_t ain[2] = { { cT, 1 }, { numo_cDFloat, 1 } };
4558
- ndfunc_arg_out_t aout[1] = { { numo_cDFloat, 1, shape_out } };
4559
- ndfunc_t ndf = { iter_int32_bincount_df, NO_LOOP | NDF_STRIDE_LOOP, 2, 1, ain, aout };
4560
-
4561
- return na_ndloop(&ndf, 2, self, weight);
4562
- }
4563
- // ------- end of Float count with weights -------
4564
-
4565
- /*
4566
- Count the number of occurrences of each non-negative integer value.
4567
- Only Integer-types has this method.
4568
-
4569
- @overload bincount([weight], minlength:nil)
4570
- @param [SFloat or DFloat or Array] weight (optional) Array of
4571
- float values. Its size along last axis should be same as that of self.
4572
- @param [Integer] minlength (keyword, optional) Minimum size along
4573
- last axis for the output array.
4574
- @return [UInt32 or UInt64 or SFloat or DFloat]
4575
- Returns Float NArray if weight array is supplied,
4576
- otherwise returns UInt32 or UInt64 depending on the size along last axis.
4577
- @example
4578
- Numo::Int32[0..4].bincount
4579
- # => Numo::UInt32#shape=[5]
4580
- # [1, 1, 1, 1, 1]
4581
-
4582
- Numo::Int32[0, 1, 1, 3, 2, 1, 7].bincount
4583
- # => Numo::UInt32#shape=[8]
4584
- # [1, 3, 1, 1, 0, 0, 0, 1]
4585
-
4586
- x = Numo::Int32[0, 1, 1, 3, 2, 1, 7, 23]
4587
- x.bincount.size == x.max+1
4588
- # => true
4589
-
4590
- w = Numo::DFloat[0.3, 0.5, 0.2, 0.7, 1.0, -0.6]
4591
- x = Numo::Int32[0, 1, 1, 2, 2, 2]
4592
- x.bincount(w)
4593
- # => Numo::DFloat#shape=[3]
4594
- # [0.3, 0.7, 1.1]
4595
-
4596
- */
4597
- static VALUE int32_bincount(int argc, VALUE* argv, VALUE self) {
4598
- VALUE weight = Qnil, kw = Qnil;
4599
- VALUE opts[1] = { Qundef };
4600
- VALUE v, wclass;
4601
- ID table[1] = { id_minlength };
4602
- size_t length, minlength;
4603
-
4604
- rb_scan_args(argc, argv, "01:", &weight, &kw);
4605
- rb_get_kwargs(kw, table, 0, 1, opts);
4606
-
4607
- v = int32_minmax(0, 0, self);
4608
- if (m_num_to_data(RARRAY_AREF(v, 0)) < 0) {
4609
- rb_raise(rb_eArgError, "array items must be non-netagive");
4610
- }
4611
- v = RARRAY_AREF(v, 1);
4612
-
4613
- length = NUM2SIZET(v) + 1;
4614
-
4615
- if (opts[0] != Qundef) {
4616
- minlength = NUM2SIZET(opts[0]);
4617
- if (minlength > length) {
4618
- length = minlength;
4619
- }
4620
- }
4621
-
4622
- if (NIL_P(weight)) {
4623
- if (length > 4294967295ul) {
4624
- return int32_bincount_64(self, length);
4625
- } else {
4626
- return int32_bincount_32(self, length);
4627
- }
4628
- } else {
4629
- wclass = rb_obj_class(weight);
4630
- if (wclass == numo_cSFloat) {
4631
- return int32_bincount_sf(self, weight, length);
4632
- } else {
4633
- return int32_bincount_df(self, weight, length);
4634
- }
4635
- }
4636
- }
4637
-
4638
- static void iter_int32_cumsum(na_loop_t* const lp) {
4639
- size_t i;
4640
- char *p1, *p2;
4641
- ssize_t s1, s2;
4642
- dtype x, y;
4643
-
4644
- INIT_COUNTER(lp, i);
4645
- INIT_PTR(lp, 0, p1, s1);
4646
- INIT_PTR(lp, 1, p2, s2);
4647
-
4648
- GET_DATA_STRIDE(p1, s1, dtype, x);
4649
- SET_DATA_STRIDE(p2, s2, dtype, x);
4650
- for (i--; i--;) {
4651
- GET_DATA_STRIDE(p1, s1, dtype, y);
4652
- m_cumsum(x, y);
4653
- SET_DATA_STRIDE(p2, s2, dtype, x);
4654
- }
4655
- }
4656
-
4657
- /*
4658
- cumsum of self.
4659
- @overload cumsum(axis:nil, nan:false)
4660
- @param [Numeric,Array,Range] axis Performs cumsum along the axis.
4661
- @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN if exists).
4662
- @return [Numo::Int32] cumsum of self.
4663
- */
4664
- static VALUE int32_cumsum(int argc, VALUE* argv, VALUE self) {
4665
- VALUE reduce;
4666
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
4667
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
4668
- ndfunc_t ndf = {
4669
- iter_int32_cumsum, STRIDE_LOOP | NDF_FLAT_REDUCE | NDF_CUM, 2, 1, ain, aout
4670
- };
4671
-
4672
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
4673
-
4674
- return na_ndloop(&ndf, 2, self, reduce);
4675
- }
4676
-
4677
- static void iter_int32_cumprod(na_loop_t* const lp) {
4678
- size_t i;
4679
- char *p1, *p2;
4680
- ssize_t s1, s2;
4681
- dtype x, y;
4682
-
4683
- INIT_COUNTER(lp, i);
4684
- INIT_PTR(lp, 0, p1, s1);
4685
- INIT_PTR(lp, 1, p2, s2);
4686
-
4687
- GET_DATA_STRIDE(p1, s1, dtype, x);
4688
- SET_DATA_STRIDE(p2, s2, dtype, x);
4689
- for (i--; i--;) {
4690
- GET_DATA_STRIDE(p1, s1, dtype, y);
4691
- m_cumprod(x, y);
4692
- SET_DATA_STRIDE(p2, s2, dtype, x);
4693
- }
4694
- }
4695
-
4696
- /*
4697
- cumprod of self.
4698
- @overload cumprod(axis:nil, nan:false)
4699
- @param [Numeric,Array,Range] axis Performs cumprod along the axis.
4700
- @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN if exists).
4701
- @return [Numo::Int32] cumprod of self.
4702
- */
4703
- static VALUE int32_cumprod(int argc, VALUE* argv, VALUE self) {
4704
- VALUE reduce;
4705
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
4706
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
4707
- ndfunc_t ndf = {
4708
- iter_int32_cumprod, STRIDE_LOOP | NDF_FLAT_REDUCE | NDF_CUM, 2, 1, ain, aout
4709
- };
4710
-
4711
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
4712
-
4713
- return na_ndloop(&ndf, 2, self, reduce);
4714
- }
4715
-
4716
- //
4717
- static void iter_int32_mulsum(na_loop_t* const lp) {
4718
- size_t i, n;
4719
- char *p1, *p2, *p3;
4720
- ssize_t s1, s2, s3;
4721
-
4722
- INIT_COUNTER(lp, n);
4723
- INIT_PTR(lp, 0, p1, s1);
4724
- INIT_PTR(lp, 1, p2, s2);
4725
- INIT_PTR(lp, 2, p3, s3);
4726
-
4727
- if (s3 == 0) {
4728
- dtype z;
4729
- // Reduce loop
4730
- GET_DATA(p3, dtype, z);
4731
- for (i = 0; i < n; i++) {
4732
- dtype x, y;
4733
- GET_DATA_STRIDE(p1, s1, dtype, x);
4734
- GET_DATA_STRIDE(p2, s2, dtype, y);
4735
- m_mulsum(x, y, z);
4736
- }
4737
- SET_DATA(p3, dtype, z);
4738
- return;
4739
- } else {
4740
- for (i = 0; i < n; i++) {
4741
- dtype x, y, z;
4742
- GET_DATA_STRIDE(p1, s1, dtype, x);
4743
- GET_DATA_STRIDE(p2, s2, dtype, y);
4744
- GET_DATA(p3, dtype, z);
4745
- m_mulsum(x, y, z);
4746
- SET_DATA_STRIDE(p3, s3, dtype, z);
4747
- }
4748
- }
4749
- }
4750
- //
4751
-
4752
- static VALUE int32_mulsum_self(int argc, VALUE* argv, VALUE self) {
4753
- VALUE v, reduce;
4754
- VALUE naryv[2];
4755
- ndfunc_arg_in_t ain[4] = { { cT, 0 }, { cT, 0 }, { sym_reduce, 0 }, { sym_init, 0 } };
4756
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
4757
- ndfunc_t ndf = { iter_int32_mulsum, STRIDE_LOOP_NIP, 4, 1, ain, aout };
4758
-
4759
- if (argc < 1) {
4760
- rb_raise(rb_eArgError, "wrong number of arguments (%d for >=1)", argc);
4761
- }
4762
- // should fix below: [self.ndim,other.ndim].max or?
4763
- naryv[0] = self;
4764
- naryv[1] = argv[0];
4765
- //
4766
- reduce = na_reduce_dimension(argc - 1, argv + 1, 2, naryv, &ndf, 0);
4767
- //
4768
-
4769
- v = na_ndloop(&ndf, 4, self, argv[0], reduce, m_mulsum_init);
4770
- return int32_extract(v);
4771
- }
4772
-
4773
- /*
4774
- Binary mulsum.
4775
-
4776
- @overload mulsum(other, axis:nil, keepdims:false)
4777
- @param [Numo::NArray,Numeric] other
4778
- @param [Numeric,Array,Range] axis Performs mulsum along the axis.
4779
- @param [TrueClass] keepdims (keyword) If true, the reduced axes are left in the result array
4780
- as dimensions with size one.
4781
- @return [Numo::NArray] mulsum of self and other.
4782
- */
4783
- static VALUE int32_mulsum(int argc, VALUE* argv, VALUE self) {
4784
- //
4785
- VALUE klass, v;
4786
- //
4787
- if (argc < 1) {
4788
- rb_raise(rb_eArgError, "wrong number of arguments (%d for >=1)", argc);
4789
- }
4790
- //
4791
- klass = na_upcast(rb_obj_class(self), rb_obj_class(argv[0]));
4792
- if (klass == cT) {
4793
- return int32_mulsum_self(argc, argv, self);
4794
- } else {
4795
- v = rb_funcall(klass, id_cast, 1, self);
4796
- //
4797
- return rb_funcallv_kw(v, rb_intern("mulsum"), argc, argv, RB_PASS_CALLED_KEYWORDS);
4798
- //
4799
- }
4800
- //
4801
- }
4802
-
4803
- typedef double seq_data_t;
4804
-
4805
- typedef double seq_count_t;
4806
-
4807
- typedef struct {
4808
- seq_data_t beg;
4809
- seq_data_t step;
4810
- seq_count_t count;
4811
- } seq_opt_t;
4812
-
4813
- static void iter_int32_seq(na_loop_t* const lp) {
4814
- size_t i;
4815
- char* p1;
4816
- ssize_t s1;
4817
- size_t* idx1;
4818
- dtype x;
4819
- seq_data_t beg, step;
4820
- seq_count_t c;
4821
- seq_opt_t* g;
4822
-
4823
- INIT_COUNTER(lp, i);
4824
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
4825
- g = (seq_opt_t*)(lp->opt_ptr);
4826
- beg = g->beg;
4827
- step = g->step;
4828
- c = g->count;
4829
- if (idx1) {
4830
- for (; i--;) {
4831
- x = f_seq(beg, step, c++);
4832
- *(dtype*)(p1 + *idx1) = x;
4833
- idx1++;
4834
- }
4835
- } else {
4836
- for (; i--;) {
4837
- x = f_seq(beg, step, c++);
4838
- *(dtype*)(p1) = x;
4839
- p1 += s1;
4840
- }
4841
- }
4842
- g->count = c;
4843
- }
4844
-
4845
- /*
4846
- Set linear sequence of numbers to self. The sequence is obtained from
4847
- beg+i*step
4848
- where i is 1-dimensional index.
4849
- @overload seq([beg,[step]])
4850
- @param [Numeric] beg beginning of sequence. (default=0)
4851
- @param [Numeric] step step of sequence. (default=1)
4852
- @return [Numo::Int32] self.
4853
- @example
4854
- Numo::DFloat.new(6).seq(1,-0.2)
4855
- # => Numo::DFloat#shape=[6]
4856
- # [1, 0.8, 0.6, 0.4, 0.2, 0]
4857
-
4858
- Numo::DComplex.new(6).seq(1,-0.2+0.2i)
4859
- # => Numo::DComplex#shape=[6]
4860
- # [1+0i, 0.8+0.2i, 0.6+0.4i, 0.4+0.6i, 0.2+0.8i, 0+1i]
4861
- */
4862
- static VALUE int32_seq(int argc, VALUE* argv, VALUE self) {
4863
- seq_opt_t* g;
4864
- VALUE vbeg = Qnil, vstep = Qnil;
4865
- ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
4866
- ndfunc_t ndf = { iter_int32_seq, FULL_LOOP, 1, 0, ain, 0 };
4867
-
4868
- g = ALLOCA_N(seq_opt_t, 1);
4869
- g->beg = m_zero;
4870
- g->step = m_one;
4871
- g->count = 0;
4872
- rb_scan_args(argc, argv, "02", &vbeg, &vstep);
4873
- if (vbeg != Qnil) {
4874
- g->beg = NUM2DBL(vbeg);
4875
- }
4876
- if (vstep != Qnil) {
4877
- g->step = NUM2DBL(vstep);
4878
- }
4879
-
4880
- na_ndloop3(&ndf, g, 1, self);
4881
- return self;
4882
- }
4883
-
4884
- static void iter_int32_eye(na_loop_t* const lp) {
4885
- size_t n0, n1;
4886
- size_t i0, i1;
4887
- ssize_t s0, s1;
4888
- char *p0, *p1;
4889
- char* g;
4890
- ssize_t kofs;
4891
- dtype data;
4892
-
4893
- g = (char*)(lp->opt_ptr);
4894
- kofs = *(ssize_t*)g;
4895
- data = *(dtype*)(g + sizeof(ssize_t));
4896
-
4897
- n0 = lp->args[0].shape[0];
4898
- n1 = lp->args[0].shape[1];
4899
- s0 = lp->args[0].iter[0].step;
4900
- s1 = lp->args[0].iter[1].step;
4901
- p0 = NDL_PTR(lp, 0);
4902
-
4903
- for (i0 = 0; i0 < n0; i0++) {
4904
- p1 = p0;
4905
- for (i1 = 0; i1 < n1; i1++) {
4906
- *(dtype*)p1 = (i0 + kofs == i1) ? data : m_zero;
4907
- p1 += s1;
4908
- }
4909
- p0 += s0;
4910
- }
4911
- }
4912
-
4913
- /*
4914
- Eye: Set a value to diagonal components, set 0 to non-diagonal components.
4915
- @overload eye([element,offset])
4916
- @param [Numeric] element Diagonal element to be stored. Default is 1.
4917
- @param [Integer] offset Diagonal offset from the main diagonal. The
4918
- default is 0. k>0 for diagonals above the main diagonal, and k<0
4919
- for diagonals below the main diagonal.
4920
- @return [Numo::Int32] eye of self.
4921
- */
4922
- static VALUE int32_eye(int argc, VALUE* argv, VALUE self) {
4923
- ndfunc_arg_in_t ain[1] = { { OVERWRITE, 2 } };
4924
- ndfunc_t ndf = { iter_int32_eye, NO_LOOP, 1, 0, ain, 0 };
4925
- ssize_t kofs;
4926
- dtype data;
4927
- char* g;
4928
- int nd;
4929
- narray_t* na;
4930
-
4931
- // check arguments
4932
- if (argc > 2) {
4933
- rb_raise(rb_eArgError, "too many arguments (%d for 0..2)", argc);
4934
- } else if (argc == 2) {
4935
- data = m_num_to_data(argv[0]);
4936
- kofs = NUM2SSIZET(argv[1]);
4937
- } else if (argc == 1) {
4938
- data = m_num_to_data(argv[0]);
4939
- kofs = 0;
4940
- } else {
4941
- data = m_one;
4942
- kofs = 0;
4943
- }
4944
-
4945
- GetNArray(self, na);
4946
- nd = na->ndim;
4947
- if (nd < 2) {
4948
- rb_raise(nary_eDimensionError, "less than 2-d array");
4949
- }
4950
-
4951
- // Diagonal offset from the main diagonal.
4952
- if (kofs >= 0) {
4953
- if ((size_t)(kofs) >= na->shape[nd - 1]) {
4954
- rb_raise(
4955
- rb_eArgError,
4956
- "invalid diagonal offset(%" SZF "d) for "
4957
- "last dimension size(%" SZF "d)",
4958
- kofs, na->shape[nd - 1]
4959
- );
4960
- }
4961
- } else {
4962
- if ((size_t)(-kofs) >= na->shape[nd - 2]) {
4963
- rb_raise(
4964
- rb_eArgError,
4965
- "invalid diagonal offset(%" SZF "d) for "
4966
- "last-1 dimension size(%" SZF "d)",
4967
- kofs, na->shape[nd - 2]
4968
- );
4969
- }
4970
- }
4971
-
4972
- g = ALLOCA_N(char, sizeof(ssize_t) + sizeof(dtype));
4973
- *(ssize_t*)g = kofs;
4974
- *(dtype*)(g + sizeof(ssize_t)) = data;
1844
+ ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1845
+ ndfunc_t ndf = { iter_int32_reciprocal, FULL_LOOP, 1, 1, ain, aout };
4975
1846
 
4976
- na_ndloop3(&ndf, g, 1, self);
4977
- return self;
1847
+ return na_ndloop(&ndf, 1, self);
4978
1848
  }
4979
1849
 
4980
- #define HWID (sizeof(dtype) * 4)
4981
-
4982
- static int msb_pos(uint32_t a) {
4983
- int width = HWID;
4984
- int pos = 0;
4985
- uint32_t mask = (((dtype)1 << HWID) - 1) << HWID;
1850
+ static void iter_int32_sign(na_loop_t* const lp) {
1851
+ size_t i, n;
1852
+ char *p1, *p2;
1853
+ ssize_t s1, s2;
1854
+ size_t *idx1, *idx2;
1855
+ dtype x;
4986
1856
 
4987
- if (a == 0) {
4988
- return -1;
4989
- }
1857
+ INIT_COUNTER(lp, n);
1858
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1859
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
4990
1860
 
4991
- while (width) {
4992
- if (a & mask) {
4993
- pos += width;
1861
+ if (idx1) {
1862
+ if (idx2) {
1863
+ for (i = 0; i < n; i++) {
1864
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1865
+ x = m_sign(x);
1866
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1867
+ }
1868
+ } else {
1869
+ for (i = 0; i < n; i++) {
1870
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1871
+ x = m_sign(x);
1872
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1873
+ }
1874
+ }
1875
+ } else {
1876
+ if (idx2) {
1877
+ for (i = 0; i < n; i++) {
1878
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1879
+ x = m_sign(x);
1880
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1881
+ }
4994
1882
  } else {
4995
- mask >>= width;
1883
+ //
1884
+ if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
1885
+ if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
1886
+ for (i = 0; i < n; i++) {
1887
+ ((dtype*)p2)[i] = m_sign(((dtype*)p1)[i]);
1888
+ }
1889
+ return;
1890
+ }
1891
+ if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
1892
+ //
1893
+ for (i = 0; i < n; i++) {
1894
+ *(dtype*)p2 = m_sign(*(dtype*)p1);
1895
+ p1 += s1;
1896
+ p2 += s2;
1897
+ }
1898
+ return;
1899
+ //
1900
+ }
1901
+ }
1902
+ for (i = 0; i < n; i++) {
1903
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1904
+ x = m_sign(x);
1905
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1906
+ }
1907
+ //
4996
1908
  }
4997
- width >>= 1;
4998
- mask &= mask << width;
4999
1909
  }
5000
- return pos;
5001
1910
  }
5002
1911
 
5003
- /* generates a random number on [0,max) */
5004
- inline static dtype m_rand(uint32_t max, int shift) {
5005
- uint32_t x;
5006
- do {
5007
- x = gen_rand32();
5008
- x >>= shift;
5009
- } while (x >= max);
5010
- return x;
5011
- }
1912
+ /*
1913
+ Unary sign.
1914
+ @overload sign
1915
+ @return [Numo::Int32] sign of self.
1916
+ */
1917
+ static VALUE int32_sign(VALUE self) {
1918
+ ndfunc_arg_in_t ain[1] = { { cT, 0 } };
1919
+ ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1920
+ ndfunc_t ndf = { iter_int32_sign, FULL_LOOP, 1, 1, ain, aout };
5012
1921
 
5013
- typedef struct {
5014
- dtype low;
5015
- uint32_t max;
5016
- } rand_opt_t;
1922
+ return na_ndloop(&ndf, 1, self);
1923
+ }
5017
1924
 
5018
- static void iter_int32_rand(na_loop_t* const lp) {
5019
- size_t i;
5020
- char* p1;
5021
- ssize_t s1;
5022
- size_t* idx1;
1925
+ static void iter_int32_square(na_loop_t* const lp) {
1926
+ size_t i, n;
1927
+ char *p1, *p2;
1928
+ ssize_t s1, s2;
1929
+ size_t *idx1, *idx2;
5023
1930
  dtype x;
5024
- rand_opt_t* g;
5025
- dtype low;
5026
- uint32_t max;
5027
- int shift;
5028
1931
 
5029
- INIT_COUNTER(lp, i);
1932
+ INIT_COUNTER(lp, n);
5030
1933
  INIT_PTR_IDX(lp, 0, p1, s1, idx1);
5031
- g = (rand_opt_t*)(lp->opt_ptr);
5032
- low = g->low;
5033
- max = g->max;
5034
- shift = 31 - msb_pos(max);
1934
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
5035
1935
 
5036
1936
  if (idx1) {
5037
- for (; i--;) {
5038
- x = m_add(m_rand(max, shift), low);
5039
- SET_DATA_INDEX(p1, idx1, dtype, x);
1937
+ if (idx2) {
1938
+ for (i = 0; i < n; i++) {
1939
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1940
+ x = m_square(x);
1941
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1942
+ }
1943
+ } else {
1944
+ for (i = 0; i < n; i++) {
1945
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1946
+ x = m_square(x);
1947
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1948
+ }
5040
1949
  }
5041
1950
  } else {
5042
- for (; i--;) {
5043
- x = m_add(m_rand(max, shift), low);
5044
- SET_DATA_STRIDE(p1, s1, dtype, x);
1951
+ if (idx2) {
1952
+ for (i = 0; i < n; i++) {
1953
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1954
+ x = m_square(x);
1955
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1956
+ }
1957
+ } else {
1958
+ //
1959
+ if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
1960
+ if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
1961
+ for (i = 0; i < n; i++) {
1962
+ ((dtype*)p2)[i] = m_square(((dtype*)p1)[i]);
1963
+ }
1964
+ return;
1965
+ }
1966
+ if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
1967
+ //
1968
+ for (i = 0; i < n; i++) {
1969
+ *(dtype*)p2 = m_square(*(dtype*)p1);
1970
+ p1 += s1;
1971
+ p2 += s2;
1972
+ }
1973
+ return;
1974
+ //
1975
+ }
1976
+ }
1977
+ for (i = 0; i < n; i++) {
1978
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1979
+ x = m_square(x);
1980
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1981
+ }
1982
+ //
5045
1983
  }
5046
1984
  }
5047
1985
  }
5048
1986
 
5049
1987
  /*
5050
- Generate uniformly distributed random numbers on self narray.
5051
- @overload rand([[low],high])
5052
- @param [Numeric] low lower inclusive boundary of random numbers. (default=0)
5053
- @param [Numeric] high upper exclusive boundary of random numbers. (default=1 or 1+1i for
5054
- complex types)
5055
- @return [Numo::Int32] self.
5056
- @example
5057
- Numo::DFloat.new(6).rand
5058
- # => Numo::DFloat#shape=[6]
5059
- # [0.0617545, 0.373067, 0.794815, 0.201042, 0.116041, 0.344032]
5060
-
5061
- Numo::DComplex.new(6).rand(5+5i)
5062
- # => Numo::DComplex#shape=[6]
5063
- # [2.69974+3.68908i, 0.825443+0.254414i, 0.540323+0.34354i, 4.52061+2.39322i, ...]
5064
-
5065
- Numo::Int32.new(6).rand(2,5)
5066
- # => Numo::Int32#shape=[6]
5067
- # [4, 3, 3, 2, 4, 2]
1988
+ Unary square.
1989
+ @overload square
1990
+ @return [Numo::Int32] square of self.
5068
1991
  */
5069
- static VALUE int32_rand(int argc, VALUE* argv, VALUE self) {
5070
- rand_opt_t g;
5071
- VALUE v1 = Qnil, v2 = Qnil;
5072
- dtype high;
5073
- ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
5074
- ndfunc_t ndf = { iter_int32_rand, FULL_LOOP, 1, 0, ain, 0 };
5075
-
5076
- rb_scan_args(argc, argv, "11", &v1, &v2);
5077
- if (v2 == Qnil) {
5078
- g.low = m_zero;
5079
- g.max = high = m_num_to_data(v1);
5080
-
5081
- } else {
5082
- g.low = m_num_to_data(v1);
5083
- high = m_num_to_data(v2);
5084
- g.max = m_sub(high, g.low);
5085
- }
5086
-
5087
- if (high <= g.low) {
5088
- rb_raise(rb_eArgError, "high must be larger than low");
5089
- }
1992
+ static VALUE int32_square(VALUE self) {
1993
+ ndfunc_arg_in_t ain[1] = { { cT, 0 } };
1994
+ ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1995
+ ndfunc_t ndf = { iter_int32_square, FULL_LOOP, 1, 1, ain, aout };
5090
1996
 
5091
- na_ndloop3(&ndf, &g, 1, self);
5092
- return self;
1997
+ return na_ndloop(&ndf, 1, self);
5093
1998
  }
5094
1999
 
5095
2000
  static void iter_int32_poly(na_loop_t* const lp) {
@@ -5715,22 +2620,91 @@ void Init_numo_int32(void) {
5715
2620
  rb_define_singleton_method(cT, "cast", int32_s_cast, 1);
5716
2621
  rb_define_method(cT, "[]", int32_aref, -1);
5717
2622
  rb_define_method(cT, "[]=", int32_aset, -1);
2623
+ /**
2624
+ * return NArray with cast to the type of self.
2625
+ * @overload coerce_cast(type)
2626
+ * @return [nil]
2627
+ */
5718
2628
  rb_define_method(cT, "coerce_cast", int32_coerce_cast, 1);
2629
+ /**
2630
+ * Convert self to Array.
2631
+ * @overload to_a
2632
+ * @return [Array]
2633
+ */
5719
2634
  rb_define_method(cT, "to_a", int32_to_a, 0);
2635
+ /**
2636
+ * Fill elements with other.
2637
+ * @overload fill other
2638
+ * @param [Numeric] other
2639
+ * @return [Numo::Int32] self.
2640
+ */
5720
2641
  rb_define_method(cT, "fill", int32_fill, 1);
2642
+ /**
2643
+ * Format elements into strings.
2644
+ * @overload format format
2645
+ * @param [String] format
2646
+ * @return [Numo::RObject] array of formatted strings.
2647
+ */
5721
2648
  rb_define_method(cT, "format", int32_format, -1);
2649
+ /**
2650
+ * Format elements into strings.
2651
+ * @overload format_to_a format
2652
+ * @param [String] format
2653
+ * @return [Array] array of formatted strings.
2654
+ */
5722
2655
  rb_define_method(cT, "format_to_a", int32_format_to_a, -1);
2656
+ /**
2657
+ * Returns a string containing a human-readable representation of NArray.
2658
+ * @overload inspect
2659
+ * @return [String]
2660
+ */
5723
2661
  rb_define_method(cT, "inspect", int32_inspect, 0);
5724
2662
  rb_define_method(cT, "each", int32_each, 0);
5725
2663
  rb_define_method(cT, "map", int32_map, 0);
5726
2664
  rb_define_method(cT, "each_with_index", int32_each_with_index, 0);
5727
2665
  rb_define_method(cT, "map_with_index", int32_map_with_index, 0);
5728
2666
  rb_define_method(cT, "abs", int32_abs, 0);
2667
+ /**
2668
+ * Binary add.
2669
+ * @overload + other
2670
+ * @param [Numo::NArray,Numeric] other
2671
+ * @return [Numo::NArray] self + other
2672
+ */
5729
2673
  rb_define_method(cT, "+", int32_add, 1);
2674
+ /**
2675
+ * Binary sub.
2676
+ * @overload - other
2677
+ * @param [Numo::NArray,Numeric] other
2678
+ * @return [Numo::NArray] self - other
2679
+ */
5730
2680
  rb_define_method(cT, "-", int32_sub, 1);
2681
+ /**
2682
+ * Binary mul.
2683
+ * @overload * other
2684
+ * @param [Numo::NArray,Numeric] other
2685
+ * @return [Numo::NArray] self * other
2686
+ */
5731
2687
  rb_define_method(cT, "*", int32_mul, 1);
2688
+ /**
2689
+ * Binary div.
2690
+ * @overload / other
2691
+ * @param [Numo::NArray,Numeric] other
2692
+ * @return [Numo::NArray] self / other
2693
+ */
5732
2694
  rb_define_method(cT, "/", int32_div, 1);
2695
+ /**
2696
+ * Binary mod.
2697
+ * @overload % other
2698
+ * @param [Numo::NArray,Numeric] other
2699
+ * @return [Numo::NArray] self % other
2700
+ */
5733
2701
  rb_define_method(cT, "%", int32_mod, 1);
2702
+ /**
2703
+ * Binary divmod.
2704
+ * @overload divmod other
2705
+ * @param [Numo::NArray,Numeric] other
2706
+ * @return [Numo::NArray] divmod of self and other.
2707
+ */
5734
2708
  rb_define_method(cT, "divmod", int32_divmod, 1);
5735
2709
  rb_define_method(cT, "**", int32_pow, 1);
5736
2710
  rb_define_alias(cT, "pow", "**");
@@ -5741,39 +2715,264 @@ void Init_numo_int32(void) {
5741
2715
  rb_define_alias(cT, "conj", "view");
5742
2716
  rb_define_alias(cT, "im", "view");
5743
2717
  rb_define_alias(cT, "conjugate", "conj");
2718
+ /**
2719
+ * Comparison eq other.
2720
+ * @overload eq other
2721
+ * @param [Numo::NArray,Numeric] other
2722
+ * @return [Numo::Bit] result of self eq other.
2723
+ */
5744
2724
  rb_define_method(cT, "eq", int32_eq, 1);
2725
+ /**
2726
+ * Comparison ne other.
2727
+ * @overload ne other
2728
+ * @param [Numo::NArray,Numeric] other
2729
+ * @return [Numo::Bit] result of self ne other.
2730
+ */
5745
2731
  rb_define_method(cT, "ne", int32_ne, 1);
5746
2732
  rb_define_alias(cT, "nearly_eq", "eq");
5747
2733
  rb_define_alias(cT, "close_to", "nearly_eq");
2734
+ /**
2735
+ * Binary bit_and.
2736
+ * @overload & other
2737
+ * @param [Numo::NArray,Numeric] other
2738
+ * @return [Numo::NArray] self & other
2739
+ */
5748
2740
  rb_define_method(cT, "&", int32_bit_and, 1);
2741
+ /**
2742
+ * Binary bit_or.
2743
+ * @overload | other
2744
+ * @param [Numo::NArray,Numeric] other
2745
+ * @return [Numo::NArray] self | other
2746
+ */
5749
2747
  rb_define_method(cT, "|", int32_bit_or, 1);
2748
+ /**
2749
+ * Binary bit_xor.
2750
+ * @overload ^ other
2751
+ * @param [Numo::NArray,Numeric] other
2752
+ * @return [Numo::NArray] self ^ other
2753
+ */
5750
2754
  rb_define_method(cT, "^", int32_bit_xor, 1);
2755
+ /**
2756
+ * Unary bit_not.
2757
+ * @overload ~
2758
+ * @return [Numo::Int32] bit_not of self.
2759
+ */
5751
2760
  rb_define_method(cT, "~", int32_bit_not, 0);
2761
+ /**
2762
+ * Binary left_shift.
2763
+ * @overload << other
2764
+ * @param [Numo::NArray,Numeric] other
2765
+ * @return [Numo::NArray] self << other
2766
+ */
5752
2767
  rb_define_method(cT, "<<", int32_left_shift, 1);
2768
+ /**
2769
+ * Binary right_shift.
2770
+ * @overload >> other
2771
+ * @param [Numo::NArray,Numeric] other
2772
+ * @return [Numo::NArray] self >> other
2773
+ */
5753
2774
  rb_define_method(cT, ">>", int32_right_shift, 1);
5754
2775
  rb_define_alias(cT, "floor", "view");
5755
2776
  rb_define_alias(cT, "round", "view");
5756
2777
  rb_define_alias(cT, "ceil", "view");
5757
2778
  rb_define_alias(cT, "trunc", "view");
5758
2779
  rb_define_alias(cT, "rint", "view");
2780
+ /**
2781
+ * Comparison gt other.
2782
+ * @overload gt other
2783
+ * @param [Numo::NArray,Numeric] other
2784
+ * @return [Numo::Bit] result of self gt other.
2785
+ */
5759
2786
  rb_define_method(cT, "gt", int32_gt, 1);
2787
+ /**
2788
+ * Comparison ge other.
2789
+ * @overload ge other
2790
+ * @param [Numo::NArray,Numeric] other
2791
+ * @return [Numo::Bit] result of self ge other.
2792
+ */
5760
2793
  rb_define_method(cT, "ge", int32_ge, 1);
2794
+ /**
2795
+ * Comparison lt other.
2796
+ * @overload lt other
2797
+ * @param [Numo::NArray,Numeric] other
2798
+ * @return [Numo::Bit] result of self lt other.
2799
+ */
5761
2800
  rb_define_method(cT, "lt", int32_lt, 1);
2801
+ /**
2802
+ * Comparison le other.
2803
+ * @overload le other
2804
+ * @param [Numo::NArray,Numeric] other
2805
+ * @return [Numo::Bit] result of self le other.
2806
+ */
5762
2807
  rb_define_method(cT, "le", int32_le, 1);
5763
2808
  rb_define_alias(cT, ">", "gt");
5764
2809
  rb_define_alias(cT, ">=", "ge");
5765
2810
  rb_define_alias(cT, "<", "lt");
5766
2811
  rb_define_alias(cT, "<=", "le");
2812
+ /**
2813
+ * Clip array elements by [min,max].
2814
+ * If either of min or max is nil, one side is clipped.
2815
+ * @overload clip(min,max)
2816
+ * @param [Numo::NArray,Numeric] min
2817
+ * @param [Numo::NArray,Numeric] max
2818
+ * @return [Numo::NArray] result of clip.
2819
+ * * * * * * * *
2820
+ * @example
2821
+ * a = Numo::Int32.new(10).seq
2822
+ * # => Numo::Int32#shape=[10]
2823
+ * # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2824
+ *
2825
+ * a.clip(1,8)
2826
+ * # => Numo::Int32#shape=[10]
2827
+ * # [1, 1, 2, 3, 4, 5, 6, 7, 8, 8]
2828
+ *
2829
+ * a.inplace.clip(3,6)
2830
+ * a
2831
+ * # => Numo::Int32#shape=[10]
2832
+ * # [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]
2833
+ *
2834
+ * b = Numo::Int32.new(10).seq
2835
+ * # => Numo::Int32#shape=[10]
2836
+ * # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2837
+ *
2838
+ * b.clip([3,4,1,1,1,4,4,4,4,4], 8)
2839
+ * # => Numo::Int32#shape=[10]
2840
+ * # [3, 4, 2, 3, 4, 5, 6, 7, 8, 8]
2841
+ */
5767
2842
  rb_define_method(cT, "clip", int32_clip, 2);
2843
+ /**
2844
+ * sum of self.
2845
+ * @overload sum(axis:nil, keepdims:false)
2846
+ * @param [Numeric,Array,Range] axis Performs sum along the axis.
2847
+ * @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
2848
+ * dimensions with size one.
2849
+ * @return [Numo::Int32] returns result of sum.
2850
+ */
5768
2851
  rb_define_method(cT, "sum", int32_sum, -1);
2852
+ /**
2853
+ * prod of self.
2854
+ * @overload prod(axis:nil, keepdims:false)
2855
+ * @param [Numeric,Array,Range] axis Performs prod along the axis.
2856
+ * @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
2857
+ * dimensions with size one.
2858
+ * @return [Numo::Int64] returns result of prod.
2859
+ */
5769
2860
  rb_define_method(cT, "prod", int32_prod, -1);
2861
+ /**
2862
+ * min of self.
2863
+ * @overload min(axis:nil, keepdims:false)
2864
+ * @param [Numeric,Array,Range] axis Performs min along the axis.
2865
+ * @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
2866
+ * dimensions with size one.
2867
+ * @return [Numo::Int32] returns result of min.
2868
+ */
5770
2869
  rb_define_method(cT, "min", int32_min, -1);
2870
+ /**
2871
+ * max of self.
2872
+ * @overload max(axis:nil, keepdims:false)
2873
+ * @param [Numeric,Array,Range] axis Performs max along the axis.
2874
+ * @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
2875
+ * dimensions with size one.
2876
+ * @return [Numo::Int32] returns result of max.
2877
+ */
5771
2878
  rb_define_method(cT, "max", int32_max, -1);
2879
+ /**
2880
+ * ptp of self.
2881
+ * @overload ptp(axis:nil, keepdims:false)
2882
+ * @param [Numeric,Array,Range] axis Performs ptp along the axis.
2883
+ * @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
2884
+ * dimensions with size one.
2885
+ * @return [Numo::Int32] returns result of ptp.
2886
+ */
5772
2887
  rb_define_method(cT, "ptp", int32_ptp, -1);
2888
+ /**
2889
+ * Index of the maximum value.
2890
+ * @overload max_index(axis:nil)
2891
+ * @param [Numeric,Array,Range] axis Finds maximum values along the axis and
2892
+ * returns **flat 1-d indices**.
2893
+ * @return [Integer,Numo::Int] returns result indices.
2894
+ * @see #argmax
2895
+ * @see #max
2896
+ *
2897
+ * @example
2898
+ * a = Numo::NArray[3,4,1,2]
2899
+ * a.max_index #=> 1
2900
+ *
2901
+ * b = Numo::NArray[[3,4,1],[2,0,5]]
2902
+ * b.max_index #=> 5
2903
+ * b.max_index(axis:1) #=> [1, 5]
2904
+ * b.max_index(axis:0) #=> [0, 1, 5]
2905
+ * b[b.max_index(axis:0)] #=> [3, 4, 5]
2906
+ */
5773
2907
  rb_define_method(cT, "max_index", int32_max_index, -1);
2908
+ /**
2909
+ * Index of the minimum value.
2910
+ * @overload min_index(axis:nil)
2911
+ * @param [Numeric,Array,Range] axis Finds minimum values along the axis and
2912
+ * returns **flat 1-d indices**.
2913
+ * @return [Integer,Numo::Int] returns result indices.
2914
+ * @see #argmin
2915
+ * @see #min
2916
+ *
2917
+ * @example
2918
+ * a = Numo::NArray[3,4,1,2]
2919
+ * a.min_index #=> 2
2920
+ *
2921
+ * b = Numo::NArray[[3,4,1],[2,0,5]]
2922
+ * b.min_index #=> 4
2923
+ * b.min_index(axis:1) #=> [2, 4]
2924
+ * b.min_index(axis:0) #=> [3, 4, 2]
2925
+ * b[b.min_index(axis:0)] #=> [2, 0, 1]
2926
+ */
5774
2927
  rb_define_method(cT, "min_index", int32_min_index, -1);
2928
+ /**
2929
+ * Index of the maximum value.
2930
+ * @overload argmax(axis:nil)
2931
+ * @param [Numeric,Array,Range] axis Finds maximum values along the axis and
2932
+ * returns **indices along the axis**.
2933
+ * @return [Integer,Numo::Int] returns the result indices.
2934
+ * @see #max_index
2935
+ * @see #max
2936
+ *
2937
+ * @example
2938
+ * a = Numo::NArray[3,4,1,2]
2939
+ * a.argmax #=> 1
2940
+ *
2941
+ * b = Numo::NArray[[3,4,1],[2,0,5]]
2942
+ * b.argmax #=> 5
2943
+ * b.argmax(axis:1) #=> [1, 2]
2944
+ * b.argmax(axis:0) #=> [0, 0, 1]
2945
+ * b.at(b.argmax(axis:0), 0..-1) #=> [3, 4, 5]
2946
+ */
5775
2947
  rb_define_method(cT, "argmax", int32_argmax, -1);
2948
+ /**
2949
+ * Index of the minimum value.
2950
+ * @overload argmin(axis:nil)
2951
+ * @param [Numeric,Array,Range] axis Finds minimum values along the axis and
2952
+ * returns **indices along the axis**.
2953
+ * @return [Integer,Numo::Int] returns the result indices.
2954
+ * @see #min_index
2955
+ * @see #min
2956
+ *
2957
+ * @example
2958
+ * a = Numo::NArray[3,4,1,2]
2959
+ * a.argmin #=> 2
2960
+ *
2961
+ * b = Numo::NArray[[3,4,1],[2,0,5]]
2962
+ * b.argmin #=> 4
2963
+ * b.argmin(axis:1) #=> [2, 1]
2964
+ * b.argmin(axis:0) #=> [1, 1, 0]
2965
+ * b.at(b.argmin(axis:0), 0..-1) #=> [2, 0, 1]
2966
+ */
5776
2967
  rb_define_method(cT, "argmin", int32_argmin, -1);
2968
+ /**
2969
+ * minmax of self.
2970
+ * @overload minmax(axis:nil, keepdims:false)
2971
+ * @param [Numeric,Array,Range] axis Finds min-max along the axis.
2972
+ * @param [TrueClass] keepdims (keyword) If true, the reduced axes are left in
2973
+ * the result array as dimensions with size one.
2974
+ * @return [Numo::Int32,Numo::Int32] min and max of self.
2975
+ */
5777
2976
  rb_define_method(cT, "minmax", int32_minmax, -1);
5778
2977
  /**
5779
2978
  * Element-wise maximum of two arrays.
@@ -5789,13 +2988,114 @@ void Init_numo_int32(void) {
5789
2988
  * @return [Numo::Int32]
5790
2989
  */
5791
2990
  rb_define_module_function(cT, "minimum", int32_s_minimum, -1);
2991
+ /**
2992
+ * Count the number of occurrences of each non-negative integer value.
2993
+ * Only Integer-types has this method.
2994
+ *
2995
+ * @overload bincount([weight], minlength:nil)
2996
+ * @param [SFloat or DFloat or Array] weight (optional) Array of
2997
+ * float values. Its size along last axis should be same as that of self.
2998
+ * @param [Integer] minlength (keyword, optional) Minimum size along
2999
+ * last axis for the output array.
3000
+ * @return [UInt32 or UInt64 or SFloat or DFloat]
3001
+ * Returns Float NArray if weight array is supplied,
3002
+ * otherwise returns UInt32 or UInt64 depending on the size along last axis.
3003
+ * @example
3004
+ * Numo::Int32[0..4].bincount
3005
+ * # => Numo::UInt32#shape=[5]
3006
+ * # [1, 1, 1, 1, 1]
3007
+ *
3008
+ * Numo::Int32[0, 1, 1, 3, 2, 1, 7].bincount
3009
+ * # => Numo::UInt32#shape=[8]
3010
+ * # [1, 3, 1, 1, 0, 0, 0, 1]
3011
+ *
3012
+ * x = Numo::Int32[0, 1, 1, 3, 2, 1, 7, 23]
3013
+ * x.bincount.size == x.max+1
3014
+ * # => true
3015
+ *
3016
+ * w = Numo::DFloat[0.3, 0.5, 0.2, 0.7, 1.0, -0.6]
3017
+ * x = Numo::Int32[0, 1, 1, 2, 2, 2]
3018
+ * x.bincount(w)
3019
+ * # => Numo::DFloat#shape=[3]
3020
+ * # [0.3, 0.7, 1.1]
3021
+ */
5792
3022
  rb_define_method(cT, "bincount", int32_bincount, -1);
3023
+ /**
3024
+ * cumsum of self.
3025
+ * @overload cumsum(axis:nil, nan:false)
3026
+ * @param [Numeric,Array,Range] axis Performs cumsum along the axis.
3027
+ * @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN if exists).
3028
+ * @return [Numo::Int32] cumsum of self.
3029
+ */
5793
3030
  rb_define_method(cT, "cumsum", int32_cumsum, -1);
3031
+ /**
3032
+ * cumprod of self.
3033
+ * @overload cumprod(axis:nil, nan:false)
3034
+ * @param [Numeric,Array,Range] axis Performs cumprod along the axis.
3035
+ * @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN if exists).
3036
+ * @return [Numo::Int32] cumprod of self.
3037
+ */
5794
3038
  rb_define_method(cT, "cumprod", int32_cumprod, -1);
3039
+ /**
3040
+ * Binary mulsum.
3041
+ *
3042
+ * @overload mulsum(other, axis:nil, keepdims:false)
3043
+ * @param [Numo::NArray,Numeric] other
3044
+ * @param [Numeric,Array,Range] axis Performs mulsum along the axis.
3045
+ * @param [TrueClass] keepdims (keyword) If true, the reduced axes are left in
3046
+ * the result array as dimensions with size one.
3047
+ * @return [Numo::NArray] mulsum of self and other.
3048
+ */
5795
3049
  rb_define_method(cT, "mulsum", int32_mulsum, -1);
3050
+ /**
3051
+ * Set linear sequence of numbers to self. The sequence is obtained from
3052
+ * beg+i*step
3053
+ * where i is 1-dimensional index.
3054
+ * @overload seq([beg,[step]])
3055
+ * @param [Numeric] beg beginning of sequence. (default=0)
3056
+ * @param [Numeric] step step of sequence. (default=1)
3057
+ * @return [Numo::Int32] self.
3058
+ * @example
3059
+ * Numo::DFloat.new(6).seq(1,-0.2)
3060
+ * # => Numo::DFloat#shape=[6]
3061
+ * # [1, 0.8, 0.6, 0.4, 0.2, 0]
3062
+ *
3063
+ * Numo::DComplex.new(6).seq(1,-0.2+0.2i)
3064
+ * # => Numo::DComplex#shape=[6]
3065
+ * # [1+0i, 0.8+0.2i, 0.6+0.4i, 0.4+0.6i, 0.2+0.8i, 0+1i]
3066
+ */
5796
3067
  rb_define_method(cT, "seq", int32_seq, -1);
3068
+ /**
3069
+ * Eye: Set a value to diagonal components, set 0 to non-diagonal components.
3070
+ * @overload eye([element,offset])
3071
+ * @param [Numeric] element Diagonal element to be stored. Default is 1.
3072
+ * @param [Integer] offset Diagonal offset from the main diagonal. The
3073
+ * default is 0. k>0 for diagonals above the main diagonal, and k<0
3074
+ * for diagonals below the main diagonal.
3075
+ * @return [Numo::Int32] eye of self.
3076
+ */
5797
3077
  rb_define_method(cT, "eye", int32_eye, -1);
5798
3078
  rb_define_alias(cT, "indgen", "seq");
3079
+ /**
3080
+ * Generate uniformly distributed random numbers on self narray.
3081
+ * @overload rand([[low],high])
3082
+ * @param [Numeric] low lower inclusive boundary of random numbers. (default=0)
3083
+ * @param [Numeric] high upper exclusive boundary of random numbers.
3084
+ * (default=1 or 1+1i for complex types)
3085
+ * @return [Numo::Int32] self.
3086
+ * @example
3087
+ * Numo::DFloat.new(6).rand
3088
+ * # => Numo::DFloat#shape=[6]
3089
+ * # [0.0617545, 0.373067, 0.794815, 0.201042, 0.116041, 0.344032]
3090
+ *
3091
+ * Numo::DComplex.new(6).rand(5+5i)
3092
+ * # => Numo::DComplex#shape=[6]
3093
+ * # [2.69974+3.68908i, 0.825443+0.254414i, 0.540323+0.34354i, 4.52061+2.39322i, ...]
3094
+ *
3095
+ * Numo::Int32.new(6).rand(2,5)
3096
+ * # => Numo::Int32#shape=[6]
3097
+ * # [4, 3, 3, 2, 4, 2]
3098
+ */
5799
3099
  rb_define_method(cT, "rand", int32_rand, -1);
5800
3100
  rb_define_method(cT, "poly", int32_poly, -2);
5801
3101