001/*
002 * $Id: RealAlgebraicNumber.java 4125 2012-08-19 19:05:22Z kredel $
003 */
004
005package edu.jas.root;
006
007
008// import edu.jas.structure.RingElem;
009import edu.jas.arith.BigDecimal;
010import edu.jas.arith.BigRational;
011import edu.jas.arith.Rational;
012import edu.jas.kern.PrettyPrint;
013import edu.jas.poly.AlgebraicNumber;
014import edu.jas.poly.GenPolynomial;
015import edu.jas.structure.GcdRingElem;
016import 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
025public class RealAlgebraicNumber<C extends GcdRingElem<C> & Rational>
026/*extends AlgebraicNumber<C>*/
027implements 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> copy() {
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        }
145        return "Real" + number.toString();
146    }
147
148
149    /**
150     * Get a scripting compatible string representation.
151     * @return script compatible representation for this Element.
152     * @see edu.jas.structure.Element#toScript()
153     */
154    //JAVA6only: @Override
155    public String toScript() {
156        // Python case
157        return number.toScript();
158    }
159
160
161    /**
162     * Get a scripting compatible string representation of the factory.
163     * @return script compatible representation for this ElemFactory.
164     * @see edu.jas.structure.Element#toScriptFactory()
165     */
166    //JAVA6only: @Override
167    public String toScriptFactory() {
168        // Python case
169        return factory().toScript();
170    }
171
172
173    /**
174     * RealAlgebraicNumber comparison.
175     * @param b RealAlgebraicNumber.
176     * @return real sign(this-b).
177     */
178    //JAVA6only: @Override
179    public int compareTo(RealAlgebraicNumber<C> b) {
180        int s = 0;
181        if (number.ring != b.number.ring) { // avoid compareTo if possible
182            s = number.ring.modul.compareTo(b.number.ring.modul);
183            System.out.println("s_mod = " + s);
184        }
185        if (s != 0) {
186            return s;
187        }
188        s = this.subtract(b).signum(); // TODO
189        //System.out.println("s_real = " + s);
190        return s;
191    }
192
193
194    /**
195     * RealAlgebraicNumber comparison.
196     * @param b AlgebraicNumber.
197     * @return polynomial sign(this-b).
198     */
199    public int compareTo(AlgebraicNumber<C> b) {
200        int s = number.compareTo(b);
201        System.out.println("s_algeb = " + s);
202        return s;
203    }
204
205
206    /**
207     * Comparison with any other object.
208     * @see java.lang.Object#equals(java.lang.Object)
209     */
210    @Override
211    @SuppressWarnings("unchecked")
212    public boolean equals(Object b) {
213        if (!(b instanceof RealAlgebraicNumber)) {
214            return false;
215        }
216        RealAlgebraicNumber<C> a = null;
217        try {
218            a = (RealAlgebraicNumber<C>) b;
219        } catch (ClassCastException e) {
220        }
221        if (a == null) {
222            return false;
223        }
224        if (!ring.equals(a.ring)) {
225            return false;
226        }
227        return number.equals(a.number);
228    }
229
230
231    /**
232     * Hash code for this RealAlgebraicNumber.
233     * @see java.lang.Object#hashCode()
234     */
235    @Override
236    public int hashCode() {
237        return 37 * number.val.hashCode() + ring.hashCode();
238    }
239
240
241    /**
242     * RealAlgebraicNumber absolute value.
243     * @return the absolute value of this.
244     * @see edu.jas.structure.RingElem#abs()
245     */
246    public RealAlgebraicNumber<C> abs() {
247        if (this.signum() < 0) {
248            return new RealAlgebraicNumber<C>(ring, number.negate());
249        }
250        return this;
251    }
252
253
254    /**
255     * RealAlgebraicNumber summation.
256     * @param S RealAlgebraicNumber.
257     * @return this+S.
258     */
259    public RealAlgebraicNumber<C> sum(RealAlgebraicNumber<C> S) {
260        return new RealAlgebraicNumber<C>(ring, number.sum(S.number));
261    }
262
263
264    /**
265     * RealAlgebraicNumber summation.
266     * @param c coefficient.
267     * @return this+c.
268     */
269    public RealAlgebraicNumber<C> sum(GenPolynomial<C> c) {
270        return new RealAlgebraicNumber<C>(ring, number.sum(c));
271    }
272
273
274    /**
275     * RealAlgebraicNumber summation.
276     * @param c polynomial.
277     * @return this+c.
278     */
279    public RealAlgebraicNumber<C> sum(C c) {
280        return new RealAlgebraicNumber<C>(ring, number.sum(c));
281    }
282
283
284    /**
285     * RealAlgebraicNumber negate.
286     * @return -this.
287     * @see edu.jas.structure.RingElem#negate()
288     */
289    public RealAlgebraicNumber<C> negate() {
290        return new RealAlgebraicNumber<C>(ring, number.negate());
291    }
292
293
294    /**
295     * RealAlgebraicNumber signum. <b>Note: </b> Modifies ring.root eventually.
296     * @see edu.jas.structure.RingElem#signum()
297     * @return real signum(this).
298     */
299    public int signum() {
300        Interval<C> v = ring.engine.invariantSignInterval(ring.root, ring.algebraic.modul, number.val);
301        ring.setRoot(v);
302        return ring.engine.realIntervalSign(v, ring.algebraic.modul, number.val);
303    }
304
305
306    /**
307     * RealAlgebraicNumber half interval.
308     */
309    public void halfInterval() {
310        Interval<C> v = ring.engine.halfInterval(ring.root, ring.algebraic.modul);
311        //System.out.println("old v = " + ring.root + ", new v = " + v);
312        ring.setRoot(v);
313    }
314
315
316    /**
317     * RealAlgebraicNumber magnitude.
318     * @return |this|.
319     */
320    public BigRational magnitude() {
321        Interval<C> v = ring.engine.invariantMagnitudeInterval(ring.root, ring.algebraic.modul, number.val,
322                        ring.getEps());
323        //System.out.println("old v = " + ring.root + ", new v = " + v);
324        ring.setRoot(v);
325        C ev = ring.engine.realIntervalMagnitude(v, ring.algebraic.modul, number.val); //, ring.eps);
326        //if ((Object) ev instanceof Rational) { // always true by type parameter
327        BigRational er = ev.getRational();
328        return er;
329        //}
330        //throw new RuntimeException("Rational expected, but was " + ev.getClass());
331    }
332
333
334    /**
335     * RealAlgebraicNumber magnitude.
336     * @return |this| as big decimal.
337     */
338    public BigDecimal decimalMagnitude() {
339        return new BigDecimal(magnitude());
340    }
341
342
343    /**
344     * RealAlgebraicNumber subtraction.
345     * @param S RealAlgebraicNumber.
346     * @return this-S.
347     */
348    public RealAlgebraicNumber<C> subtract(RealAlgebraicNumber<C> S) {
349        return new RealAlgebraicNumber<C>(ring, number.subtract(S.number));
350    }
351
352
353    /**
354     * RealAlgebraicNumber division.
355     * @param S RealAlgebraicNumber.
356     * @return this/S.
357     */
358    public RealAlgebraicNumber<C> divide(RealAlgebraicNumber<C> S) {
359        return multiply(S.inverse());
360    }
361
362
363    /**
364     * RealAlgebraicNumber inverse.
365     * @see edu.jas.structure.RingElem#inverse()
366     * @throws NotInvertibleException if the element is not invertible.
367     * @return S with S = 1/this if defined.
368     */
369    public RealAlgebraicNumber<C> inverse() {
370        return new RealAlgebraicNumber<C>(ring, number.inverse());
371    }
372
373
374    /**
375     * RealAlgebraicNumber remainder.
376     * @param S RealAlgebraicNumber.
377     * @return this - (this/S)*S.
378     */
379    public RealAlgebraicNumber<C> remainder(RealAlgebraicNumber<C> S) {
380        return new RealAlgebraicNumber<C>(ring, number.remainder(S.number));
381    }
382
383
384    /**
385     * RealAlgebraicNumber multiplication.
386     * @param S RealAlgebraicNumber.
387     * @return this*S.
388     */
389    public RealAlgebraicNumber<C> multiply(RealAlgebraicNumber<C> S) {
390        return new RealAlgebraicNumber<C>(ring, number.multiply(S.number));
391    }
392
393
394    /**
395     * RealAlgebraicNumber multiplication.
396     * @param c coefficient.
397     * @return this*c.
398     */
399    public RealAlgebraicNumber<C> multiply(C c) {
400        return new RealAlgebraicNumber<C>(ring, number.multiply(c));
401    }
402
403
404    /**
405     * RealAlgebraicNumber multiplication.
406     * @param c polynomial.
407     * @return this*c.
408     */
409    public RealAlgebraicNumber<C> multiply(GenPolynomial<C> c) {
410        return new RealAlgebraicNumber<C>(ring, number.multiply(c));
411    }
412
413
414    /**
415     * RealAlgebraicNumber monic.
416     * @return this with monic value part.
417     */
418    public RealAlgebraicNumber<C> monic() {
419        return new RealAlgebraicNumber<C>(ring, number.monic());
420    }
421
422
423    /**
424     * RealAlgebraicNumber greatest common divisor.
425     * @param S RealAlgebraicNumber.
426     * @return gcd(this,S).
427     */
428    public RealAlgebraicNumber<C> gcd(RealAlgebraicNumber<C> S) {
429        return new RealAlgebraicNumber<C>(ring, number.gcd(S.number));
430    }
431
432
433    /**
434     * RealAlgebraicNumber extended greatest common divisor.
435     * @param S RealAlgebraicNumber.
436     * @return [ gcd(this,S), a, b ] with a*this + b*S = gcd(this,S).
437     */
438    @SuppressWarnings("unchecked")
439    public RealAlgebraicNumber<C>[] egcd(RealAlgebraicNumber<C> S) {
440        AlgebraicNumber<C>[] aret = number.egcd(S.number);
441        RealAlgebraicNumber<C>[] ret = new RealAlgebraicNumber[3];
442        ret[0] = new RealAlgebraicNumber<C>(ring, aret[0]);
443        ret[1] = new RealAlgebraicNumber<C>(ring, aret[1]);
444        ret[2] = new RealAlgebraicNumber<C>(ring, aret[2]);
445        return ret;
446    }
447
448}