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