UNPKG

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