diff --git a/package-lock.json b/package-lock.json index 7ba987d4b..87b1fae49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "complex.js": "^2.2.5", "decimal.js": "^10.4.3", "escape-latex": "^1.2.0", - "fraction.js": "^5.0.4", + "fraction.js": "^5.2.1", "javascript-natural-sort": "^0.7.1", "seedrandom": "^3.0.5", "tiny-emitter": "^2.1.0", @@ -6827,9 +6827,9 @@ } }, "node_modules/fraction.js": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.0.4.tgz", - "integrity": "sha512-5b1NochKz6Hi46IXReWs8L+RteW/OQ6OMoLGLm/Zy7ZsPwH+to52ZrjcdRFAOTdlO/Uifyjn8HgiNnliz9KDeg==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.2.1.tgz", + "integrity": "sha512-Ah6t/7YCYjrPUFUFsOsRLMXAdnYM+aQwmojD2Ayb/Ezr82SwES0vuyQ8qZ3QO8n9j7W14VJuVZZet8U3bhSdQQ==", "license": "MIT", "engines": { "node": ">= 12" diff --git a/package.json b/package.json index 1ae3791a4..da24a1f1f 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "complex.js": "^2.2.5", "decimal.js": "^10.4.3", "escape-latex": "^1.2.0", - "fraction.js": "^5.0.4", + "fraction.js": "^5.2.1", "javascript-natural-sort": "^0.7.1", "seedrandom": "^3.0.5", "tiny-emitter": "^2.1.0", diff --git a/src/function/arithmetic/log.js b/src/function/arithmetic/log.js index b41ab76c5..fed470b3b 100644 --- a/src/function/arithmetic/log.js +++ b/src/function/arithmetic/log.js @@ -2,9 +2,9 @@ import { factory } from '../../utils/factory.js' import { logNumber } from '../../plain/number/index.js' const name = 'log' -const dependencies = ['config', 'typed', 'divideScalar', 'Complex'] +const dependencies = ['config', 'typed', 'typeOf', 'divideScalar', 'Complex'] -export const createLog = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, divideScalar, Complex }) => { +export const createLog = /* #__PURE__ */ factory(name, dependencies, ({ typed, typeOf, config, divideScalar, Complex }) => { /** * Calculate the logarithm of a value. * @@ -32,12 +32,12 @@ export const createLog = /* #__PURE__ */ factory(name, dependencies, ({ typed, c * * exp, log2, log10, log1p * - * @param {number | BigNumber | Complex} x + * @param {number | BigNumber | Fraction | Complex} x * Value for which to calculate the logarithm. - * @param {number | BigNumber | Complex} [base=e] + * @param {number | BigNumber | Fraction | Complex} [base=e] * Optional base for the logarithm. If not provided, the natural * logarithm of `x` is calculated. - * @return {number | BigNumber | Complex} + * @return {number | BigNumber | Fraction | Complex} * Returns the logarithm of `x` */ return typed(name, { @@ -65,6 +65,15 @@ export const createLog = /* #__PURE__ */ factory(name, dependencies, ({ typed, c 'any, any': typed.referToSelf(self => (x, base) => { // calculate logarithm for a specified base, log(x, base) + + if (typeOf(x) === 'Fraction' && typeOf(base) === 'Fraction') { + const result = x.log(base) + + if (result !== null) { + return result + } + } + return divideScalar(self(x), self(base)) }) }) diff --git a/test/unit-tests/function/arithmetic/log.test.js b/test/unit-tests/function/arithmetic/log.test.js index 231344753..646677496 100644 --- a/test/unit-tests/function/arithmetic/log.test.js +++ b/test/unit-tests/function/arithmetic/log.test.js @@ -7,6 +7,7 @@ const mathPredictable = math.create({ predictable: true }) const complex = math.complex const matrix = math.matrix const unit = math.unit +const fraction = math.fraction const log = math.log describe('log', function () { @@ -93,6 +94,13 @@ describe('log', function () { approxDeepEqual(log(complex(1, 0)), complex(0, 0)) }) + it('should return the log of a Fraction', function () { + approxDeepEqual(log(fraction(27, 8), fraction(9, 4)), fraction(3, 2)) + assert.throws(() => log(fraction(27, 8), fraction(-2, 5)), + /Cannot implicitly convert a Fraction to BigNumber or vice versa/ + ) + }) + it('should handle complex number with large imaginary part', function () { const tau4 = math.tau / 4 const real = [0, -1, 1]