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 }