pow.js (5557B)
1 import { factory } from '../../utils/factory.js'; 2 import { isInteger } from '../../utils/number.js'; 3 import { arraySize as size } from '../../utils/array.js'; 4 import { powNumber } from '../../plain/number/index.js'; 5 var name = 'pow'; 6 var dependencies = ['typed', 'config', 'identity', 'multiply', 'matrix', 'fraction', 'number', 'Complex']; 7 export 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 var result = x.pow(y); 65 66 if (result != null) { 67 return result; 68 } 69 70 if (config.predictable) { 71 throw new Error('Result of pow is non-rational and cannot be expressed as a fraction'); 72 } else { 73 return _pow(x.valueOf(), y.valueOf()); 74 } 75 }, 76 'Array, number': _powArray, 77 'Array, BigNumber': function ArrayBigNumber(x, y) { 78 return _powArray(x, y.toNumber()); 79 }, 80 'Matrix, number': _powMatrix, 81 'Matrix, BigNumber': function MatrixBigNumber(x, y) { 82 return _powMatrix(x, y.toNumber()); 83 }, 84 'Unit, number | BigNumber': function UnitNumberBigNumber(x, y) { 85 return x.pow(y); 86 } 87 }); 88 /** 89 * Calculates the power of x to y, x^y, for two numbers. 90 * @param {number} x 91 * @param {number} y 92 * @return {number | Complex} res 93 * @private 94 */ 95 96 function _pow(x, y) { 97 // Alternatively could define a 'realmode' config option or something, but 98 // 'predictable' will work for now 99 if (config.predictable && !isInteger(y) && x < 0) { 100 // Check to see if y can be represented as a fraction 101 try { 102 var yFrac = fraction(y); 103 var yNum = number(yFrac); 104 105 if (y === yNum || Math.abs((y - yNum) / y) < 1e-14) { 106 if (yFrac.d % 2 === 1) { 107 return (yFrac.n % 2 === 0 ? 1 : -1) * Math.pow(-x, y); 108 } 109 } 110 } catch (ex) {// fraction() throws an error if y is Infinity, etc. 111 } // Unable to express y as a fraction, so continue on 112 113 } // **for predictable mode** x^Infinity === NaN if x < -1 114 // N.B. this behavour is different from `Math.pow` which gives 115 // (-2)^Infinity === Infinity 116 117 118 if (config.predictable && (x < -1 && y === Infinity || x > -1 && x < 0 && y === -Infinity)) { 119 return NaN; 120 } 121 122 if (isInteger(y) || x >= 0 || config.predictable) { 123 return powNumber(x, y); 124 } else { 125 // TODO: the following infinity checks are duplicated from powNumber. Deduplicate this somehow 126 // x^Infinity === 0 if -1 < x < 1 127 // A real number 0 is returned instead of complex(0) 128 if (x * x < 1 && y === Infinity || x * x > 1 && y === -Infinity) { 129 return 0; 130 } 131 132 return new Complex(x, 0).pow(y, 0); 133 } 134 } 135 /** 136 * Calculate the power of a 2d array 137 * @param {Array} x must be a 2 dimensional, square matrix 138 * @param {number} y a positive, integer value 139 * @returns {Array} 140 * @private 141 */ 142 143 144 function _powArray(x, y) { 145 if (!isInteger(y) || y < 0) { 146 throw new TypeError('For A^b, b must be a positive integer (value is ' + y + ')'); 147 } // verify that A is a 2 dimensional square matrix 148 149 150 var s = size(x); 151 152 if (s.length !== 2) { 153 throw new Error('For A^b, A must be 2 dimensional (A has ' + s.length + ' dimensions)'); 154 } 155 156 if (s[0] !== s[1]) { 157 throw new Error('For A^b, A must be square (size is ' + s[0] + 'x' + s[1] + ')'); 158 } 159 160 var res = identity(s[0]).valueOf(); 161 var px = x; 162 163 while (y >= 1) { 164 if ((y & 1) === 1) { 165 res = multiply(px, res); 166 } 167 168 y >>= 1; 169 px = multiply(px, px); 170 } 171 172 return res; 173 } 174 /** 175 * Calculate the power of a 2d matrix 176 * @param {Matrix} x must be a 2 dimensional, square matrix 177 * @param {number} y a positive, integer value 178 * @returns {Matrix} 179 * @private 180 */ 181 182 183 function _powMatrix(x, y) { 184 return matrix(_powArray(x.valueOf(), y)); 185 } 186 });