package math.number;


/**
 * A complex number with arbitrary precision rational components.
 * @author Daniel Weschke
 */
public class RationalComplex{
    private final BigRational re;
    private final BigRational im;

    /**
     * create a new object with the given real and imaginary parts
     * @param real
     * @param imag
     */
    public RationalComplex(BigRational real, BigRational imag){
        re = real;
        im = imag;
    }

    /**
     * add a complex number
     * @param b complex number
     * @return added complex number
     */
    public RationalComplex plus(RationalComplex b){
        RationalComplex a = this;
        BigRational real = a.re.plus(b.re);
        BigRational imag = a.im.plus(b.im);
        return new RationalComplex(real, imag);
    }

    /**
     * subtract a complex number
     * @param b complex number to subtract
     * @return subtracted complex number
     */
    public RationalComplex minus(RationalComplex b) {
        RationalComplex a = this;
        BigRational real = a.re.minus(b.re);
        BigRational imag = a.im.minus(b.im);
        return new RationalComplex(real, imag);
    }

    /**
     * @param b 
     * @return a new Complex object whose value is (this * b)
     */
    public RationalComplex times(RationalComplex b) {
        RationalComplex a = this;
        BigRational real = (a.re.times(b.re)).minus(a.im.times(b.im));
        BigRational imag = (a.re.times(b.im)).plus(a.im.times(b.re));
        return new RationalComplex(real, imag);
    }

    /**
     * @return square of 2 norm
     */
    public BigRational normSquared(){
        return re.times(re).plus(im.times(im));
    }

    /**
     * return a string representation of the invoking Complex object
     */
    @Override
	public String toString(){
        if (im.equals(BigRational.ZERO)) return re + "";
        if (re.equals(BigRational.ZERO)) return im + "i";
        if (im.isNegative()) return re + " - " + (im.negate()) + "i";
        return re + " + " + im + "i";
    }


    /**
     * test client
     * @param args
     */
    public static void main(String[] args) {
        BigRational a1 = new BigRational(5, 1);
        BigRational a2 = new BigRational(6, 1);
        BigRational b1 = new BigRational(-1, 3);
        BigRational b2 = new BigRational(2, 7);
        RationalComplex a = new RationalComplex(a1, a2);
        RationalComplex b = new RationalComplex(b1, b2);

        System.out.println("a      = " + a);
        System.out.println("b      = " + b);
        System.out.println("b + a  = " + b.plus(a));
        System.out.println("a - b  = " + a.minus(b));
        System.out.println("a * b  = " + a.times(b));
        System.out.println("b * a  = " + b.times(a));
    }
}