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