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