UNPKG

@pfm37/better-math

Version:

A math module which adds more flexibility to math, that means more math functions

166 lines (150 loc) 5.6 kB
module.exports = { // Basic Math Functions factorial(n) { if (n < 0) return NaN; // No factorial for negative numbers if (n === 0) return 1; let result = 1; for (let i = 1; i <= n; i++) result *= i; return result; }, isPrime(n) { if (n < 2) return false; for (let i = 2; i <= Math.sqrt(n); i++) { if (n % i === 0) return false; } return true; }, gcd(a, b) { while (b) { [a, b] = [b, a % b]; } return a; }, lcm(a, b) { return (a * b) / this.gcd(a, b); }, // Statistics Functions mean(arr) { return arr.reduce((sum, val) => sum + val, 0) / arr.length; }, median(arr) { arr.sort((a, b) => a - b); const mid = Math.floor(arr.length / 2); return arr.length % 2 === 0 ? (arr[mid - 1] + arr[mid]) / 2 : arr[mid]; }, mode(arr) { const freq = {}; arr.forEach(num => freq[num] = (freq[num] || 0) + 1); const maxFreq = Math.max(...Object.values(freq)); return Object.keys(freq).filter(key => freq[key] === maxFreq).map(Number); }, variance(arr) { const mean = this.mean(arr); return arr.reduce((sum, num) => sum + Math.pow(num - mean, 2), 0) / arr.length; }, stdDev(arr) { return Math.sqrt(this.variance(arr)); }, // BODMAS Expression Solver evaluate(expr) { return Function(`"use strict"; return (${expr})`)(); }, // Matrix Operations addMatrices(A, B) { return A.map((row, i) => row.map((val, j) => val + B[i][j])); }, multiplyMatrices(A, B) { return A.map((row, i) => B[0].map((_, j) => row.reduce((sum, val, k) => sum + val * B[k][j], 0) )); }, transposeMatrix(A) { return A[0].map((_, i) => A.map(row => row[i])); }, determinant(A) { if (A.length !== A[0].length) throw new Error("Matrix must be square"); if (A.length === 2) return A[0][0] * A[1][1] - A[0][1] * A[1][0]; return A[0].reduce((det, val, j) => det + (-1) ** j * val * this.determinant(A.slice(1).map(row => row.filter((_, k) => k !== j))), 0); }, inverseMatrix(A) { const det = this.determinant(A); if (det === 0) throw new Error("Matrix is singular and cannot be inverted"); if (A.length === 2) return [[A[1][1] / det, -A[0][1] / det], [-A[1][0] / det, A[0][0] / det]]; const adjugate = A.map((row, i) => row.map((_, j) => (-1) ** (i + j) * this.determinant(A.filter((_, r) => r !== i).map(row => row.filter((_, c) => c !== j))) ) ); return this.transposeMatrix(adjugate).map(row => row.map(val => val / det)); }, // Hyperbolic Functions sinh(x) { return (Math.exp(x) - Math.exp(-x)) / 2; }, cosh(x) { return (Math.exp(x) + Math.exp(-x)) / 2; }, tanh(x) { return this.sinh(x) / this.cosh(x); }, csch(x) { return 1 / this.sinh(x); }, sech(x) { return 1 / this.cosh(x); }, coth(x) { return 1 / this.tanh(x); }, // Inverse Trigonometric Functions asin(x) { return Math.asin(x); }, acos(x) { return Math.acos(x); }, atan(x) { return Math.atan(x); }, // Inverse Hyperbolic Functions asinh(x) { return Math.log(x + Math.sqrt(x*x + 1)); }, acosh(x) { return Math.log(x + Math.sqrt(x*x - 1)); }, atanh(x) { return 0.5 * Math.log((1 + x) / (1 - x)); }, // Secant, Cosecant, Cotangent sec(x) { return 1 / Math.cos(x); }, csc(x) { return 1 / Math.sin(x); }, cot(x) { return 1 / Math.tan(x); }, // Complex Number Operations addComplex(a, b) { return { real: a.real + b.real, imag: a.imag + b.imag }; }, subtractComplex(a, b) { return { real: a.real - b.real, imag: a.imag - b.imag }; }, multiplyComplex(a, b) { return { real: a.real * b.real - a.imag * b.imag, imag: a.real * b.imag + a.imag * b.real }; }, divideComplex(a, b) { const denominator = b.real * b.real + b.imag * b.imag; return { real: (a.real * b.real + a.imag * b.imag) / denominator, imag: (a.imag * b.real - a.real * b.imag) / denominator }; }, magnitudeComplex(a) { return Math.sqrt(a.real * a.real + a.imag * a.imag); }, conjugateComplex(a) { return { real: a.real, imag: -a.imag }; }, // Derivative of a Polynomial derivative(coeffs) { return coeffs.map((coef, index) => coef * index).slice(1); }, // Definite Integral of a Polynomial integral(coeffs, lower, upper) { const integralCoeffs = coeffs.map((coef, index) => coef / (index + 1)); const evaluate = (x) => integralCoeffs.reduce((sum, coef, index) => sum + coef * Math.pow(x, index + 1), 0); return evaluate(upper) - evaluate(lower); }, // Limits using numerical approximation limit(f, x, h = 1e-5) { return (f(x + h) - f(x)) / h; }, // Taylor Series Expansion (up to N terms) around x0 taylorSeries(f, fDerivatives, x0, n) { return (x) => { let sum = f(x0); for (let i = 1; i < n; i++) { sum += (fDerivatives[i](x0) / module.exports.factorial(i)) * Math.pow(x - x0, i); } return sum; }; }, }