herta
Version:
Advanced mathematics framework for scientific, engineering, and financial applications
256 lines (221 loc) • 7.21 kB
JavaScript
/**
* Core algebra operations for herta.js
* Provides symbolic manipulation, equation solving, and polynomial operations
*/
const Decimal = require('decimal.js');
const Complex = require('complex.js');
// Algebra module
const algebra = {};
/**
* Solve a linear equation or system of linear equations
* @param {string|Array} equations - The equation(s) to solve
* @param {string|Array} variable - The variable(s) to solve for
* @returns {Object} - Solution with variable names as keys
*/
algebra.solve = function (equations, variables) {
// Handle single equation case
if (typeof equations === 'string') {
equations = [equations];
}
// Handle single variable case
if (typeof variables === 'string') {
variables = [variables];
}
// For simple single-variable linear equations
if (equations.length === 1 && variables.length === 1) {
return solveLinearEquation(equations[0], variables[0]);
}
// For systems of linear equations
if (equations.length === variables.length) {
return solveLinearSystem(equations, variables);
}
throw new Error('Unsupported equation type or mismatch between equations and variables');
};
/**
* Solve a single-variable linear equation
* @private
* @param {string} equation - The equation to solve
* @param {string} variable - The variable to solve for
* @returns {Object} - Solution with variable name as key
*/
function solveLinearEquation(equation, variable) {
// Parse the equation into left and right sides
const sides = equation.split('=');
if (sides.length !== 2) {
throw new Error('Invalid equation format. Must contain exactly one equals sign.');
}
// Move all terms with the variable to the left side and constants to the right
const leftSide = sides[0].trim();
const rightSide = sides[1].trim();
// Collect coefficients of the variable and constants
const coefficientRegex = new RegExp(`([+-]?\\s*\\d*\\.?\\d*)\\s*\\*?\\s*${variable}`, 'g');
const coefficientMatches = leftSide.match(coefficientRegex) || [];
let coefficient = 0;
for (const match of coefficientMatches) {
const coef = match.replace(variable, '').replace('*', '').trim();
coefficient += coef === '' ? 1 : coef === '-' ? -1 : parseFloat(coef);
}
// Extract constants from the left side
let leftConstants = 0;
const leftConstantTerms = leftSide.replace(coefficientRegex, '').match(/[+-]?\s*\d+\.?\d*/g) || [];
for (const term of leftConstantTerms) {
leftConstants += parseFloat(term);
}
// Extract constants from the right side
let rightConstants = 0;
const rightConstantTerms = rightSide.match(/[+-]?\s*\d+\.?\d*/g) || [];
for (const term of rightConstantTerms) {
rightConstants += parseFloat(term);
}
// Solve for the variable
const solution = (rightConstants - leftConstants) / coefficient;
// Return the solution as an object
const result = {};
result[variable] = solution;
return result;
}
/**
* Solve a system of linear equations
* @private
* @param {Array} equations - The equations to solve
* @param {Array} variables - The variables to solve for
* @returns {Object} - Solution with variable names as keys
*/
function solveLinearSystem(equations, variables) {
// Implementation of Gaussian elimination would go here
// For now, return a placeholder
const result = {};
variables.forEach((variable) => {
result[variable] = 0; // Placeholder
});
return result;
}
/**
* Simplify an algebraic expression
* @param {string} expr - The expression to simplify
* @returns {string} - The simplified expression
*/
algebra.simplify = function (expr) {
// Basic simplification logic
// This would be expanded with more comprehensive rules
return expr
.replace(/\s+/g, '') // Remove whitespace
.replace(/\+\-/g, '-') // Combine +- to -
.replace(/\-\+/g, '-') // Combine -+ to -
.replace(/\-\-/g, '+') // Combine -- to +
.replace(/\+\+/g, '+') // Combine ++ to +
.replace(/\+0/g, '') // Remove +0
.replace(/\-0/g, '') // Remove -0
.replace(/\*1/g, '') // Remove *1
.replace(/\/1/g, ''); // Remove /1
};
/**
* Expand an algebraic expression
* @param {string} expr - The expression to expand
* @returns {string} - The expanded expression
*/
algebra.expand = function (expr) {
// Placeholder for expansion logic
return expr;
};
/**
* Factor an algebraic expression
* @param {string} expr - The expression to factor
* @returns {string} - The factored expression
*/
algebra.factor = function (expr) {
// Placeholder for factoring logic
return expr;
};
/**
* Compute the greatest common divisor of two numbers
* @param {number} a - First number
* @param {number} b - Second number
* @returns {number} - The greatest common divisor
*/
algebra.gcd = function (a, b) {
a = Math.abs(a);
b = Math.abs(b);
while (b !== 0) {
const temp = b;
b = a % b;
a = temp;
}
return a;
};
/**
* Compute the least common multiple of two numbers
* @param {number} a - First number
* @param {number} b - Second number
* @returns {number} - The least common multiple
*/
algebra.lcm = function (a, b) {
return Math.abs(a * b) / algebra.gcd(a, b);
};
/**
* Create a polynomial from coefficients
* @param {Array} coefficients - Coefficients from highest to lowest degree
* @returns {Object} - Polynomial object with evaluation and other methods
*/
algebra.polynomial = function (coefficients) {
return {
coefficients,
/**
* Evaluate the polynomial at a given value
* @param {number} x - The value to evaluate at
* @returns {number} - The result of evaluation
*/
evaluate(x) {
let result = 0;
for (let i = 0; i < this.coefficients.length; i++) {
result += this.coefficients[i] * x ** (this.coefficients.length - i - 1);
}
return result;
},
/**
* Get the derivative of the polynomial
* @returns {Object} - A new polynomial representing the derivative
*/
derivative() {
const newCoefficients = [];
for (let i = 0; i < this.coefficients.length - 1; i++) {
newCoefficients.push(this.coefficients[i] * (this.coefficients.length - i - 1));
}
return algebra.polynomial(newCoefficients);
},
/**
* Get the roots of the polynomial (placeholder implementation)
* @returns {Array} - The roots of the polynomial
*/
roots() {
// Placeholder - would implement numerical methods for root finding
return [];
},
/**
* Convert the polynomial to a string
* @returns {string} - String representation
*/
toString() {
let result = '';
for (let i = 0; i < this.coefficients.length; i++) {
const coef = this.coefficients[i];
const power = this.coefficients.length - i - 1;
if (coef === 0) continue;
if (result !== '' && coef > 0) {
result += '+';
}
if (coef !== 1 || power === 0) {
result += coef;
}
if (power > 0) {
result += 'x';
if (power > 1) {
result += `^${power}`;
}
}
}
return result || '0';
}
};
};
module.exports = algebra;