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