UNPKG

dsp-collection

Version:

A collection of JavaScript modules for digital signal processing (written in TypeScript)

131 lines 3.98 kB
import * as MathUtils from "./MathUtils.js"; class Complex { constructor(re, im = 0) { this.re = re; this.im = im; } toString() { return "(" + this.re + ", " + this.im + ")"; } toNumber(eps) { const absIm = Math.abs(this.im); if (!(absIm <= eps || absIm <= Math.abs(this.re) * eps)) { throw new Error("The imaginary part of the complex number is not neglectable small for the conversion to a real number. re=" + this.re + " im=" + this.im + " eps=" + eps + "."); } return this.re; } isNaN() { return isNaN(this.re) || isNaN(this.im); } isInfinite() { return this.re == Infinity || this.re == -Infinity || this.im == Infinity || this.im == -Infinity; } isFinite() { return isFinite(this.re) && isFinite(this.im); } equals(x) { return x && this.re == x.re && this.im == x.im; } fuzzyEquals(x, eps) { return MathUtils.fuzzyEquals(this.re, x.re, eps) && MathUtils.fuzzyEquals(this.im, x.im, eps); } static expj(arg) { return new Complex(Math.cos(arg), Math.sin(arg)); } static fromPolar(abs, arg) { return new Complex(abs * Math.cos(arg), abs * Math.sin(arg)); } abs() { return Math.hypot(this.re, this.im); } arg() { return Math.atan2(this.im, this.re); } conj() { return new Complex(this.re, -this.im); } neg() { return new Complex(-this.re, -this.im); } reciprocal() { if (this.isNaN()) { return Complex.NaN; } if (this.isInfinite()) { return Complex.ZERO; } const scale = this.re * this.re + this.im * this.im; if (scale == 0) { return Complex.INFINITY; } return new Complex(this.re / scale, -this.im / scale); } exp() { return Complex.fromPolar(Math.exp(this.re), this.im); } log() { return new Complex(Math.log(this.abs()), this.arg()); } sqr() { return new Complex(this.re * this.re - this.im * this.im, 2 * this.re * this.im); } sqrt() { if (this.re == 0 && this.im == 0) { return Complex.ZERO; } const m = this.abs(); return new Complex(Math.sqrt((m + this.re) / 2), Math.sign(this.im) * Math.sqrt((m - this.re) / 2)); } addReal(x) { return new Complex(this.re + x, this.im); } add(x) { return new Complex(this.re + x.re, this.im + x.im); } subReal(x) { return new Complex(this.re - x, this.im); } static subFromReal(x, y) { return new Complex(x - y.re, -y.im); } sub(x) { return new Complex(this.re - x.re, this.im - x.im); } mulReal(x) { return new Complex(this.re * x, this.im * x); } mul(x) { return new Complex(this.re * x.re - this.im * x.im, this.re * x.im + this.im * x.re); } divReal(x) { return new Complex(this.re / x, this.im / x); } div(x) { const m = x.re * x.re + x.im * x.im; return new Complex((this.re * x.re + this.im * x.im) / m, (this.im * x.re - this.re * x.im) / m); } static divFromReal(x, y) { const m = y.re * y.re + y.im * y.im; return new Complex(x * y.re / m, -x * y.im / m); } powInt(x) { if (!Number.isInteger(x)) { throw new Error("powInt() used with non-integer exponent."); } return Complex.fromPolar(Math.pow(this.abs(), x), this.arg() * x); } powReal(x) { return this.log().mulReal(x).exp(); } pow(x) { return this.log().mul(x).exp(); } } Complex.I = new Complex(0, 1); Complex.ZERO = new Complex(0); Complex.ONE = new Complex(1); Complex.TWO = new Complex(2); Complex.NaN = new Complex(NaN, NaN); Complex.INFINITY = new Complex(Infinity, Infinity); export default Complex; //# sourceMappingURL=Complex.js.map