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