package funkin.audiovis.dsp; /** Complex number representation. **/ @:forward(real, imag) @:notNull @:pure abstract Complex({ final real:Float; final imag:Float; }) { public inline function new(real:Float, imag:Float) this = {real: real, imag: imag}; /** Makes a Complex number with the given Float as its real part and a zero imag part. **/ @:from public static inline function fromReal(r:Float) return new Complex(r, 0); /** Complex argument, in radians. **/ public var angle(get, never):Float; inline function get_angle() return Math.atan2(this.imag, this.real); /** Complex module. **/ public var magnitude(get, never):Float; inline function get_magnitude() return Math.sqrt(this.real * this.real + this.imag * this.imag); @:op(A + B) public inline function add(rhs:Complex):Complex return new Complex(this.real + rhs.real, this.imag + rhs.imag); @:op(A - B) public inline function sub(rhs:Complex):Complex return new Complex(this.real - rhs.real, this.imag - rhs.imag); @:op(A * B) public inline function mult(rhs:Complex):Complex return new Complex(this.real * rhs.real - this.imag * rhs.imag, this.real * rhs.imag + this.imag * rhs.real); /** Returns the complex conjugate, does not modify this object. **/ public inline function conj():Complex return new Complex(this.real, -this.imag); /** Multiplication by a real factor, does not modify this object. **/ public inline function scale(k:Float):Complex return new Complex(this.real * k, this.imag * k); public inline function copy():Complex return new Complex(this.real, this.imag); /** The imaginary unit. **/ public static final im = new Complex(0, 1); /** The complex zero. **/ public static final zero = new Complex(0, 0); /** Computes the complex exponential `e^(iw)`. **/ public static inline function exp(w:Float) return new Complex(Math.cos(w), Math.sin(w)); }