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