001/* 002 * $Id: ComplexAlgebraicNumber.java 5916 2018-08-29 20:21:02Z 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 @SuppressWarnings("unchecked") 348 public ComplexAlgebraicNumber<C>[] quotientRemainder(ComplexAlgebraicNumber<C> S) { 349 return new ComplexAlgebraicNumber[] { divide(S), remainder(S) }; 350 } 351 352 353 /** 354 * ComplexAlgebraicNumber multiplication. 355 * @param S ComplexAlgebraicNumber. 356 * @return this*S. 357 */ 358 public ComplexAlgebraicNumber<C> multiply(ComplexAlgebraicNumber<C> S) { 359 return new ComplexAlgebraicNumber<C>(ring, number.multiply(S.number)); 360 } 361 362 363 /** 364 * ComplexAlgebraicNumber multiplication. 365 * @param c coefficient. 366 * @return this*c. 367 */ 368 public ComplexAlgebraicNumber<C> multiply(Complex<C> c) { 369 return new ComplexAlgebraicNumber<C>(ring, number.multiply(c)); 370 } 371 372 373 /** 374 * ComplexAlgebraicNumber multiplication. 375 * @param c polynomial. 376 * @return this*c. 377 */ 378 public ComplexAlgebraicNumber<C> multiply(GenPolynomial<Complex<C>> c) { 379 return new ComplexAlgebraicNumber<C>(ring, number.multiply(c)); 380 } 381 382 383 /** 384 * ComplexAlgebraicNumber monic. 385 * @return this with monic value part. 386 */ 387 public ComplexAlgebraicNumber<C> monic() { 388 return new ComplexAlgebraicNumber<C>(ring, number.monic()); 389 } 390 391 392 /** 393 * ComplexAlgebraicNumber greatest common divisor. 394 * @param S ComplexAlgebraicNumber. 395 * @return gcd(this,S). 396 */ 397 public ComplexAlgebraicNumber<C> gcd(ComplexAlgebraicNumber<C> S) { 398 return new ComplexAlgebraicNumber<C>(ring, number.gcd(S.number)); 399 } 400 401 402 /** 403 * ComplexAlgebraicNumber extended greatest common divisor. 404 * @param S ComplexAlgebraicNumber. 405 * @return [ gcd(this,S), a, b ] with a*this + b*S = gcd(this,S). 406 */ 407 @SuppressWarnings("unchecked") 408 public ComplexAlgebraicNumber<C>[] egcd(ComplexAlgebraicNumber<C> S) { 409 AlgebraicNumber<Complex<C>>[] aret = number.egcd(S.number); 410 ComplexAlgebraicNumber<C>[] ret = new ComplexAlgebraicNumber[3]; 411 ret[0] = new ComplexAlgebraicNumber<C>(ring, aret[0]); 412 ret[1] = new ComplexAlgebraicNumber<C>(ring, aret[1]); 413 ret[2] = new ComplexAlgebraicNumber<C>(ring, aret[2]); 414 return ret; 415 } 416 417 418 /** 419 * ComplexAlgebraicNumber signum. 420 * @see edu.jas.structure.RingElem#signum() 421 * @return signum(this). 422 */ 423 public int signum() { 424 ring.ensureEngine(); 425 try { 426 Rectangle<C> v = ring.engine.invariantRectangle(ring.root, ring.algebraic.modul, number.val); 427 ring.setRoot(v); 428 Complex<C> c = v.getCenter(); 429 return c.signum(); 430 } catch (InvalidBoundaryException e) { // should not happen 431 e.printStackTrace(); 432 throw new RuntimeException(e); 433 } 434 } 435 436 437 /** 438 * ComplexAlgebraicNumber magnitude. 439 * @return |this| as complex rational number. 440 */ 441 public Complex<BigRational> magnitude() { 442 ring.ensureEngine(); 443 try { 444 Rectangle<C> v = ring.engine.invariantMagnitudeRectangle(ring.root, ring.algebraic.modul, 445 number.val, ring.getEps()); 446 ring.setRoot(v); 447 //System.out.println("new v = " + v); 448 Complex<C> ev = ring.engine.complexRectangleMagnitude(v, ring.algebraic.modul, number.val); //, ring.eps); 449 BigRational er = ev.getRe().getRational(); 450 BigRational ei = ev.getIm().getRational(); 451 ComplexRing<BigRational> cr = new ComplexRing<BigRational>(er.factory()); 452 return new Complex<BigRational>(cr, er, ei); 453 } catch (InvalidBoundaryException e) { // should not happen 454 e.printStackTrace(); 455 throw new RuntimeException(e); 456 } 457 } 458 459 460 /** 461 * ComplexAlgebraicNumber magnitude. 462 * @return |this| as complex big decimal. 463 */ 464 public Complex<BigDecimal> decimalMagnitude() { 465 Complex<BigRational> cr = magnitude(); 466 ComplexRing<BigDecimal> dr = new ComplexRing<BigDecimal>(BigDecimal.ZERO); 467 return new Complex<BigDecimal>(dr, new BigDecimal(cr.getRe()), new BigDecimal(cr.getIm())); 468 } 469 470}