@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
JavaScript
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;
};
},
}