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