dsp-collection
Version:
A collection of JavaScript modules for digital signal processing (written in TypeScript)
131 lines • 3.98 kB
JavaScript
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