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