nthRoot.js 5.1 KB

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