nthRoot.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import { factory } from '../../utils/factory.js';
  2. import { createMatAlgo01xDSid } from '../../type/matrix/utils/matAlgo01xDSid.js';
  3. import { createMatAlgo02xDS0 } from '../../type/matrix/utils/matAlgo02xDS0.js';
  4. import { createMatAlgo06xS0S0 } from '../../type/matrix/utils/matAlgo06xS0S0.js';
  5. import { createMatAlgo11xS0s } from '../../type/matrix/utils/matAlgo11xS0s.js';
  6. import { createMatrixAlgorithmSuite } from '../../type/matrix/utils/matrixAlgorithmSuite.js';
  7. import { nthRootNumber } from '../../plain/number/index.js';
  8. var name = 'nthRoot';
  9. var dependencies = ['typed', 'matrix', 'equalScalar', 'BigNumber', 'concat'];
  10. export var createNthRoot = /* #__PURE__ */factory(name, dependencies, _ref => {
  11. var {
  12. typed,
  13. matrix,
  14. equalScalar,
  15. BigNumber: _BigNumber,
  16. concat
  17. } = _ref;
  18. var matAlgo01xDSid = createMatAlgo01xDSid({
  19. typed
  20. });
  21. var matAlgo02xDS0 = createMatAlgo02xDS0({
  22. typed,
  23. equalScalar
  24. });
  25. var matAlgo06xS0S0 = createMatAlgo06xS0S0({
  26. typed,
  27. equalScalar
  28. });
  29. var matAlgo11xS0s = createMatAlgo11xS0s({
  30. typed,
  31. equalScalar
  32. });
  33. var matrixAlgorithmSuite = createMatrixAlgorithmSuite({
  34. typed,
  35. matrix,
  36. concat
  37. });
  38. /**
  39. * Calculate the nth root of a value.
  40. * The principal nth root of a positive real number A, is the positive real
  41. * solution of the equation
  42. *
  43. * x^root = A
  44. *
  45. * For matrices, the function is evaluated element wise.
  46. *
  47. * Syntax:
  48. *
  49. * math.nthRoot(a)
  50. * math.nthRoot(a, root)
  51. *
  52. * Examples:
  53. *
  54. * math.nthRoot(9, 2) // returns 3 (since 3^2 == 9)
  55. * math.sqrt(9) // returns 3 (since 3^2 == 9)
  56. * math.nthRoot(64, 3) // returns 4 (since 4^3 == 64)
  57. *
  58. * See also:
  59. *
  60. * sqrt, pow
  61. *
  62. * @param {number | BigNumber | Array | Matrix | Complex} a
  63. * Value for which to calculate the nth root
  64. * @param {number | BigNumber} [root=2] The root.
  65. * @return {number | Complex | Array | Matrix} Returns the nth root of `a`
  66. */
  67. function complexErr() {
  68. throw new Error('Complex number not supported in function nthRoot. Use nthRoots instead.');
  69. }
  70. return typed(name, {
  71. number: nthRootNumber,
  72. 'number, number': nthRootNumber,
  73. BigNumber: x => _bigNthRoot(x, new _BigNumber(2)),
  74. 'BigNumber, BigNumber': _bigNthRoot,
  75. Complex: complexErr,
  76. 'Complex, number': complexErr,
  77. Array: typed.referTo('DenseMatrix,number', selfDn => x => selfDn(matrix(x), 2).valueOf()),
  78. DenseMatrix: typed.referTo('DenseMatrix,number', selfDn => x => selfDn(x, 2)),
  79. SparseMatrix: typed.referTo('SparseMatrix,number', selfSn => x => selfSn(x, 2)),
  80. 'SparseMatrix, SparseMatrix': typed.referToSelf(self => (x, y) => {
  81. // density must be one (no zeros in matrix)
  82. if (y.density() === 1) {
  83. // sparse + sparse
  84. return matAlgo06xS0S0(x, y, self);
  85. } else {
  86. // throw exception
  87. throw new Error('Root must be non-zero');
  88. }
  89. }),
  90. 'DenseMatrix, SparseMatrix': typed.referToSelf(self => (x, y) => {
  91. // density must be one (no zeros in matrix)
  92. if (y.density() === 1) {
  93. // dense + sparse
  94. return matAlgo01xDSid(x, y, self, false);
  95. } else {
  96. // throw exception
  97. throw new Error('Root must be non-zero');
  98. }
  99. }),
  100. 'Array, SparseMatrix': typed.referTo('DenseMatrix,SparseMatrix', selfDS => (x, y) => selfDS(matrix(x), y)),
  101. 'number | BigNumber, SparseMatrix': typed.referToSelf(self => (x, y) => {
  102. // density must be one (no zeros in matrix)
  103. if (y.density() === 1) {
  104. // sparse - scalar
  105. return matAlgo11xS0s(y, x, self, true);
  106. } else {
  107. // throw exception
  108. throw new Error('Root must be non-zero');
  109. }
  110. })
  111. }, matrixAlgorithmSuite({
  112. scalar: 'number | BigNumber',
  113. SD: matAlgo02xDS0,
  114. Ss: matAlgo11xS0s,
  115. sS: false
  116. }));
  117. /**
  118. * Calculate the nth root of a for BigNumbers, solve x^root == a
  119. * https://rosettacode.org/wiki/Nth_root#JavaScript
  120. * @param {BigNumber} a
  121. * @param {BigNumber} root
  122. * @private
  123. */
  124. function _bigNthRoot(a, root) {
  125. var precision = _BigNumber.precision;
  126. var Big = _BigNumber.clone({
  127. precision: precision + 2
  128. });
  129. var zero = new _BigNumber(0);
  130. var one = new Big(1);
  131. var inv = root.isNegative();
  132. if (inv) {
  133. root = root.neg();
  134. }
  135. if (root.isZero()) {
  136. throw new Error('Root must be non-zero');
  137. }
  138. if (a.isNegative() && !root.abs().mod(2).equals(1)) {
  139. throw new Error('Root must be odd when a is negative.');
  140. }
  141. // edge cases zero and infinity
  142. if (a.isZero()) {
  143. return inv ? new Big(Infinity) : 0;
  144. }
  145. if (!a.isFinite()) {
  146. return inv ? zero : a;
  147. }
  148. var x = a.abs().pow(one.div(root));
  149. // If a < 0, we require that root is an odd integer,
  150. // so (-1) ^ (1/root) = -1
  151. x = a.isNeg() ? x.neg() : x;
  152. return new _BigNumber((inv ? one.div(x) : x).toPrecision(precision));
  153. }
  154. });
  155. export var createNthRootNumber = /* #__PURE__ */factory(name, ['typed'], _ref2 => {
  156. var {
  157. typed
  158. } = _ref2;
  159. return typed(name, {
  160. number: nthRootNumber,
  161. 'number, number': nthRootNumber
  162. });
  163. });