package openmods.math; public class Complex { public static final Complex ZERO = new Complex(0, 0); public static final Complex ONE = new Complex(1, 0); public static final Complex I = new Complex(0, 1); public final double re; public final double im; private Complex(double real, double imaginary) { this.re = real; this.im = imaginary; } public static Complex real(double v) { return new Complex(v, 0); } public static Complex imaginary(double v) { return new Complex(0, v); } public static Complex polar(double r, double phase) { return new Complex(r * Math.cos(phase), r * Math.sin(phase)); } public static Complex cartesian(double x, double y) { return new Complex(x, y); } public static Complex create(double re, double im) { return new Complex(re, im); } public Complex conj() { return new Complex(this.re, -this.im); } public Complex add(Complex other) { return new Complex(this.re + other.re, this.im + other.im); } public Complex subtract(Complex other) { return new Complex(this.re - other.re, this.im - other.im); } public Complex negate() { return new Complex(-this.re, -this.im); } public Complex multiply(double scalar) { return new Complex(scalar * this.re, scalar * this.im); } public Complex multiply(Complex other) { return new Complex(this.re * other.re - this.im * other.im, this.im * other.re + this.re * other.im); } public Complex divide(double scalar) { return new Complex(this.re / scalar, this.im / scalar); } public Complex divide(Complex other) { final double denominator = other.squareModule(); return new Complex((this.re * other.re + this.im * other.im) / denominator, (this.im * other.re - this.re * other.im) / denominator); } public double squareModule() { return this.re * this.re + this.im * this.im; } public double abs() { return Math.sqrt(squareModule()); } public double phase() { return Math.atan2(this.im, this.re); } public Complex exp() { final double r = Math.exp(this.re); return new Complex(r * Math.cos(this.im), r * Math.sin(this.im)); } public Complex ln() { return new Complex(Math.log(abs()), phase()); } @Override public int hashCode() { final int prime = 31; int result = 1; long temp; temp = Double.doubleToLongBits(im); result = prime * result + (int)(temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(re); result = prime * result + (int)(temp ^ (temp >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj instanceof Complex) { final Complex other = (Complex)obj; return (Double.doubleToLongBits(im) == Double.doubleToLongBits(other.im)) && (Double.doubleToLongBits(re) == Double.doubleToLongBits(other.re)); } return false; } @Override public String toString() { return "(" + re + "+" + im + "I)"; } }