package mandelbrot; import java.util.Objects; /** * The {@code Complex} class represents a complex number. * Complex numbers are immutable: their values cannot be changed after they * are created. * It includes methods for addition, subtraction, multiplication, division, * conjugation, and other common functions on complex numbers. * * @author Arnaud Labourel * @author Guyslain Naves */ public class Complex { /** * The real part of a complex number. */ private final double real; /** * The imaginary part of a complex number. */ private final double imaginary; /** * Initializes a complex number with the specified real and imaginary parts. * * @param real the real part * @param imaginary the imaginary part */ public Complex(double real, double imaginary) { this.real = real; this.imaginary = imaginary; } /** * Zero as a complex number, i.e., a number representing "0.0 + 0.0i". */ public static final Complex ZERO = new Complex(0, 0); /** * One as a complex number, i.e., a number representing "1.0 + 0.0i". */ public static final Complex ONE = new Complex(1, 0); /** * The square root of -1, i.e., a number representing "0.0 + 1.0i". */ public static final Complex I = new Complex(0, 1); /** * Returns the real part of this complex number. * * @return the real part of this complex number */ public double getReal() { return real; } /** * Returns the imaginary part of this complex number. * * @return the imaginary part of this complex number */ public double getImaginary() { return imaginary; } /** * Returns a complex number, whose multiplication corresponds to a rotation by the given angle in the complex plane. * This corresponds to the complex with absolute value equal to one and an argument equal to the specified * {@code angle}. * * @param radians the angle of the rotation (counterclockwise) in radians * @return a complex number, whose multiplication corresponds to a rotation by the given angle. */ public static Complex rotation(double radians) { return new Complex(Math.cos(radians), Math.sin(radians)); } /** * Creates a complex number with the specified real part and an imaginary part equal to zero. * * @param real the real component * @return the complex {@code real + 0i} */ public static Complex real(double real) { return new Complex(real, 0); } /** * Returns a {@code Complex} whose value is {@code (this + addend)}. * * @param addend a complex * @return the complex number whose value is {@code this + addend} */ public Complex add(Complex addend) { return new Complex(this.real + addend.real, this.imaginary + addend.imaginary); } /** * Returns the negation of this complex number. * * @return A complex <code>c</code> such that <code>this + c = 0</code> */ public Complex negate() { return new Complex(-this.real, -this.imaginary); } /** * Returns the conjugate of this complex number. * * @return A complex <code>c</code> such that <code>this * c = ||this|| ** 2</code> */ public Complex conjugate() { return new Complex(this.real, -this.imaginary); } /** * Returns a {@code Complex} whose value is {@code (this - subtrahend)}. * * @param subtrahend the complex to be subtracted from {@code this} * @return the complex number {@code (this - subtrahend)} */ public Complex subtract(Complex subtrahend) { return new Complex(this.real - subtrahend.real, this.imaginary - subtrahend.imaginary); } /** * Returns a {@code Complex} whose value is {@code this * factor} * * @param factor the complex number to multiply to {@code this} * @return the complex number {@code this * factor} */ public Complex multiply(Complex factor) { return new Complex( this.real * factor.real - this.imaginary * factor.imaginary, this.real * factor.imaginary + this.imaginary * factor.real); } /** * Returns the squared modulus of this complex number. * * @return <code>||this|| ** 2</code> */ public double squaredModulus() { return real * real + imaginary * imaginary; } /** * Returns the modulus (distance to zero) of this complex number. * * @return <code>||this||</code> */ public double modulus() { return Math.sqrt(squaredModulus()); } /** * Returns the reciprocal of this complex number. * * @return a complex number <code>c</code> such that <code>this * c = 1</code> */ public Complex reciprocal() { if (this.equals(ZERO)){ throw new ArithmeticException("divide by zero"); } double m = squaredModulus(); return this.conjugate().scale(1. / m); } /** * Returns a {@code Complex} whose value is <code>this / divisor</code>. * * @param divisor the denominator (a complex number) * @return the complex number <code>this / divisor</code> */ public Complex divide(Complex divisor) { return this.multiply(divisor.reciprocal()); } /** * Returns the integral power of this complex number. * * @param p a non-negative integer * @return the complex number <code>this ** p</code> */ public Complex pow(int p) { if (p == 0) return ONE; Complex result = (this.multiply(this)).pow(p / 2); if (p % 2 == 1) result = result.multiply(this); return result; } /** * Returns the scalar multiplication of this complex number. * * @param lambda a scalar number * @return the complex number <code>lambda * this</code> */ public Complex scale(double lambda) { return new Complex(lambda * real, lambda * imaginary); } /** * Test for equality with another object. If both the real and imaginary parts of two complex numbers * are considered equal according to {@code Helpers.doubleCompare} (i.e., within {@code Helpers.RANGE}), the two * Complex objects are considered to be equal. * * @param other Object to test for equality with this instance. * @return {@code true} if the objects are equal, {@code false} if object is {@code null}, not an instance of * {@code Complex}, or not equal to this instance. */ @Override public boolean equals(Object other) { if (this == other) return true; if (!(other instanceof Complex)) return false; Complex complex = (Complex) other; return Helpers.doubleCompare(complex.real, real) == 0 && Helpers.doubleCompare(complex.imaginary, imaginary) == 0; } /** * Returns a string representation of this complex number. * * @return a string representation of this complex number of the form 42.0 - 1024.0i. */ @Override public String toString() { if (Helpers.doubleCompare(imaginary, 0) == 0) return real + ""; if (Helpers.doubleCompare(real, 0) == 0) return imaginary + "i"; if (Helpers.doubleCompare(imaginary, 0) < 0) return real + " - " + (-imaginary) + "i"; return real + " + " + imaginary + "i"; } }