UNPKG

dist-javascript-algorithms-and-data-structures

Version:

Algorithms and data-structures implemented on JavaScript

178 lines (147 loc) 4.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _radianToDegree = _interopRequireDefault(require("../radian/radianToDegree")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class ComplexNumber { /** * z = re + im * i * z = radius * e^(i * phase) * * @param {number} [re] * @param {number} [im] */ constructor({ re = 0, im = 0 } = {}) { this.re = re; this.im = im; } /** * @param {ComplexNumber|number} addend * @return {ComplexNumber} */ add(addend) { // Make sure we're dealing with complex number. const complexAddend = this.toComplexNumber(addend); return new ComplexNumber({ re: this.re + complexAddend.re, im: this.im + complexAddend.im }); } /** * @param {ComplexNumber|number} subtrahend * @return {ComplexNumber} */ subtract(subtrahend) { // Make sure we're dealing with complex number. const complexSubtrahend = this.toComplexNumber(subtrahend); return new ComplexNumber({ re: this.re - complexSubtrahend.re, im: this.im - complexSubtrahend.im }); } /** * @param {ComplexNumber|number} multiplicand * @return {ComplexNumber} */ multiply(multiplicand) { // Make sure we're dealing with complex number. const complexMultiplicand = this.toComplexNumber(multiplicand); return new ComplexNumber({ re: this.re * complexMultiplicand.re - this.im * complexMultiplicand.im, im: this.re * complexMultiplicand.im + this.im * complexMultiplicand.re }); } /** * @param {ComplexNumber|number} divider * @return {ComplexNumber} */ divide(divider) { // Make sure we're dealing with complex number. const complexDivider = this.toComplexNumber(divider); // Get divider conjugate. const dividerConjugate = this.conjugate(complexDivider); // Multiply dividend by divider's conjugate. const finalDivident = this.multiply(dividerConjugate); // Calculating final divider using formula (a + bi)(a − bi) = a^2 + b^2 const finalDivider = complexDivider.re ** 2 + complexDivider.im ** 2; return new ComplexNumber({ re: finalDivident.re / finalDivider, im: finalDivident.im / finalDivider }); } /** * @param {ComplexNumber|number} number */ conjugate(number) { // Make sure we're dealing with complex number. const complexNumber = this.toComplexNumber(number); return new ComplexNumber({ re: complexNumber.re, im: -1 * complexNumber.im }); } /** * @return {number} */ getRadius() { return Math.sqrt(this.re ** 2 + this.im ** 2); } /** * @param {boolean} [inRadians] * @return {number} */ getPhase(inRadians = true) { let phase = Math.atan(Math.abs(this.im) / Math.abs(this.re)); if (this.re < 0 && this.im > 0) { phase = Math.PI - phase; } else if (this.re < 0 && this.im < 0) { phase = -(Math.PI - phase); } else if (this.re > 0 && this.im < 0) { phase = -phase; } else if (this.re === 0 && this.im > 0) { phase = Math.PI / 2; } else if (this.re === 0 && this.im < 0) { phase = -Math.PI / 2; } else if (this.re < 0 && this.im === 0) { phase = Math.PI; } else if (this.re > 0 && this.im === 0) { phase = 0; } else if (this.re === 0 && this.im === 0) { // More correctly would be to set 'indeterminate'. // But just for simplicity reasons let's set zero. phase = 0; } if (!inRadians) { phase = (0, _radianToDegree.default)(phase); } return phase; } /** * @param {boolean} [inRadians] * @return {{radius: number, phase: number}} */ getPolarForm(inRadians = true) { return { radius: this.getRadius(), phase: this.getPhase(inRadians) }; } /** * Convert real numbers to complex number. * In case if complex number is provided then lefts it as is. * * @param {ComplexNumber|number} number * @return {ComplexNumber} */ toComplexNumber(number) { if (number instanceof ComplexNumber) { return number; } return new ComplexNumber({ re: number }); } } exports.default = ComplexNumber;