001/*
002 * $Id$
003 */
004
005package edu.jas.root;
006
007
008import java.io.Serializable;
009import java.util.List;
010
011import edu.jas.arith.Rational;
012import edu.jas.poly.AlgebraicNumberRing;
013import edu.jas.poly.GenPolynomial;
014import edu.jas.poly.Complex;
015import edu.jas.structure.GcdRingElem;
016
017
018/**
019 * Container for the real and complex algebraic roots of a univariate
020 * polynomial.
021 * @param <C> coefficient type.
022 * @author Heinz Kredel
023 */
024public class AlgebraicRoots<C extends GcdRingElem<C> & Rational> implements Serializable {
025
026
027    /**
028     * Univariate polynomial.
029     */
030    public final GenPolynomial<C> p;
031
032
033    /**
034     * Real algebraic roots.
035     */
036    public final List<RealAlgebraicNumber<C>> real;
037
038
039    /**
040     * Univariate polynomial with complex coefficients equivalent to p.
041     */
042    public final GenPolynomial<Complex<C>> cp;
043
044
045    /**
046     * Complex algebraic roots.
047     */
048    public final List<ComplexAlgebraicNumber<C>> complex;
049
050
051    /**
052     * Constructor not for use.
053     */
054    protected AlgebraicRoots() {
055        throw new IllegalArgumentException("do not use this constructor");
056    }
057
058
059    /**
060     * Constructor.
061     * @param p univariate polynomial
062     * @param cp univariate polynomial with compelx coefficients
063     * @param r list of real algebraic roots
064     * @param c list of complex algebraic roots
065     */
066    public AlgebraicRoots(GenPolynomial<C> p, GenPolynomial<Complex<C>> cp, List<RealAlgebraicNumber<C>> r,
067                    List<ComplexAlgebraicNumber<C>> c) {
068        this.p = p;
069        this.cp = cp;
070        this.real = r;
071        this.complex = c;
072    }
073
074
075    /**
076     * String representation of AlgebraicRoots.
077     * @see java.lang.Object#toString()
078     */
079    @Override
080    public String toString() {
081        return "[" + p + ", real=" + real + ", complex=" + complex + "]";
082    }
083
084
085    /**
086     * Get a scripting compatible string representation.
087     * @return script compatible representation for this roots.
088     */
089    public String toScript() {
090        // Python case
091        StringBuffer sb = new StringBuffer("[");
092        sb.append(p.toScript());
093        //sb.append(", ");
094        //sb.append(cp.toScript());
095        if (!real.isEmpty()) {
096            sb.append(", real=[");
097            boolean first = true;
098            for (RealAlgebraicNumber<C> r : real) {
099                if (first) {
100                    first = false;
101                } else {
102                    sb.append(", ");
103                }
104                sb.append(r.ring.root.toScript());
105            }
106            sb.append("]");
107        }
108        if (!complex.isEmpty()) {
109            sb.append(", complex=[");
110            boolean first = true;
111            for (ComplexAlgebraicNumber<C> c : complex) {
112                if (first) {
113                    first = false;
114                } else {
115                    sb.append(", ");
116                }
117                sb.append(c.ring.root.toScript());
118            }
119            sb.append("]");
120        }
121        sb.append("]");
122        return sb.toString();
123    }
124
125
126    /**
127     * Get a decimal number scripting compatible string representation.
128     * @return decimal number script compatible representation for this roots.
129     */
130    public String toDecimalScript() {
131        // Python case
132        StringBuffer sb = new StringBuffer("[");
133        sb.append(p.toScript());
134        //sb.append(", ");
135        //sb.append(cp.toScript());
136        if (!real.isEmpty()) {
137            sb.append(", real=[");
138            boolean first = true;
139            for (RealAlgebraicNumber<C> r : real) {
140                if (first) {
141                    first = false;
142                } else {
143                    sb.append(", ");
144                }
145                r.ring.refineRoot();
146                sb.append(r.ring.root.toDecimal().toScript());
147            }
148            sb.append("]");
149        }
150        if (!complex.isEmpty()) {
151            sb.append(", complex=[");
152            boolean first = true;
153            for (ComplexAlgebraicNumber<C> c : complex) {
154                if (first) {
155                    first = false;
156                } else {
157                    sb.append(", ");
158                }
159                c.ring.refineRoot();
160                sb.append(c.ring.root.getDecimalCenter().toScript());
161            }
162            sb.append("]");
163        }
164        sb.append("]");
165        return sb.toString();
166    }
167
168
169    /**
170     * Copy this.
171     * @return a copy of this.
172     */
173    public AlgebraicRoots<C> copy() {
174        return new AlgebraicRoots<C>(p, cp, real, complex);
175    }
176
177
178    /**
179     * Comparison with any other object.
180     * @see java.lang.Object#equals(java.lang.Object)
181     */
182    @Override
183    @SuppressWarnings("unchecked")
184    public boolean equals(Object b) {
185        if (!(b instanceof AlgebraicRoots)) {
186            return false;
187        }
188        AlgebraicRoots<C> a = null;
189        try {
190            a = (AlgebraicRoots<C>) b;
191        } catch (ClassCastException e) {
192            return false;
193        }
194        return p.equals(a.p) && real.equals(a.real) && complex.equals(a.complex);
195    }
196
197
198    /**
199     * Hash code for this AlgebraicRoots.
200     * @see java.lang.Object#hashCode()
201     */
202    @Override
203    public int hashCode() {
204        return (161 * p.hashCode() + 37) * real.hashCode() + complex.hashCode();
205    }
206
207
208    /**
209     * Algebraic number ring.
210     * @return algebraic ring of roots.
211     */
212    public AlgebraicNumberRing<C> getAlgebraicRing() {
213        AlgebraicNumberRing<C> anr = new AlgebraicNumberRing<C>(p);
214        return anr;
215    }
216}