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