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