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