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
@@ -38,10 +38,42 @@ static ID id_to_a;
38
38
  VALUE cT;
39
39
  extern VALUE cRT;
40
40
 
41
+ #include "mh/coerce_cast.h"
42
+ #include "mh/to_a.h"
43
+ #include "mh/fill.h"
44
+ #include "mh/format.h"
45
+ #include "mh/format_to_a.h"
46
+ #include "mh/inspect.h"
47
+ #include "mh/op/add.h"
48
+ #include "mh/op/sub.h"
49
+ #include "mh/op/mul.h"
50
+ #include "mh/op/div.h"
51
+ #include "mh/comp/eq.h"
52
+ #include "mh/comp/ne.h"
53
+ #include "mh/comp/nearly_eq.h"
54
+ #include "mh/round/floor.h"
55
+ #include "mh/round/round.h"
56
+ #include "mh/round/ceil.h"
57
+ #include "mh/round/trunc.h"
58
+ #include "mh/round/rint.h"
59
+ #include "mh/isnan.h"
60
+ #include "mh/isinf.h"
61
+ #include "mh/isposinf.h"
62
+ #include "mh/isneginf.h"
63
+ #include "mh/isfinite.h"
64
+ #include "mh/sum.h"
65
+ #include "mh/prod.h"
41
66
  #include "mh/mean.h"
42
67
  #include "mh/var.h"
43
68
  #include "mh/stddev.h"
44
69
  #include "mh/rms.h"
70
+ #include "mh/cumsum.h"
71
+ #include "mh/cumprod.h"
72
+ #include "mh/mulsum.h"
73
+ #include "mh/seq.h"
74
+ #include "mh/logseq.h"
75
+ #include "mh/eye.h"
76
+ #include "mh/rand.h"
45
77
  #include "mh/math/sqrt.h"
46
78
  #include "mh/math/cbrt.h"
47
79
  #include "mh/math/log.h"
@@ -64,10 +96,42 @@ extern VALUE cRT;
64
96
  #include "mh/math/atanh.h"
65
97
  #include "mh/math/sinc.h"
66
98
 
99
+ DEF_NARRAY_COERCE_CAST_METHOD_FUNC(dcomplex)
100
+ DEF_NARRAY_TO_A_METHOD_FUNC(dcomplex)
101
+ DEF_NARRAY_FILL_METHOD_FUNC(dcomplex)
102
+ DEF_NARRAY_FORMAT_METHOD_FUNC(dcomplex)
103
+ DEF_NARRAY_FORMAT_TO_A_METHOD_FUNC(dcomplex)
104
+ DEF_NARRAY_INSPECT_METHOD_FUNC(dcomplex)
105
+ DEF_NARRAY_ADD_METHOD_FUNC(dcomplex, numo_cDComplex)
106
+ DEF_NARRAY_SUB_METHOD_FUNC(dcomplex, numo_cDComplex)
107
+ DEF_NARRAY_MUL_METHOD_FUNC(dcomplex, numo_cDComplex)
108
+ DEF_NARRAY_FLT_DIV_METHOD_FUNC(dcomplex, numo_cDComplex)
109
+ DEF_NARRAY_EQ_METHOD_FUNC(dcomplex, numo_cDComplex)
110
+ DEF_NARRAY_NE_METHOD_FUNC(dcomplex, numo_cDComplex)
111
+ DEF_NARRAY_NEARLY_EQ_METHOD_FUNC(dcomplex, numo_cDComplex)
112
+ DEF_NARRAY_FLT_FLOOR_METHOD_FUNC(dcomplex, numo_cDComplex)
113
+ DEF_NARRAY_FLT_ROUND_METHOD_FUNC(dcomplex, numo_cDComplex)
114
+ DEF_NARRAY_FLT_CEIL_METHOD_FUNC(dcomplex, numo_cDComplex)
115
+ DEF_NARRAY_FLT_TRUNC_METHOD_FUNC(dcomplex, numo_cDComplex)
116
+ DEF_NARRAY_FLT_RINT_METHOD_FUNC(dcomplex, numo_cDComplex)
117
+ DEF_NARRAY_FLT_ISNAN_METHOD_FUNC(dcomplex, numo_cDComplex)
118
+ DEF_NARRAY_FLT_ISINF_METHOD_FUNC(dcomplex, numo_cDComplex)
119
+ DEF_NARRAY_FLT_ISPOSINF_METHOD_FUNC(dcomplex, numo_cDComplex)
120
+ DEF_NARRAY_FLT_ISNEGINF_METHOD_FUNC(dcomplex, numo_cDComplex)
121
+ DEF_NARRAY_FLT_ISFINITE_METHOD_FUNC(dcomplex, numo_cDComplex)
122
+ DEF_NARRAY_FLT_SUM_METHOD_FUNC(dcomplex, numo_cDComplex)
123
+ DEF_NARRAY_FLT_PROD_METHOD_FUNC(dcomplex, numo_cDComplex)
67
124
  DEF_NARRAY_FLT_MEAN_METHOD_FUNC(dcomplex, numo_cDComplex, dcomplex, numo_cDComplex)
68
125
  DEF_NARRAY_FLT_VAR_METHOD_FUNC(dcomplex, numo_cDComplex, double, numo_cDFloat)
69
126
  DEF_NARRAY_FLT_STDDEV_METHOD_FUNC(dcomplex, numo_cDComplex, double, numo_cDFloat)
70
127
  DEF_NARRAY_FLT_RMS_METHOD_FUNC(dcomplex, numo_cDComplex, double, numo_cDFloat)
128
+ DEF_NARRAY_FLT_CUMSUM_METHOD_FUNC(dcomplex, numo_cDComplex)
129
+ DEF_NARRAY_FLT_CUMPROD_METHOD_FUNC(dcomplex, numo_cDComplex)
130
+ DEF_NARRAY_FLT_MULSUM_METHOD_FUNC(dcomplex, numo_cDComplex)
131
+ DEF_NARRAY_FLT_SEQ_METHOD_FUNC(dcomplex)
132
+ DEF_NARRAY_FLT_LOGSEQ_METHOD_FUNC(dcomplex)
133
+ DEF_NARRAY_EYE_METHOD_FUNC(dcomplex)
134
+ DEF_NARRAY_FLT_RAND_METHOD_FUNC(dcomplex)
71
135
  DEF_NARRAY_FLT_SQRT_METHOD_FUNC(dcomplex, numo_cDComplex)
72
136
  DEF_NARRAY_FLT_CBRT_METHOD_FUNC(dcomplex, numo_cDComplex)
73
137
  DEF_NARRAY_FLT_LOG_METHOD_FUNC(dcomplex, numo_cDComplex)
@@ -1373,204 +1437,6 @@ static VALUE dcomplex_aset(int argc, VALUE* argv, VALUE self) {
1373
1437
  return argv[argc];
1374
1438
  }
1375
1439
 
1376
- /*
1377
- return NArray with cast to the type of self.
1378
- @overload coerce_cast(type)
1379
- @return [nil]
1380
- */
1381
- static VALUE dcomplex_coerce_cast(VALUE self, VALUE type) {
1382
- return Qnil;
1383
- }
1384
-
1385
- static void iter_dcomplex_to_a(na_loop_t* const lp) {
1386
- size_t i, s1;
1387
- char* p1;
1388
- size_t* idx1;
1389
- dtype x;
1390
- volatile VALUE a, y;
1391
-
1392
- INIT_COUNTER(lp, i);
1393
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1394
- a = rb_ary_new2(i);
1395
- rb_ary_push(lp->args[1].value, a);
1396
- if (idx1) {
1397
- for (; i--;) {
1398
- GET_DATA_INDEX(p1, idx1, dtype, x);
1399
- y = m_data_to_num(x);
1400
- rb_ary_push(a, y);
1401
- }
1402
- } else {
1403
- for (; i--;) {
1404
- GET_DATA_STRIDE(p1, s1, dtype, x);
1405
- y = m_data_to_num(x);
1406
- rb_ary_push(a, y);
1407
- }
1408
- }
1409
- }
1410
-
1411
- /*
1412
- Convert self to Array.
1413
- @overload to_a
1414
- @return [Array]
1415
- */
1416
- static VALUE dcomplex_to_a(VALUE self) {
1417
- ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { sym_loop_opt }, { sym_option } };
1418
- ndfunc_arg_out_t aout[1] = { { rb_cArray, 0 } }; // dummy?
1419
- ndfunc_t ndf = { iter_dcomplex_to_a, FULL_LOOP_NIP, 3, 1, ain, aout };
1420
- return na_ndloop_cast_narray_to_rarray(&ndf, self, Qnil);
1421
- }
1422
-
1423
- static void iter_dcomplex_fill(na_loop_t* const lp) {
1424
- size_t i;
1425
- char* p1;
1426
- ssize_t s1;
1427
- size_t* idx1;
1428
- VALUE x = lp->option;
1429
- dtype y;
1430
- INIT_COUNTER(lp, i);
1431
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1432
- y = m_num_to_data(x);
1433
- if (idx1) {
1434
- for (; i--;) {
1435
- SET_DATA_INDEX(p1, idx1, dtype, y);
1436
- }
1437
- } else {
1438
- for (; i--;) {
1439
- SET_DATA_STRIDE(p1, s1, dtype, y);
1440
- }
1441
- }
1442
- }
1443
-
1444
- /*
1445
- Fill elements with other.
1446
- @overload fill other
1447
- @param [Numeric] other
1448
- @return [Numo::DComplex] self.
1449
- */
1450
- static VALUE dcomplex_fill(VALUE self, VALUE val) {
1451
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { sym_option } };
1452
- ndfunc_t ndf = { iter_dcomplex_fill, FULL_LOOP, 2, 0, ain, 0 };
1453
-
1454
- na_ndloop(&ndf, 2, self, val);
1455
- return self;
1456
- }
1457
-
1458
- static VALUE format_dcomplex(VALUE fmt, dtype* x) {
1459
- // fix-me
1460
- char s[48];
1461
- int n;
1462
-
1463
- if (NIL_P(fmt)) {
1464
- n = m_sprintf(s, *x);
1465
- return rb_str_new(s, n);
1466
- }
1467
- return rb_funcall(fmt, '%', 1, m_data_to_num(*x));
1468
- }
1469
-
1470
- static void iter_dcomplex_format(na_loop_t* const lp) {
1471
- size_t i;
1472
- char *p1, *p2;
1473
- ssize_t s1, s2;
1474
- size_t* idx1;
1475
- dtype* x;
1476
- VALUE y;
1477
- VALUE fmt = lp->option;
1478
- INIT_COUNTER(lp, i);
1479
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1480
- INIT_PTR(lp, 1, p2, s2);
1481
- if (idx1) {
1482
- for (; i--;) {
1483
- x = (dtype*)(p1 + *idx1);
1484
- idx1++;
1485
- y = format_dcomplex(fmt, x);
1486
- SET_DATA_STRIDE(p2, s2, VALUE, y);
1487
- }
1488
- } else {
1489
- for (; i--;) {
1490
- x = (dtype*)p1;
1491
- p1 += s1;
1492
- y = format_dcomplex(fmt, x);
1493
- SET_DATA_STRIDE(p2, s2, VALUE, y);
1494
- }
1495
- }
1496
- }
1497
-
1498
- /*
1499
- Format elements into strings.
1500
- @overload format format
1501
- @param [String] format
1502
- @return [Numo::RObject] array of formatted strings.
1503
- */
1504
- static VALUE dcomplex_format(int argc, VALUE* argv, VALUE self) {
1505
- VALUE fmt = Qnil;
1506
-
1507
- ndfunc_arg_in_t ain[2] = { { Qnil, 0 }, { sym_option } };
1508
- ndfunc_arg_out_t aout[1] = { { numo_cRObject, 0 } };
1509
- ndfunc_t ndf = { iter_dcomplex_format, FULL_LOOP_NIP, 2, 1, ain, aout };
1510
-
1511
- rb_scan_args(argc, argv, "01", &fmt);
1512
- return na_ndloop(&ndf, 2, self, fmt);
1513
- }
1514
-
1515
- static void iter_dcomplex_format_to_a(na_loop_t* const lp) {
1516
- size_t i;
1517
- char* p1;
1518
- ssize_t s1;
1519
- size_t* idx1;
1520
- dtype* x;
1521
- VALUE y;
1522
- volatile VALUE a;
1523
- VALUE fmt = lp->option;
1524
- INIT_COUNTER(lp, i);
1525
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1526
- a = rb_ary_new2(i);
1527
- rb_ary_push(lp->args[1].value, a);
1528
- if (idx1) {
1529
- for (; i--;) {
1530
- x = (dtype*)(p1 + *idx1);
1531
- idx1++;
1532
- y = format_dcomplex(fmt, x);
1533
- rb_ary_push(a, y);
1534
- }
1535
- } else {
1536
- for (; i--;) {
1537
- x = (dtype*)p1;
1538
- p1 += s1;
1539
- y = format_dcomplex(fmt, x);
1540
- rb_ary_push(a, y);
1541
- }
1542
- }
1543
- }
1544
-
1545
- /*
1546
- Format elements into strings.
1547
- @overload format_to_a format
1548
- @param [String] format
1549
- @return [Array] array of formatted strings.
1550
- */
1551
- static VALUE dcomplex_format_to_a(int argc, VALUE* argv, VALUE self) {
1552
- VALUE fmt = Qnil;
1553
- ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { sym_loop_opt }, { sym_option } };
1554
- ndfunc_arg_out_t aout[1] = { { rb_cArray, 0 } }; // dummy?
1555
- ndfunc_t ndf = { iter_dcomplex_format_to_a, FULL_LOOP_NIP, 3, 1, ain, aout };
1556
-
1557
- rb_scan_args(argc, argv, "01", &fmt);
1558
- return na_ndloop_cast_narray_to_rarray(&ndf, self, fmt);
1559
- }
1560
-
1561
- static VALUE iter_dcomplex_inspect(char* ptr, size_t pos, VALUE fmt) {
1562
- return format_dcomplex(fmt, (dtype*)(ptr + pos));
1563
- }
1564
-
1565
- /*
1566
- Returns a string containing a human-readable representation of NArray.
1567
- @overload inspect
1568
- @return [String]
1569
- */
1570
- static VALUE dcomplex_inspect(VALUE ary) {
1571
- return na_ndloop_inspect(ary, iter_dcomplex_inspect, Qnil);
1572
- }
1573
-
1574
1440
  static void iter_dcomplex_each(na_loop_t* const lp) {
1575
1441
  size_t i, s1;
1576
1442
  char* p1;
@@ -1897,568 +1763,246 @@ static VALUE dcomplex_abs(VALUE self) {
1897
1763
  return na_ndloop(&ndf, 1, self);
1898
1764
  }
1899
1765
 
1900
- #define check_intdivzero(y) \
1901
- {}
1902
-
1903
- static void iter_dcomplex_add(na_loop_t* const lp) {
1904
- size_t i = 0;
1905
- size_t n;
1766
+ static void iter_dcomplex_pow(na_loop_t* const lp) {
1767
+ size_t i;
1906
1768
  char *p1, *p2, *p3;
1907
1769
  ssize_t s1, s2, s3;
1908
-
1909
- INIT_COUNTER(lp, n);
1770
+ dtype x, y;
1771
+ INIT_COUNTER(lp, i);
1910
1772
  INIT_PTR(lp, 0, p1, s1);
1911
1773
  INIT_PTR(lp, 1, p2, s2);
1912
1774
  INIT_PTR(lp, 2, p3, s3);
1913
-
1914
- //
1915
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
1916
- is_aligned(p3, sizeof(dtype))) {
1917
-
1918
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
1919
- if (p1 == p3) { // inplace case
1920
- for (; i < n; i++) {
1921
- check_intdivzero(((dtype*)p2)[i]);
1922
- ((dtype*)p1)[i] = m_add(((dtype*)p1)[i], ((dtype*)p2)[i]);
1923
- }
1924
- } else {
1925
- for (; i < n; i++) {
1926
- check_intdivzero(((dtype*)p2)[i]);
1927
- ((dtype*)p3)[i] = m_add(((dtype*)p1)[i], ((dtype*)p2)[i]);
1928
- }
1929
- }
1930
- return;
1931
- }
1932
-
1933
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
1934
- is_aligned_step(s3, sizeof(dtype))) {
1935
- //
1936
-
1937
- if (s2 == 0) { // Broadcasting from scalar value.
1938
- check_intdivzero(*(dtype*)p2);
1939
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
1940
- if (p1 == p3) { // inplace case
1941
- for (; i < n; i++) {
1942
- ((dtype*)p1)[i] = m_add(((dtype*)p1)[i], *(dtype*)p2);
1943
- }
1944
- } else {
1945
- for (; i < n; i++) {
1946
- ((dtype*)p3)[i] = m_add(((dtype*)p1)[i], *(dtype*)p2);
1947
- }
1948
- }
1949
- } else {
1950
- for (i = 0; i < n; i++) {
1951
- *(dtype*)p3 = m_add(*(dtype*)p1, *(dtype*)p2);
1952
- p1 += s1;
1953
- p3 += s3;
1954
- }
1955
- }
1956
- } else {
1957
- if (p1 == p3) { // inplace case
1958
- for (i = 0; i < n; i++) {
1959
- check_intdivzero(*(dtype*)p2);
1960
- *(dtype*)p1 = m_add(*(dtype*)p1, *(dtype*)p2);
1961
- p1 += s1;
1962
- p2 += s2;
1963
- }
1964
- } else {
1965
- for (i = 0; i < n; i++) {
1966
- check_intdivzero(*(dtype*)p2);
1967
- *(dtype*)p3 = m_add(*(dtype*)p1, *(dtype*)p2);
1968
- p1 += s1;
1969
- p2 += s2;
1970
- p3 += s3;
1971
- }
1972
- }
1973
- }
1974
-
1975
- return;
1976
- //
1977
- }
1978
- }
1979
- for (i = 0; i < n; i++) {
1980
- dtype x, y, z;
1775
+ for (; i--;) {
1981
1776
  GET_DATA_STRIDE(p1, s1, dtype, x);
1982
1777
  GET_DATA_STRIDE(p2, s2, dtype, y);
1983
- check_intdivzero(y);
1984
- z = m_add(x, y);
1985
- SET_DATA_STRIDE(p3, s3, dtype, z);
1778
+ x = m_pow(x, y);
1779
+ SET_DATA_STRIDE(p3, s3, dtype, x);
1780
+ }
1781
+ }
1782
+
1783
+ static void iter_dcomplex_pow_int32(na_loop_t* const lp) {
1784
+ size_t i;
1785
+ char *p1, *p2, *p3;
1786
+ ssize_t s1, s2, s3;
1787
+ dtype x;
1788
+ int32_t y;
1789
+ INIT_COUNTER(lp, i);
1790
+ INIT_PTR(lp, 0, p1, s1);
1791
+ INIT_PTR(lp, 1, p2, s2);
1792
+ INIT_PTR(lp, 2, p3, s3);
1793
+ for (; i--;) {
1794
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1795
+ GET_DATA_STRIDE(p2, s2, int32_t, y);
1796
+ x = m_pow_int(x, y);
1797
+ SET_DATA_STRIDE(p3, s3, dtype, x);
1986
1798
  }
1987
- //
1988
1799
  }
1989
- #undef check_intdivzero
1990
1800
 
1991
- static VALUE dcomplex_add_self(VALUE self, VALUE other) {
1801
+ static VALUE dcomplex_pow_self(VALUE self, VALUE other) {
1992
1802
  ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
1803
+ ndfunc_arg_in_t ain_i[2] = { { cT, 0 }, { numo_cInt32, 0 } };
1993
1804
  ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1994
- ndfunc_t ndf = { iter_dcomplex_add, STRIDE_LOOP, 2, 1, ain, aout };
1805
+ ndfunc_t ndf = { iter_dcomplex_pow, STRIDE_LOOP, 2, 1, ain, aout };
1806
+ ndfunc_t ndf_i = { iter_dcomplex_pow_int32, STRIDE_LOOP, 2, 1, ain_i, aout };
1995
1807
 
1996
- return na_ndloop(&ndf, 2, self, other);
1808
+ // fixme : use na.integer?
1809
+ if (FIXNUM_P(other) || rb_obj_is_kind_of(other, numo_cInt32)) {
1810
+ return na_ndloop(&ndf_i, 2, self, other);
1811
+ } else {
1812
+ return na_ndloop(&ndf, 2, self, other);
1813
+ }
1997
1814
  }
1998
1815
 
1999
1816
  /*
2000
- Binary add.
2001
- @overload + other
1817
+ Binary power.
1818
+ @overload ** other
2002
1819
  @param [Numo::NArray,Numeric] other
2003
- @return [Numo::NArray] self + other
1820
+ @return [Numo::NArray] self to the other-th power.
2004
1821
  */
2005
- static VALUE dcomplex_add(VALUE self, VALUE other) {
1822
+ static VALUE dcomplex_pow(VALUE self, VALUE other) {
2006
1823
 
2007
1824
  VALUE klass, v;
2008
-
2009
1825
  klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2010
1826
  if (klass == cT) {
2011
- return dcomplex_add_self(self, other);
1827
+ return dcomplex_pow_self(self, other);
2012
1828
  } else {
2013
1829
  v = rb_funcall(klass, id_cast, 1, self);
2014
- return rb_funcall(v, '+', 1, other);
1830
+ return rb_funcall(v, id_pow, 1, other);
2015
1831
  }
2016
1832
  }
2017
1833
 
2018
- #define check_intdivzero(y) \
2019
- {}
2020
-
2021
- static void iter_dcomplex_sub(na_loop_t* const lp) {
2022
- size_t i = 0;
2023
- size_t n;
2024
- char *p1, *p2, *p3;
2025
- ssize_t s1, s2, s3;
1834
+ static void iter_dcomplex_minus(na_loop_t* const lp) {
1835
+ size_t i, n;
1836
+ char *p1, *p2;
1837
+ ssize_t s1, s2;
1838
+ size_t *idx1, *idx2;
1839
+ dtype x;
2026
1840
 
2027
1841
  INIT_COUNTER(lp, n);
2028
- INIT_PTR(lp, 0, p1, s1);
2029
- INIT_PTR(lp, 1, p2, s2);
2030
- INIT_PTR(lp, 2, p3, s3);
2031
-
2032
- //
2033
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2034
- is_aligned(p3, sizeof(dtype))) {
1842
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1843
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2035
1844
 
2036
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2037
- if (p1 == p3) { // inplace case
2038
- for (; i < n; i++) {
2039
- check_intdivzero(((dtype*)p2)[i]);
2040
- ((dtype*)p1)[i] = m_sub(((dtype*)p1)[i], ((dtype*)p2)[i]);
2041
- }
2042
- } else {
2043
- for (; i < n; i++) {
2044
- check_intdivzero(((dtype*)p2)[i]);
2045
- ((dtype*)p3)[i] = m_sub(((dtype*)p1)[i], ((dtype*)p2)[i]);
2046
- }
2047
- }
2048
- return;
1845
+ if (idx1) {
1846
+ if (idx2) {
1847
+ for (i = 0; i < n; i++) {
1848
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1849
+ x = m_minus(x);
1850
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1851
+ }
1852
+ } else {
1853
+ for (i = 0; i < n; i++) {
1854
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1855
+ x = m_minus(x);
1856
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1857
+ }
2049
1858
  }
2050
-
2051
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2052
- is_aligned_step(s3, sizeof(dtype))) {
1859
+ } else {
1860
+ if (idx2) {
1861
+ for (i = 0; i < n; i++) {
1862
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1863
+ x = m_minus(x);
1864
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1865
+ }
1866
+ } else {
2053
1867
  //
2054
-
2055
- if (s2 == 0) { // Broadcasting from scalar value.
2056
- check_intdivzero(*(dtype*)p2);
2057
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2058
- if (p1 == p3) { // inplace case
2059
- for (; i < n; i++) {
2060
- ((dtype*)p1)[i] = m_sub(((dtype*)p1)[i], *(dtype*)p2);
2061
- }
2062
- } else {
2063
- for (; i < n; i++) {
2064
- ((dtype*)p3)[i] = m_sub(((dtype*)p1)[i], *(dtype*)p2);
2065
- }
2066
- }
2067
- } else {
1868
+ if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
1869
+ if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2068
1870
  for (i = 0; i < n; i++) {
2069
- *(dtype*)p3 = m_sub(*(dtype*)p1, *(dtype*)p2);
2070
- p1 += s1;
2071
- p3 += s3;
1871
+ ((dtype*)p2)[i] = m_minus(((dtype*)p1)[i]);
2072
1872
  }
1873
+ return;
2073
1874
  }
2074
- } else {
2075
- if (p1 == p3) { // inplace case
2076
- for (i = 0; i < n; i++) {
2077
- check_intdivzero(*(dtype*)p2);
2078
- *(dtype*)p1 = m_sub(*(dtype*)p1, *(dtype*)p2);
2079
- p1 += s1;
2080
- p2 += s2;
2081
- }
2082
- } else {
1875
+ if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
1876
+ //
2083
1877
  for (i = 0; i < n; i++) {
2084
- check_intdivzero(*(dtype*)p2);
2085
- *(dtype*)p3 = m_sub(*(dtype*)p1, *(dtype*)p2);
1878
+ *(dtype*)p2 = m_minus(*(dtype*)p1);
2086
1879
  p1 += s1;
2087
1880
  p2 += s2;
2088
- p3 += s3;
2089
1881
  }
1882
+ return;
1883
+ //
2090
1884
  }
2091
1885
  }
2092
-
2093
- return;
1886
+ for (i = 0; i < n; i++) {
1887
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1888
+ x = m_minus(x);
1889
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1890
+ }
2094
1891
  //
2095
1892
  }
2096
1893
  }
2097
- for (i = 0; i < n; i++) {
2098
- dtype x, y, z;
2099
- GET_DATA_STRIDE(p1, s1, dtype, x);
2100
- GET_DATA_STRIDE(p2, s2, dtype, y);
2101
- check_intdivzero(y);
2102
- z = m_sub(x, y);
2103
- SET_DATA_STRIDE(p3, s3, dtype, z);
2104
- }
2105
- //
2106
- }
2107
- #undef check_intdivzero
2108
-
2109
- static VALUE dcomplex_sub_self(VALUE self, VALUE other) {
2110
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2111
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2112
- ndfunc_t ndf = { iter_dcomplex_sub, STRIDE_LOOP, 2, 1, ain, aout };
2113
-
2114
- return na_ndloop(&ndf, 2, self, other);
2115
1894
  }
2116
1895
 
2117
1896
  /*
2118
- Binary sub.
2119
- @overload - other
2120
- @param [Numo::NArray,Numeric] other
2121
- @return [Numo::NArray] self - other
1897
+ Unary minus.
1898
+ @overload -@
1899
+ @return [Numo::DComplex] minus of self.
2122
1900
  */
2123
- static VALUE dcomplex_sub(VALUE self, VALUE other) {
2124
-
2125
- VALUE klass, v;
1901
+ static VALUE dcomplex_minus(VALUE self) {
1902
+ ndfunc_arg_in_t ain[1] = { { cT, 0 } };
1903
+ ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1904
+ ndfunc_t ndf = { iter_dcomplex_minus, FULL_LOOP, 1, 1, ain, aout };
2126
1905
 
2127
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2128
- if (klass == cT) {
2129
- return dcomplex_sub_self(self, other);
2130
- } else {
2131
- v = rb_funcall(klass, id_cast, 1, self);
2132
- return rb_funcall(v, '-', 1, other);
2133
- }
1906
+ return na_ndloop(&ndf, 1, self);
2134
1907
  }
2135
1908
 
2136
- #define check_intdivzero(y) \
2137
- {}
2138
-
2139
- static void iter_dcomplex_mul(na_loop_t* const lp) {
2140
- size_t i = 0;
2141
- size_t n;
2142
- char *p1, *p2, *p3;
2143
- ssize_t s1, s2, s3;
1909
+ static void iter_dcomplex_reciprocal(na_loop_t* const lp) {
1910
+ size_t i, n;
1911
+ char *p1, *p2;
1912
+ ssize_t s1, s2;
1913
+ size_t *idx1, *idx2;
1914
+ dtype x;
2144
1915
 
2145
1916
  INIT_COUNTER(lp, n);
2146
- INIT_PTR(lp, 0, p1, s1);
2147
- INIT_PTR(lp, 1, p2, s2);
2148
- INIT_PTR(lp, 2, p3, s3);
2149
-
2150
- //
2151
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2152
- is_aligned(p3, sizeof(dtype))) {
1917
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1918
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2153
1919
 
2154
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2155
- if (p1 == p3) { // inplace case
2156
- for (; i < n; i++) {
2157
- check_intdivzero(((dtype*)p2)[i]);
2158
- ((dtype*)p1)[i] = m_mul(((dtype*)p1)[i], ((dtype*)p2)[i]);
2159
- }
2160
- } else {
2161
- for (; i < n; i++) {
2162
- check_intdivzero(((dtype*)p2)[i]);
2163
- ((dtype*)p3)[i] = m_mul(((dtype*)p1)[i], ((dtype*)p2)[i]);
2164
- }
1920
+ if (idx1) {
1921
+ if (idx2) {
1922
+ for (i = 0; i < n; i++) {
1923
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1924
+ x = m_reciprocal(x);
1925
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1926
+ }
1927
+ } else {
1928
+ for (i = 0; i < n; i++) {
1929
+ GET_DATA_INDEX(p1, idx1, dtype, x);
1930
+ x = m_reciprocal(x);
1931
+ SET_DATA_STRIDE(p2, s2, dtype, x);
2165
1932
  }
2166
- return;
2167
1933
  }
2168
-
2169
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2170
- is_aligned_step(s3, sizeof(dtype))) {
1934
+ } else {
1935
+ if (idx2) {
1936
+ for (i = 0; i < n; i++) {
1937
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1938
+ x = m_reciprocal(x);
1939
+ SET_DATA_INDEX(p2, idx2, dtype, x);
1940
+ }
1941
+ } else {
2171
1942
  //
2172
-
2173
- if (s2 == 0) { // Broadcasting from scalar value.
2174
- check_intdivzero(*(dtype*)p2);
2175
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2176
- if (p1 == p3) { // inplace case
2177
- for (; i < n; i++) {
2178
- ((dtype*)p1)[i] = m_mul(((dtype*)p1)[i], *(dtype*)p2);
2179
- }
2180
- } else {
2181
- for (; i < n; i++) {
2182
- ((dtype*)p3)[i] = m_mul(((dtype*)p1)[i], *(dtype*)p2);
2183
- }
2184
- }
2185
- } else {
1943
+ if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
1944
+ if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2186
1945
  for (i = 0; i < n; i++) {
2187
- *(dtype*)p3 = m_mul(*(dtype*)p1, *(dtype*)p2);
2188
- p1 += s1;
2189
- p3 += s3;
1946
+ ((dtype*)p2)[i] = m_reciprocal(((dtype*)p1)[i]);
2190
1947
  }
1948
+ return;
2191
1949
  }
2192
- } else {
2193
- if (p1 == p3) { // inplace case
2194
- for (i = 0; i < n; i++) {
2195
- check_intdivzero(*(dtype*)p2);
2196
- *(dtype*)p1 = m_mul(*(dtype*)p1, *(dtype*)p2);
2197
- p1 += s1;
2198
- p2 += s2;
2199
- }
2200
- } else {
1950
+ if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
1951
+ //
2201
1952
  for (i = 0; i < n; i++) {
2202
- check_intdivzero(*(dtype*)p2);
2203
- *(dtype*)p3 = m_mul(*(dtype*)p1, *(dtype*)p2);
1953
+ *(dtype*)p2 = m_reciprocal(*(dtype*)p1);
2204
1954
  p1 += s1;
2205
1955
  p2 += s2;
2206
- p3 += s3;
2207
1956
  }
1957
+ return;
1958
+ //
2208
1959
  }
2209
1960
  }
2210
-
2211
- return;
1961
+ for (i = 0; i < n; i++) {
1962
+ GET_DATA_STRIDE(p1, s1, dtype, x);
1963
+ x = m_reciprocal(x);
1964
+ SET_DATA_STRIDE(p2, s2, dtype, x);
1965
+ }
2212
1966
  //
2213
1967
  }
2214
1968
  }
2215
- for (i = 0; i < n; i++) {
2216
- dtype x, y, z;
2217
- GET_DATA_STRIDE(p1, s1, dtype, x);
2218
- GET_DATA_STRIDE(p2, s2, dtype, y);
2219
- check_intdivzero(y);
2220
- z = m_mul(x, y);
2221
- SET_DATA_STRIDE(p3, s3, dtype, z);
2222
- }
2223
- //
2224
- }
2225
- #undef check_intdivzero
2226
-
2227
- static VALUE dcomplex_mul_self(VALUE self, VALUE other) {
2228
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2229
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2230
- ndfunc_t ndf = { iter_dcomplex_mul, STRIDE_LOOP, 2, 1, ain, aout };
2231
-
2232
- return na_ndloop(&ndf, 2, self, other);
2233
1969
  }
2234
1970
 
2235
1971
  /*
2236
- Binary mul.
2237
- @overload * other
2238
- @param [Numo::NArray,Numeric] other
2239
- @return [Numo::NArray] self * other
1972
+ Unary reciprocal.
1973
+ @overload reciprocal
1974
+ @return [Numo::DComplex] reciprocal of self.
2240
1975
  */
2241
- static VALUE dcomplex_mul(VALUE self, VALUE other) {
2242
-
2243
- VALUE klass, v;
1976
+ static VALUE dcomplex_reciprocal(VALUE self) {
1977
+ ndfunc_arg_in_t ain[1] = { { cT, 0 } };
1978
+ ndfunc_arg_out_t aout[1] = { { cT, 0 } };
1979
+ ndfunc_t ndf = { iter_dcomplex_reciprocal, FULL_LOOP, 1, 1, ain, aout };
2244
1980
 
2245
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2246
- if (klass == cT) {
2247
- return dcomplex_mul_self(self, other);
2248
- } else {
2249
- v = rb_funcall(klass, id_cast, 1, self);
2250
- return rb_funcall(v, '*', 1, other);
2251
- }
1981
+ return na_ndloop(&ndf, 1, self);
2252
1982
  }
2253
1983
 
2254
- #define check_intdivzero(y) \
2255
- {}
2256
-
2257
- static void iter_dcomplex_div(na_loop_t* const lp) {
2258
- size_t i = 0;
2259
- size_t n;
2260
- char *p1, *p2, *p3;
2261
- ssize_t s1, s2, s3;
1984
+ static void iter_dcomplex_sign(na_loop_t* const lp) {
1985
+ size_t i, n;
1986
+ char *p1, *p2;
1987
+ ssize_t s1, s2;
1988
+ size_t *idx1, *idx2;
1989
+ dtype x;
2262
1990
 
2263
1991
  INIT_COUNTER(lp, n);
2264
- INIT_PTR(lp, 0, p1, s1);
2265
- INIT_PTR(lp, 1, p2, s2);
2266
- INIT_PTR(lp, 2, p3, s3);
2267
-
2268
- //
2269
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2270
- is_aligned(p3, sizeof(dtype))) {
2271
-
2272
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2273
- if (p1 == p3) { // inplace case
2274
- for (; i < n; i++) {
2275
- check_intdivzero(((dtype*)p2)[i]);
2276
- ((dtype*)p1)[i] = m_div(((dtype*)p1)[i], ((dtype*)p2)[i]);
2277
- }
2278
- } else {
2279
- for (; i < n; i++) {
2280
- check_intdivzero(((dtype*)p2)[i]);
2281
- ((dtype*)p3)[i] = m_div(((dtype*)p1)[i], ((dtype*)p2)[i]);
2282
- }
2283
- }
2284
- return;
2285
- }
2286
-
2287
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2288
- is_aligned_step(s3, sizeof(dtype))) {
2289
- //
2290
-
2291
- if (s2 == 0) { // Broadcasting from scalar value.
2292
- check_intdivzero(*(dtype*)p2);
2293
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2294
- if (p1 == p3) { // inplace case
2295
- for (; i < n; i++) {
2296
- ((dtype*)p1)[i] = m_div(((dtype*)p1)[i], *(dtype*)p2);
2297
- }
2298
- } else {
2299
- for (; i < n; i++) {
2300
- ((dtype*)p3)[i] = m_div(((dtype*)p1)[i], *(dtype*)p2);
2301
- }
2302
- }
2303
- } else {
2304
- for (i = 0; i < n; i++) {
2305
- *(dtype*)p3 = m_div(*(dtype*)p1, *(dtype*)p2);
2306
- p1 += s1;
2307
- p3 += s3;
2308
- }
2309
- }
2310
- } else {
2311
- if (p1 == p3) { // inplace case
2312
- for (i = 0; i < n; i++) {
2313
- check_intdivzero(*(dtype*)p2);
2314
- *(dtype*)p1 = m_div(*(dtype*)p1, *(dtype*)p2);
2315
- p1 += s1;
2316
- p2 += s2;
2317
- }
2318
- } else {
2319
- for (i = 0; i < n; i++) {
2320
- check_intdivzero(*(dtype*)p2);
2321
- *(dtype*)p3 = m_div(*(dtype*)p1, *(dtype*)p2);
2322
- p1 += s1;
2323
- p2 += s2;
2324
- p3 += s3;
2325
- }
2326
- }
2327
- }
2328
-
2329
- return;
2330
- //
2331
- }
2332
- }
2333
- for (i = 0; i < n; i++) {
2334
- dtype x, y, z;
2335
- GET_DATA_STRIDE(p1, s1, dtype, x);
2336
- GET_DATA_STRIDE(p2, s2, dtype, y);
2337
- check_intdivzero(y);
2338
- z = m_div(x, y);
2339
- SET_DATA_STRIDE(p3, s3, dtype, z);
2340
- }
2341
- //
2342
- }
2343
- #undef check_intdivzero
2344
-
2345
- static VALUE dcomplex_div_self(VALUE self, VALUE other) {
2346
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2347
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2348
- ndfunc_t ndf = { iter_dcomplex_div, STRIDE_LOOP, 2, 1, ain, aout };
2349
-
2350
- return na_ndloop(&ndf, 2, self, other);
2351
- }
2352
-
2353
- /*
2354
- Binary div.
2355
- @overload / other
2356
- @param [Numo::NArray,Numeric] other
2357
- @return [Numo::NArray] self / other
2358
- */
2359
- static VALUE dcomplex_div(VALUE self, VALUE other) {
2360
-
2361
- VALUE klass, v;
2362
-
2363
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2364
- if (klass == cT) {
2365
- return dcomplex_div_self(self, other);
2366
- } else {
2367
- v = rb_funcall(klass, id_cast, 1, self);
2368
- return rb_funcall(v, '/', 1, other);
2369
- }
2370
- }
2371
-
2372
- static void iter_dcomplex_pow(na_loop_t* const lp) {
2373
- size_t i;
2374
- char *p1, *p2, *p3;
2375
- ssize_t s1, s2, s3;
2376
- dtype x, y;
2377
- INIT_COUNTER(lp, i);
2378
- INIT_PTR(lp, 0, p1, s1);
2379
- INIT_PTR(lp, 1, p2, s2);
2380
- INIT_PTR(lp, 2, p3, s3);
2381
- for (; i--;) {
2382
- GET_DATA_STRIDE(p1, s1, dtype, x);
2383
- GET_DATA_STRIDE(p2, s2, dtype, y);
2384
- x = m_pow(x, y);
2385
- SET_DATA_STRIDE(p3, s3, dtype, x);
2386
- }
2387
- }
2388
-
2389
- static void iter_dcomplex_pow_int32(na_loop_t* const lp) {
2390
- size_t i;
2391
- char *p1, *p2, *p3;
2392
- ssize_t s1, s2, s3;
2393
- dtype x;
2394
- int32_t y;
2395
- INIT_COUNTER(lp, i);
2396
- INIT_PTR(lp, 0, p1, s1);
2397
- INIT_PTR(lp, 1, p2, s2);
2398
- INIT_PTR(lp, 2, p3, s3);
2399
- for (; i--;) {
2400
- GET_DATA_STRIDE(p1, s1, dtype, x);
2401
- GET_DATA_STRIDE(p2, s2, int32_t, y);
2402
- x = m_pow_int(x, y);
2403
- SET_DATA_STRIDE(p3, s3, dtype, x);
2404
- }
2405
- }
2406
-
2407
- static VALUE dcomplex_pow_self(VALUE self, VALUE other) {
2408
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
2409
- ndfunc_arg_in_t ain_i[2] = { { cT, 0 }, { numo_cInt32, 0 } };
2410
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2411
- ndfunc_t ndf = { iter_dcomplex_pow, STRIDE_LOOP, 2, 1, ain, aout };
2412
- ndfunc_t ndf_i = { iter_dcomplex_pow_int32, STRIDE_LOOP, 2, 1, ain_i, aout };
2413
-
2414
- // fixme : use na.integer?
2415
- if (FIXNUM_P(other) || rb_obj_is_kind_of(other, numo_cInt32)) {
2416
- return na_ndloop(&ndf_i, 2, self, other);
2417
- } else {
2418
- return na_ndloop(&ndf, 2, self, other);
2419
- }
2420
- }
2421
-
2422
- /*
2423
- Binary power.
2424
- @overload ** other
2425
- @param [Numo::NArray,Numeric] other
2426
- @return [Numo::NArray] self to the other-th power.
2427
- */
2428
- static VALUE dcomplex_pow(VALUE self, VALUE other) {
2429
-
2430
- VALUE klass, v;
2431
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
2432
- if (klass == cT) {
2433
- return dcomplex_pow_self(self, other);
2434
- } else {
2435
- v = rb_funcall(klass, id_cast, 1, self);
2436
- return rb_funcall(v, id_pow, 1, other);
2437
- }
2438
- }
2439
-
2440
- static void iter_dcomplex_minus(na_loop_t* const lp) {
2441
- size_t i, n;
2442
- char *p1, *p2;
2443
- ssize_t s1, s2;
2444
- size_t *idx1, *idx2;
2445
- dtype x;
2446
-
2447
- INIT_COUNTER(lp, n);
2448
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2449
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
1992
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
1993
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2450
1994
 
2451
1995
  if (idx1) {
2452
1996
  if (idx2) {
2453
1997
  for (i = 0; i < n; i++) {
2454
1998
  GET_DATA_INDEX(p1, idx1, dtype, x);
2455
- x = m_minus(x);
1999
+ x = m_sign(x);
2456
2000
  SET_DATA_INDEX(p2, idx2, dtype, x);
2457
2001
  }
2458
2002
  } else {
2459
2003
  for (i = 0; i < n; i++) {
2460
2004
  GET_DATA_INDEX(p1, idx1, dtype, x);
2461
- x = m_minus(x);
2005
+ x = m_sign(x);
2462
2006
  SET_DATA_STRIDE(p2, s2, dtype, x);
2463
2007
  }
2464
2008
  }
@@ -2466,7 +2010,7 @@ static void iter_dcomplex_minus(na_loop_t* const lp) {
2466
2010
  if (idx2) {
2467
2011
  for (i = 0; i < n; i++) {
2468
2012
  GET_DATA_STRIDE(p1, s1, dtype, x);
2469
- x = m_minus(x);
2013
+ x = m_sign(x);
2470
2014
  SET_DATA_INDEX(p2, idx2, dtype, x);
2471
2015
  }
2472
2016
  } else {
@@ -2474,14 +2018,14 @@ static void iter_dcomplex_minus(na_loop_t* const lp) {
2474
2018
  if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2475
2019
  if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2476
2020
  for (i = 0; i < n; i++) {
2477
- ((dtype*)p2)[i] = m_minus(((dtype*)p1)[i]);
2021
+ ((dtype*)p2)[i] = m_sign(((dtype*)p1)[i]);
2478
2022
  }
2479
2023
  return;
2480
2024
  }
2481
2025
  if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2482
2026
  //
2483
2027
  for (i = 0; i < n; i++) {
2484
- *(dtype*)p2 = m_minus(*(dtype*)p1);
2028
+ *(dtype*)p2 = m_sign(*(dtype*)p1);
2485
2029
  p1 += s1;
2486
2030
  p2 += s2;
2487
2031
  }
@@ -2491,7 +2035,7 @@ static void iter_dcomplex_minus(na_loop_t* const lp) {
2491
2035
  }
2492
2036
  for (i = 0; i < n; i++) {
2493
2037
  GET_DATA_STRIDE(p1, s1, dtype, x);
2494
- x = m_minus(x);
2038
+ x = m_sign(x);
2495
2039
  SET_DATA_STRIDE(p2, s2, dtype, x);
2496
2040
  }
2497
2041
  //
@@ -2500,19 +2044,19 @@ static void iter_dcomplex_minus(na_loop_t* const lp) {
2500
2044
  }
2501
2045
 
2502
2046
  /*
2503
- Unary minus.
2504
- @overload -@
2505
- @return [Numo::DComplex] minus of self.
2047
+ Unary sign.
2048
+ @overload sign
2049
+ @return [Numo::DComplex] sign of self.
2506
2050
  */
2507
- static VALUE dcomplex_minus(VALUE self) {
2051
+ static VALUE dcomplex_sign(VALUE self) {
2508
2052
  ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2509
2053
  ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2510
- ndfunc_t ndf = { iter_dcomplex_minus, FULL_LOOP, 1, 1, ain, aout };
2054
+ ndfunc_t ndf = { iter_dcomplex_sign, FULL_LOOP, 1, 1, ain, aout };
2511
2055
 
2512
2056
  return na_ndloop(&ndf, 1, self);
2513
2057
  }
2514
2058
 
2515
- static void iter_dcomplex_reciprocal(na_loop_t* const lp) {
2059
+ static void iter_dcomplex_square(na_loop_t* const lp) {
2516
2060
  size_t i, n;
2517
2061
  char *p1, *p2;
2518
2062
  ssize_t s1, s2;
@@ -2527,13 +2071,13 @@ static void iter_dcomplex_reciprocal(na_loop_t* const lp) {
2527
2071
  if (idx2) {
2528
2072
  for (i = 0; i < n; i++) {
2529
2073
  GET_DATA_INDEX(p1, idx1, dtype, x);
2530
- x = m_reciprocal(x);
2074
+ x = m_square(x);
2531
2075
  SET_DATA_INDEX(p2, idx2, dtype, x);
2532
2076
  }
2533
2077
  } else {
2534
2078
  for (i = 0; i < n; i++) {
2535
2079
  GET_DATA_INDEX(p1, idx1, dtype, x);
2536
- x = m_reciprocal(x);
2080
+ x = m_square(x);
2537
2081
  SET_DATA_STRIDE(p2, s2, dtype, x);
2538
2082
  }
2539
2083
  }
@@ -2541,7 +2085,7 @@ static void iter_dcomplex_reciprocal(na_loop_t* const lp) {
2541
2085
  if (idx2) {
2542
2086
  for (i = 0; i < n; i++) {
2543
2087
  GET_DATA_STRIDE(p1, s1, dtype, x);
2544
- x = m_reciprocal(x);
2088
+ x = m_square(x);
2545
2089
  SET_DATA_INDEX(p2, idx2, dtype, x);
2546
2090
  }
2547
2091
  } else {
@@ -2549,14 +2093,14 @@ static void iter_dcomplex_reciprocal(na_loop_t* const lp) {
2549
2093
  if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2550
2094
  if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2551
2095
  for (i = 0; i < n; i++) {
2552
- ((dtype*)p2)[i] = m_reciprocal(((dtype*)p1)[i]);
2096
+ ((dtype*)p2)[i] = m_square(((dtype*)p1)[i]);
2553
2097
  }
2554
2098
  return;
2555
2099
  }
2556
2100
  if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2557
2101
  //
2558
2102
  for (i = 0; i < n; i++) {
2559
- *(dtype*)p2 = m_reciprocal(*(dtype*)p1);
2103
+ *(dtype*)p2 = m_square(*(dtype*)p1);
2560
2104
  p1 += s1;
2561
2105
  p2 += s2;
2562
2106
  }
@@ -2566,7 +2110,7 @@ static void iter_dcomplex_reciprocal(na_loop_t* const lp) {
2566
2110
  }
2567
2111
  for (i = 0; i < n; i++) {
2568
2112
  GET_DATA_STRIDE(p1, s1, dtype, x);
2569
- x = m_reciprocal(x);
2113
+ x = m_square(x);
2570
2114
  SET_DATA_STRIDE(p2, s2, dtype, x);
2571
2115
  }
2572
2116
  //
@@ -2575,19 +2119,19 @@ static void iter_dcomplex_reciprocal(na_loop_t* const lp) {
2575
2119
  }
2576
2120
 
2577
2121
  /*
2578
- Unary reciprocal.
2579
- @overload reciprocal
2580
- @return [Numo::DComplex] reciprocal of self.
2122
+ Unary square.
2123
+ @overload square
2124
+ @return [Numo::DComplex] square of self.
2581
2125
  */
2582
- static VALUE dcomplex_reciprocal(VALUE self) {
2126
+ static VALUE dcomplex_square(VALUE self) {
2583
2127
  ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2584
2128
  ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2585
- ndfunc_t ndf = { iter_dcomplex_reciprocal, FULL_LOOP, 1, 1, ain, aout };
2129
+ ndfunc_t ndf = { iter_dcomplex_square, FULL_LOOP, 1, 1, ain, aout };
2586
2130
 
2587
2131
  return na_ndloop(&ndf, 1, self);
2588
2132
  }
2589
2133
 
2590
- static void iter_dcomplex_sign(na_loop_t* const lp) {
2134
+ static void iter_dcomplex_conj(na_loop_t* const lp) {
2591
2135
  size_t i, n;
2592
2136
  char *p1, *p2;
2593
2137
  ssize_t s1, s2;
@@ -2602,13 +2146,13 @@ static void iter_dcomplex_sign(na_loop_t* const lp) {
2602
2146
  if (idx2) {
2603
2147
  for (i = 0; i < n; i++) {
2604
2148
  GET_DATA_INDEX(p1, idx1, dtype, x);
2605
- x = m_sign(x);
2149
+ x = m_conj(x);
2606
2150
  SET_DATA_INDEX(p2, idx2, dtype, x);
2607
2151
  }
2608
2152
  } else {
2609
2153
  for (i = 0; i < n; i++) {
2610
2154
  GET_DATA_INDEX(p1, idx1, dtype, x);
2611
- x = m_sign(x);
2155
+ x = m_conj(x);
2612
2156
  SET_DATA_STRIDE(p2, s2, dtype, x);
2613
2157
  }
2614
2158
  }
@@ -2616,7 +2160,7 @@ static void iter_dcomplex_sign(na_loop_t* const lp) {
2616
2160
  if (idx2) {
2617
2161
  for (i = 0; i < n; i++) {
2618
2162
  GET_DATA_STRIDE(p1, s1, dtype, x);
2619
- x = m_sign(x);
2163
+ x = m_conj(x);
2620
2164
  SET_DATA_INDEX(p2, idx2, dtype, x);
2621
2165
  }
2622
2166
  } else {
@@ -2624,14 +2168,14 @@ static void iter_dcomplex_sign(na_loop_t* const lp) {
2624
2168
  if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2625
2169
  if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2626
2170
  for (i = 0; i < n; i++) {
2627
- ((dtype*)p2)[i] = m_sign(((dtype*)p1)[i]);
2171
+ ((dtype*)p2)[i] = m_conj(((dtype*)p1)[i]);
2628
2172
  }
2629
2173
  return;
2630
2174
  }
2631
2175
  if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2632
2176
  //
2633
2177
  for (i = 0; i < n; i++) {
2634
- *(dtype*)p2 = m_sign(*(dtype*)p1);
2178
+ *(dtype*)p2 = m_conj(*(dtype*)p1);
2635
2179
  p1 += s1;
2636
2180
  p2 += s2;
2637
2181
  }
@@ -2641,7 +2185,7 @@ static void iter_dcomplex_sign(na_loop_t* const lp) {
2641
2185
  }
2642
2186
  for (i = 0; i < n; i++) {
2643
2187
  GET_DATA_STRIDE(p1, s1, dtype, x);
2644
- x = m_sign(x);
2188
+ x = m_conj(x);
2645
2189
  SET_DATA_STRIDE(p2, s2, dtype, x);
2646
2190
  }
2647
2191
  //
@@ -2650,19 +2194,19 @@ static void iter_dcomplex_sign(na_loop_t* const lp) {
2650
2194
  }
2651
2195
 
2652
2196
  /*
2653
- Unary sign.
2654
- @overload sign
2655
- @return [Numo::DComplex] sign of self.
2197
+ Unary conj.
2198
+ @overload conj
2199
+ @return [Numo::DComplex] conj of self.
2656
2200
  */
2657
- static VALUE dcomplex_sign(VALUE self) {
2201
+ static VALUE dcomplex_conj(VALUE self) {
2658
2202
  ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2659
2203
  ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2660
- ndfunc_t ndf = { iter_dcomplex_sign, FULL_LOOP, 1, 1, ain, aout };
2204
+ ndfunc_t ndf = { iter_dcomplex_conj, FULL_LOOP, 1, 1, ain, aout };
2661
2205
 
2662
2206
  return na_ndloop(&ndf, 1, self);
2663
2207
  }
2664
2208
 
2665
- static void iter_dcomplex_square(na_loop_t* const lp) {
2209
+ static void iter_dcomplex_im(na_loop_t* const lp) {
2666
2210
  size_t i, n;
2667
2211
  char *p1, *p2;
2668
2212
  ssize_t s1, s2;
@@ -2677,13 +2221,13 @@ static void iter_dcomplex_square(na_loop_t* const lp) {
2677
2221
  if (idx2) {
2678
2222
  for (i = 0; i < n; i++) {
2679
2223
  GET_DATA_INDEX(p1, idx1, dtype, x);
2680
- x = m_square(x);
2224
+ x = m_im(x);
2681
2225
  SET_DATA_INDEX(p2, idx2, dtype, x);
2682
2226
  }
2683
2227
  } else {
2684
2228
  for (i = 0; i < n; i++) {
2685
2229
  GET_DATA_INDEX(p1, idx1, dtype, x);
2686
- x = m_square(x);
2230
+ x = m_im(x);
2687
2231
  SET_DATA_STRIDE(p2, s2, dtype, x);
2688
2232
  }
2689
2233
  }
@@ -2691,7 +2235,7 @@ static void iter_dcomplex_square(na_loop_t* const lp) {
2691
2235
  if (idx2) {
2692
2236
  for (i = 0; i < n; i++) {
2693
2237
  GET_DATA_STRIDE(p1, s1, dtype, x);
2694
- x = m_square(x);
2238
+ x = m_im(x);
2695
2239
  SET_DATA_INDEX(p2, idx2, dtype, x);
2696
2240
  }
2697
2241
  } else {
@@ -2699,14 +2243,14 @@ static void iter_dcomplex_square(na_loop_t* const lp) {
2699
2243
  if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2700
2244
  if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2701
2245
  for (i = 0; i < n; i++) {
2702
- ((dtype*)p2)[i] = m_square(((dtype*)p1)[i]);
2246
+ ((dtype*)p2)[i] = m_im(((dtype*)p1)[i]);
2703
2247
  }
2704
2248
  return;
2705
2249
  }
2706
2250
  if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2707
2251
  //
2708
2252
  for (i = 0; i < n; i++) {
2709
- *(dtype*)p2 = m_square(*(dtype*)p1);
2253
+ *(dtype*)p2 = m_im(*(dtype*)p1);
2710
2254
  p1 += s1;
2711
2255
  p2 += s2;
2712
2256
  }
@@ -2716,7 +2260,7 @@ static void iter_dcomplex_square(na_loop_t* const lp) {
2716
2260
  }
2717
2261
  for (i = 0; i < n; i++) {
2718
2262
  GET_DATA_STRIDE(p1, s1, dtype, x);
2719
- x = m_square(x);
2263
+ x = m_im(x);
2720
2264
  SET_DATA_STRIDE(p2, s2, dtype, x);
2721
2265
  }
2722
2266
  //
@@ -2725,181 +2269,31 @@ static void iter_dcomplex_square(na_loop_t* const lp) {
2725
2269
  }
2726
2270
 
2727
2271
  /*
2728
- Unary square.
2729
- @overload square
2730
- @return [Numo::DComplex] square of self.
2272
+ Unary im.
2273
+ @overload im
2274
+ @return [Numo::DComplex] im of self.
2731
2275
  */
2732
- static VALUE dcomplex_square(VALUE self) {
2276
+ static VALUE dcomplex_im(VALUE self) {
2733
2277
  ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2734
2278
  ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2735
- ndfunc_t ndf = { iter_dcomplex_square, FULL_LOOP, 1, 1, ain, aout };
2279
+ ndfunc_t ndf = { iter_dcomplex_im, FULL_LOOP, 1, 1, ain, aout };
2736
2280
 
2737
2281
  return na_ndloop(&ndf, 1, self);
2738
2282
  }
2739
2283
 
2740
- static void iter_dcomplex_conj(na_loop_t* const lp) {
2741
- size_t i, n;
2284
+ static void iter_dcomplex_real(na_loop_t* const lp) {
2285
+ size_t i;
2742
2286
  char *p1, *p2;
2743
2287
  ssize_t s1, s2;
2744
2288
  size_t *idx1, *idx2;
2745
2289
  dtype x;
2746
-
2747
- INIT_COUNTER(lp, n);
2290
+ rtype y;
2291
+ INIT_COUNTER(lp, i);
2748
2292
  INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2749
2293
  INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2750
-
2751
2294
  if (idx1) {
2752
2295
  if (idx2) {
2753
- for (i = 0; i < n; i++) {
2754
- GET_DATA_INDEX(p1, idx1, dtype, x);
2755
- x = m_conj(x);
2756
- SET_DATA_INDEX(p2, idx2, dtype, x);
2757
- }
2758
- } else {
2759
- for (i = 0; i < n; i++) {
2760
- GET_DATA_INDEX(p1, idx1, dtype, x);
2761
- x = m_conj(x);
2762
- SET_DATA_STRIDE(p2, s2, dtype, x);
2763
- }
2764
- }
2765
- } else {
2766
- if (idx2) {
2767
- for (i = 0; i < n; i++) {
2768
- GET_DATA_STRIDE(p1, s1, dtype, x);
2769
- x = m_conj(x);
2770
- SET_DATA_INDEX(p2, idx2, dtype, x);
2771
- }
2772
- } else {
2773
- //
2774
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2775
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2776
- for (i = 0; i < n; i++) {
2777
- ((dtype*)p2)[i] = m_conj(((dtype*)p1)[i]);
2778
- }
2779
- return;
2780
- }
2781
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2782
- //
2783
- for (i = 0; i < n; i++) {
2784
- *(dtype*)p2 = m_conj(*(dtype*)p1);
2785
- p1 += s1;
2786
- p2 += s2;
2787
- }
2788
- return;
2789
- //
2790
- }
2791
- }
2792
- for (i = 0; i < n; i++) {
2793
- GET_DATA_STRIDE(p1, s1, dtype, x);
2794
- x = m_conj(x);
2795
- SET_DATA_STRIDE(p2, s2, dtype, x);
2796
- }
2797
- //
2798
- }
2799
- }
2800
- }
2801
-
2802
- /*
2803
- Unary conj.
2804
- @overload conj
2805
- @return [Numo::DComplex] conj of self.
2806
- */
2807
- static VALUE dcomplex_conj(VALUE self) {
2808
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2809
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2810
- ndfunc_t ndf = { iter_dcomplex_conj, FULL_LOOP, 1, 1, ain, aout };
2811
-
2812
- return na_ndloop(&ndf, 1, self);
2813
- }
2814
-
2815
- static void iter_dcomplex_im(na_loop_t* const lp) {
2816
- size_t i, n;
2817
- char *p1, *p2;
2818
- ssize_t s1, s2;
2819
- size_t *idx1, *idx2;
2820
- dtype x;
2821
-
2822
- INIT_COUNTER(lp, n);
2823
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2824
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2825
-
2826
- if (idx1) {
2827
- if (idx2) {
2828
- for (i = 0; i < n; i++) {
2829
- GET_DATA_INDEX(p1, idx1, dtype, x);
2830
- x = m_im(x);
2831
- SET_DATA_INDEX(p2, idx2, dtype, x);
2832
- }
2833
- } else {
2834
- for (i = 0; i < n; i++) {
2835
- GET_DATA_INDEX(p1, idx1, dtype, x);
2836
- x = m_im(x);
2837
- SET_DATA_STRIDE(p2, s2, dtype, x);
2838
- }
2839
- }
2840
- } else {
2841
- if (idx2) {
2842
- for (i = 0; i < n; i++) {
2843
- GET_DATA_STRIDE(p1, s1, dtype, x);
2844
- x = m_im(x);
2845
- SET_DATA_INDEX(p2, idx2, dtype, x);
2846
- }
2847
- } else {
2848
- //
2849
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
2850
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
2851
- for (i = 0; i < n; i++) {
2852
- ((dtype*)p2)[i] = m_im(((dtype*)p1)[i]);
2853
- }
2854
- return;
2855
- }
2856
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
2857
- //
2858
- for (i = 0; i < n; i++) {
2859
- *(dtype*)p2 = m_im(*(dtype*)p1);
2860
- p1 += s1;
2861
- p2 += s2;
2862
- }
2863
- return;
2864
- //
2865
- }
2866
- }
2867
- for (i = 0; i < n; i++) {
2868
- GET_DATA_STRIDE(p1, s1, dtype, x);
2869
- x = m_im(x);
2870
- SET_DATA_STRIDE(p2, s2, dtype, x);
2871
- }
2872
- //
2873
- }
2874
- }
2875
- }
2876
-
2877
- /*
2878
- Unary im.
2879
- @overload im
2880
- @return [Numo::DComplex] im of self.
2881
- */
2882
- static VALUE dcomplex_im(VALUE self) {
2883
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
2884
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2885
- ndfunc_t ndf = { iter_dcomplex_im, FULL_LOOP, 1, 1, ain, aout };
2886
-
2887
- return na_ndloop(&ndf, 1, self);
2888
- }
2889
-
2890
- static void iter_dcomplex_real(na_loop_t* const lp) {
2891
- size_t i;
2892
- char *p1, *p2;
2893
- ssize_t s1, s2;
2894
- size_t *idx1, *idx2;
2895
- dtype x;
2896
- rtype y;
2897
- INIT_COUNTER(lp, i);
2898
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
2899
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
2900
- if (idx1) {
2901
- if (idx2) {
2902
- for (; i--;) {
2296
+ for (; i--;) {
2903
2297
  GET_DATA_INDEX(p1, idx1, dtype, x);
2904
2298
  y = m_real(x);
2905
2299
  SET_DATA_INDEX(p2, idx2, rtype, y);
@@ -3155,1563 +2549,170 @@ static VALUE dcomplex_set_real(VALUE self, VALUE a1) {
3155
2549
  return a1;
3156
2550
  }
3157
2551
 
3158
- static void iter_dcomplex_eq(na_loop_t* const lp) {
3159
- size_t i;
3160
- char *p1, *p2;
3161
- BIT_DIGIT* a3;
3162
- size_t p3;
3163
- ssize_t s1, s2, s3;
3164
- dtype x, y;
3165
- BIT_DIGIT b;
3166
- INIT_COUNTER(lp, i);
3167
- INIT_PTR(lp, 0, p1, s1);
3168
- INIT_PTR(lp, 1, p2, s2);
3169
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
3170
- for (; i--;) {
3171
- GET_DATA_STRIDE(p1, s1, dtype, x);
3172
- GET_DATA_STRIDE(p2, s2, dtype, y);
3173
- b = (m_eq(x, y)) ? 1 : 0;
3174
- STORE_BIT(a3, p3, b);
3175
- p3 += s3;
3176
- }
3177
- }
3178
-
3179
- static VALUE dcomplex_eq_self(VALUE self, VALUE other) {
3180
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3181
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3182
- ndfunc_t ndf = { iter_dcomplex_eq, STRIDE_LOOP, 2, 1, ain, aout };
3183
-
3184
- return na_ndloop(&ndf, 2, self, other);
3185
- }
3186
-
3187
- /*
3188
- Comparison eq other.
3189
- @overload eq other
3190
- @param [Numo::NArray,Numeric] other
3191
- @return [Numo::Bit] result of self eq other.
3192
- */
3193
- static VALUE dcomplex_eq(VALUE self, VALUE other) {
3194
-
3195
- VALUE klass, v;
3196
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3197
- if (klass == cT) {
3198
- return dcomplex_eq_self(self, other);
3199
- } else {
3200
- v = rb_funcall(klass, id_cast, 1, self);
3201
- return rb_funcall(v, id_eq, 1, other);
3202
- }
3203
- }
2552
+ #define check_intdivzero(y) \
2553
+ {}
3204
2554
 
3205
- static void iter_dcomplex_ne(na_loop_t* const lp) {
3206
- size_t i;
3207
- char *p1, *p2;
3208
- BIT_DIGIT* a3;
3209
- size_t p3;
2555
+ static void iter_dcomplex_copysign(na_loop_t* const lp) {
2556
+ size_t i = 0;
2557
+ size_t n;
2558
+ char *p1, *p2, *p3;
3210
2559
  ssize_t s1, s2, s3;
3211
- dtype x, y;
3212
- BIT_DIGIT b;
3213
- INIT_COUNTER(lp, i);
3214
- INIT_PTR(lp, 0, p1, s1);
3215
- INIT_PTR(lp, 1, p2, s2);
3216
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
3217
- for (; i--;) {
3218
- GET_DATA_STRIDE(p1, s1, dtype, x);
3219
- GET_DATA_STRIDE(p2, s2, dtype, y);
3220
- b = (m_ne(x, y)) ? 1 : 0;
3221
- STORE_BIT(a3, p3, b);
3222
- p3 += s3;
3223
- }
3224
- }
3225
-
3226
- static VALUE dcomplex_ne_self(VALUE self, VALUE other) {
3227
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3228
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3229
- ndfunc_t ndf = { iter_dcomplex_ne, STRIDE_LOOP, 2, 1, ain, aout };
3230
-
3231
- return na_ndloop(&ndf, 2, self, other);
3232
- }
3233
-
3234
- /*
3235
- Comparison ne other.
3236
- @overload ne other
3237
- @param [Numo::NArray,Numeric] other
3238
- @return [Numo::Bit] result of self ne other.
3239
- */
3240
- static VALUE dcomplex_ne(VALUE self, VALUE other) {
3241
-
3242
- VALUE klass, v;
3243
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3244
- if (klass == cT) {
3245
- return dcomplex_ne_self(self, other);
3246
- } else {
3247
- v = rb_funcall(klass, id_cast, 1, self);
3248
- return rb_funcall(v, id_ne, 1, other);
3249
- }
3250
- }
3251
2560
 
3252
- static void iter_dcomplex_nearly_eq(na_loop_t* const lp) {
3253
- size_t i;
3254
- char *p1, *p2;
3255
- BIT_DIGIT* a3;
3256
- size_t p3;
3257
- ssize_t s1, s2, s3;
3258
- dtype x, y;
3259
- BIT_DIGIT b;
3260
- INIT_COUNTER(lp, i);
2561
+ INIT_COUNTER(lp, n);
3261
2562
  INIT_PTR(lp, 0, p1, s1);
3262
2563
  INIT_PTR(lp, 1, p2, s2);
3263
- INIT_PTR_BIT(lp, 2, a3, p3, s3);
3264
- for (; i--;) {
3265
- GET_DATA_STRIDE(p1, s1, dtype, x);
3266
- GET_DATA_STRIDE(p2, s2, dtype, y);
3267
- b = (m_nearly_eq(x, y)) ? 1 : 0;
3268
- STORE_BIT(a3, p3, b);
3269
- p3 += s3;
3270
- }
3271
- }
2564
+ INIT_PTR(lp, 2, p3, s3);
3272
2565
 
3273
- static VALUE dcomplex_nearly_eq_self(VALUE self, VALUE other) {
3274
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3275
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3276
- ndfunc_t ndf = { iter_dcomplex_nearly_eq, STRIDE_LOOP, 2, 1, ain, aout };
2566
+ //
2567
+ if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
2568
+ is_aligned(p3, sizeof(dtype))) {
3277
2569
 
3278
- return na_ndloop(&ndf, 2, self, other);
3279
- }
2570
+ if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
2571
+ if (p1 == p3) { // inplace case
2572
+ for (; i < n; i++) {
2573
+ check_intdivzero(((dtype*)p2)[i]);
2574
+ ((dtype*)p1)[i] = m_copysign(((dtype*)p1)[i], ((dtype*)p2)[i]);
2575
+ }
2576
+ } else {
2577
+ for (; i < n; i++) {
2578
+ check_intdivzero(((dtype*)p2)[i]);
2579
+ ((dtype*)p3)[i] = m_copysign(((dtype*)p1)[i], ((dtype*)p2)[i]);
2580
+ }
2581
+ }
2582
+ return;
2583
+ }
3280
2584
 
3281
- /*
3282
- Comparison nearly_eq other.
3283
- @overload nearly_eq other
3284
- @param [Numo::NArray,Numeric] other
3285
- @return [Numo::Bit] result of self nearly_eq other.
3286
- */
3287
- static VALUE dcomplex_nearly_eq(VALUE self, VALUE other) {
2585
+ if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
2586
+ is_aligned_step(s3, sizeof(dtype))) {
2587
+ //
3288
2588
 
3289
- VALUE klass, v;
3290
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3291
- if (klass == cT) {
3292
- return dcomplex_nearly_eq_self(self, other);
3293
- } else {
3294
- v = rb_funcall(klass, id_cast, 1, self);
3295
- return rb_funcall(v, id_nearly_eq, 1, other);
3296
- }
3297
- }
3298
-
3299
- static void iter_dcomplex_floor(na_loop_t* const lp) {
3300
- size_t i, n;
3301
- char *p1, *p2;
3302
- ssize_t s1, s2;
3303
- size_t *idx1, *idx2;
3304
- dtype x;
3305
-
3306
- INIT_COUNTER(lp, n);
3307
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3308
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
3309
-
3310
- if (idx1) {
3311
- if (idx2) {
3312
- for (i = 0; i < n; i++) {
3313
- GET_DATA_INDEX(p1, idx1, dtype, x);
3314
- x = m_floor(x);
3315
- SET_DATA_INDEX(p2, idx2, dtype, x);
3316
- }
3317
- } else {
3318
- for (i = 0; i < n; i++) {
3319
- GET_DATA_INDEX(p1, idx1, dtype, x);
3320
- x = m_floor(x);
3321
- SET_DATA_STRIDE(p2, s2, dtype, x);
3322
- }
3323
- }
3324
- } else {
3325
- if (idx2) {
3326
- for (i = 0; i < n; i++) {
3327
- GET_DATA_STRIDE(p1, s1, dtype, x);
3328
- x = m_floor(x);
3329
- SET_DATA_INDEX(p2, idx2, dtype, x);
3330
- }
3331
- } else {
3332
- //
3333
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
3334
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
3335
- for (i = 0; i < n; i++) {
3336
- ((dtype*)p2)[i] = m_floor(((dtype*)p1)[i]);
2589
+ if (s2 == 0) { // Broadcasting from scalar value.
2590
+ check_intdivzero(*(dtype*)p2);
2591
+ if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
2592
+ if (p1 == p3) { // inplace case
2593
+ for (; i < n; i++) {
2594
+ ((dtype*)p1)[i] = m_copysign(((dtype*)p1)[i], *(dtype*)p2);
2595
+ }
2596
+ } else {
2597
+ for (; i < n; i++) {
2598
+ ((dtype*)p3)[i] = m_copysign(((dtype*)p1)[i], *(dtype*)p2);
2599
+ }
3337
2600
  }
3338
- return;
3339
- }
3340
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
3341
- //
2601
+ } else {
3342
2602
  for (i = 0; i < n; i++) {
3343
- *(dtype*)p2 = m_floor(*(dtype*)p1);
2603
+ *(dtype*)p3 = m_copysign(*(dtype*)p1, *(dtype*)p2);
3344
2604
  p1 += s1;
3345
- p2 += s2;
3346
- }
3347
- return;
3348
- //
3349
- }
3350
- }
3351
- for (i = 0; i < n; i++) {
3352
- GET_DATA_STRIDE(p1, s1, dtype, x);
3353
- x = m_floor(x);
3354
- SET_DATA_STRIDE(p2, s2, dtype, x);
3355
- }
3356
- //
3357
- }
3358
- }
3359
- }
3360
-
3361
- /*
3362
- Unary floor.
3363
- @overload floor
3364
- @return [Numo::DComplex] floor of self.
3365
- */
3366
- static VALUE dcomplex_floor(VALUE self) {
3367
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3368
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3369
- ndfunc_t ndf = { iter_dcomplex_floor, FULL_LOOP, 1, 1, ain, aout };
3370
-
3371
- return na_ndloop(&ndf, 1, self);
3372
- }
3373
-
3374
- static void iter_dcomplex_round(na_loop_t* const lp) {
3375
- size_t i, n;
3376
- char *p1, *p2;
3377
- ssize_t s1, s2;
3378
- size_t *idx1, *idx2;
3379
- dtype x;
3380
-
3381
- INIT_COUNTER(lp, n);
3382
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3383
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
3384
-
3385
- if (idx1) {
3386
- if (idx2) {
3387
- for (i = 0; i < n; i++) {
3388
- GET_DATA_INDEX(p1, idx1, dtype, x);
3389
- x = m_round(x);
3390
- SET_DATA_INDEX(p2, idx2, dtype, x);
3391
- }
3392
- } else {
3393
- for (i = 0; i < n; i++) {
3394
- GET_DATA_INDEX(p1, idx1, dtype, x);
3395
- x = m_round(x);
3396
- SET_DATA_STRIDE(p2, s2, dtype, x);
3397
- }
3398
- }
3399
- } else {
3400
- if (idx2) {
3401
- for (i = 0; i < n; i++) {
3402
- GET_DATA_STRIDE(p1, s1, dtype, x);
3403
- x = m_round(x);
3404
- SET_DATA_INDEX(p2, idx2, dtype, x);
3405
- }
3406
- } else {
3407
- //
3408
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
3409
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
3410
- for (i = 0; i < n; i++) {
3411
- ((dtype*)p2)[i] = m_round(((dtype*)p1)[i]);
2605
+ p3 += s3;
3412
2606
  }
3413
- return;
3414
2607
  }
3415
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
3416
- //
2608
+ } else {
2609
+ if (p1 == p3) { // inplace case
3417
2610
  for (i = 0; i < n; i++) {
3418
- *(dtype*)p2 = m_round(*(dtype*)p1);
2611
+ check_intdivzero(*(dtype*)p2);
2612
+ *(dtype*)p1 = m_copysign(*(dtype*)p1, *(dtype*)p2);
3419
2613
  p1 += s1;
3420
2614
  p2 += s2;
3421
2615
  }
3422
- return;
3423
- //
3424
- }
3425
- }
3426
- for (i = 0; i < n; i++) {
3427
- GET_DATA_STRIDE(p1, s1, dtype, x);
3428
- x = m_round(x);
3429
- SET_DATA_STRIDE(p2, s2, dtype, x);
3430
- }
3431
- //
3432
- }
3433
- }
3434
- }
3435
-
3436
- /*
3437
- Unary round.
3438
- @overload round
3439
- @return [Numo::DComplex] round of self.
3440
- */
3441
- static VALUE dcomplex_round(VALUE self) {
3442
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3443
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3444
- ndfunc_t ndf = { iter_dcomplex_round, FULL_LOOP, 1, 1, ain, aout };
3445
-
3446
- return na_ndloop(&ndf, 1, self);
3447
- }
3448
-
3449
- static void iter_dcomplex_ceil(na_loop_t* const lp) {
3450
- size_t i, n;
3451
- char *p1, *p2;
3452
- ssize_t s1, s2;
3453
- size_t *idx1, *idx2;
3454
- dtype x;
3455
-
3456
- INIT_COUNTER(lp, n);
3457
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3458
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
3459
-
3460
- if (idx1) {
3461
- if (idx2) {
3462
- for (i = 0; i < n; i++) {
3463
- GET_DATA_INDEX(p1, idx1, dtype, x);
3464
- x = m_ceil(x);
3465
- SET_DATA_INDEX(p2, idx2, dtype, x);
3466
- }
3467
- } else {
3468
- for (i = 0; i < n; i++) {
3469
- GET_DATA_INDEX(p1, idx1, dtype, x);
3470
- x = m_ceil(x);
3471
- SET_DATA_STRIDE(p2, s2, dtype, x);
3472
- }
3473
- }
3474
- } else {
3475
- if (idx2) {
3476
- for (i = 0; i < n; i++) {
3477
- GET_DATA_STRIDE(p1, s1, dtype, x);
3478
- x = m_ceil(x);
3479
- SET_DATA_INDEX(p2, idx2, dtype, x);
3480
- }
3481
- } else {
3482
- //
3483
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
3484
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
3485
- for (i = 0; i < n; i++) {
3486
- ((dtype*)p2)[i] = m_ceil(((dtype*)p1)[i]);
3487
- }
3488
- return;
3489
- }
3490
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
3491
- //
2616
+ } else {
3492
2617
  for (i = 0; i < n; i++) {
3493
- *(dtype*)p2 = m_ceil(*(dtype*)p1);
2618
+ check_intdivzero(*(dtype*)p2);
2619
+ *(dtype*)p3 = m_copysign(*(dtype*)p1, *(dtype*)p2);
3494
2620
  p1 += s1;
3495
2621
  p2 += s2;
2622
+ p3 += s3;
3496
2623
  }
3497
- return;
3498
- //
3499
2624
  }
3500
2625
  }
3501
- for (i = 0; i < n; i++) {
3502
- GET_DATA_STRIDE(p1, s1, dtype, x);
3503
- x = m_ceil(x);
3504
- SET_DATA_STRIDE(p2, s2, dtype, x);
3505
- }
3506
- //
3507
- }
3508
- }
3509
- }
3510
-
3511
- /*
3512
- Unary ceil.
3513
- @overload ceil
3514
- @return [Numo::DComplex] ceil of self.
3515
- */
3516
- static VALUE dcomplex_ceil(VALUE self) {
3517
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3518
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3519
- ndfunc_t ndf = { iter_dcomplex_ceil, FULL_LOOP, 1, 1, ain, aout };
3520
-
3521
- return na_ndloop(&ndf, 1, self);
3522
- }
3523
-
3524
- static void iter_dcomplex_trunc(na_loop_t* const lp) {
3525
- size_t i, n;
3526
- char *p1, *p2;
3527
- ssize_t s1, s2;
3528
- size_t *idx1, *idx2;
3529
- dtype x;
3530
-
3531
- INIT_COUNTER(lp, n);
3532
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3533
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
3534
2626
 
3535
- if (idx1) {
3536
- if (idx2) {
3537
- for (i = 0; i < n; i++) {
3538
- GET_DATA_INDEX(p1, idx1, dtype, x);
3539
- x = m_trunc(x);
3540
- SET_DATA_INDEX(p2, idx2, dtype, x);
3541
- }
3542
- } else {
3543
- for (i = 0; i < n; i++) {
3544
- GET_DATA_INDEX(p1, idx1, dtype, x);
3545
- x = m_trunc(x);
3546
- SET_DATA_STRIDE(p2, s2, dtype, x);
3547
- }
3548
- }
3549
- } else {
3550
- if (idx2) {
3551
- for (i = 0; i < n; i++) {
3552
- GET_DATA_STRIDE(p1, s1, dtype, x);
3553
- x = m_trunc(x);
3554
- SET_DATA_INDEX(p2, idx2, dtype, x);
3555
- }
3556
- } else {
3557
- //
3558
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
3559
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
3560
- for (i = 0; i < n; i++) {
3561
- ((dtype*)p2)[i] = m_trunc(((dtype*)p1)[i]);
3562
- }
3563
- return;
3564
- }
3565
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
3566
- //
3567
- for (i = 0; i < n; i++) {
3568
- *(dtype*)p2 = m_trunc(*(dtype*)p1);
3569
- p1 += s1;
3570
- p2 += s2;
3571
- }
3572
- return;
3573
- //
3574
- }
3575
- }
3576
- for (i = 0; i < n; i++) {
3577
- GET_DATA_STRIDE(p1, s1, dtype, x);
3578
- x = m_trunc(x);
3579
- SET_DATA_STRIDE(p2, s2, dtype, x);
3580
- }
3581
- //
3582
- }
3583
- }
3584
- }
3585
-
3586
- /*
3587
- Unary trunc.
3588
- @overload trunc
3589
- @return [Numo::DComplex] trunc of self.
3590
- */
3591
- static VALUE dcomplex_trunc(VALUE self) {
3592
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3593
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3594
- ndfunc_t ndf = { iter_dcomplex_trunc, FULL_LOOP, 1, 1, ain, aout };
3595
-
3596
- return na_ndloop(&ndf, 1, self);
3597
- }
3598
-
3599
- static void iter_dcomplex_rint(na_loop_t* const lp) {
3600
- size_t i, n;
3601
- char *p1, *p2;
3602
- ssize_t s1, s2;
3603
- size_t *idx1, *idx2;
3604
- dtype x;
3605
-
3606
- INIT_COUNTER(lp, n);
3607
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3608
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
3609
-
3610
- if (idx1) {
3611
- if (idx2) {
3612
- for (i = 0; i < n; i++) {
3613
- GET_DATA_INDEX(p1, idx1, dtype, x);
3614
- x = m_rint(x);
3615
- SET_DATA_INDEX(p2, idx2, dtype, x);
3616
- }
3617
- } else {
3618
- for (i = 0; i < n; i++) {
3619
- GET_DATA_INDEX(p1, idx1, dtype, x);
3620
- x = m_rint(x);
3621
- SET_DATA_STRIDE(p2, s2, dtype, x);
3622
- }
3623
- }
3624
- } else {
3625
- if (idx2) {
3626
- for (i = 0; i < n; i++) {
3627
- GET_DATA_STRIDE(p1, s1, dtype, x);
3628
- x = m_rint(x);
3629
- SET_DATA_INDEX(p2, idx2, dtype, x);
3630
- }
3631
- } else {
3632
- //
3633
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
3634
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
3635
- for (i = 0; i < n; i++) {
3636
- ((dtype*)p2)[i] = m_rint(((dtype*)p1)[i]);
3637
- }
3638
- return;
3639
- }
3640
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
3641
- //
3642
- for (i = 0; i < n; i++) {
3643
- *(dtype*)p2 = m_rint(*(dtype*)p1);
3644
- p1 += s1;
3645
- p2 += s2;
3646
- }
3647
- return;
3648
- //
3649
- }
3650
- }
3651
- for (i = 0; i < n; i++) {
3652
- GET_DATA_STRIDE(p1, s1, dtype, x);
3653
- x = m_rint(x);
3654
- SET_DATA_STRIDE(p2, s2, dtype, x);
3655
- }
3656
- //
3657
- }
3658
- }
3659
- }
3660
-
3661
- /*
3662
- Unary rint.
3663
- @overload rint
3664
- @return [Numo::DComplex] rint of self.
3665
- */
3666
- static VALUE dcomplex_rint(VALUE self) {
3667
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3668
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3669
- ndfunc_t ndf = { iter_dcomplex_rint, FULL_LOOP, 1, 1, ain, aout };
3670
-
3671
- return na_ndloop(&ndf, 1, self);
3672
- }
3673
-
3674
- #define check_intdivzero(y) \
3675
- {}
3676
-
3677
- static void iter_dcomplex_copysign(na_loop_t* const lp) {
3678
- size_t i = 0;
3679
- size_t n;
3680
- char *p1, *p2, *p3;
3681
- ssize_t s1, s2, s3;
3682
-
3683
- INIT_COUNTER(lp, n);
3684
- INIT_PTR(lp, 0, p1, s1);
3685
- INIT_PTR(lp, 1, p2, s2);
3686
- INIT_PTR(lp, 2, p3, s3);
3687
-
3688
- //
3689
- if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
3690
- is_aligned(p3, sizeof(dtype))) {
3691
-
3692
- if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
3693
- if (p1 == p3) { // inplace case
3694
- for (; i < n; i++) {
3695
- check_intdivzero(((dtype*)p2)[i]);
3696
- ((dtype*)p1)[i] = m_copysign(((dtype*)p1)[i], ((dtype*)p2)[i]);
3697
- }
3698
- } else {
3699
- for (; i < n; i++) {
3700
- check_intdivzero(((dtype*)p2)[i]);
3701
- ((dtype*)p3)[i] = m_copysign(((dtype*)p1)[i], ((dtype*)p2)[i]);
3702
- }
3703
- }
3704
- return;
3705
- }
3706
-
3707
- if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
3708
- is_aligned_step(s3, sizeof(dtype))) {
3709
- //
3710
-
3711
- if (s2 == 0) { // Broadcasting from scalar value.
3712
- check_intdivzero(*(dtype*)p2);
3713
- if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
3714
- if (p1 == p3) { // inplace case
3715
- for (; i < n; i++) {
3716
- ((dtype*)p1)[i] = m_copysign(((dtype*)p1)[i], *(dtype*)p2);
3717
- }
3718
- } else {
3719
- for (; i < n; i++) {
3720
- ((dtype*)p3)[i] = m_copysign(((dtype*)p1)[i], *(dtype*)p2);
3721
- }
3722
- }
3723
- } else {
3724
- for (i = 0; i < n; i++) {
3725
- *(dtype*)p3 = m_copysign(*(dtype*)p1, *(dtype*)p2);
3726
- p1 += s1;
3727
- p3 += s3;
3728
- }
3729
- }
3730
- } else {
3731
- if (p1 == p3) { // inplace case
3732
- for (i = 0; i < n; i++) {
3733
- check_intdivzero(*(dtype*)p2);
3734
- *(dtype*)p1 = m_copysign(*(dtype*)p1, *(dtype*)p2);
3735
- p1 += s1;
3736
- p2 += s2;
3737
- }
3738
- } else {
3739
- for (i = 0; i < n; i++) {
3740
- check_intdivzero(*(dtype*)p2);
3741
- *(dtype*)p3 = m_copysign(*(dtype*)p1, *(dtype*)p2);
3742
- p1 += s1;
3743
- p2 += s2;
3744
- p3 += s3;
3745
- }
3746
- }
3747
- }
3748
-
3749
- return;
2627
+ return;
3750
2628
  //
3751
2629
  }
3752
2630
  }
3753
2631
  for (i = 0; i < n; i++) {
3754
- dtype x, y, z;
3755
- GET_DATA_STRIDE(p1, s1, dtype, x);
3756
- GET_DATA_STRIDE(p2, s2, dtype, y);
3757
- check_intdivzero(y);
3758
- z = m_copysign(x, y);
3759
- SET_DATA_STRIDE(p3, s3, dtype, z);
3760
- }
3761
- //
3762
- }
3763
- #undef check_intdivzero
3764
-
3765
- static VALUE dcomplex_copysign_self(VALUE self, VALUE other) {
3766
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
3767
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
3768
- ndfunc_t ndf = { iter_dcomplex_copysign, STRIDE_LOOP, 2, 1, ain, aout };
3769
-
3770
- return na_ndloop(&ndf, 2, self, other);
3771
- }
3772
-
3773
- /*
3774
- Binary copysign.
3775
- @overload copysign other
3776
- @param [Numo::NArray,Numeric] other
3777
- @return [Numo::NArray] self copysign other
3778
- */
3779
- static VALUE dcomplex_copysign(VALUE self, VALUE other) {
3780
-
3781
- VALUE klass, v;
3782
-
3783
- klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
3784
- if (klass == cT) {
3785
- return dcomplex_copysign_self(self, other);
3786
- } else {
3787
- v = rb_funcall(klass, id_cast, 1, self);
3788
- return rb_funcall(v, id_copysign, 1, other);
3789
- }
3790
- }
3791
-
3792
- static void iter_dcomplex_isnan(na_loop_t* const lp) {
3793
- size_t i;
3794
- char* p1;
3795
- BIT_DIGIT* a2;
3796
- size_t p2;
3797
- ssize_t s1, s2;
3798
- size_t* idx1;
3799
- dtype x;
3800
- BIT_DIGIT b;
3801
- INIT_COUNTER(lp, i);
3802
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3803
- INIT_PTR_BIT(lp, 1, a2, p2, s2);
3804
- if (idx1) {
3805
- for (; i--;) {
3806
- GET_DATA_INDEX(p1, idx1, dtype, x);
3807
- b = (m_isnan(x)) ? 1 : 0;
3808
- STORE_BIT(a2, p2, b);
3809
- p2 += s2;
3810
- }
3811
- } else {
3812
- for (; i--;) {
3813
- GET_DATA_STRIDE(p1, s1, dtype, x);
3814
- b = (m_isnan(x)) ? 1 : 0;
3815
- STORE_BIT(a2, p2, b);
3816
- p2 += s2;
3817
- }
3818
- }
3819
- }
3820
-
3821
- /*
3822
- Condition of isnan.
3823
- @overload isnan
3824
- @return [Numo::Bit] Condition of isnan.
3825
- */
3826
- static VALUE dcomplex_isnan(VALUE self) {
3827
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3828
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3829
- ndfunc_t ndf = { iter_dcomplex_isnan, FULL_LOOP, 1, 1, ain, aout };
3830
-
3831
- return na_ndloop(&ndf, 1, self);
3832
- }
3833
-
3834
- static void iter_dcomplex_isinf(na_loop_t* const lp) {
3835
- size_t i;
3836
- char* p1;
3837
- BIT_DIGIT* a2;
3838
- size_t p2;
3839
- ssize_t s1, s2;
3840
- size_t* idx1;
3841
- dtype x;
3842
- BIT_DIGIT b;
3843
- INIT_COUNTER(lp, i);
3844
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3845
- INIT_PTR_BIT(lp, 1, a2, p2, s2);
3846
- if (idx1) {
3847
- for (; i--;) {
3848
- GET_DATA_INDEX(p1, idx1, dtype, x);
3849
- b = (m_isinf(x)) ? 1 : 0;
3850
- STORE_BIT(a2, p2, b);
3851
- p2 += s2;
3852
- }
3853
- } else {
3854
- for (; i--;) {
3855
- GET_DATA_STRIDE(p1, s1, dtype, x);
3856
- b = (m_isinf(x)) ? 1 : 0;
3857
- STORE_BIT(a2, p2, b);
3858
- p2 += s2;
3859
- }
3860
- }
3861
- }
3862
-
3863
- /*
3864
- Condition of isinf.
3865
- @overload isinf
3866
- @return [Numo::Bit] Condition of isinf.
3867
- */
3868
- static VALUE dcomplex_isinf(VALUE self) {
3869
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3870
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3871
- ndfunc_t ndf = { iter_dcomplex_isinf, FULL_LOOP, 1, 1, ain, aout };
3872
-
3873
- return na_ndloop(&ndf, 1, self);
3874
- }
3875
-
3876
- static void iter_dcomplex_isposinf(na_loop_t* const lp) {
3877
- size_t i;
3878
- char* p1;
3879
- BIT_DIGIT* a2;
3880
- size_t p2;
3881
- ssize_t s1, s2;
3882
- size_t* idx1;
3883
- dtype x;
3884
- BIT_DIGIT b;
3885
- INIT_COUNTER(lp, i);
3886
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3887
- INIT_PTR_BIT(lp, 1, a2, p2, s2);
3888
- if (idx1) {
3889
- for (; i--;) {
3890
- GET_DATA_INDEX(p1, idx1, dtype, x);
3891
- b = (m_isposinf(x)) ? 1 : 0;
3892
- STORE_BIT(a2, p2, b);
3893
- p2 += s2;
3894
- }
3895
- } else {
3896
- for (; i--;) {
3897
- GET_DATA_STRIDE(p1, s1, dtype, x);
3898
- b = (m_isposinf(x)) ? 1 : 0;
3899
- STORE_BIT(a2, p2, b);
3900
- p2 += s2;
3901
- }
3902
- }
3903
- }
3904
-
3905
- /*
3906
- Condition of isposinf.
3907
- @overload isposinf
3908
- @return [Numo::Bit] Condition of isposinf.
3909
- */
3910
- static VALUE dcomplex_isposinf(VALUE self) {
3911
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3912
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3913
- ndfunc_t ndf = { iter_dcomplex_isposinf, FULL_LOOP, 1, 1, ain, aout };
3914
-
3915
- return na_ndloop(&ndf, 1, self);
3916
- }
3917
-
3918
- static void iter_dcomplex_isneginf(na_loop_t* const lp) {
3919
- size_t i;
3920
- char* p1;
3921
- BIT_DIGIT* a2;
3922
- size_t p2;
3923
- ssize_t s1, s2;
3924
- size_t* idx1;
3925
- dtype x;
3926
- BIT_DIGIT b;
3927
- INIT_COUNTER(lp, i);
3928
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3929
- INIT_PTR_BIT(lp, 1, a2, p2, s2);
3930
- if (idx1) {
3931
- for (; i--;) {
3932
- GET_DATA_INDEX(p1, idx1, dtype, x);
3933
- b = (m_isneginf(x)) ? 1 : 0;
3934
- STORE_BIT(a2, p2, b);
3935
- p2 += s2;
3936
- }
3937
- } else {
3938
- for (; i--;) {
3939
- GET_DATA_STRIDE(p1, s1, dtype, x);
3940
- b = (m_isneginf(x)) ? 1 : 0;
3941
- STORE_BIT(a2, p2, b);
3942
- p2 += s2;
3943
- }
3944
- }
3945
- }
3946
-
3947
- /*
3948
- Condition of isneginf.
3949
- @overload isneginf
3950
- @return [Numo::Bit] Condition of isneginf.
3951
- */
3952
- static VALUE dcomplex_isneginf(VALUE self) {
3953
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3954
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3955
- ndfunc_t ndf = { iter_dcomplex_isneginf, FULL_LOOP, 1, 1, ain, aout };
3956
-
3957
- return na_ndloop(&ndf, 1, self);
3958
- }
3959
-
3960
- static void iter_dcomplex_isfinite(na_loop_t* const lp) {
3961
- size_t i;
3962
- char* p1;
3963
- BIT_DIGIT* a2;
3964
- size_t p2;
3965
- ssize_t s1, s2;
3966
- size_t* idx1;
3967
- dtype x;
3968
- BIT_DIGIT b;
3969
- INIT_COUNTER(lp, i);
3970
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
3971
- INIT_PTR_BIT(lp, 1, a2, p2, s2);
3972
- if (idx1) {
3973
- for (; i--;) {
3974
- GET_DATA_INDEX(p1, idx1, dtype, x);
3975
- b = (m_isfinite(x)) ? 1 : 0;
3976
- STORE_BIT(a2, p2, b);
3977
- p2 += s2;
3978
- }
3979
- } else {
3980
- for (; i--;) {
3981
- GET_DATA_STRIDE(p1, s1, dtype, x);
3982
- b = (m_isfinite(x)) ? 1 : 0;
3983
- STORE_BIT(a2, p2, b);
3984
- p2 += s2;
3985
- }
3986
- }
3987
- }
3988
-
3989
- /*
3990
- Condition of isfinite.
3991
- @overload isfinite
3992
- @return [Numo::Bit] Condition of isfinite.
3993
- */
3994
- static VALUE dcomplex_isfinite(VALUE self) {
3995
- ndfunc_arg_in_t ain[1] = { { cT, 0 } };
3996
- ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
3997
- ndfunc_t ndf = { iter_dcomplex_isfinite, FULL_LOOP, 1, 1, ain, aout };
3998
-
3999
- return na_ndloop(&ndf, 1, self);
4000
- }
4001
-
4002
- static void iter_dcomplex_sum(na_loop_t* const lp) {
4003
- size_t n;
4004
- char *p1, *p2;
4005
- ssize_t s1;
4006
-
4007
- INIT_COUNTER(lp, n);
4008
- INIT_PTR(lp, 0, p1, s1);
4009
- p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
4010
-
4011
- *(dtype*)p2 = f_sum(n, p1, s1);
4012
- }
4013
- static void iter_dcomplex_sum_nan(na_loop_t* const lp) {
4014
- size_t n;
4015
- char *p1, *p2;
4016
- ssize_t s1;
4017
-
4018
- INIT_COUNTER(lp, n);
4019
- INIT_PTR(lp, 0, p1, s1);
4020
- p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
4021
-
4022
- *(dtype*)p2 = f_sum_nan(n, p1, s1);
4023
- }
4024
-
4025
- /*
4026
- sum of self.
4027
- @overload sum(axis:nil, keepdims:false, nan:false)
4028
- @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN for sum/mean etc, or,
4029
- return NaN for min/max etc).
4030
- @param [Numeric,Array,Range] axis Performs sum along the axis.
4031
- @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
4032
- dimensions with size one.
4033
- @return [Numo::DComplex] returns result of sum.
4034
- */
4035
- static VALUE dcomplex_sum(int argc, VALUE* argv, VALUE self) {
4036
- VALUE v, reduce;
4037
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
4038
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
4039
- ndfunc_t ndf = { iter_dcomplex_sum, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout };
4040
-
4041
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_dcomplex_sum_nan);
4042
-
4043
- v = na_ndloop(&ndf, 2, self, reduce);
4044
-
4045
- return dcomplex_extract(v);
4046
- }
4047
-
4048
- static void iter_dcomplex_prod(na_loop_t* const lp) {
4049
- size_t n;
4050
- char *p1, *p2;
4051
- ssize_t s1;
4052
-
4053
- INIT_COUNTER(lp, n);
4054
- INIT_PTR(lp, 0, p1, s1);
4055
- p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
4056
-
4057
- *(dtype*)p2 = f_prod(n, p1, s1);
4058
- }
4059
- static void iter_dcomplex_prod_nan(na_loop_t* const lp) {
4060
- size_t n;
4061
- char *p1, *p2;
4062
- ssize_t s1;
4063
-
4064
- INIT_COUNTER(lp, n);
4065
- INIT_PTR(lp, 0, p1, s1);
4066
- p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
4067
-
4068
- *(dtype*)p2 = f_prod_nan(n, p1, s1);
4069
- }
4070
-
4071
- /*
4072
- prod of self.
4073
- @overload prod(axis:nil, keepdims:false, nan:false)
4074
- @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN for sum/mean etc, or,
4075
- return NaN for min/max etc).
4076
- @param [Numeric,Array,Range] axis Performs prod along the axis.
4077
- @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
4078
- dimensions with size one.
4079
- @return [Numo::DComplex] returns result of prod.
4080
- */
4081
- static VALUE dcomplex_prod(int argc, VALUE* argv, VALUE self) {
4082
- VALUE v, reduce;
4083
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
4084
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
4085
- ndfunc_t ndf = { iter_dcomplex_prod, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout };
4086
-
4087
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_dcomplex_prod_nan);
4088
-
4089
- v = na_ndloop(&ndf, 2, self, reduce);
4090
-
4091
- return dcomplex_extract(v);
4092
- }
4093
-
4094
- static void iter_dcomplex_kahan_sum(na_loop_t* const lp) {
4095
- size_t n;
4096
- char *p1, *p2;
4097
- ssize_t s1;
4098
-
4099
- INIT_COUNTER(lp, n);
4100
- INIT_PTR(lp, 0, p1, s1);
4101
- p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
4102
-
4103
- *(dtype*)p2 = f_kahan_sum(n, p1, s1);
4104
- }
4105
- static void iter_dcomplex_kahan_sum_nan(na_loop_t* const lp) {
4106
- size_t n;
4107
- char *p1, *p2;
4108
- ssize_t s1;
4109
-
4110
- INIT_COUNTER(lp, n);
4111
- INIT_PTR(lp, 0, p1, s1);
4112
- p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
4113
-
4114
- *(dtype*)p2 = f_kahan_sum_nan(n, p1, s1);
4115
- }
4116
-
4117
- /*
4118
- kahan_sum of self.
4119
- @overload kahan_sum(axis:nil, keepdims:false, nan:false)
4120
- @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN for sum/mean etc, or,
4121
- return NaN for min/max etc).
4122
- @param [Numeric,Array,Range] axis Performs kahan_sum along the axis.
4123
- @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
4124
- dimensions with size one.
4125
- @return [Numo::DComplex] returns result of kahan_sum.
4126
- */
4127
- static VALUE dcomplex_kahan_sum(int argc, VALUE* argv, VALUE self) {
4128
- VALUE v, reduce;
4129
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
4130
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
4131
- ndfunc_t ndf = {
4132
- iter_dcomplex_kahan_sum, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout
4133
- };
4134
-
4135
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_dcomplex_kahan_sum_nan);
4136
-
4137
- v = na_ndloop(&ndf, 2, self, reduce);
4138
-
4139
- return dcomplex_extract(v);
4140
- }
4141
-
4142
- static void iter_dcomplex_cumsum(na_loop_t* const lp) {
4143
- size_t i;
4144
- char *p1, *p2;
4145
- ssize_t s1, s2;
4146
- dtype x, y;
4147
-
4148
- INIT_COUNTER(lp, i);
4149
- INIT_PTR(lp, 0, p1, s1);
4150
- INIT_PTR(lp, 1, p2, s2);
4151
-
4152
- GET_DATA_STRIDE(p1, s1, dtype, x);
4153
- SET_DATA_STRIDE(p2, s2, dtype, x);
4154
- for (i--; i--;) {
4155
- GET_DATA_STRIDE(p1, s1, dtype, y);
4156
- m_cumsum(x, y);
4157
- SET_DATA_STRIDE(p2, s2, dtype, x);
4158
- }
4159
- }
4160
- static void iter_dcomplex_cumsum_nan(na_loop_t* const lp) {
4161
- size_t i;
4162
- char *p1, *p2;
4163
- ssize_t s1, s2;
4164
- dtype x, y;
4165
-
4166
- INIT_COUNTER(lp, i);
4167
- INIT_PTR(lp, 0, p1, s1);
4168
- INIT_PTR(lp, 1, p2, s2);
4169
-
4170
- GET_DATA_STRIDE(p1, s1, dtype, x);
4171
- SET_DATA_STRIDE(p2, s2, dtype, x);
4172
- for (i--; i--;) {
4173
- GET_DATA_STRIDE(p1, s1, dtype, y);
4174
- m_cumsum_nan(x, y);
4175
- SET_DATA_STRIDE(p2, s2, dtype, x);
4176
- }
4177
- }
4178
-
4179
- /*
4180
- cumsum of self.
4181
- @overload cumsum(axis:nil, nan:false)
4182
- @param [Numeric,Array,Range] axis Performs cumsum along the axis.
4183
- @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN if exists).
4184
- @return [Numo::DComplex] cumsum of self.
4185
- */
4186
- static VALUE dcomplex_cumsum(int argc, VALUE* argv, VALUE self) {
4187
- VALUE reduce;
4188
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
4189
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
4190
- ndfunc_t ndf = {
4191
- iter_dcomplex_cumsum, STRIDE_LOOP | NDF_FLAT_REDUCE | NDF_CUM, 2, 1, ain, aout
4192
- };
4193
-
4194
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_dcomplex_cumsum_nan);
4195
-
4196
- return na_ndloop(&ndf, 2, self, reduce);
4197
- }
4198
-
4199
- static void iter_dcomplex_cumprod(na_loop_t* const lp) {
4200
- size_t i;
4201
- char *p1, *p2;
4202
- ssize_t s1, s2;
4203
- dtype x, y;
4204
-
4205
- INIT_COUNTER(lp, i);
4206
- INIT_PTR(lp, 0, p1, s1);
4207
- INIT_PTR(lp, 1, p2, s2);
4208
-
4209
- GET_DATA_STRIDE(p1, s1, dtype, x);
4210
- SET_DATA_STRIDE(p2, s2, dtype, x);
4211
- for (i--; i--;) {
4212
- GET_DATA_STRIDE(p1, s1, dtype, y);
4213
- m_cumprod(x, y);
4214
- SET_DATA_STRIDE(p2, s2, dtype, x);
4215
- }
4216
- }
4217
- static void iter_dcomplex_cumprod_nan(na_loop_t* const lp) {
4218
- size_t i;
4219
- char *p1, *p2;
4220
- ssize_t s1, s2;
4221
- dtype x, y;
4222
-
4223
- INIT_COUNTER(lp, i);
4224
- INIT_PTR(lp, 0, p1, s1);
4225
- INIT_PTR(lp, 1, p2, s2);
4226
-
4227
- GET_DATA_STRIDE(p1, s1, dtype, x);
4228
- SET_DATA_STRIDE(p2, s2, dtype, x);
4229
- for (i--; i--;) {
4230
- GET_DATA_STRIDE(p1, s1, dtype, y);
4231
- m_cumprod_nan(x, y);
4232
- SET_DATA_STRIDE(p2, s2, dtype, x);
4233
- }
4234
- }
4235
-
4236
- /*
4237
- cumprod of self.
4238
- @overload cumprod(axis:nil, nan:false)
4239
- @param [Numeric,Array,Range] axis Performs cumprod along the axis.
4240
- @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN if exists).
4241
- @return [Numo::DComplex] cumprod of self.
4242
- */
4243
- static VALUE dcomplex_cumprod(int argc, VALUE* argv, VALUE self) {
4244
- VALUE reduce;
4245
- ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
4246
- ndfunc_arg_out_t aout[1] = { { cT, 0 } };
4247
- ndfunc_t ndf = {
4248
- iter_dcomplex_cumprod, STRIDE_LOOP | NDF_FLAT_REDUCE | NDF_CUM, 2, 1, ain, aout
4249
- };
4250
-
4251
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_dcomplex_cumprod_nan);
4252
-
4253
- return na_ndloop(&ndf, 2, self, reduce);
4254
- }
4255
-
4256
- //
4257
- static void iter_dcomplex_mulsum(na_loop_t* const lp) {
4258
- size_t i, n;
4259
- char *p1, *p2, *p3;
4260
- ssize_t s1, s2, s3;
4261
-
4262
- INIT_COUNTER(lp, n);
4263
- INIT_PTR(lp, 0, p1, s1);
4264
- INIT_PTR(lp, 1, p2, s2);
4265
- INIT_PTR(lp, 2, p3, s3);
4266
-
4267
- if (s3 == 0) {
4268
- dtype z;
4269
- // Reduce loop
4270
- GET_DATA(p3, dtype, z);
4271
- for (i = 0; i < n; i++) {
4272
- dtype x, y;
4273
- GET_DATA_STRIDE(p1, s1, dtype, x);
4274
- GET_DATA_STRIDE(p2, s2, dtype, y);
4275
- m_mulsum(x, y, z);
4276
- }
4277
- SET_DATA(p3, dtype, z);
4278
- return;
4279
- } else {
4280
- for (i = 0; i < n; i++) {
4281
- dtype x, y, z;
4282
- GET_DATA_STRIDE(p1, s1, dtype, x);
4283
- GET_DATA_STRIDE(p2, s2, dtype, y);
4284
- GET_DATA(p3, dtype, z);
4285
- m_mulsum(x, y, z);
4286
- SET_DATA_STRIDE(p3, s3, dtype, z);
4287
- }
4288
- }
4289
- }
4290
- //
4291
- static void iter_dcomplex_mulsum_nan(na_loop_t* const lp) {
4292
- size_t i, n;
4293
- char *p1, *p2, *p3;
4294
- ssize_t s1, s2, s3;
4295
-
4296
- INIT_COUNTER(lp, n);
4297
- INIT_PTR(lp, 0, p1, s1);
4298
- INIT_PTR(lp, 1, p2, s2);
4299
- INIT_PTR(lp, 2, p3, s3);
4300
-
4301
- if (s3 == 0) {
4302
- dtype z;
4303
- // Reduce loop
4304
- GET_DATA(p3, dtype, z);
4305
- for (i = 0; i < n; i++) {
4306
- dtype x, y;
4307
- GET_DATA_STRIDE(p1, s1, dtype, x);
4308
- GET_DATA_STRIDE(p2, s2, dtype, y);
4309
- m_mulsum_nan(x, y, z);
4310
- }
4311
- SET_DATA(p3, dtype, z);
4312
- return;
4313
- } else {
4314
- for (i = 0; i < n; i++) {
4315
- dtype x, y, z;
4316
- GET_DATA_STRIDE(p1, s1, dtype, x);
4317
- GET_DATA_STRIDE(p2, s2, dtype, y);
4318
- GET_DATA(p3, dtype, z);
4319
- m_mulsum_nan(x, y, z);
4320
- SET_DATA_STRIDE(p3, s3, dtype, z);
4321
- }
2632
+ dtype x, y, z;
2633
+ GET_DATA_STRIDE(p1, s1, dtype, x);
2634
+ GET_DATA_STRIDE(p2, s2, dtype, y);
2635
+ check_intdivzero(y);
2636
+ z = m_copysign(x, y);
2637
+ SET_DATA_STRIDE(p3, s3, dtype, z);
4322
2638
  }
2639
+ //
4323
2640
  }
4324
- //
2641
+ #undef check_intdivzero
4325
2642
 
4326
- static VALUE dcomplex_mulsum_self(int argc, VALUE* argv, VALUE self) {
4327
- VALUE v, reduce;
4328
- VALUE naryv[2];
4329
- ndfunc_arg_in_t ain[4] = { { cT, 0 }, { cT, 0 }, { sym_reduce, 0 }, { sym_init, 0 } };
2643
+ static VALUE dcomplex_copysign_self(VALUE self, VALUE other) {
2644
+ ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
4330
2645
  ndfunc_arg_out_t aout[1] = { { cT, 0 } };
4331
- ndfunc_t ndf = { iter_dcomplex_mulsum, STRIDE_LOOP_NIP, 4, 1, ain, aout };
4332
-
4333
- if (argc < 1) {
4334
- rb_raise(rb_eArgError, "wrong number of arguments (%d for >=1)", argc);
4335
- }
4336
- // should fix below: [self.ndim,other.ndim].max or?
4337
- naryv[0] = self;
4338
- naryv[1] = argv[0];
4339
- //
4340
- reduce = na_reduce_dimension(argc - 1, argv + 1, 2, naryv, &ndf, iter_dcomplex_mulsum_nan);
4341
- //
2646
+ ndfunc_t ndf = { iter_dcomplex_copysign, STRIDE_LOOP, 2, 1, ain, aout };
4342
2647
 
4343
- v = na_ndloop(&ndf, 4, self, argv[0], reduce, m_mulsum_init);
4344
- return dcomplex_extract(v);
2648
+ return na_ndloop(&ndf, 2, self, other);
4345
2649
  }
4346
2650
 
4347
2651
  /*
4348
- Binary mulsum.
4349
-
4350
- @overload mulsum(other, axis:nil, keepdims:false, nan:false)
2652
+ Binary copysign.
2653
+ @overload copysign other
4351
2654
  @param [Numo::NArray,Numeric] other
4352
- @param [Numeric,Array,Range] axis Performs mulsum along the axis.
4353
- @param [TrueClass] keepdims (keyword) If true, the reduced axes are left in the result array
4354
- as dimensions with size one.
4355
- @param [TrueClass] nan (keyword) If true, apply NaN-aware algorithm (avoid NaN if exists).
4356
- @return [Numo::NArray] mulsum of self and other.
2655
+ @return [Numo::NArray] self copysign other
4357
2656
  */
4358
- static VALUE dcomplex_mulsum(int argc, VALUE* argv, VALUE self) {
4359
- //
2657
+ static VALUE dcomplex_copysign(VALUE self, VALUE other) {
2658
+
4360
2659
  VALUE klass, v;
4361
- //
4362
- if (argc < 1) {
4363
- rb_raise(rb_eArgError, "wrong number of arguments (%d for >=1)", argc);
4364
- }
4365
- //
4366
- klass = na_upcast(rb_obj_class(self), rb_obj_class(argv[0]));
2660
+
2661
+ klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
4367
2662
  if (klass == cT) {
4368
- return dcomplex_mulsum_self(argc, argv, self);
2663
+ return dcomplex_copysign_self(self, other);
4369
2664
  } else {
4370
2665
  v = rb_funcall(klass, id_cast, 1, self);
4371
- //
4372
- return rb_funcallv_kw(v, rb_intern("mulsum"), argc, argv, RB_PASS_CALLED_KEYWORDS);
4373
- //
4374
- }
4375
- //
4376
- }
4377
-
4378
- typedef dtype seq_data_t;
4379
-
4380
- typedef double seq_count_t;
4381
-
4382
- typedef struct {
4383
- seq_data_t beg;
4384
- seq_data_t step;
4385
- seq_count_t count;
4386
- } seq_opt_t;
4387
-
4388
- static void iter_dcomplex_seq(na_loop_t* const lp) {
4389
- size_t i;
4390
- char* p1;
4391
- ssize_t s1;
4392
- size_t* idx1;
4393
- dtype x;
4394
- seq_data_t beg, step;
4395
- seq_count_t c;
4396
- seq_opt_t* g;
4397
-
4398
- INIT_COUNTER(lp, i);
4399
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
4400
- g = (seq_opt_t*)(lp->opt_ptr);
4401
- beg = g->beg;
4402
- step = g->step;
4403
- c = g->count;
4404
- if (idx1) {
4405
- for (; i--;) {
4406
- x = f_seq(beg, step, c++);
4407
- *(dtype*)(p1 + *idx1) = x;
4408
- idx1++;
4409
- }
4410
- } else {
4411
- for (; i--;) {
4412
- x = f_seq(beg, step, c++);
4413
- *(dtype*)(p1) = x;
4414
- p1 += s1;
4415
- }
4416
- }
4417
- g->count = c;
4418
- }
4419
-
4420
- /*
4421
- Set linear sequence of numbers to self. The sequence is obtained from
4422
- beg+i*step
4423
- where i is 1-dimensional index.
4424
- @overload seq([beg,[step]])
4425
- @param [Numeric] beg beginning of sequence. (default=0)
4426
- @param [Numeric] step step of sequence. (default=1)
4427
- @return [Numo::DComplex] self.
4428
- @example
4429
- Numo::DFloat.new(6).seq(1,-0.2)
4430
- # => Numo::DFloat#shape=[6]
4431
- # [1, 0.8, 0.6, 0.4, 0.2, 0]
4432
-
4433
- Numo::DComplex.new(6).seq(1,-0.2+0.2i)
4434
- # => Numo::DComplex#shape=[6]
4435
- # [1+0i, 0.8+0.2i, 0.6+0.4i, 0.4+0.6i, 0.2+0.8i, 0+1i]
4436
- */
4437
- static VALUE dcomplex_seq(int argc, VALUE* argv, VALUE self) {
4438
- seq_opt_t* g;
4439
- VALUE vbeg = Qnil, vstep = Qnil;
4440
- ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
4441
- ndfunc_t ndf = { iter_dcomplex_seq, FULL_LOOP, 1, 0, ain, 0 };
4442
-
4443
- g = ALLOCA_N(seq_opt_t, 1);
4444
- g->beg = m_zero;
4445
- g->step = m_one;
4446
- g->count = 0;
4447
- rb_scan_args(argc, argv, "02", &vbeg, &vstep);
4448
- if (vbeg != Qnil) {
4449
- g->beg = m_num_to_data(vbeg);
4450
- }
4451
- if (vstep != Qnil) {
4452
- g->step = m_num_to_data(vstep);
2666
+ return rb_funcall(v, id_copysign, 1, other);
4453
2667
  }
4454
-
4455
- na_ndloop3(&ndf, g, 1, self);
4456
- return self;
4457
2668
  }
4458
2669
 
4459
- typedef struct {
4460
- seq_data_t beg;
4461
- seq_data_t step;
4462
- seq_data_t base;
4463
- seq_count_t count;
4464
- } logseq_opt_t;
4465
-
4466
- static void iter_dcomplex_logseq(na_loop_t* const lp) {
4467
- size_t i;
4468
- char* p1;
2670
+ static void iter_dcomplex_kahan_sum(na_loop_t* const lp) {
2671
+ size_t n;
2672
+ char *p1, *p2;
4469
2673
  ssize_t s1;
4470
- size_t* idx1;
4471
- dtype x;
4472
- seq_data_t beg, step, base;
4473
- seq_count_t c;
4474
- logseq_opt_t* g;
4475
-
4476
- INIT_COUNTER(lp, i);
4477
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
4478
- g = (logseq_opt_t*)(lp->opt_ptr);
4479
- beg = g->beg;
4480
- step = g->step;
4481
- base = g->base;
4482
- c = g->count;
4483
- if (idx1) {
4484
- for (; i--;) {
4485
- x = f_seq(beg, step, c++);
4486
- *(dtype*)(p1 + *idx1) = m_pow(base, x);
4487
- idx1++;
4488
- }
4489
- } else {
4490
- for (; i--;) {
4491
- x = f_seq(beg, step, c++);
4492
- *(dtype*)(p1) = m_pow(base, x);
4493
- p1 += s1;
4494
- }
4495
- }
4496
- g->count = c;
4497
- }
4498
-
4499
- /*
4500
- Set logarithmic sequence of numbers to self. The sequence is obtained from
4501
- `base**(beg+i*step)`
4502
- where i is 1-dimensional index.
4503
- Applicable classes: DFloat, SFloat, DComplex, SCopmplex.
4504
-
4505
- @overload logseq(beg,step,[base])
4506
- @param [Numeric] beg The beginning of sequence.
4507
- @param [Numeric] step The step of sequence.
4508
- @param [Numeric] base The base of log space. (default=10)
4509
- @return [Numo::DComplex] self.
4510
-
4511
- @example
4512
- Numo::DFloat.new(5).logseq(4,-1,2)
4513
- # => Numo::DFloat#shape=[5]
4514
- # [16, 8, 4, 2, 1]
4515
-
4516
- Numo::DComplex.new(5).logseq(0,1i*Math::PI/3,Math::E)
4517
- # => Numo::DComplex#shape=[5]
4518
- # [1+7.26156e-310i, 0.5+0.866025i, -0.5+0.866025i, -1+1.22465e-16i, ...]
4519
- */
4520
- static VALUE dcomplex_logseq(int argc, VALUE* argv, VALUE self) {
4521
- logseq_opt_t* g;
4522
- VALUE vbeg, vstep, vbase;
4523
- ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
4524
- ndfunc_t ndf = { iter_dcomplex_logseq, FULL_LOOP, 1, 0, ain, 0 };
4525
-
4526
- g = ALLOCA_N(logseq_opt_t, 1);
4527
- rb_scan_args(argc, argv, "21", &vbeg, &vstep, &vbase);
4528
- g->beg = m_num_to_data(vbeg);
4529
- g->step = m_num_to_data(vstep);
4530
- if (vbase == Qnil) {
4531
- g->base = m_from_real(10);
4532
- } else {
4533
- g->base = m_num_to_data(vbase);
4534
- }
4535
- na_ndloop3(&ndf, g, 1, self);
4536
- return self;
4537
- }
4538
-
4539
- static void iter_dcomplex_eye(na_loop_t* const lp) {
4540
- size_t n0, n1;
4541
- size_t i0, i1;
4542
- ssize_t s0, s1;
4543
- char *p0, *p1;
4544
- char* g;
4545
- ssize_t kofs;
4546
- dtype data;
4547
-
4548
- g = (char*)(lp->opt_ptr);
4549
- kofs = *(ssize_t*)g;
4550
- data = *(dtype*)(g + sizeof(ssize_t));
4551
-
4552
- n0 = lp->args[0].shape[0];
4553
- n1 = lp->args[0].shape[1];
4554
- s0 = lp->args[0].iter[0].step;
4555
- s1 = lp->args[0].iter[1].step;
4556
- p0 = NDL_PTR(lp, 0);
4557
-
4558
- for (i0 = 0; i0 < n0; i0++) {
4559
- p1 = p0;
4560
- for (i1 = 0; i1 < n1; i1++) {
4561
- *(dtype*)p1 = (i0 + kofs == i1) ? data : m_zero;
4562
- p1 += s1;
4563
- }
4564
- p0 += s0;
4565
- }
4566
- }
4567
-
4568
- /*
4569
- Eye: Set a value to diagonal components, set 0 to non-diagonal components.
4570
- @overload eye([element,offset])
4571
- @param [Numeric] element Diagonal element to be stored. Default is 1.
4572
- @param [Integer] offset Diagonal offset from the main diagonal. The
4573
- default is 0. k>0 for diagonals above the main diagonal, and k<0
4574
- for diagonals below the main diagonal.
4575
- @return [Numo::DComplex] eye of self.
4576
- */
4577
- static VALUE dcomplex_eye(int argc, VALUE* argv, VALUE self) {
4578
- ndfunc_arg_in_t ain[1] = { { OVERWRITE, 2 } };
4579
- ndfunc_t ndf = { iter_dcomplex_eye, NO_LOOP, 1, 0, ain, 0 };
4580
- ssize_t kofs;
4581
- dtype data;
4582
- char* g;
4583
- int nd;
4584
- narray_t* na;
4585
-
4586
- // check arguments
4587
- if (argc > 2) {
4588
- rb_raise(rb_eArgError, "too many arguments (%d for 0..2)", argc);
4589
- } else if (argc == 2) {
4590
- data = m_num_to_data(argv[0]);
4591
- kofs = NUM2SSIZET(argv[1]);
4592
- } else if (argc == 1) {
4593
- data = m_num_to_data(argv[0]);
4594
- kofs = 0;
4595
- } else {
4596
- data = m_one;
4597
- kofs = 0;
4598
- }
4599
-
4600
- GetNArray(self, na);
4601
- nd = na->ndim;
4602
- if (nd < 2) {
4603
- rb_raise(nary_eDimensionError, "less than 2-d array");
4604
- }
4605
-
4606
- // Diagonal offset from the main diagonal.
4607
- if (kofs >= 0) {
4608
- if ((size_t)(kofs) >= na->shape[nd - 1]) {
4609
- rb_raise(
4610
- rb_eArgError,
4611
- "invalid diagonal offset(%" SZF "d) for "
4612
- "last dimension size(%" SZF "d)",
4613
- kofs, na->shape[nd - 1]
4614
- );
4615
- }
4616
- } else {
4617
- if ((size_t)(-kofs) >= na->shape[nd - 2]) {
4618
- rb_raise(
4619
- rb_eArgError,
4620
- "invalid diagonal offset(%" SZF "d) for "
4621
- "last-1 dimension size(%" SZF "d)",
4622
- kofs, na->shape[nd - 2]
4623
- );
4624
- }
4625
- }
4626
2674
 
4627
- g = ALLOCA_N(char, sizeof(ssize_t) + sizeof(dtype));
4628
- *(ssize_t*)g = kofs;
4629
- *(dtype*)(g + sizeof(ssize_t)) = data;
2675
+ INIT_COUNTER(lp, n);
2676
+ INIT_PTR(lp, 0, p1, s1);
2677
+ p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
4630
2678
 
4631
- na_ndloop3(&ndf, g, 1, self);
4632
- return self;
2679
+ *(dtype*)p2 = f_kahan_sum(n, p1, s1);
4633
2680
  }
4634
-
4635
- typedef struct {
4636
- dtype low;
4637
- dtype max;
4638
- } rand_opt_t;
4639
-
4640
- static void iter_dcomplex_rand(na_loop_t* const lp) {
4641
- size_t i;
4642
- char* p1;
2681
+ static void iter_dcomplex_kahan_sum_nan(na_loop_t* const lp) {
2682
+ size_t n;
2683
+ char *p1, *p2;
4643
2684
  ssize_t s1;
4644
- size_t* idx1;
4645
- dtype x;
4646
- rand_opt_t* g;
4647
- dtype low;
4648
- dtype max;
4649
2685
 
4650
- INIT_COUNTER(lp, i);
4651
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
4652
- g = (rand_opt_t*)(lp->opt_ptr);
4653
- low = g->low;
4654
- max = g->max;
2686
+ INIT_COUNTER(lp, n);
2687
+ INIT_PTR(lp, 0, p1, s1);
2688
+ p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
4655
2689
 
4656
- if (idx1) {
4657
- for (; i--;) {
4658
- x = m_add(m_rand(max), low);
4659
- SET_DATA_INDEX(p1, idx1, dtype, x);
4660
- }
4661
- } else {
4662
- for (; i--;) {
4663
- x = m_add(m_rand(max), low);
4664
- SET_DATA_STRIDE(p1, s1, dtype, x);
4665
- }
4666
- }
2690
+ *(dtype*)p2 = f_kahan_sum_nan(n, p1, s1);
4667
2691
  }
4668
2692
 
4669
2693
  /*
4670
- Generate uniformly distributed random numbers on self narray.
4671
- @overload rand([[low],high])
4672
- @param [Numeric] low lower inclusive boundary of random numbers. (default=0)
4673
- @param [Numeric] high upper exclusive boundary of random numbers. (default=1 or 1+1i for
4674
- complex types)
4675
- @return [Numo::DComplex] self.
4676
- @example
4677
- Numo::DFloat.new(6).rand
4678
- # => Numo::DFloat#shape=[6]
4679
- # [0.0617545, 0.373067, 0.794815, 0.201042, 0.116041, 0.344032]
4680
-
4681
- Numo::DComplex.new(6).rand(5+5i)
4682
- # => Numo::DComplex#shape=[6]
4683
- # [2.69974+3.68908i, 0.825443+0.254414i, 0.540323+0.34354i, 4.52061+2.39322i, ...]
4684
-
4685
- Numo::Int32.new(6).rand(2,5)
4686
- # => Numo::Int32#shape=[6]
4687
- # [4, 3, 3, 2, 4, 2]
2694
+ kahan_sum of self.
2695
+ @overload kahan_sum(axis:nil, keepdims:false, nan:false)
2696
+ @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN for sum/mean etc, or,
2697
+ return NaN for min/max etc).
2698
+ @param [Numeric,Array,Range] axis Performs kahan_sum along the axis.
2699
+ @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
2700
+ dimensions with size one.
2701
+ @return [Numo::DComplex] returns result of kahan_sum.
4688
2702
  */
4689
- static VALUE dcomplex_rand(int argc, VALUE* argv, VALUE self) {
4690
- rand_opt_t g;
4691
- VALUE v1 = Qnil, v2 = Qnil;
4692
- dtype high;
4693
- ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
4694
- ndfunc_t ndf = { iter_dcomplex_rand, FULL_LOOP, 1, 0, ain, 0 };
4695
-
4696
- rb_scan_args(argc, argv, "02", &v1, &v2);
4697
- if (v2 == Qnil) {
4698
- g.low = m_zero;
4699
- if (v1 == Qnil) {
4700
-
4701
- g.max = high = c_new(1, 1);
2703
+ static VALUE dcomplex_kahan_sum(int argc, VALUE* argv, VALUE self) {
2704
+ VALUE v, reduce;
2705
+ ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
2706
+ ndfunc_arg_out_t aout[1] = { { cT, 0 } };
2707
+ ndfunc_t ndf = {
2708
+ iter_dcomplex_kahan_sum, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout
2709
+ };
4702
2710
 
4703
- } else {
4704
- g.max = high = m_num_to_data(v1);
4705
- }
2711
+ reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_dcomplex_kahan_sum_nan);
4706
2712
 
4707
- } else {
4708
- g.low = m_num_to_data(v1);
4709
- high = m_num_to_data(v2);
4710
- g.max = m_sub(high, g.low);
4711
- }
2713
+ v = na_ndloop(&ndf, 2, self, reduce);
4712
2714
 
4713
- na_ndloop3(&ndf, &g, 1, self);
4714
- return self;
2715
+ return dcomplex_extract(v);
4715
2716
  }
4716
2717
 
4717
2718
  typedef struct {
@@ -4930,20 +2931,77 @@ void Init_numo_dcomplex(void) {
4930
2931
  rb_define_singleton_method(cT, "cast", dcomplex_s_cast, 1);
4931
2932
  rb_define_method(cT, "[]", dcomplex_aref, -1);
4932
2933
  rb_define_method(cT, "[]=", dcomplex_aset, -1);
2934
+ /**
2935
+ * return NArray with cast to the type of self.
2936
+ * @overload coerce_cast(type)
2937
+ * @return [nil]
2938
+ */
4933
2939
  rb_define_method(cT, "coerce_cast", dcomplex_coerce_cast, 1);
2940
+ /**
2941
+ * Convert self to Array.
2942
+ * @overload to_a
2943
+ * @return [Array]
2944
+ */
4934
2945
  rb_define_method(cT, "to_a", dcomplex_to_a, 0);
2946
+ /**
2947
+ * Fill elements with other.
2948
+ * @overload fill other
2949
+ * @param [Numeric] other
2950
+ * @return [Numo::DComplex] self.
2951
+ */
4935
2952
  rb_define_method(cT, "fill", dcomplex_fill, 1);
2953
+ /**
2954
+ * Format elements into strings.
2955
+ * @overload format format
2956
+ * @param [String] format
2957
+ * @return [Numo::RObject] array of formatted strings.
2958
+ */
4936
2959
  rb_define_method(cT, "format", dcomplex_format, -1);
2960
+ /**
2961
+ * Format elements into strings.
2962
+ * @overload format_to_a format
2963
+ * @param [String] format
2964
+ * @return [Array] array of formatted strings.
2965
+ */
4937
2966
  rb_define_method(cT, "format_to_a", dcomplex_format_to_a, -1);
2967
+ /**
2968
+ * Returns a string containing a human-readable representation of NArray.
2969
+ * @overload inspect
2970
+ * @return [String]
2971
+ */
4938
2972
  rb_define_method(cT, "inspect", dcomplex_inspect, 0);
4939
2973
  rb_define_method(cT, "each", dcomplex_each, 0);
4940
2974
  rb_define_method(cT, "map", dcomplex_map, 0);
4941
2975
  rb_define_method(cT, "each_with_index", dcomplex_each_with_index, 0);
4942
2976
  rb_define_method(cT, "map_with_index", dcomplex_map_with_index, 0);
4943
2977
  rb_define_method(cT, "abs", dcomplex_abs, 0);
2978
+ /**
2979
+ * Binary add.
2980
+ * @overload + other
2981
+ * @param [Numo::NArray,Numeric] other
2982
+ * @return [Numo::NArray] self + other
2983
+ */
4944
2984
  rb_define_method(cT, "+", dcomplex_add, 1);
2985
+ /**
2986
+ * Binary sub.
2987
+ * @overload - other
2988
+ * @param [Numo::NArray,Numeric] other
2989
+ * @return [Numo::NArray] self - other
2990
+ */
4945
2991
  rb_define_method(cT, "-", dcomplex_sub, 1);
2992
+ /**
2993
+ * Binary mul.
2994
+ * @overload * other
2995
+ * @param [Numo::NArray,Numeric] other
2996
+ * @return [Numo::NArray] self * other
2997
+ */
4946
2998
  rb_define_method(cT, "*", dcomplex_mul, 1);
2999
+ /**
3000
+ * Binary div.
3001
+ * @overload / other
3002
+ * @param [Numo::NArray,Numeric] other
3003
+ * @return [Numo::NArray] self / other
3004
+ */
4947
3005
  rb_define_method(cT, "/", dcomplex_div, 1);
4948
3006
  rb_define_method(cT, "**", dcomplex_pow, 1);
4949
3007
  rb_define_alias(cT, "pow", "**");
@@ -4962,22 +3020,110 @@ void Init_numo_dcomplex(void) {
4962
3020
  rb_define_alias(cT, "imag=", "set_imag");
4963
3021
  rb_define_alias(cT, "real=", "set_real");
4964
3022
  rb_define_alias(cT, "conjugate", "conj");
3023
+ /**
3024
+ * Comparison eq other.
3025
+ * @overload eq other
3026
+ * @param [Numo::NArray,Numeric] other
3027
+ * @return [Numo::Bit] result of self eq other.
3028
+ */
4965
3029
  rb_define_method(cT, "eq", dcomplex_eq, 1);
3030
+ /**
3031
+ * Comparison ne other.
3032
+ * @overload ne other
3033
+ * @param [Numo::NArray,Numeric] other
3034
+ * @return [Numo::Bit] result of self ne other.
3035
+ */
4966
3036
  rb_define_method(cT, "ne", dcomplex_ne, 1);
3037
+ /**
3038
+ * Comparison nearly_eq other.
3039
+ * @overload nearly_eq other
3040
+ * @param [Numo::NArray,Numeric] other
3041
+ * @return [Numo::Bit] result of self nearly_eq other.
3042
+ */
4967
3043
  rb_define_method(cT, "nearly_eq", dcomplex_nearly_eq, 1);
4968
3044
  rb_define_alias(cT, "close_to", "nearly_eq");
3045
+ /**
3046
+ * Unary floor.
3047
+ * @overload floor
3048
+ * @return [Numo::DComplex] floor of self.
3049
+ */
4969
3050
  rb_define_method(cT, "floor", dcomplex_floor, 0);
3051
+ /**
3052
+ * Unary round.
3053
+ * @overload round
3054
+ * @return [Numo::DComplex] round of self.
3055
+ */
4970
3056
  rb_define_method(cT, "round", dcomplex_round, 0);
3057
+ /**
3058
+ * Unary ceil.
3059
+ * @overload ceil
3060
+ * @return [Numo::DComplex] ceil of self.
3061
+ */
4971
3062
  rb_define_method(cT, "ceil", dcomplex_ceil, 0);
3063
+ /**
3064
+ * Unary trunc.
3065
+ * @overload trunc
3066
+ * @return [Numo::DComplex] trunc of self.
3067
+ */
4972
3068
  rb_define_method(cT, "trunc", dcomplex_trunc, 0);
3069
+ /**
3070
+ * Unary rint.
3071
+ * @overload rint
3072
+ * @return [Numo::DComplex] rint of self.
3073
+ */
4973
3074
  rb_define_method(cT, "rint", dcomplex_rint, 0);
4974
3075
  rb_define_method(cT, "copysign", dcomplex_copysign, 1);
3076
+ /**
3077
+ * Condition of isnan.
3078
+ * @overload isnan
3079
+ * @return [Numo::Bit] Condition of isnan.
3080
+ */
4975
3081
  rb_define_method(cT, "isnan", dcomplex_isnan, 0);
3082
+ /**
3083
+ * Condition of isinf.
3084
+ * @overload isinf
3085
+ * @return [Numo::Bit] Condition of isinf.
3086
+ */
4976
3087
  rb_define_method(cT, "isinf", dcomplex_isinf, 0);
3088
+ /**
3089
+ * Condition of isposinf.
3090
+ * @overload isposinf
3091
+ * @return [Numo::Bit] Condition of isposinf.
3092
+ */
4977
3093
  rb_define_method(cT, "isposinf", dcomplex_isposinf, 0);
3094
+ /**
3095
+ * Condition of isneginf.
3096
+ * @overload isneginf
3097
+ * @return [Numo::Bit] Condition of isneginf.
3098
+ */
4978
3099
  rb_define_method(cT, "isneginf", dcomplex_isneginf, 0);
3100
+ /**
3101
+ * Condition of isfinite.
3102
+ * @overload isfinite
3103
+ * @return [Numo::Bit] Condition of isfinite.
3104
+ */
4979
3105
  rb_define_method(cT, "isfinite", dcomplex_isfinite, 0);
3106
+ /**
3107
+ * sum of self.
3108
+ * @overload sum(axis:nil, keepdims:false, nan:false)
3109
+ * @param [TrueClass] nan If true, apply NaN-aware algorithm
3110
+ * (avoid NaN for sum/mean etc, or, return NaN for min/max etc).
3111
+ * @param [Numeric,Array,Range] axis Performs sum along the axis.
3112
+ * @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
3113
+ * dimensions with size one.
3114
+ * @return [Numo::DComplex] returns result of sum.
3115
+ */
4980
3116
  rb_define_method(cT, "sum", dcomplex_sum, -1);
3117
+ /**
3118
+ * prod of self.
3119
+ * @overload prod(axis:nil, keepdims:false, nan:false)
3120
+ * @param [TrueClass] nan If true, apply NaN-aware algorithm
3121
+ * (avoid NaN for sum/mean etc, or, return NaN for min/max etc).
3122
+ * @param [Numeric,Array,Range] axis Performs prod along the axis.
3123
+ * @param [TrueClass] keepdims If true, the reduced axes are left in the result array as
3124
+ * dimensions with size one.
3125
+ * @return [Numo::DComplex] returns result of prod.
3126
+ */
4981
3127
  rb_define_method(cT, "prod", dcomplex_prod, -1);
4982
3128
  rb_define_method(cT, "kahan_sum", dcomplex_kahan_sum, -1);
4983
3129
  /**
@@ -5024,13 +3170,106 @@ void Init_numo_dcomplex(void) {
5024
3170
  * @return [Numo::DFloat] returns result of rms.
5025
3171
  */
5026
3172
  rb_define_method(cT, "rms", dcomplex_rms, -1);
3173
+ /**
3174
+ * cumsum of self.
3175
+ * @overload cumsum(axis:nil, nan:false)
3176
+ * @param [Numeric,Array,Range] axis Performs cumsum along the axis.
3177
+ * @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN if exists).
3178
+ * @return [Numo::DComplex] cumsum of self.
3179
+ */
5027
3180
  rb_define_method(cT, "cumsum", dcomplex_cumsum, -1);
3181
+ /**
3182
+ * cumprod of self.
3183
+ * @overload cumprod(axis:nil, nan:false)
3184
+ * @param [Numeric,Array,Range] axis Performs cumprod along the axis.
3185
+ * @param [TrueClass] nan If true, apply NaN-aware algorithm (avoid NaN if exists).
3186
+ * @return [Numo::DComplex] cumprod of self.
3187
+ */
5028
3188
  rb_define_method(cT, "cumprod", dcomplex_cumprod, -1);
3189
+ /**
3190
+ * Binary mulsum.
3191
+ *
3192
+ * @overload mulsum(other, axis:nil, keepdims:false, nan:false)
3193
+ * @param [Numo::NArray,Numeric] other
3194
+ * @param [Numeric,Array,Range] axis Performs mulsum along the axis.
3195
+ * @param [TrueClass] keepdims (keyword) If true, the reduced axes are left in
3196
+ * the result array as dimensions with size one.
3197
+ * @param [TrueClass] nan (keyword) If true, apply NaN-aware algorithm
3198
+ * (avoid NaN if exists).
3199
+ * @return [Numo::NArray] mulsum of self and other.
3200
+ */
5029
3201
  rb_define_method(cT, "mulsum", dcomplex_mulsum, -1);
3202
+ /**
3203
+ * Set linear sequence of numbers to self. The sequence is obtained from
3204
+ * beg+i*step
3205
+ * where i is 1-dimensional index.
3206
+ * @overload seq([beg,[step]])
3207
+ * @param [Numeric] beg beginning of sequence. (default=0)
3208
+ * @param [Numeric] step step of sequence. (default=1)
3209
+ * @return [Numo::DComplex] self.
3210
+ * @example
3211
+ * Numo::DFloat.new(6).seq(1,-0.2)
3212
+ * # => Numo::DFloat#shape=[6]
3213
+ * # [1, 0.8, 0.6, 0.4, 0.2, 0]
3214
+ *
3215
+ * Numo::DComplex.new(6).seq(1,-0.2+0.2i)
3216
+ * # => Numo::DComplex#shape=[6]
3217
+ * # [1+0i, 0.8+0.2i, 0.6+0.4i, 0.4+0.6i, 0.2+0.8i, 0+1i]
3218
+ */
5030
3219
  rb_define_method(cT, "seq", dcomplex_seq, -1);
3220
+ /**
3221
+ * Set logarithmic sequence of numbers to self. The sequence is obtained from
3222
+ * `base**(beg+i*step)`
3223
+ * where i is 1-dimensional index.
3224
+ * Applicable classes: DFloat, SFloat, DComplex, SCopmplex.
3225
+ *
3226
+ * @overload logseq(beg,step,[base])
3227
+ * @param [Numeric] beg The beginning of sequence.
3228
+ * @param [Numeric] step The step of sequence.
3229
+ * @param [Numeric] base The base of log space. (default=10)
3230
+ * @return [Numo::DComplex] self.
3231
+ *
3232
+ * @example
3233
+ * Numo::DFloat.new(5).logseq(4,-1,2)
3234
+ * # => Numo::DFloat#shape=[5]
3235
+ * # [16, 8, 4, 2, 1]
3236
+ *
3237
+ * Numo::DComplex.new(5).logseq(0,1i*Math::PI/3,Math::E)
3238
+ * # => Numo::DComplex#shape=[5]
3239
+ * # [1+7.26156e-310i, 0.5+0.866025i, -0.5+0.866025i, -1+1.22465e-16i, ...]
3240
+ */
5031
3241
  rb_define_method(cT, "logseq", dcomplex_logseq, -1);
3242
+ /**
3243
+ * Eye: Set a value to diagonal components, set 0 to non-diagonal components.
3244
+ * @overload eye([element,offset])
3245
+ * @param [Numeric] element Diagonal element to be stored. Default is 1.
3246
+ * @param [Integer] offset Diagonal offset from the main diagonal. The
3247
+ * default is 0. k>0 for diagonals above the main diagonal, and k<0
3248
+ * for diagonals below the main diagonal.
3249
+ * @return [Numo::DComplex] eye of self.
3250
+ */
5032
3251
  rb_define_method(cT, "eye", dcomplex_eye, -1);
5033
3252
  rb_define_alias(cT, "indgen", "seq");
3253
+ /**
3254
+ * Generate uniformly distributed random numbers on self narray.
3255
+ * @overload rand([[low],high])
3256
+ * @param [Numeric] low lower inclusive boundary of random numbers. (default=0)
3257
+ * @param [Numeric] high upper exclusive boundary of random numbers.
3258
+ * (default=1 or 1+1i for complex types)
3259
+ * @return [Numo::DComplex] self.
3260
+ * @example
3261
+ * Numo::DFloat.new(6).rand
3262
+ * # => Numo::DFloat#shape=[6]
3263
+ * # [0.0617545, 0.373067, 0.794815, 0.201042, 0.116041, 0.344032]
3264
+ *
3265
+ * Numo::DComplex.new(6).rand(5+5i)
3266
+ * # => Numo::DComplex#shape=[6]
3267
+ * # [2.69974+3.68908i, 0.825443+0.254414i, 0.540323+0.34354i, 4.52061+2.39322i, ...]
3268
+ *
3269
+ * Numo::Int32.new(6).rand(2,5)
3270
+ * # => Numo::Int32#shape=[6]
3271
+ * # [4, 3, 3, 2, 4, 2]
3272
+ */
5034
3273
  rb_define_method(cT, "rand", dcomplex_rand, -1);
5035
3274
  rb_define_method(cT, "rand_norm", dcomplex_rand_norm, -1);
5036
3275
  rb_define_method(cT, "poly", dcomplex_poly, -2);