001/* 002 * $Id: ComplexAlgebraicNumber.java 5820 2018-05-10 19:03:37Z 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>*/ 028 implements 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 * Is ComplexAlgebraicNumber a root of unity. 129 * @return true if |this**i| == 1, for some 0 < i ≤ deg(modul), else 130 * false. 131 */ 132 public boolean isRootOfUnity() { 133 return number.isRootOfUnity(); 134 } 135 136 137 /** 138 * Get the String representation as RingElem. 139 * @see java.lang.Object#toString() 140 */ 141 @Override 142 public String toString() { 143 if (PrettyPrint.isTrue()) { 144 return "{ " + number.toString() + " }"; 145 } 146 return "Complex" + number.toString(); 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 @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 @Override 168 public String toScriptFactory() { 169 // Python case 170 return factory().toScript(); 171 } 172 173 174 /** 175 * ComplexAlgebraicNumber comparison. 176 * @param b ComplexAlgebraicNumber. 177 * @return sign(this-b). 178 */ 179 @Override 180 public int compareTo(ComplexAlgebraicNumber<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 = number.compareTo(b.number); // TODO 190 //System.out.println("s_real = " + s); 191 return s; 192 } 193 194 195 /** 196 * ComplexAlgebraicNumber comparison. 197 * @param b AlgebraicNumber. 198 * @return polynomial sign(this-b). 199 */ 200 public int compareTo(AlgebraicNumber<Complex<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 == null) { 215 return false; 216 } 217 if (!(b instanceof ComplexAlgebraicNumber)) { 218 return false; 219 } 220 ComplexAlgebraicNumber<C> a = (ComplexAlgebraicNumber<C>) b; 221 if (!ring.equals(a.ring)) { 222 return false; 223 } 224 return number.equals(a.number); 225 } 226 227 228 /** 229 * Hash code for this ComplexAlgebraicNumber. 230 * @see java.lang.Object#hashCode() 231 */ 232 @Override 233 public int hashCode() { 234 return 37 * number.val.hashCode() + ring.hashCode(); 235 } 236 237 238 /** 239 * ComplexAlgebraicNumber absolute value. 240 * @return the absolute value of this. 241 * @see edu.jas.structure.RingElem#abs() 242 */ 243 public ComplexAlgebraicNumber<C> abs() { 244 if (this.signum() < 0) { 245 return new ComplexAlgebraicNumber<C>(ring, number.negate()); 246 } 247 return this; 248 } 249 250 251 /** 252 * ComplexAlgebraicNumber summation. 253 * @param S ComplexAlgebraicNumber. 254 * @return this+S. 255 */ 256 public ComplexAlgebraicNumber<C> sum(ComplexAlgebraicNumber<C> S) { 257 return new ComplexAlgebraicNumber<C>(ring, number.sum(S.number)); 258 } 259 260 261 /** 262 * ComplexAlgebraicNumber summation. 263 * @param c complex polynomial. 264 * @return this+c. 265 */ 266 public ComplexAlgebraicNumber<C> sum(GenPolynomial<Complex<C>> c) { 267 return new ComplexAlgebraicNumber<C>(ring, number.sum(c)); 268 } 269 270 271 /** 272 * ComplexAlgebraicNumber summation. 273 * @param c algebraic number. 274 * @return this+c. 275 */ 276 public ComplexAlgebraicNumber<C> sum(AlgebraicNumber<Complex<C>> c) { 277 return new ComplexAlgebraicNumber<C>(ring, number.sum(c)); 278 } 279 280 281 /** 282 * ComplexAlgebraicNumber summation. 283 * @param c coefficient. 284 * @return this+c. 285 */ 286 public ComplexAlgebraicNumber<C> sum(Complex<C> c) { 287 return new ComplexAlgebraicNumber<C>(ring, number.sum(c)); 288 } 289 290 291 /** 292 * ComplexAlgebraicNumber negate. 293 * @return -this. 294 * @see edu.jas.structure.RingElem#negate() 295 */ 296 public ComplexAlgebraicNumber<C> negate() { 297 return new ComplexAlgebraicNumber<C>(ring, number.negate()); 298 } 299 300 301 /** 302 * ComplexAlgebraicNumber subtraction. 303 * @param S ComplexAlgebraicNumber. 304 * @return this-S. 305 */ 306 public ComplexAlgebraicNumber<C> subtract(ComplexAlgebraicNumber<C> S) { 307 return new ComplexAlgebraicNumber<C>(ring, number.subtract(S.number)); 308 } 309 310 311 /** 312 * ComplexAlgebraicNumber division. 313 * @param S ComplexAlgebraicNumber. 314 * @return this/S. 315 */ 316 public ComplexAlgebraicNumber<C> divide(ComplexAlgebraicNumber<C> S) { 317 return multiply(S.inverse()); 318 } 319 320 321 /** 322 * ComplexAlgebraicNumber inverse. 323 * @see edu.jas.structure.RingElem#inverse() 324 * @throws NotInvertibleException if the element is not invertible. 325 * @return S with S = 1/this if defined. 326 */ 327 public ComplexAlgebraicNumber<C> inverse() { 328 return new ComplexAlgebraicNumber<C>(ring, number.inverse()); 329 } 330 331 332 /** 333 * ComplexAlgebraicNumber remainder. 334 * @param S ComplexAlgebraicNumber. 335 * @return this - (this/S)*S. 336 */ 337 public ComplexAlgebraicNumber<C> remainder(ComplexAlgebraicNumber<C> S) { 338 return new ComplexAlgebraicNumber<C>(ring, number.remainder(S.number)); 339 } 340 341 342 /** 343 * Quotient and remainder by division of this by S. 344 * @param S a ComplexAlgebraicNumber 345 * @return [this/S, this - (this/S)*S]. 346 */ 347 public ComplexAlgebraicNumber<C>[] quotientRemainder(ComplexAlgebraicNumber<C> S) { 348 return new ComplexAlgebraicNumber[] { divide(S), remainder(S) }; 349 } 350 351 352 /** 353 * ComplexAlgebraicNumber multiplication. 354 * @param S ComplexAlgebraicNumber. 355 * @return this*S. 356 */ 357 public ComplexAlgebraicNumber<C> multiply(ComplexAlgebraicNumber<C> S) { 358 return new ComplexAlgebraicNumber<C>(ring, number.multiply(S.number)); 359 } 360 361 362 /** 363 * ComplexAlgebraicNumber multiplication. 364 * @param c coefficient. 365 * @return this*c. 366 */ 367 public ComplexAlgebraicNumber<C> multiply(Complex<C> c) { 368 return new ComplexAlgebraicNumber<C>(ring, number.multiply(c)); 369 } 370 371 372 /** 373 * ComplexAlgebraicNumber multiplication. 374 * @param c polynomial. 375 * @return this*c. 376 */ 377 public ComplexAlgebraicNumber<C> multiply(GenPolynomial<Complex<C>> c) { 378 return new ComplexAlgebraicNumber<C>(ring, number.multiply(c)); 379 } 380 381 382 /** 383 * ComplexAlgebraicNumber monic. 384 * @return this with monic value part. 385 */ 386 public ComplexAlgebraicNumber<C> monic() { 387 return new ComplexAlgebraicNumber<C>(ring, number.monic()); 388 } 389 390 391 /** 392 * ComplexAlgebraicNumber greatest common divisor. 393 * @param S ComplexAlgebraicNumber. 394 * @return gcd(this,S). 395 */ 396 public ComplexAlgebraicNumber<C> gcd(ComplexAlgebraicNumber<C> S) { 397 return new ComplexAlgebraicNumber<C>(ring, number.gcd(S.number)); 398 } 399 400 401 /** 402 * ComplexAlgebraicNumber extended greatest common divisor. 403 * @param S ComplexAlgebraicNumber. 404 * @return [ gcd(this,S), a, b ] with a*this + b*S = gcd(this,S). 405 */ 406 @SuppressWarnings("unchecked") 407 public ComplexAlgebraicNumber<C>[] egcd(ComplexAlgebraicNumber<C> S) { 408 AlgebraicNumber<Complex<C>>[] aret = number.egcd(S.number); 409 ComplexAlgebraicNumber<C>[] ret = new ComplexAlgebraicNumber[3]; 410 ret[0] = new ComplexAlgebraicNumber<C>(ring, aret[0]); 411 ret[1] = new ComplexAlgebraicNumber<C>(ring, aret[1]); 412 ret[2] = new ComplexAlgebraicNumber<C>(ring, aret[2]); 413 return ret; 414 } 415 416 417 /** 418 * ComplexAlgebraicNumber signum. 419 * @see edu.jas.structure.RingElem#signum() 420 * @return signum(this). 421 */ 422 public int signum() { 423 ring.ensureEngine(); 424 try { 425 Rectangle<C> v = ring.engine.invariantRectangle(ring.root, ring.algebraic.modul, number.val); 426 ring.setRoot(v); 427 Complex<C> c = v.getCenter(); 428 return c.signum(); 429 } catch (InvalidBoundaryException e) { // should not happen 430 e.printStackTrace(); 431 throw new RuntimeException(e); 432 } 433 } 434 435 436 /** 437 * ComplexAlgebraicNumber magnitude. 438 * @return |this| as complex rational number. 439 */ 440 public Complex<BigRational> magnitude() { 441 ring.ensureEngine(); 442 try { 443 Rectangle<C> v = ring.engine.invariantMagnitudeRectangle(ring.root, ring.algebraic.modul, 444 number.val, ring.getEps()); 445 ring.setRoot(v); 446 //System.out.println("new v = " + v); 447 Complex<C> ev = ring.engine.complexRectangleMagnitude(v, ring.algebraic.modul, number.val); //, ring.eps); 448 BigRational er = ev.getRe().getRational(); 449 BigRational ei = ev.getIm().getRational(); 450 ComplexRing<BigRational> cr = new ComplexRing<BigRational>(er.factory()); 451 return new Complex<BigRational>(cr, er, ei); 452 } catch (InvalidBoundaryException e) { // should not happen 453 e.printStackTrace(); 454 throw new RuntimeException(e); 455 } 456 } 457 458 459 /** 460 * ComplexAlgebraicNumber magnitude. 461 * @return |this| as complex big decimal. 462 */ 463 public Complex<BigDecimal> decimalMagnitude() { 464 Complex<BigRational> cr = magnitude(); 465 ComplexRing<BigDecimal> dr = new ComplexRing<BigDecimal>(BigDecimal.ZERO); 466 return new Complex<BigDecimal>(dr, new BigDecimal(cr.getRe()), new BigDecimal(cr.getIm())); 467 } 468 469}