herta
Version:
Advanced mathematics framework for scientific, engineering, and financial applications
329 lines (296 loc) • 8.23 kB
JavaScript
/**
* Complex numbers module for herta.js
*/
const Complex = require('complex.js');
// Complex numbers module
const complex = {};
/**
* Create a complex number
* @param {number} real - The real part
* @param {number} [imag=0] - The imaginary part
* @returns {Complex} - The complex number
*/
complex.complex = function (real, imag = 0) {
return new Complex(real, imag);
};
/**
* Create a complex number from polar coordinates
* @param {number} r - The magnitude (radius)
* @param {number} phi - The phase angle in radians
* @returns {Complex} - The complex number
*/
complex.fromPolar = function (r, phi) {
return Complex.fromPolar(r, phi);
};
/**
* Get the real part of a complex number
* @param {Complex|number} a - The complex number
* @returns {number} - The real part
*/
complex.re = function (a) {
return a instanceof Complex ? a.re : a;
};
/**
* Get the imaginary part of a complex number
* @param {Complex|number} a - The complex number
* @returns {number} - The imaginary part
*/
complex.im = function (a) {
return a instanceof Complex ? a.im : 0;
};
/**
* Get the magnitude (absolute value) of a complex number
* @param {Complex|number} a - The complex number
* @returns {number} - The magnitude
*/
complex.abs = function (a) {
return a instanceof Complex ? a.abs() : Math.abs(a);
};
/**
* Get the argument (phase) of a complex number
* @param {Complex|number} a - The complex number
* @returns {number} - The argument in radians
*/
complex.arg = function (a) {
if (a instanceof Complex) {
return a.arg();
} if (a >= 0) {
return 0;
}
return Math.PI;
};
/**
* Get the conjugate of a complex number
* @param {Complex|number} a - The complex number
* @returns {Complex|number} - The conjugate
*/
complex.conj = function (a) {
return a instanceof Complex ? a.conjugate() : a;
};
/**
* Add two complex numbers
* @param {Complex|number} a - First complex number
* @param {Complex|number} b - Second complex number
* @returns {Complex|number} - Sum of the complex numbers
*/
complex.add = function (a, b) {
if (a instanceof Complex || b instanceof Complex) {
const aComplex = a instanceof Complex ? a : new Complex(a);
const bComplex = b instanceof Complex ? b : new Complex(b);
return aComplex.add(bComplex);
}
return a + b;
};
/**
* Subtract two complex numbers
* @param {Complex|number} a - First complex number
* @param {Complex|number} b - Second complex number
* @returns {Complex|number} - Difference of the complex numbers
*/
complex.subtract = function (a, b) {
if (a instanceof Complex || b instanceof Complex) {
const aComplex = a instanceof Complex ? a : new Complex(a);
const bComplex = b instanceof Complex ? b : new Complex(b);
return aComplex.sub(bComplex);
}
return a - b;
};
/**
* Multiply two complex numbers
* @param {Complex|number} a - First complex number
* @param {Complex|number} b - Second complex number
* @returns {Complex|number} - Product of the complex numbers
*/
complex.multiply = function (a, b) {
if (a instanceof Complex || b instanceof Complex) {
const aComplex = a instanceof Complex ? a : new Complex(a);
const bComplex = b instanceof Complex ? b : new Complex(b);
return aComplex.mul(bComplex);
}
return a * b;
};
/**
* Divide two complex numbers
* @param {Complex|number} a - First complex number (numerator)
* @param {Complex|number} b - Second complex number (denominator)
* @returns {Complex|number} - Quotient of the complex numbers
*/
complex.divide = function (a, b) {
if (a instanceof Complex || b instanceof Complex) {
const aComplex = a instanceof Complex ? a : new Complex(a);
const bComplex = b instanceof Complex ? b : new Complex(b);
return aComplex.div(bComplex);
}
if (b === 0) {
throw new Error('Division by zero');
}
return a / b;
};
/**
* Raise a complex number to a power
* @param {Complex|number} a - The base
* @param {Complex|number} b - The exponent
* @returns {Complex|number} - The result of exponentiation
*/
complex.pow = function (a, b) {
if (a instanceof Complex || b instanceof Complex) {
const aComplex = a instanceof Complex ? a : new Complex(a);
const bComplex = b instanceof Complex ? b : new Complex(b);
return aComplex.pow(bComplex);
}
return a ** b;
};
/**
* Calculate the square root of a complex number
* @param {Complex|number} a - The complex number
* @returns {Complex|number} - The square root
*/
complex.sqrt = function (a) {
if (a instanceof Complex) {
return a.sqrt();
} if (a >= 0) {
return Math.sqrt(a);
}
return new Complex(0, Math.sqrt(-a));
};
/**
* Calculate the exponential of a complex number
* @param {Complex|number} a - The complex number
* @returns {Complex|number} - The exponential
*/
complex.exp = function (a) {
if (a instanceof Complex) {
return a.exp();
}
return Math.exp(a);
};
/**
* Calculate the natural logarithm of a complex number
* @param {Complex|number} a - The complex number
* @returns {Complex|number} - The natural logarithm
*/
complex.log = function (a) {
if (a instanceof Complex) {
return a.log();
} if (a > 0) {
return Math.log(a);
} if (a === 0) {
throw new Error('Logarithm of zero');
} else {
return new Complex(Math.log(-a), Math.PI);
}
};
/**
* Calculate the sine of a complex number
* @param {Complex|number} a - The complex number
* @returns {Complex|number} - The sine
*/
complex.sin = function (a) {
if (a instanceof Complex) {
return a.sin();
}
return Math.sin(a);
};
/**
* Calculate the cosine of a complex number
* @param {Complex|number} a - The complex number
* @returns {Complex|number} - The cosine
*/
complex.cos = function (a) {
if (a instanceof Complex) {
return a.cos();
}
return Math.cos(a);
};
/**
* Calculate the tangent of a complex number
* @param {Complex|number} a - The complex number
* @returns {Complex|number} - The tangent
*/
complex.tan = function (a) {
if (a instanceof Complex) {
return a.tan();
}
return Math.tan(a);
};
/**
* Calculate the hyperbolic sine of a complex number
* @param {Complex|number} a - The complex number
* @returns {Complex|number} - The hyperbolic sine
*/
complex.sinh = function (a) {
if (a instanceof Complex) {
return a.sinh();
}
return Math.sinh(a);
};
/**
* Calculate the hyperbolic cosine of a complex number
* @param {Complex|number} a - The complex number
* @returns {Complex|number} - The hyperbolic cosine
*/
complex.cosh = function (a) {
if (a instanceof Complex) {
return a.cosh();
}
return Math.cosh(a);
};
/**
* Calculate the hyperbolic tangent of a complex number
* @param {Complex|number} a - The complex number
* @returns {Complex|number} - The hyperbolic tangent
*/
complex.tanh = function (a) {
if (a instanceof Complex) {
return a.tanh();
}
return Math.tanh(a);
};
/**
* Convert a complex number to a string
* @param {Complex|number} a - The complex number
* @returns {string} - String representation
*/
complex.toString = function (a) {
if (a instanceof Complex) {
return a.toString();
}
return a.toString();
};
/**
* Check if a value is a complex number
* @param {any} a - The value to check
* @returns {boolean} - True if the value is a complex number
*/
complex.isComplex = function (a) {
return a instanceof Complex;
};
/**
* Create a complex number from a string
* @param {string} str - The string representation
* @returns {Complex} - The complex number
*/
complex.parse = function (str) {
// Remove spaces
str = str.replace(/\s/g, '');
// Check for simple imaginary number notation
if (str === 'i') {
return new Complex(0, 1);
}
// Check for a+bi format
const match = str.match(/^([-+]?\d*\.?\d*)(?:([-+])(?:(\d*\.?\d*))?i)?$/);
if (match) {
const real = match[1] ? parseFloat(match[1]) : 0;
let imag = 0;
if (match[2]) {
if (match[3]) {
imag = parseFloat(match[2] + match[3]);
} else {
imag = match[2] === '+' ? 1 : -1;
}
}
return new Complex(real, imag);
}
throw new Error(`Cannot parse "${str}" as a complex number`);
};
module.exports = complex;