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