nthRoots.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.createNthRoots = void 0;
  6. var _factory = require("../../utils/factory.js");
  7. var name = 'nthRoots';
  8. var dependencies = ['config', 'typed', 'divideScalar', 'Complex'];
  9. var createNthRoots = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
  10. var typed = _ref.typed,
  11. config = _ref.config,
  12. divideScalar = _ref.divideScalar,
  13. Complex = _ref.Complex;
  14. /**
  15. * Each function here returns a real multiple of i as a Complex value.
  16. * @param {number} val
  17. * @return {Complex} val, i*val, -val or -i*val for index 0, 1, 2, 3
  18. */
  19. // This is used to fix float artifacts for zero-valued components.
  20. var _calculateExactResult = [function realPos(val) {
  21. return new Complex(val, 0);
  22. }, function imagPos(val) {
  23. return new Complex(0, val);
  24. }, function realNeg(val) {
  25. return new Complex(-val, 0);
  26. }, function imagNeg(val) {
  27. return new Complex(0, -val);
  28. }];
  29. /**
  30. * Calculate the nth root of a Complex Number a using De Movire's Theorem.
  31. * @param {Complex} a
  32. * @param {number} root
  33. * @return {Array} array of n Complex Roots
  34. */
  35. function _nthComplexRoots(a, root) {
  36. if (root < 0) throw new Error('Root must be greater than zero');
  37. if (root === 0) throw new Error('Root must be non-zero');
  38. if (root % 1 !== 0) throw new Error('Root must be an integer');
  39. if (a === 0 || a.abs() === 0) return [new Complex(0, 0)];
  40. var aIsNumeric = typeof a === 'number';
  41. var offset;
  42. // determine the offset (argument of a)/(pi/2)
  43. if (aIsNumeric || a.re === 0 || a.im === 0) {
  44. if (aIsNumeric) {
  45. offset = 2 * +(a < 0); // numeric value on the real axis
  46. } else if (a.im === 0) {
  47. offset = 2 * +(a.re < 0); // complex value on the real axis
  48. } else {
  49. offset = 2 * +(a.im < 0) + 1; // complex value on the imaginary axis
  50. }
  51. }
  52. var arg = a.arg();
  53. var abs = a.abs();
  54. var roots = [];
  55. var r = Math.pow(abs, 1 / root);
  56. for (var k = 0; k < root; k++) {
  57. var halfPiFactor = (offset + 4 * k) / root;
  58. /**
  59. * If (offset + 4*k)/root is an integral multiple of pi/2
  60. * then we can produce a more exact result.
  61. */
  62. if (halfPiFactor === Math.round(halfPiFactor)) {
  63. roots.push(_calculateExactResult[halfPiFactor % 4](r));
  64. continue;
  65. }
  66. roots.push(new Complex({
  67. r: r,
  68. phi: (arg + 2 * Math.PI * k) / root
  69. }));
  70. }
  71. return roots;
  72. }
  73. /**
  74. * Calculate the nth roots of a value.
  75. * An nth root of a positive real number A,
  76. * is a positive real solution of the equation "x^root = A".
  77. * This function returns an array of complex values.
  78. *
  79. * Syntax:
  80. *
  81. * math.nthRoots(x)
  82. * math.nthRoots(x, root)
  83. *
  84. * Examples:
  85. *
  86. * math.nthRoots(1)
  87. * // returns [
  88. * // {re: 1, im: 0},
  89. * // {re: -1, im: 0}
  90. * // ]
  91. * math.nthRoots(1, 3)
  92. * // returns [
  93. * // { re: 1, im: 0 },
  94. * // { re: -0.4999999999999998, im: 0.8660254037844387 },
  95. * // { re: -0.5000000000000004, im: -0.8660254037844385 }
  96. * // ]
  97. *
  98. * See also:
  99. *
  100. * nthRoot, pow, sqrt
  101. *
  102. * @param {number | BigNumber | Fraction | Complex} x Number to be rounded
  103. * @return {number | BigNumber | Fraction | Complex} Rounded value
  104. */
  105. return typed(name, {
  106. Complex: function Complex(x) {
  107. return _nthComplexRoots(x, 2);
  108. },
  109. 'Complex, number': _nthComplexRoots
  110. });
  111. });
  112. exports.createNthRoots = createNthRoots;