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