UNPKG

5.55 kBJavaScriptView Raw
1import { factory } from '../../utils/factory.js';
2import { isInteger } from '../../utils/number.js';
3import { arraySize as size } from '../../utils/array.js';
4import { powNumber } from '../../plain/number/index.js';
5var name = 'pow';
6var dependencies = ['typed', 'config', 'identity', 'multiply', 'matrix', 'fraction', 'number', 'Complex'];
7export var createPow = /* #__PURE__ */factory(name, dependencies, (_ref) => {
8 var {
9 typed,
10 config,
11 identity,
12 multiply,
13 matrix,
14 number,
15 fraction,
16 Complex
17 } = _ref;
18
19 /**
20 * Calculates the power of x to y, `x ^ y`.
21 * Matrix exponentiation is supported for square matrices `x`, and positive
22 * integer exponents `y`.
23 *
24 * For cubic roots of negative numbers, the function returns the principal
25 * root by default. In order to let the function return the real root,
26 * math.js can be configured with `math.config({predictable: true})`.
27 * To retrieve all cubic roots of a value, use `math.cbrt(x, true)`.
28 *
29 * Syntax:
30 *
31 * math.pow(x, y)
32 *
33 * Examples:
34 *
35 * math.pow(2, 3) // returns number 8
36 *
37 * const a = math.complex(2, 3)
38 * math.pow(a, 2) // returns Complex -5 + 12i
39 *
40 * const b = [[1, 2], [4, 3]]
41 * math.pow(b, 2) // returns Array [[9, 8], [16, 17]]
42 *
43 * See also:
44 *
45 * multiply, sqrt, cbrt, nthRoot
46 *
47 * @param {number | BigNumber | Complex | Unit | Array | Matrix} x The base
48 * @param {number | BigNumber | Complex} y The exponent
49 * @return {number | BigNumber | Complex | Array | Matrix} The value of `x` to the power `y`
50 */
51 return typed(name, {
52 'number, number': _pow,
53 'Complex, Complex': function ComplexComplex(x, y) {
54 return x.pow(y);
55 },
56 'BigNumber, BigNumber': function BigNumberBigNumber(x, y) {
57 if (y.isInteger() || x >= 0 || config.predictable) {
58 return x.pow(y);
59 } else {
60 return new Complex(x.toNumber(), 0).pow(y.toNumber(), 0);
61 }
62 },
63 'Fraction, Fraction': function FractionFraction(x, y) {
64 if (y.d !== 1) {
65 if (config.predictable) {
66 throw new Error('Function pow does not support non-integer exponents for fractions.');
67 } else {
68 return _pow(x.valueOf(), y.valueOf());
69 }
70 } else {
71 return x.pow(y);
72 }
73 },
74 'Array, number': _powArray,
75 'Array, BigNumber': function ArrayBigNumber(x, y) {
76 return _powArray(x, y.toNumber());
77 },
78 'Matrix, number': _powMatrix,
79 'Matrix, BigNumber': function MatrixBigNumber(x, y) {
80 return _powMatrix(x, y.toNumber());
81 },
82 'Unit, number | BigNumber': function UnitNumberBigNumber(x, y) {
83 return x.pow(y);
84 }
85 });
86 /**
87 * Calculates the power of x to y, x^y, for two numbers.
88 * @param {number} x
89 * @param {number} y
90 * @return {number | Complex} res
91 * @private
92 */
93
94 function _pow(x, y) {
95 // Alternatively could define a 'realmode' config option or something, but
96 // 'predictable' will work for now
97 if (config.predictable && !isInteger(y) && x < 0) {
98 // Check to see if y can be represented as a fraction
99 try {
100 var yFrac = fraction(y);
101 var yNum = number(yFrac);
102
103 if (y === yNum || Math.abs((y - yNum) / y) < 1e-14) {
104 if (yFrac.d % 2 === 1) {
105 return (yFrac.n % 2 === 0 ? 1 : -1) * Math.pow(-x, y);
106 }
107 }
108 } catch (ex) {// fraction() throws an error if y is Infinity, etc.
109 } // Unable to express y as a fraction, so continue on
110
111 } // **for predictable mode** x^Infinity === NaN if x < -1
112 // N.B. this behavour is different from `Math.pow` which gives
113 // (-2)^Infinity === Infinity
114
115
116 if (config.predictable && (x < -1 && y === Infinity || x > -1 && x < 0 && y === -Infinity)) {
117 return NaN;
118 }
119
120 if (isInteger(y) || x >= 0 || config.predictable) {
121 return powNumber(x, y);
122 } else {
123 // TODO: the following infinity checks are duplicated from powNumber. Deduplicate this somehow
124 // x^Infinity === 0 if -1 < x < 1
125 // A real number 0 is returned instead of complex(0)
126 if (x * x < 1 && y === Infinity || x * x > 1 && y === -Infinity) {
127 return 0;
128 }
129
130 return new Complex(x, 0).pow(y, 0);
131 }
132 }
133 /**
134 * Calculate the power of a 2d array
135 * @param {Array} x must be a 2 dimensional, square matrix
136 * @param {number} y a positive, integer value
137 * @returns {Array}
138 * @private
139 */
140
141
142 function _powArray(x, y) {
143 if (!isInteger(y) || y < 0) {
144 throw new TypeError('For A^b, b must be a positive integer (value is ' + y + ')');
145 } // verify that A is a 2 dimensional square matrix
146
147
148 var s = size(x);
149
150 if (s.length !== 2) {
151 throw new Error('For A^b, A must be 2 dimensional (A has ' + s.length + ' dimensions)');
152 }
153
154 if (s[0] !== s[1]) {
155 throw new Error('For A^b, A must be square (size is ' + s[0] + 'x' + s[1] + ')');
156 }
157
158 var res = identity(s[0]).valueOf();
159 var px = x;
160
161 while (y >= 1) {
162 if ((y & 1) === 1) {
163 res = multiply(px, res);
164 }
165
166 y >>= 1;
167 px = multiply(px, px);
168 }
169
170 return res;
171 }
172 /**
173 * Calculate the power of a 2d matrix
174 * @param {Matrix} x must be a 2 dimensional, square matrix
175 * @param {number} y a positive, integer value
176 * @returns {Matrix}
177 * @private
178 */
179
180
181 function _powMatrix(x, y) {
182 return matrix(_powArray(x.valueOf(), y));
183 }
184});
\No newline at end of file