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 }