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