/*
 * $Id$
 */

package edu.jas.root;


// import edu.jas.structure.RingElem;
import edu.jas.arith.BigDecimal;
import edu.jas.arith.BigRational;
import edu.jas.arith.Rational;
import edu.jas.kern.PrettyPrint;
import edu.jas.poly.AlgebraicNumber;
import edu.jas.poly.Complex;
import edu.jas.poly.ComplexRing;
import edu.jas.poly.GenPolynomial;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.NotInvertibleException;


/**
 * Complex algebraic number class based on AlgebraicNumber. Objects of this
 * class are immutable.
 * @author Heinz Kredel
 */

public class ComplexAlgebraicNumber & Rational>
/*extends AlgebraicNumber*/
implements GcdRingElem> {


    /**
     * Representing AlgebraicNumber.
     */
    public final AlgebraicNumber> number;


    /**
     * Ring part of the data structure.
     */
    public final ComplexAlgebraicRing ring;


    /**
     * The constructor creates a ComplexAlgebraicNumber object from
     * ComplexAlgebraicRing modul and a GenPolynomial value.
     * @param r ring ComplexAlgebraicRing.
     * @param a value GenPolynomial.
     */
    public ComplexAlgebraicNumber(ComplexAlgebraicRing r, GenPolynomial> a) {
        number = new AlgebraicNumber>(r.algebraic, a);
        ring = r;
    }


    /**
     * The constructor creates a ComplexAlgebraicNumber object from
     * ComplexAlgebraicRing modul and a AlgebraicNumber value.
     * @param r ring ComplexAlgebraicRing.
     * @param a value AlgebraicNumber.
     */
    public ComplexAlgebraicNumber(ComplexAlgebraicRing r, AlgebraicNumber> a) {
        number = a;
        ring = r;
    }


    /**
     * The constructor creates a ComplexAlgebraicNumber object from a
     * GenPolynomial object module.
     * @param r ring ComplexAlgebraicRing.
     */
    public ComplexAlgebraicNumber(ComplexAlgebraicRing r) {
        this(r, r.algebraic.getZERO());
    }


    /**
     * Get the corresponding element factory.
     * @return factory for this Element.
     * @see edu.jas.structure.Element#factory()
     */
    public ComplexAlgebraicRing factory() {
        return ring;
    }


    /**
     * Clone this.
     * @see java.lang.Object#clone()
     */
    @Override
    public ComplexAlgebraicNumber copy() {
        return new ComplexAlgebraicNumber(ring, number);
    }


    /**
     * Is ComplexAlgebraicNumber zero.
     * @return If this is 0 then true is returned, else false.
     * @see edu.jas.structure.RingElem#isZERO()
     */
    public boolean isZERO() {
        return number.isZERO();
    }


    /**
     * Is ComplexAlgebraicNumber one.
     * @return If this is 1 then true is returned, else false.
     * @see edu.jas.structure.RingElem#isONE()
     */
    public boolean isONE() {
        return number.isONE();
    }


    /**
     * Is ComplexAlgebraicNumber unit.
     * @return If this is a unit then true is returned, else false.
     * @see edu.jas.structure.RingElem#isUnit()
     */
    public boolean isUnit() {
        return number.isUnit();
    }


    /**
     * Get the String representation as RingElem.
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        if (PrettyPrint.isTrue()) {
            return "{ " + number.toString() + " }";
        }
        return "Complex" + number.toString();
    }


    /**
     * Get a scripting compatible string representation.
     * @return script compatible representation for this Element.
     * @see edu.jas.structure.Element#toScript()
     */
    @Override
    public String toScript() {
        // Python case
        return number.toScript();
    }


    /**
     * Get a scripting compatible string representation of the factory.
     * @return script compatible representation for this ElemFactory.
     * @see edu.jas.structure.Element#toScriptFactory()
     */
    @Override
    public String toScriptFactory() {
        // Python case
        return factory().toScript();
    }


    /**
     * ComplexAlgebraicNumber comparison.
     * @param b ComplexAlgebraicNumber.
     * @return sign(this-b).
     */
    @Override
    public int compareTo(ComplexAlgebraicNumber b) {
        int s = 0;
        if (number.ring != b.number.ring) { // avoid compareTo if possible
            s = number.ring.modul.compareTo(b.number.ring.modul);
            System.out.println("s_mod = " + s);
        }
        if (s != 0) {
            return s;
        }
        s = number.compareTo(b.number); // TODO
        //System.out.println("s_real = " + s);
        return s;
    }


    /**
     * ComplexAlgebraicNumber comparison.
     * @param b AlgebraicNumber.
     * @return polynomial sign(this-b).
     */
    public int compareTo(AlgebraicNumber> b) {
        int s = number.compareTo(b);
        //System.out.println("s_algeb = " + s);
        return s;
    }


    /**
     * Comparison with any other object.
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    @SuppressWarnings("unchecked")
    public boolean equals(Object b) {
        if (!(b instanceof ComplexAlgebraicNumber)) {
            return false;
        }
        ComplexAlgebraicNumber a = null;
        try {
            a = (ComplexAlgebraicNumber) b;
        } catch (ClassCastException e) {
        }
        if (a == null) {
            return false;
        }
        if (!ring.equals(a.ring)) {
            return false;
        }
        return number.equals(a.number);
    }


    /**
     * Hash code for this ComplexAlgebraicNumber.
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        return 37 * number.val.hashCode() + ring.hashCode();
    }


    /**
     * ComplexAlgebraicNumber absolute value.
     * @return the absolute value of this.
     * @see edu.jas.structure.RingElem#abs()
     */
    public ComplexAlgebraicNumber abs() {
        if (this.signum() < 0) {
            return new ComplexAlgebraicNumber(ring, number.negate());
        }
        return this;
    }


    /**
     * ComplexAlgebraicNumber summation.
     * @param S ComplexAlgebraicNumber.
     * @return this+S.
     */
    public ComplexAlgebraicNumber sum(ComplexAlgebraicNumber S) {
        return new ComplexAlgebraicNumber(ring, number.sum(S.number));
    }


    /**
     * ComplexAlgebraicNumber summation.
     * @param c complex polynomial.
     * @return this+c.
     */
    public ComplexAlgebraicNumber sum(GenPolynomial> c) {
        return new ComplexAlgebraicNumber(ring, number.sum(c));
    }


    /**
     * ComplexAlgebraicNumber summation.
     * @param c algebraic number.
     * @return this+c.
     */
    public ComplexAlgebraicNumber sum(AlgebraicNumber> c) {
        return new ComplexAlgebraicNumber(ring, number.sum(c));
    }


    /**
     * ComplexAlgebraicNumber summation.
     * @param c coefficient.
     * @return this+c.
     */
    public ComplexAlgebraicNumber sum(Complex c) {
        return new ComplexAlgebraicNumber(ring, number.sum(c));
    }


    /**
     * ComplexAlgebraicNumber negate.
     * @return -this.
     * @see edu.jas.structure.RingElem#negate()
     */
    public ComplexAlgebraicNumber negate() {
        return new ComplexAlgebraicNumber(ring, number.negate());
    }


    /**
     * ComplexAlgebraicNumber subtraction.
     * @param S ComplexAlgebraicNumber.
     * @return this-S.
     */
    public ComplexAlgebraicNumber subtract(ComplexAlgebraicNumber S) {
        return new ComplexAlgebraicNumber(ring, number.subtract(S.number));
    }


    /**
     * ComplexAlgebraicNumber division.
     * @param S ComplexAlgebraicNumber.
     * @return this/S.
     */
    public ComplexAlgebraicNumber divide(ComplexAlgebraicNumber S) {
        return multiply(S.inverse());
    }


    /**
     * ComplexAlgebraicNumber inverse.
     * @see edu.jas.structure.RingElem#inverse()
     * @throws NotInvertibleException if the element is not invertible.
     * @return S with S = 1/this if defined.
     */
    public ComplexAlgebraicNumber inverse() {
        return new ComplexAlgebraicNumber(ring, number.inverse());
    }


    /**
     * ComplexAlgebraicNumber remainder.
     * @param S ComplexAlgebraicNumber.
     * @return this - (this/S)*S.
     */
    public ComplexAlgebraicNumber remainder(ComplexAlgebraicNumber S) {
        return new ComplexAlgebraicNumber(ring, number.remainder(S.number));
    }


    /**
     * Quotient and remainder by division of this by S.
     * @param S a ComplexAlgebraicNumber
     * @return [this/S, this - (this/S)*S].
     */
    public ComplexAlgebraicNumber[] quotientRemainder(ComplexAlgebraicNumber S) {
        return new ComplexAlgebraicNumber[] { divide(S), remainder(S) };
    }


    /**
     * ComplexAlgebraicNumber multiplication.
     * @param S ComplexAlgebraicNumber.
     * @return this*S.
     */
    public ComplexAlgebraicNumber multiply(ComplexAlgebraicNumber S) {
        return new ComplexAlgebraicNumber(ring, number.multiply(S.number));
    }


    /**
     * ComplexAlgebraicNumber multiplication.
     * @param c coefficient.
     * @return this*c.
     */
    public ComplexAlgebraicNumber multiply(Complex c) {
        return new ComplexAlgebraicNumber(ring, number.multiply(c));
    }


    /**
     * ComplexAlgebraicNumber multiplication.
     * @param c polynomial.
     * @return this*c.
     */
    public ComplexAlgebraicNumber multiply(GenPolynomial> c) {
        return new ComplexAlgebraicNumber(ring, number.multiply(c));
    }


    /**
     * ComplexAlgebraicNumber monic.
     * @return this with monic value part.
     */
    public ComplexAlgebraicNumber monic() {
        return new ComplexAlgebraicNumber(ring, number.monic());
    }


    /**
     * ComplexAlgebraicNumber greatest common divisor.
     * @param S ComplexAlgebraicNumber.
     * @return gcd(this,S).
     */
    public ComplexAlgebraicNumber gcd(ComplexAlgebraicNumber S) {
        return new ComplexAlgebraicNumber(ring, number.gcd(S.number));
    }


    /**
     * ComplexAlgebraicNumber extended greatest common divisor.
     * @param S ComplexAlgebraicNumber.
     * @return [ gcd(this,S), a, b ] with a*this + b*S = gcd(this,S).
     */
    @SuppressWarnings("unchecked")
    public ComplexAlgebraicNumber[] egcd(ComplexAlgebraicNumber S) {
        AlgebraicNumber>[] aret = number.egcd(S.number);
        ComplexAlgebraicNumber[] ret = new ComplexAlgebraicNumber[3];
        ret[0] = new ComplexAlgebraicNumber(ring, aret[0]);
        ret[1] = new ComplexAlgebraicNumber(ring, aret[1]);
        ret[2] = new ComplexAlgebraicNumber(ring, aret[2]);
        return ret;
    }


    /**
     * ComplexAlgebraicNumber signum.
     * @see edu.jas.structure.RingElem#signum()
     * @return signum(this).
     */
    public int signum() {
        try {
            Rectangle v = ring.engine.invariantRectangle(ring.root, ring.algebraic.modul, number.val);
            ring.setRoot(v);
            Complex c = v.getCenter();
            return c.signum();
        } catch (InvalidBoundaryException e) { // should not happen
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }


    /**
     * ComplexAlgebraicNumber magnitude.
     * @return |this| as complex rational number.
     */
    public Complex magnitude() {
        try {
            Rectangle v = ring.engine.invariantMagnitudeRectangle(ring.root, ring.algebraic.modul,
                            number.val, ring.getEps());
            ring.setRoot(v);
            //System.out.println("new v = " + v);
            Complex ev = ring.engine.complexRectangleMagnitude(v, ring.algebraic.modul, number.val); //, ring.eps);
            //C re = ev.getRe();
            //if ( (Object) re instanceof Rational) { // true by type parameter
            BigRational er = ev.getRe().getRational();
            BigRational ei = ev.getIm().getRational();
            ComplexRing cr = new ComplexRing(er.factory());
            return new Complex(cr, er, ei);
            //} else {
            //    throw new RuntimeException("Rational expected, but was " + ev.getClass());
            //}
        } catch (InvalidBoundaryException e) { // should not happen
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }


    /**
     * ComplexAlgebraicNumber magnitude.
     * @return |this| as complex big decimal.
     */
    public Complex decimalMagnitude() {
        Complex cr = magnitude();
        ComplexRing dr = new ComplexRing(BigDecimal.ZERO);
        return new Complex(dr, new BigDecimal(cr.getRe()), new BigDecimal(cr.getIm()));
    }

}

 

Ads help maintain this website.