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