001/*
002 * $Id: RealAlgebraicNumber.java 4125 2012-08-19 19:05:22Z kredel $
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()); // todo: 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    //JAVA6only: @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     * Get the String representation as RingElem.
155     * @see java.lang.Object#toString()
156     */
157    @Override
158    public String toString() {
159        if (PrettyPrint.isTrue()) {
160            return "{ " + number.toString() + " }";
161        }
162        return "Complex" + number.toString();
163    }
164
165
166    /**
167     * Get a scripting compatible string representation.
168     * @return script compatible representation for this Element.
169     * @see edu.jas.structure.Element#toScript()
170     */
171    //JAVA6only: @Override
172    public String toScript() {
173        // Python case
174        return number.toScript();
175    }
176
177
178    /**
179     * Get a scripting compatible string representation of the factory.
180     * @return script compatible representation for this ElemFactory.
181     * @see edu.jas.structure.Element#toScriptFactory()
182     */
183    //JAVA6only: @Override
184    public String toScriptFactory() {
185        // Python case
186        return factory().toScript();
187    }
188
189
190    /**
191     * RealAlgebraicNumber comparison.
192     * @param b RealAlgebraicNumber.
193     * @return sign(this-b).
194     */
195    //JAVA6only: @Override
196    public int compareTo(RealAlgebraicNumber<C> b) {
197        int s = 0;
198        if (number.ring != b.number.ring) {
199            s = (number.ring.equals(b.number.ring) ? 0 : 1);
200            System.out.println("s_mod = " + s);
201        }
202        if (s != 0) {
203            return s;
204        }
205        s = number.compareTo(b.number); // TODO
206        //System.out.println("s_real = " + s);
207        return s;
208    }
209
210
211    /**
212     * RealAlgebraicNumber comparison.
213     * @param b AlgebraicNumber.
214     * @return polynomial sign(this-b).
215     */
216    public int compareTo(edu.jas.root.RealAlgebraicNumber<edu.jas.root.RealAlgebraicNumber<C>> b) {
217        int s = number.compareTo(b);
218        //System.out.println("s_algeb = " + s);
219        return s;
220    }
221
222
223    /**
224     * Comparison with any other object.
225     * @see java.lang.Object#equals(java.lang.Object)
226     */
227    @Override
228    @SuppressWarnings("unchecked")
229    public boolean equals(Object b) {
230        if (!(b instanceof RealAlgebraicNumber)) {
231            return false;
232        }
233        RealAlgebraicNumber<C> a = null;
234        try {
235            a = (RealAlgebraicNumber<C>) b;
236        } catch (ClassCastException e) {
237        }
238        if (a == null) {
239            return false;
240        }
241        if (!ring.equals(a.ring)) {
242            return false;
243        }
244        return number.equals(a.number);
245    }
246
247
248    /**
249     * Hash code for this RealAlgebraicNumber.
250     * @see java.lang.Object#hashCode()
251     */
252    @Override
253    public int hashCode() {
254        return 37 * number.hashCode() + ring.hashCode();
255    }
256
257
258    /**
259     * RealAlgebraicNumber absolute value.
260     * @return the absolute value of this.
261     * @see edu.jas.structure.RingElem#abs()
262     */
263    public RealAlgebraicNumber<C> abs() {
264        if (this.signum() < 0) {
265            return new RealAlgebraicNumber<C>(ring, number.negate());
266        }
267        return this;
268    }
269
270
271    /**
272     * RealAlgebraicNumber summation.
273     * @param S RealAlgebraicNumber.
274     * @return this+S.
275     */
276    public RealAlgebraicNumber<C> sum(RealAlgebraicNumber<C> S) {
277        return new RealAlgebraicNumber<C>(ring, number.sum(S.number));
278    }
279
280
281    /**
282     * RealAlgebraicNumber summation.
283     * @param c recursive real algebraic number.
284     * @return this+c.
285     */
286    public RealAlgebraicNumber<C> sum(edu.jas.root.RealAlgebraicNumber<edu.jas.root.RealAlgebraicNumber<C>> c) {
287        return new RealAlgebraicNumber<C>(ring, number.sum(c));
288    }
289
290
291    /**
292     * RealAlgebraicNumber negate.
293     * @return -this.
294     * @see edu.jas.structure.RingElem#negate()
295     */
296    public RealAlgebraicNumber<C> negate() {
297        return new RealAlgebraicNumber<C>(ring, number.negate());
298    }
299
300
301    /**
302     * RealAlgebraicNumber subtraction.
303     * @param S RealAlgebraicNumber.
304     * @return this-S.
305     */
306    public RealAlgebraicNumber<C> subtract(RealAlgebraicNumber<C> S) {
307        return new RealAlgebraicNumber<C>(ring, number.subtract(S.number));
308    }
309
310
311    /**
312     * RealAlgebraicNumber division.
313     * @param S RealAlgebraicNumber.
314     * @return this/S.
315     */
316    public RealAlgebraicNumber<C> divide(RealAlgebraicNumber<C> S) {
317        return multiply(S.inverse());
318    }
319
320
321    /**
322     * RealAlgebraicNumber 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 RealAlgebraicNumber<C> inverse() {
328        return new RealAlgebraicNumber<C>(ring, number.inverse());
329    }
330
331
332    /**
333     * RealAlgebraicNumber remainder.
334     * @param S RealAlgebraicNumber.
335     * @return this - (this/S)*S.
336     */
337    public RealAlgebraicNumber<C> remainder(RealAlgebraicNumber<C> S) {
338        return new RealAlgebraicNumber<C>(ring, number.remainder(S.number));
339    }
340
341
342    /**
343     * RealAlgebraicNumber multiplication.
344     * @param S RealAlgebraicNumber.
345     * @return this*S.
346     */
347    public RealAlgebraicNumber<C> multiply(RealAlgebraicNumber<C> S) {
348        return new RealAlgebraicNumber<C>(ring, number.multiply(S.number));
349    }
350
351
352    /**
353     * RealAlgebraicNumber multiplication.
354     * @param c recursive real algebraic number.
355     * @return this*c.
356     */
357    public RealAlgebraicNumber<C> multiply(
358                    edu.jas.root.RealAlgebraicNumber<edu.jas.root.RealAlgebraicNumber<C>> c) {
359        return new RealAlgebraicNumber<C>(ring, number.multiply(c));
360    }
361
362
363    /**
364     * RealAlgebraicNumber monic.
365     * @return this with monic value part.
366     */
367    public RealAlgebraicNumber<C> monic() {
368        return new RealAlgebraicNumber<C>(ring, number.monic());
369    }
370
371
372    /**
373     * RealAlgebraicNumber greatest common divisor.
374     * @param S RealAlgebraicNumber.
375     * @return gcd(this,S).
376     */
377    public RealAlgebraicNumber<C> gcd(RealAlgebraicNumber<C> S) {
378        return new RealAlgebraicNumber<C>(ring, number.gcd(S.number));
379    }
380
381
382    /**
383     * RealAlgebraicNumber extended greatest common divisor.
384     * @param S RealAlgebraicNumber.
385     * @return [ gcd(this,S), a, b ] with a*this + b*S = gcd(this,S).
386     */
387    @SuppressWarnings("unchecked")
388    public RealAlgebraicNumber<C>[] egcd(RealAlgebraicNumber<C> S) {
389        edu.jas.root.RealAlgebraicNumber<edu.jas.root.RealAlgebraicNumber<C>>[] aret = number.egcd(S.number);
390        RealAlgebraicNumber<C>[] ret = new RealAlgebraicNumber[3];
391        ret[0] = new RealAlgebraicNumber<C>(ring, aret[0]);
392        ret[1] = new RealAlgebraicNumber<C>(ring, aret[1]);
393        ret[2] = new RealAlgebraicNumber<C>(ring, aret[2]);
394        return ret;
395    }
396
397
398    /**
399     * RealAlgebraicNumber signum.
400     * @see edu.jas.structure.RingElem#signum()
401     * @return signum(this).
402     */
403    public int signum() {
404        //         if ( number == null ) { // no synchronization required
405        //             GenPolynomial<C> p = number.val;
406        //             number = ring.realRing.parse(p.toString()); // todo: convert
407        //             //System.out.println("number = " + number);
408        //      }
409        return number.signum();
410    }
411
412
413    /**
414     * RealAlgebraicNumber magnitude.
415     * @return |this| as rational number.
416     */
417    public BigRational magnitude() {
418        //         if ( number == null ) { // no synchronization required
419        //             GenPolynomial<C> p = number.val;
420        //             number = ring.realRing.parse(p.toString()); // todo: convert
421        //             //System.out.println("number = " + number);
422        //      }
423        return number.magnitude();
424    }
425
426
427    /**
428     * RealAlgebraicNumber decimal magnitude.
429     * @return |this| as big decimal.
430     */
431    public BigDecimal decimalMagnitude() {
432        BigRational cr = magnitude();
433        return new BigDecimal(cr);
434    }
435
436}