001 /* 002 * $Id: Quotient.java 3365 2010-10-24 12:59:34Z kredel $ 003 */ 004 005 package edu.jas.poly; 006 007 008 import org.apache.log4j.Logger; 009 010 import edu.jas.structure.Element; 011 import edu.jas.structure.RingElem; 012 import edu.jas.structure.RingFactory; 013 import edu.jas.structure.GcdRingElem; 014 015 016 /** 017 * Quotient element based on RingElem pairs. 018 * Objects of this class are immutable. 019 * @author Heinz Kredel 020 */ 021 public class Quotient<C extends RingElem<C> > 022 implements RingElem< Quotient<C> > { 023 024 private static final Logger logger = Logger.getLogger(Quotient.class); 025 private boolean debug = logger.isDebugEnabled(); 026 027 028 /** Quotient class factory data structure. 029 */ 030 public final QuotientRing<C> ring; 031 032 033 /** Numerator part of the element data structure. 034 */ 035 public final C num; 036 037 038 /** Denominator part of the element data structure. 039 */ 040 public final C den; 041 042 043 /** The constructor creates a Quotient object 044 * from a ring factory. 045 * @param r ring factory. 046 */ 047 public Quotient(QuotientRing<C> r) { 048 this( r, r.ring.getZERO() ); 049 } 050 051 052 /** The constructor creates a Quotient object 053 * from a ring factory and a numerator element. 054 * The denominator is assumed to be 1. 055 * @param r ring factory. 056 * @param n numerator. 057 */ 058 public Quotient(QuotientRing<C> r, C n) { 059 this( r, n, r.ring.getONE(), true ); 060 } 061 062 063 /** The constructor creates a Quotient object 064 * from a ring factory and a numerator and denominator element. 065 * @param r ring factory. 066 * @param n numerator. 067 * @param d denominator. 068 */ 069 public Quotient(QuotientRing<C> r, 070 C n, C d) { 071 this(r,n,d,false); 072 } 073 074 075 /** The constructor creates a Quotient object 076 * from a ring factory and a numerator and denominator element. 077 * @param r ring factory. 078 * @param n numerator. 079 * @param d denominator. 080 * @param isred true if gcd(n,d) == 1, else false. 081 */ 082 @SuppressWarnings("unchecked") 083 protected Quotient(QuotientRing<C> r, 084 C n, C d, 085 boolean isred) { 086 if ( d == null || d.isZERO() ) { 087 throw new IllegalArgumentException("denominator may not be zero"); 088 } 089 ring = r; 090 if ( d.signum() < 0 ) { 091 n = n.negate(); 092 d = d.negate(); 093 } 094 if ( isred ) { 095 num = n; 096 den = d; 097 return; 098 } 099 // must reduce to lowest terms 100 if ( n instanceof GcdRingElem && d instanceof GcdRingElem ) { 101 GcdRingElem ng = (GcdRingElem)n; 102 GcdRingElem dg = (GcdRingElem)d; 103 C gcd = (C) ng.gcd( dg ); 104 if ( debug ) { 105 logger.info("gcd = " + gcd); 106 } 107 //RingElem<C> gcd = ring.ring.getONE(); 108 if ( gcd.isONE() ) { 109 num = n; 110 den = d; 111 } else { 112 num = n.divide( gcd ); 113 den = d.divide( gcd ); 114 } 115 // } else { // univariate polynomial? 116 } else { 117 if ( true || debug ) { 118 logger.info("gcd = ????"); 119 } 120 num = n; 121 den = d; 122 } 123 } 124 125 126 /** 127 * Get the corresponding element factory. 128 * @return factory for this Element. 129 * @see edu.jas.structure.Element#factory() 130 */ 131 public QuotientRing<C> factory() { 132 return ring; 133 } 134 135 136 /** Clone this. 137 * @see java.lang.Object#clone() 138 */ 139 @Override 140 public Quotient<C> clone() { 141 return new Quotient<C>( ring, num, den, true ); 142 } 143 144 145 /** Is Quotient zero. 146 * @return If this is 0 then true is returned, else false. 147 * @see edu.jas.structure.RingElem#isZERO() 148 */ 149 public boolean isZERO() { 150 return num.isZERO(); 151 } 152 153 154 /** Is Quotient one. 155 * @return If this is 1 then true is returned, else false. 156 * @see edu.jas.structure.RingElem#isONE() 157 */ 158 public boolean isONE() { 159 return num.equals( den ); 160 } 161 162 163 /** Is Quotient unit. 164 * @return If this is a unit then true is returned, else false. 165 * @see edu.jas.structure.RingElem#isUnit() 166 */ 167 public boolean isUnit() { 168 if ( num.isZERO() ) { 169 return false; 170 } else { 171 return true; 172 } 173 } 174 175 176 /** Get the String representation as RingElem. 177 * @see java.lang.Object#toString() 178 */ 179 @Override 180 public String toString() { 181 return "Quotient[ " + num.toString() 182 + " / " + den.toString() + " ]"; 183 } 184 185 186 /** Get a scripting compatible string representation. 187 * @return script compatible representation for this Element. 188 * @see edu.jas.structure.Element#toScript() 189 */ 190 //JAVA6only: @Override 191 public String toScript() { 192 // Python case 193 return "Quotient( " + num.toScript() 194 + " , " + den.toScript() + " )"; 195 } 196 197 198 /** Get a scripting compatible string representation of the factory. 199 * @return script compatible representation for this ElemFactory. 200 * @see edu.jas.structure.Element#toScriptFactory() 201 */ 202 //JAVA6only: @Override 203 public String toScriptFactory() { 204 // Python case 205 return factory().toScript(); 206 } 207 208 209 /** Quotient comparison. 210 * @param b Quotient. 211 * @return sign(this-b). 212 */ 213 //JAVA6only: @Override 214 public int compareTo(Quotient<C> b) { 215 if ( b == null || b.isZERO() ) { 216 return this.signum(); 217 } 218 C r = num.multiply( b.den ); 219 C s = den.multiply( b.num ); 220 C x = r.subtract( s ); 221 return x.signum(); 222 } 223 224 225 /** Comparison with any other object. 226 * @see java.lang.Object#equals(java.lang.Object) 227 */ 228 @SuppressWarnings("unchecked") // not jet working 229 @Override 230 public boolean equals(Object b) { 231 if ( ! ( b instanceof Quotient ) ) { 232 return false; 233 } 234 Quotient<C> a = null; 235 try { 236 a = (Quotient<C>) b; 237 } catch (ClassCastException e) { 238 } 239 if ( a == null ) { 240 return false; 241 } 242 return ( 0 == compareTo( a ) ); 243 } 244 245 246 /** Hash code for this local. 247 * @see java.lang.Object#hashCode() 248 */ 249 @Override 250 public int hashCode() { 251 int h; 252 h = ring.hashCode(); 253 h = 37 * h + num.hashCode(); 254 h = 37 * h + den.hashCode(); 255 return h; 256 } 257 258 259 /** Quotient absolute value. 260 * @return the absolute value of this. 261 * @see edu.jas.structure.RingElem#abs() 262 */ 263 public Quotient<C> abs() { 264 return new Quotient<C>( ring, num.abs(), den, true ); 265 } 266 267 268 /** Quotient summation. 269 * @param S Quotient. 270 * @return this+S. 271 */ 272 public Quotient<C> sum(Quotient<C> S) { 273 if ( S == null || S.isZERO() ) { 274 return this; 275 } 276 C n = num.multiply( S.den ); 277 n = n.sum( den.multiply( S.num ) ); 278 C d = den.multiply( S.den ); 279 return new Quotient<C>( ring, n, d, false ); 280 } 281 282 283 /** Quotient negate. 284 * @return -this. 285 * @see edu.jas.structure.RingElem#negate() 286 */ 287 public Quotient<C> negate() { 288 return new Quotient<C>( ring, num.negate(), den, true ); 289 } 290 291 292 /** Quotient signum. 293 * @see edu.jas.structure.RingElem#signum() 294 * @return signum(this). 295 */ 296 public int signum() { 297 return num.signum(); 298 } 299 300 301 /** Quotient subtraction. 302 * @param S Quotient. 303 * @return this-S. 304 */ 305 public Quotient<C> subtract(Quotient<C> S) { 306 if ( S == null || S.isZERO() ) { 307 return this; 308 } 309 C n = num.multiply( S.den ); 310 n = n.subtract( den.multiply( S.num ) ); 311 C d = den.multiply( S.den ); 312 return new Quotient<C>( ring, n, d, false ); 313 } 314 315 316 /** Quotient division. 317 * @param S Quotient. 318 * @return this/S. 319 */ 320 public Quotient<C> divide(Quotient<C> S) { 321 return multiply( S.inverse() ); 322 } 323 324 325 /** Quotient inverse. 326 * @see edu.jas.structure.RingElem#inverse() 327 * @return S with S = 1/this. 328 */ 329 public Quotient<C> inverse() { 330 return new Quotient<C>( ring, den, num, true ); 331 } 332 333 334 /** Quotient remainder. 335 * @param S Quotient. 336 * @return this - (this/S)*S. 337 */ 338 public Quotient<C> remainder(Quotient<C> S) { 339 if ( num.isZERO() ) { 340 throw new ArithmeticException("element not invertible " + this); 341 } 342 return ring.getZERO(); 343 } 344 345 346 /** Quotient multiplication. 347 * @param S Quotient. 348 * @return this*S. 349 */ 350 public Quotient<C> multiply(Quotient<C> S) { 351 if ( S == null || S.isZERO() ) { 352 return S; 353 } 354 if ( num.isZERO() ) { 355 return this; 356 } 357 if ( S.isONE() ) { 358 return this; 359 } 360 if ( this.isONE() ) { 361 return S; 362 } 363 C n = num.multiply( S.num ); 364 C d = den.multiply( S.den ); 365 return new Quotient<C>( ring, n, d, false ); 366 } 367 368 369 /** Quotient monic. 370 * @return this with monic value part. 371 */ 372 public Quotient<C> monic() { 373 logger.info("monic not implemented"); 374 return this; 375 } 376 377 378 /** 379 * Greatest common divisor. 380 * <b>Note: </b>Not implemented, throws UnsupportedOperationException. 381 * @param b other element. 382 * @return gcd(this,b). 383 */ 384 public Quotient<C> gcd(Quotient<C> b) { 385 throw new UnsupportedOperationException("gcd not implemented " + this.getClass().getName()); 386 } 387 388 389 /** 390 * Extended greatest common divisor. 391 * <b>Note: </b>Not implemented, throws UnsupportedOperationException. 392 * @param b other element. 393 * @return [ gcd(this,b), c1, c2 ] with c1*this + c2*b = gcd(this,b). 394 */ 395 public Quotient<C>[] egcd(Quotient<C> b) { 396 throw new UnsupportedOperationException("egcd not implemented " + this.getClass().getName()); 397 } 398 399 }