001/*
002 * $Id$
003 */
004
005package edu.jas.root;
006
007
008import edu.jas.arith.BigDecimal;
009import edu.jas.arith.BigRational;
010import edu.jas.arith.Rational;
011import edu.jas.kern.PrettyPrint;
012import edu.jas.poly.AlgebraicNumber;
013import edu.jas.poly.Complex;
014import edu.jas.poly.ComplexRing;
015import edu.jas.poly.GenPolynomial;
016import edu.jas.structure.GcdRingElem;
017import edu.jas.structure.NotInvertibleException;
018
019
020/**
021 * Complex algebraic number class based on AlgebraicNumber. Objects of this
022 * class are immutable.
023 * @author Heinz Kredel
024 */
025
026public class ComplexAlgebraicNumber<C extends GcdRingElem<C> & Rational>
027                /*extends AlgebraicNumber<C>*/
028                implements GcdRingElem<ComplexAlgebraicNumber<C>> {
029
030
031    /**
032     * Representing AlgebraicNumber.
033     */
034    public final AlgebraicNumber<Complex<C>> number;
035
036
037    /**
038     * Ring part of the data structure.
039     */
040    public final ComplexAlgebraicRing<C> ring;
041
042
043    /**
044     * The constructor creates a ComplexAlgebraicNumber object from
045     * ComplexAlgebraicRing modul and a GenPolynomial value.
046     * @param r ring ComplexAlgebraicRing<C>.
047     * @param a value GenPolynomial<C>.
048     */
049    public ComplexAlgebraicNumber(ComplexAlgebraicRing<C> r, GenPolynomial<Complex<C>> a) {
050        number = new AlgebraicNumber<Complex<C>>(r.algebraic, a);
051        ring = r;
052    }
053
054
055    /**
056     * The constructor creates a ComplexAlgebraicNumber object from
057     * ComplexAlgebraicRing modul and a AlgebraicNumber value.
058     * @param r ring ComplexAlgebraicRing<C>.
059     * @param a value AlgebraicNumber<C>.
060     */
061    public ComplexAlgebraicNumber(ComplexAlgebraicRing<C> r, AlgebraicNumber<Complex<C>> a) {
062        number = a;
063        ring = r;
064    }
065
066
067    /**
068     * The constructor creates a ComplexAlgebraicNumber object from a
069     * GenPolynomial object module.
070     * @param r ring ComplexAlgebraicRing<C>.
071     */
072    public ComplexAlgebraicNumber(ComplexAlgebraicRing<C> r) {
073        this(r, r.algebraic.getZERO());
074    }
075
076
077    /**
078     * Get the corresponding element factory.
079     * @return factory for this Element.
080     * @see edu.jas.structure.Element#factory()
081     */
082    public ComplexAlgebraicRing<C> factory() {
083        return ring;
084    }
085
086
087    /**
088     * Copy this.
089     * @see edu.jas.structure.Element#copy()
090     */
091    @Override
092    public ComplexAlgebraicNumber<C> copy() {
093        return new ComplexAlgebraicNumber<C>(ring, number);
094    }
095
096
097    /**
098     * Is ComplexAlgebraicNumber zero.
099     * @return If this is 0 then true is returned, else false.
100     * @see edu.jas.structure.RingElem#isZERO()
101     */
102    public boolean isZERO() {
103        return number.isZERO();
104    }
105
106
107    /**
108     * Is ComplexAlgebraicNumber one.
109     * @return If this is 1 then true is returned, else false.
110     * @see edu.jas.structure.RingElem#isONE()
111     */
112    public boolean isONE() {
113        return number.isONE();
114    }
115
116
117    /**
118     * Is ComplexAlgebraicNumber unit.
119     * @return If this is a unit then true is returned, else false.
120     * @see edu.jas.structure.RingElem#isUnit()
121     */
122    public boolean isUnit() {
123        return number.isUnit();
124    }
125
126
127    /**
128     * Is ComplexAlgebraicNumber a root of unity.
129     * @return true if |this**i| == 1, for some 0 &lt; i &le; deg(modul), else
130     *         false.
131     */
132    public boolean isRootOfUnity() {
133        return number.isRootOfUnity();
134    }
135
136
137    /**
138     * Get the String representation as RingElem.
139     * @see java.lang.Object#toString()
140     */
141    @Override
142    public String toString() {
143        if (PrettyPrint.isTrue()) {
144            return "{ " + number.toString() + " }";
145        }
146        return "Complex" + number.toString();
147    }
148
149
150    /**
151     * Get a scripting compatible string representation.
152     * @return script compatible representation for this Element.
153     * @see edu.jas.structure.Element#toScript()
154     */
155    @Override
156    public String toScript() {
157        // Python case
158        return number.toScript();
159    }
160
161
162    /**
163     * Get a scripting compatible string representation of the factory.
164     * @return script compatible representation for this ElemFactory.
165     * @see edu.jas.structure.Element#toScriptFactory()
166     */
167    @Override
168    public String toScriptFactory() {
169        // Python case
170        return factory().toScript();
171    }
172
173
174    /**
175     * ComplexAlgebraicNumber comparison.
176     * @param b ComplexAlgebraicNumber.
177     * @return sign(this-b).
178     */
179    @Override
180    public int compareTo(ComplexAlgebraicNumber<C> b) {
181        int s = 0;
182        if (number.ring != b.number.ring) { // avoid compareTo if possible
183            s = number.ring.modul.compareTo(b.number.ring.modul);
184            System.out.println("s_mod = " + s);
185        }
186        if (s != 0) {
187            return s;
188        }
189        s = number.compareTo(b.number); // TODO
190        //System.out.println("s_real = " + s);
191        return s;
192    }
193
194
195    /**
196     * ComplexAlgebraicNumber comparison.
197     * @param b AlgebraicNumber.
198     * @return polynomial sign(this-b).
199     */
200    public int compareTo(AlgebraicNumber<Complex<C>> b) {
201        int s = number.compareTo(b);
202        //System.out.println("s_algeb = " + s);
203        return s;
204    }
205
206
207    /**
208     * Comparison with any other object.
209     * @see java.lang.Object#equals(java.lang.Object)
210     */
211    @Override
212    @SuppressWarnings("unchecked")
213    public boolean equals(Object b) {
214        if (b == null) {
215            return false;
216        }
217        if (!(b instanceof ComplexAlgebraicNumber)) {
218            return false;
219        }
220        ComplexAlgebraicNumber<C> a = (ComplexAlgebraicNumber<C>) b;
221        if (!ring.equals(a.ring)) {
222            return false;
223        }
224        return number.equals(a.number);
225    }
226
227
228    /**
229     * Hash code for this ComplexAlgebraicNumber.
230     * @see java.lang.Object#hashCode()
231     */
232    @Override
233    public int hashCode() {
234        return 37 * number.val.hashCode() + ring.hashCode();
235    }
236
237
238    /**
239     * ComplexAlgebraicNumber absolute value.
240     * @return the absolute value of this.
241     * @see edu.jas.structure.RingElem#abs()
242     */
243    public ComplexAlgebraicNumber<C> abs() {
244        if (this.signum() < 0) {
245            return new ComplexAlgebraicNumber<C>(ring, number.negate());
246        }
247        return this;
248    }
249
250
251    /**
252     * ComplexAlgebraicNumber summation.
253     * @param S ComplexAlgebraicNumber.
254     * @return this+S.
255     */
256    public ComplexAlgebraicNumber<C> sum(ComplexAlgebraicNumber<C> S) {
257        return new ComplexAlgebraicNumber<C>(ring, number.sum(S.number));
258    }
259
260
261    /**
262     * ComplexAlgebraicNumber summation.
263     * @param c complex polynomial.
264     * @return this+c.
265     */
266    public ComplexAlgebraicNumber<C> sum(GenPolynomial<Complex<C>> c) {
267        return new ComplexAlgebraicNumber<C>(ring, number.sum(c));
268    }
269
270
271    /**
272     * ComplexAlgebraicNumber summation.
273     * @param c algebraic number.
274     * @return this+c.
275     */
276    public ComplexAlgebraicNumber<C> sum(AlgebraicNumber<Complex<C>> c) {
277        return new ComplexAlgebraicNumber<C>(ring, number.sum(c));
278    }
279
280
281    /**
282     * ComplexAlgebraicNumber summation.
283     * @param c coefficient.
284     * @return this+c.
285     */
286    public ComplexAlgebraicNumber<C> sum(Complex<C> c) {
287        return new ComplexAlgebraicNumber<C>(ring, number.sum(c));
288    }
289
290
291    /**
292     * ComplexAlgebraicNumber negate.
293     * @return -this.
294     * @see edu.jas.structure.RingElem#negate()
295     */
296    public ComplexAlgebraicNumber<C> negate() {
297        return new ComplexAlgebraicNumber<C>(ring, number.negate());
298    }
299
300
301    /**
302     * ComplexAlgebraicNumber subtraction.
303     * @param S ComplexAlgebraicNumber.
304     * @return this-S.
305     */
306    public ComplexAlgebraicNumber<C> subtract(ComplexAlgebraicNumber<C> S) {
307        return new ComplexAlgebraicNumber<C>(ring, number.subtract(S.number));
308    }
309
310
311    /**
312     * ComplexAlgebraicNumber division.
313     * @param S ComplexAlgebraicNumber.
314     * @return this/S.
315     */
316    public ComplexAlgebraicNumber<C> divide(ComplexAlgebraicNumber<C> S) {
317        return multiply(S.inverse());
318    }
319
320
321    /**
322     * ComplexAlgebraicNumber inverse.
323     * @see edu.jas.structure.RingElem#inverse()
324     * @throws NotInvertibleException if the element is not invertible.
325     * @return S with S = 1/this if defined.
326     */
327    public ComplexAlgebraicNumber<C> inverse() {
328        return new ComplexAlgebraicNumber<C>(ring, number.inverse());
329    }
330
331
332    /**
333     * ComplexAlgebraicNumber remainder.
334     * @param S ComplexAlgebraicNumber.
335     * @return this - (this/S)*S.
336     */
337    public ComplexAlgebraicNumber<C> remainder(ComplexAlgebraicNumber<C> S) {
338        return new ComplexAlgebraicNumber<C>(ring, number.remainder(S.number));
339    }
340
341
342    /**
343     * Quotient and remainder by division of this by S.
344     * @param S a ComplexAlgebraicNumber
345     * @return [this/S, this - (this/S)*S].
346     */
347    @SuppressWarnings("unchecked")
348    public ComplexAlgebraicNumber<C>[] quotientRemainder(ComplexAlgebraicNumber<C> S) {
349        return new ComplexAlgebraicNumber[] { divide(S), remainder(S) };
350    }
351
352
353    /**
354     * ComplexAlgebraicNumber multiplication.
355     * @param S ComplexAlgebraicNumber.
356     * @return this*S.
357     */
358    public ComplexAlgebraicNumber<C> multiply(ComplexAlgebraicNumber<C> S) {
359        return new ComplexAlgebraicNumber<C>(ring, number.multiply(S.number));
360    }
361
362
363    /**
364     * ComplexAlgebraicNumber multiplication.
365     * @param c coefficient.
366     * @return this*c.
367     */
368    public ComplexAlgebraicNumber<C> multiply(Complex<C> c) {
369        return new ComplexAlgebraicNumber<C>(ring, number.multiply(c));
370    }
371
372
373    /**
374     * ComplexAlgebraicNumber multiplication.
375     * @param c polynomial.
376     * @return this*c.
377     */
378    public ComplexAlgebraicNumber<C> multiply(GenPolynomial<Complex<C>> c) {
379        return new ComplexAlgebraicNumber<C>(ring, number.multiply(c));
380    }
381
382
383    /**
384     * ComplexAlgebraicNumber monic.
385     * @return this with monic value part.
386     */
387    public ComplexAlgebraicNumber<C> monic() {
388        return new ComplexAlgebraicNumber<C>(ring, number.monic());
389    }
390
391
392    /**
393     * ComplexAlgebraicNumber greatest common divisor.
394     * @param S ComplexAlgebraicNumber.
395     * @return gcd(this,S).
396     */
397    public ComplexAlgebraicNumber<C> gcd(ComplexAlgebraicNumber<C> S) {
398        return new ComplexAlgebraicNumber<C>(ring, number.gcd(S.number));
399    }
400
401
402    /**
403     * ComplexAlgebraicNumber extended greatest common divisor.
404     * @param S ComplexAlgebraicNumber.
405     * @return [ gcd(this,S), a, b ] with a*this + b*S = gcd(this,S).
406     */
407    @SuppressWarnings("unchecked")
408    public ComplexAlgebraicNumber<C>[] egcd(ComplexAlgebraicNumber<C> S) {
409        AlgebraicNumber<Complex<C>>[] aret = number.egcd(S.number);
410        ComplexAlgebraicNumber<C>[] ret = new ComplexAlgebraicNumber[3];
411        ret[0] = new ComplexAlgebraicNumber<C>(ring, aret[0]);
412        ret[1] = new ComplexAlgebraicNumber<C>(ring, aret[1]);
413        ret[2] = new ComplexAlgebraicNumber<C>(ring, aret[2]);
414        return ret;
415    }
416
417
418    /**
419     * ComplexAlgebraicNumber signum.
420     * @see edu.jas.structure.RingElem#signum()
421     * @return signum(this).
422     */
423    public int signum() {
424        ring.ensureEngine();
425        try {
426            Rectangle<C> v = ring.engine.invariantRectangle(ring.root, ring.algebraic.modul, number.val);
427            ring.setRoot(v);
428            Complex<C> c = v.getCenter();
429            return c.signum();
430        } catch (InvalidBoundaryException e) { // should not happen
431            e.printStackTrace();
432            throw new RuntimeException(e);
433        }
434    }
435
436
437    /**
438     * ComplexAlgebraicNumber magnitude.
439     * @return |this| as complex rational number.
440     */
441    public Complex<BigRational> magnitude() {
442        ring.ensureEngine();
443        try {
444            Rectangle<C> v = ring.engine.invariantMagnitudeRectangle(ring.root, ring.algebraic.modul,
445                            number.val, ring.getEps());
446            ring.setRoot(v);
447            //System.out.println("new v = " + v);
448            Complex<C> ev = ring.engine.complexRectangleMagnitude(v, ring.algebraic.modul, number.val); //, ring.eps);
449            BigRational er = ev.getRe().getRational();
450            BigRational ei = ev.getIm().getRational();
451            ComplexRing<BigRational> cr = new ComplexRing<BigRational>(er.factory());
452            return new Complex<BigRational>(cr, er, ei);
453        } catch (InvalidBoundaryException e) { // should not happen
454            e.printStackTrace();
455            throw new RuntimeException(e);
456        }
457    }
458
459
460    /**
461     * ComplexAlgebraicNumber magnitude.
462     * @return |this| as complex big decimal.
463     */
464    public Complex<BigDecimal> decimalMagnitude() {
465        Complex<BigRational> cr = magnitude();
466        ComplexRing<BigDecimal> dr = new ComplexRing<BigDecimal>(BigDecimal.ZERO);
467        return new Complex<BigDecimal>(dr, new BigDecimal(cr.getRe()), new BigDecimal(cr.getIm()));
468    }
469
470}