001/* 002 * $Id: RealAlgebraicNumber.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.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 } 113 114 115 /** 116 * Is RealAlgebraicNumber one. 117 * @return If this is 1 then true is returned, else false. 118 * @see edu.jas.structure.RingElem#isONE() 119 */ 120 public boolean isONE() { 121 return number.isONE(); 122 } 123 124 125 /** 126 * Is RealAlgebraicNumber unit. 127 * @return If this is a unit then true is returned, else false. 128 * @see edu.jas.structure.RingElem#isUnit() 129 */ 130 public boolean isUnit() { 131 return number.isUnit(); 132 } 133 134 135 /** 136 * Is RealAlgebraicNumber a root of unity. 137 * @return true if |this**i| == 1, for some 0 < i ≤ deg(modul), else 138 * false. 139 */ 140 public boolean isRootOfUnity() { 141 return number.isRootOfUnity(); 142 } 143 144 145 /** 146 * Get the String representation as RingElem. 147 * @see java.lang.Object#toString() 148 */ 149 @Override 150 public String toString() { 151 if (PrettyPrint.isTrue()) { 152 return "{ " + number.toString() + " }"; 153 } 154 return "Real" + number.toString(); 155 } 156 157 158 /** 159 * Get a scripting compatible string representation. 160 * @return script compatible representation for this Element. 161 * @see edu.jas.structure.Element#toScript() 162 */ 163 @Override 164 public String toScript() { 165 // Python case 166 return number.toScript(); 167 } 168 169 170 /** 171 * Get a scripting compatible string representation of the factory. 172 * @return script compatible representation for this ElemFactory. 173 * @see edu.jas.structure.Element#toScriptFactory() 174 */ 175 @Override 176 public String toScriptFactory() { 177 // Python case 178 return factory().toScript(); 179 } 180 181 182 /** 183 * RealAlgebraicNumber comparison. 184 * @param b RealAlgebraicNumber. 185 * @return real sign(this-b). 186 */ 187 @Override 188 public int compareTo(RealAlgebraicNumber<C> b) { 189 int s = 0; 190 if (number.ring != b.number.ring) { // avoid compareTo if possible 191 s = number.ring.modul.compareTo(b.number.ring.modul); 192 System.out.println("s_mod = " + s); 193 } 194 if (s != 0) { 195 return s; 196 } 197 s = this.subtract(b).signum(); // avoid subtract if possible 198 //System.out.println("s_real = " + s); 199 return s; 200 } 201 202 203 /** 204 * RealAlgebraicNumber comparison. 205 * @param b AlgebraicNumber. 206 * @return polynomial sign(this-b). 207 */ 208 public int compareTo(AlgebraicNumber<C> b) { 209 int s = number.compareTo(b); 210 System.out.println("s_algeb = " + s); 211 return s; 212 } 213 214 215 /** 216 * Comparison with any other object. 217 * @see java.lang.Object#equals(java.lang.Object) 218 */ 219 @Override 220 @SuppressWarnings("unchecked") 221 public boolean equals(Object b) { 222 if (b == null) { 223 return false; 224 } 225 if (!(b instanceof RealAlgebraicNumber)) { 226 return false; 227 } 228 RealAlgebraicNumber<C> a = (RealAlgebraicNumber<C>) b; 229 if (!ring.equals(a.ring)) { 230 return false; 231 } 232 return number.equals(a.number); 233 } 234 235 236 /** 237 * Hash code for this RealAlgebraicNumber. 238 * @see java.lang.Object#hashCode() 239 */ 240 @Override 241 public int hashCode() { 242 return 37 * number.val.hashCode() + ring.hashCode(); 243 } 244 245 246 /** 247 * RealAlgebraicNumber absolute value. 248 * @return the absolute value of this. 249 * @see edu.jas.structure.RingElem#abs() 250 */ 251 public RealAlgebraicNumber<C> abs() { 252 if (this.signum() < 0) { 253 return new RealAlgebraicNumber<C>(ring, number.negate()); 254 } 255 return this; 256 } 257 258 259 /** 260 * RealAlgebraicNumber summation. 261 * @param S RealAlgebraicNumber. 262 * @return this+S. 263 */ 264 public RealAlgebraicNumber<C> sum(RealAlgebraicNumber<C> S) { 265 return new RealAlgebraicNumber<C>(ring, number.sum(S.number)); 266 } 267 268 269 /** 270 * RealAlgebraicNumber summation. 271 * @param c coefficient. 272 * @return this+c. 273 */ 274 public RealAlgebraicNumber<C> sum(GenPolynomial<C> c) { 275 return new RealAlgebraicNumber<C>(ring, number.sum(c)); 276 } 277 278 279 /** 280 * RealAlgebraicNumber summation. 281 * @param c polynomial. 282 * @return this+c. 283 */ 284 public RealAlgebraicNumber<C> sum(C c) { 285 return new RealAlgebraicNumber<C>(ring, number.sum(c)); 286 } 287 288 289 /** 290 * RealAlgebraicNumber negate. 291 * @return -this. 292 * @see edu.jas.structure.RingElem#negate() 293 */ 294 public RealAlgebraicNumber<C> negate() { 295 return new RealAlgebraicNumber<C>(ring, number.negate()); 296 } 297 298 299 /** 300 * RealAlgebraicNumber signum. <b>Note: </b> Modifies ring.root eventually. 301 * @see edu.jas.structure.RingElem#signum() 302 * @return real signum(this). 303 */ 304 public int signum() { 305 Interval<C> v = ring.engine.invariantSignInterval(ring.root, ring.algebraic.modul, number.val); 306 ring.setRoot(v); 307 return ring.engine.realIntervalSign(v, ring.algebraic.modul, number.val); 308 } 309 310 311 /** 312 * RealAlgebraicNumber half interval. 313 */ 314 public void halfInterval() { 315 Interval<C> v = ring.engine.halfInterval(ring.root, ring.algebraic.modul); 316 //System.out.println("old v = " + ring.root + ", new v = " + v); 317 ring.setRoot(v); 318 } 319 320 321 /** 322 * RealAlgebraicNumber magnitude. 323 * @return |this|. 324 */ 325 public BigRational magnitude() { 326 Interval<C> v = ring.engine.invariantMagnitudeInterval(ring.root, ring.algebraic.modul, number.val, 327 ring.getEps()); 328 //System.out.println("old v = " + ring.root + ", new v = " + v); 329 ring.setRoot(v); 330 C ev = ring.engine.realIntervalMagnitude(v, ring.algebraic.modul, number.val); //, ring.eps); 331 //if ((Object) ev instanceof Rational) { // always true by type parameter 332 BigRational er = ev.getRational(); 333 return er; 334 //} 335 //throw new RuntimeException("Rational expected, but was " + ev.getClass()); 336 } 337 338 339 /** 340 * RealAlgebraicNumber magnitude. 341 * @return |this| as big decimal. 342 */ 343 public BigDecimal decimalMagnitude() { 344 return new BigDecimal(magnitude()); 345 } 346 347 348 /** 349 * RealAlgebraicNumber subtraction. 350 * @param S RealAlgebraicNumber. 351 * @return this-S. 352 */ 353 public RealAlgebraicNumber<C> subtract(RealAlgebraicNumber<C> S) { 354 return new RealAlgebraicNumber<C>(ring, number.subtract(S.number)); 355 } 356 357 358 /** 359 * RealAlgebraicNumber division. 360 * @param S RealAlgebraicNumber. 361 * @return this/S. 362 */ 363 public RealAlgebraicNumber<C> divide(RealAlgebraicNumber<C> S) { 364 return multiply(S.inverse()); 365 } 366 367 368 /** 369 * RealAlgebraicNumber inverse. 370 * @see edu.jas.structure.RingElem#inverse() 371 * @throws NotInvertibleException if the element is not invertible. 372 * @return S with S = 1/this if defined. 373 */ 374 public RealAlgebraicNumber<C> inverse() { 375 return new RealAlgebraicNumber<C>(ring, number.inverse()); 376 } 377 378 379 /** 380 * RealAlgebraicNumber remainder. 381 * @param S RealAlgebraicNumber. 382 * @return this - (this/S)*S. 383 */ 384 public RealAlgebraicNumber<C> remainder(RealAlgebraicNumber<C> S) { 385 return new RealAlgebraicNumber<C>(ring, number.remainder(S.number)); 386 } 387 388 389 /** 390 * Quotient and remainder by division of this by S. 391 * @param S a RealAlgebraicNumber 392 * @return [this/S, this - (this/S)*S]. 393 */ 394 @SuppressWarnings("unchecked") 395 public RealAlgebraicNumber<C>[] quotientRemainder(RealAlgebraicNumber<C> S) { 396 return new RealAlgebraicNumber[] { divide(S), remainder(S) }; 397 } 398 399 400 /** 401 * RealAlgebraicNumber multiplication. 402 * @param S RealAlgebraicNumber. 403 * @return this*S. 404 */ 405 public RealAlgebraicNumber<C> multiply(RealAlgebraicNumber<C> S) { 406 return new RealAlgebraicNumber<C>(ring, number.multiply(S.number)); 407 } 408 409 410 /** 411 * RealAlgebraicNumber multiplication. 412 * @param c coefficient. 413 * @return this*c. 414 */ 415 public RealAlgebraicNumber<C> multiply(C c) { 416 return new RealAlgebraicNumber<C>(ring, number.multiply(c)); 417 } 418 419 420 /** 421 * RealAlgebraicNumber multiplication. 422 * @param c polynomial. 423 * @return this*c. 424 */ 425 public RealAlgebraicNumber<C> multiply(GenPolynomial<C> c) { 426 return new RealAlgebraicNumber<C>(ring, number.multiply(c)); 427 } 428 429 430 /** 431 * RealAlgebraicNumber monic. 432 * @return this with monic value part. 433 */ 434 public RealAlgebraicNumber<C> monic() { 435 return new RealAlgebraicNumber<C>(ring, number.monic()); 436 } 437 438 439 /** 440 * RealAlgebraicNumber greatest common divisor. 441 * @param S RealAlgebraicNumber. 442 * @return gcd(this,S). 443 */ 444 public RealAlgebraicNumber<C> gcd(RealAlgebraicNumber<C> S) { 445 return new RealAlgebraicNumber<C>(ring, number.gcd(S.number)); 446 } 447 448 449 /** 450 * RealAlgebraicNumber extended greatest common divisor. 451 * @param S RealAlgebraicNumber. 452 * @return [ gcd(this,S), a, b ] with a*this + b*S = gcd(this,S). 453 */ 454 @SuppressWarnings("unchecked") 455 public RealAlgebraicNumber<C>[] egcd(RealAlgebraicNumber<C> S) { 456 AlgebraicNumber<C>[] aret = number.egcd(S.number); 457 RealAlgebraicNumber<C>[] ret = new RealAlgebraicNumber[3]; 458 ret[0] = new RealAlgebraicNumber<C>(ring, aret[0]); 459 ret[1] = new RealAlgebraicNumber<C>(ring, aret[1]); 460 ret[2] = new RealAlgebraicNumber<C>(ring, aret[2]); 461 return ret; 462 } 463 464}