001/* 002 * $Id$ 003 */ 004 005package edu.jas.application; 006 007 008import java.io.Serializable; 009import java.util.ArrayList; 010import java.util.Collection; 011import java.util.Comparator; 012import java.util.List; 013import java.util.Map; 014 015import org.apache.logging.log4j.LogManager; 016import org.apache.logging.log4j.Logger; 017 018import edu.jas.poly.ExpVector; 019import edu.jas.poly.GenPolynomial; 020import edu.jas.poly.GenSolvablePolynomial; 021import edu.jas.structure.RingElem; 022 023 024/** 025 * Colored Polynomials with green, red and white coefficients. Not implementing 026 * RingElem. <b>Note:</b> not general purpose, use only in comprehensive GB. 027 * @param <C> coefficient type 028 * @author Heinz Kredel 029 */ 030 031public class ColorPolynomial<C extends RingElem<C>> implements Serializable 032/* implements RingElem< ColorPolynomial<C> > */ { 033 034 035 private static final Logger logger = LogManager.getLogger(ColorPolynomial.class); 036 037 038 /** 039 * The part with green (= zero) terms and coefficients. 040 */ 041 public final GenPolynomial<GenPolynomial<C>> green; 042 043 044 /** 045 * The part with red (= non zero) terms and coefficients. 046 */ 047 public final GenPolynomial<GenPolynomial<C>> red; 048 049 050 /** 051 * The part with white (= unknown color) terms and coefficients. 052 */ 053 public final GenPolynomial<GenPolynomial<C>> white; 054 055 056 /** 057 * The constructor creates a colored polynomial from the colored parts. 058 * @param g green colored terms and coefficients. 059 * @param r red colored terms and coefficients. 060 * @param w white colored terms and coefficients. 061 */ 062 public ColorPolynomial(GenPolynomial<GenPolynomial<C>> g, GenPolynomial<GenPolynomial<C>> r, 063 GenPolynomial<GenPolynomial<C>> w) { 064 if (g == null || r == null || w == null) { 065 throw new IllegalArgumentException("g,r,w may not be null"); 066 } 067 green = g; 068 red = r; 069 white = w; 070 } 071 072 073 /** 074 * String representation of ColorPolynomial. 075 * @see java.lang.Object#toString() 076 */ 077 @Override 078 public String toString() { 079 StringBuffer s = new StringBuffer(); 080 s.append(":green: "); 081 s.append(green.toString()); 082 s.append(" :red: "); 083 s.append(red.toString()); 084 s.append(" :white: "); 085 s.append(white.toString()); 086 return s.toString(); 087 } 088 089 090 /** 091 * Script representation of ColorPolynomial. 092 * @see edu.jas.structure.Element#toScript() 093 */ 094 public String toScript() { 095 StringBuffer s = new StringBuffer(); 096 s.append(":green: "); 097 s.append(green.toScript()); 098 s.append(" :red: "); 099 s.append(red.toScript()); 100 s.append(" :white: "); 101 s.append(white.toScript()); 102 return s.toString(); 103 } 104 105 106 /** 107 * Is this polynomial ZERO. 108 * @return true, if there are only green terms, else false. 109 */ 110 public boolean isZERO() { 111 return (red.isZERO() && white.isZERO()); 112 } 113 114 115 /** 116 * Is this polynomial ONE. 117 * @return true, if the only non green term is 1, else false. 118 */ 119 public boolean isONE() { 120 return ((red.isZERO() && white.isONE()) || (red.isONE() && white.isZERO())); 121 } 122 123 124 /** 125 * Is this polynomial equal to other. 126 * @param p other polynomial. 127 * @return true, if this is equal to other, else false. 128 */ 129 @Override 130 @SuppressWarnings("unchecked") 131 public boolean equals(Object p) { 132 ColorPolynomial<C> cp = null; 133 try { 134 cp = (ColorPolynomial<C>) p; 135 } catch (ClassCastException e) { 136 return false; 137 } 138 if (cp == null) { 139 return false; 140 } 141 return (green.equals(cp.green) && red.equals(cp.red) && white.equals(cp.white)); 142 } 143 144 145 /** 146 * Hash code for this colored polynomial. 147 * @see java.lang.Object#hashCode() 148 */ 149 @Override 150 public int hashCode() { 151 int h; 152 h = green.hashCode(); 153 h = h << 11; 154 h += red.hashCode(); 155 h = h << 11; 156 h += white.hashCode(); 157 return h; 158 } 159 160 161 /** 162 * Is this polynomial determined. 163 * @return true, if there are nonzero red terms or if this == 0, else false. 164 */ 165 public boolean isDetermined() { 166 return (!red.isZERO() || white.isZERO()); 167 } 168 169 170 /** 171 * Check ordering invariants. TT(green) > LT(red) and TT(red) > 172 * LT(white). 173 * @return true, if all ordering invariants are met, else false. 174 */ 175 public boolean checkInvariant() { 176 boolean t = true; 177 ExpVector ttg, ltr, ttr, ltw; 178 Comparator<ExpVector> cmp; 179 if (green.isZERO() && red.isZERO() && white.isZERO()) { 180 return true; 181 } 182 if (green.isZERO() && red.isZERO()) { 183 return true; 184 } 185 if (red.isZERO() && white.isZERO()) { 186 return true; 187 } 188 189 if (!green.isZERO() && !red.isZERO()) { 190 ttg = green.trailingExpVector(); 191 ltr = red.leadingExpVector(); 192 cmp = green.ring.tord.getDescendComparator(); 193 t = t && (cmp.compare(ttg, ltr) < 0); 194 } 195 if (!red.isZERO() && !white.isZERO()) { 196 ttr = red.trailingExpVector(); 197 ltw = white.leadingExpVector(); 198 cmp = white.ring.tord.getDescendComparator(); 199 t = t && (cmp.compare(ttr, ltw) < 0); 200 } 201 if (red.isZERO() && !green.isZERO() && !white.isZERO()) { 202 ttg = green.trailingExpVector(); 203 ltw = white.leadingExpVector(); 204 cmp = white.ring.tord.getDescendComparator(); 205 t = t && (cmp.compare(ttg, ltw) < 0); 206 } 207 if (!t) { 208 System.out.println("not invariant " + this); 209 // throw new RuntimeException("test"); 210 } 211 return t; 212 } 213 214 215 /** 216 * Get zero condition on coefficients. 217 * @return green coefficients. 218 */ 219 public List<GenPolynomial<C>> getGreenCoefficients() { 220 Collection<GenPolynomial<C>> c = green.getMap().values(); 221 return new ArrayList<GenPolynomial<C>>(c); 222 } 223 224 225 /** 226 * Get non zero condition on coefficients. 227 * @return red coefficients. 228 */ 229 public List<GenPolynomial<C>> getRedCoefficients() { 230 Collection<GenPolynomial<C>> c = red.getMap().values(); 231 return new ArrayList<GenPolynomial<C>>(c); 232 } 233 234 235 /** 236 * Get full polynomial. 237 * @return sum of all parts. 238 */ 239 public GenPolynomial<GenPolynomial<C>> getPolynomial() { 240 GenPolynomial<GenPolynomial<C>> f = green.sum(red).sum(white); 241 int s = green.length() + red.length() + white.length(); 242 int t = f.length(); 243 if (t != s) { 244 throw new RuntimeException("illegal coloring state " + s + " != " + t); 245 } 246 return f; 247 } 248 249 250 /** 251 * Get essential polynomial. 252 * @return sum of red and white parts. 253 */ 254 public GenPolynomial<GenPolynomial<C>> getEssentialPolynomial() { 255 GenPolynomial<GenPolynomial<C>> f = red.sum(white); 256 int s = red.length() + white.length(); 257 int t = f.length(); 258 if (t != s) { 259 logger.warn("incomplete coloring state {} != {}", s, t); 260 logger.info("f = {}, red = {}, white = {}", f, red, white); 261 //throw new RuntimeException("illegal coloring state " + s + " != " + t); 262 } 263 return f; 264 } 265 266 267 /** 268 * Length of red and white parts. 269 * @return length of essential parts. 270 */ 271 public int length() { 272 int s = red.length() + white.length(); 273 return s; 274 } 275 276 277 /** 278 * Get leading exponent vector. 279 * @return LT of red or white parts. 280 */ 281 public ExpVector leadingExpVector() { 282 if (!red.isZERO()) { 283 return red.leadingExpVector(); 284 } 285 return white.leadingExpVector(); 286 } 287 288 289 /** 290 * Get leading monomial. 291 * @return LM of red or white parts. 292 */ 293 public Map.Entry<ExpVector, GenPolynomial<C>> leadingMonomial() { 294 if (!red.isZERO()) { 295 return red.leadingMonomial(); 296 } 297 return white.leadingMonomial(); 298 } 299 300 301 /** 302 * ColorPolynomial absolute value. 303 * @return abs(this). 304 */ 305 public ColorPolynomial<C> abs() { 306 GenPolynomial<GenPolynomial<C>> g, r, w; 307 int s = green.signum(); 308 if (s > 0) { 309 return this; 310 } 311 if (s < 0) { 312 g = green.negate(); 313 r = red.negate(); 314 w = white.negate(); 315 return new ColorPolynomial<C>(g, r, w); 316 } 317 // green == 0 318 g = green; 319 s = red.signum(); 320 if (s > 0) { 321 return this; 322 } 323 if (s < 0) { 324 r = red.negate(); 325 w = white.negate(); 326 return new ColorPolynomial<C>(g, r, w); 327 } 328 // red == 0 329 r = red; 330 s = white.signum(); 331 if (s > 0) { 332 return this; 333 } 334 if (s < 0) { 335 w = white.negate(); 336 return new ColorPolynomial<C>(g, r, w); 337 } 338 // white == 0 339 w = white; 340 return new ColorPolynomial<C>(g, r, w); 341 } 342 343 344 /** 345 * ColorPolynomial summation. <b>Note:</b> green coefficients stay green, 346 * all others become white. 347 * @param S ColorPolynomial. 348 * @return this+S. 349 */ 350 public ColorPolynomial<C> sum(ColorPolynomial<C> S) { 351 GenPolynomial<GenPolynomial<C>> g, r, w; 352 g = green.sum(S.green); 353 r = red.ring.getZERO(); 354 w = getEssentialPolynomial().sum(S.getEssentialPolynomial()); 355 return new ColorPolynomial<C>(g, r, w); 356 } 357 358 359 /** 360 * ColorPolynomial summation. 361 * @param s GenPolynomial. 362 * @param e exponent vector. 363 * @return this+(c e). 364 */ 365 public ColorPolynomial<C> sum(GenPolynomial<C> s, ExpVector e) { 366 GenPolynomial<GenPolynomial<C>> g, r, w; 367 g = green; 368 r = red; 369 w = white; 370 if (green.getMap().keySet().contains(e)) { 371 g = green.sum(s, e); 372 } else if (red.getMap().keySet().contains(e)) { 373 r = red.sum(s, e); 374 } else { 375 w = white.sum(s, e); 376 } 377 return new ColorPolynomial<C>(g, r, w); 378 } 379 380 381 /** 382 * ColorPolynomial subtraction. <b>Note:</b> green coefficients stay green, 383 * all others become white. 384 * @param S ColorPolynomial. 385 * @return this-S. 386 */ 387 public ColorPolynomial<C> subtract(ColorPolynomial<C> S) { 388 GenPolynomial<GenPolynomial<C>> g, r, w; 389 g = green.subtract(S.green); 390 r = red.ring.getZERO(); 391 w = getEssentialPolynomial().subtract(S.getEssentialPolynomial()); 392 return new ColorPolynomial<C>(g, r, w); 393 } 394 395 396 /** 397 * ColorPolynomial subtract. 398 * @param s GenPolynomial. 399 * @param e exponent vector. 400 * @return this-(c e). 401 */ 402 public ColorPolynomial<C> subtract(GenPolynomial<C> s, ExpVector e) { 403 GenPolynomial<GenPolynomial<C>> g, r, w; 404 g = green; 405 r = red; 406 w = white; 407 if (green.getMap().keySet().contains(e)) { 408 g = green.subtract(s, e); 409 } else if (red.getMap().keySet().contains(e)) { 410 r = red.subtract(s, e); 411 } else { 412 w = white.subtract(s, e); 413 } 414 return new ColorPolynomial<C>(g, r, w); 415 } 416 417 418 /** 419 * ColorPolynomial multiplication by monomial. 420 * @param s Coefficient. 421 * @param e Expvector. 422 * @return this * (c t). 423 */ 424 public ColorPolynomial<C> multiply(GenPolynomial<C> s, ExpVector e) { 425 GenPolynomial<GenPolynomial<C>> g, r, w; 426 if (green instanceof GenSolvablePolynomial) { 427 logger.info("use left multiplication"); 428 GenSolvablePolynomial<GenPolynomial<C>> gs, rs, ws; 429 gs = (GenSolvablePolynomial<GenPolynomial<C>>) green; 430 rs = (GenSolvablePolynomial<GenPolynomial<C>>) red; 431 ws = (GenSolvablePolynomial<GenPolynomial<C>>) white; 432 g = gs.multiplyLeft(s, e); 433 r = rs.multiplyLeft(s, e); 434 w = ws.multiplyLeft(s, e); 435 } else { 436 g = green.multiply(s, e); 437 r = red.multiply(s, e); 438 w = white.multiply(s, e); 439 } 440 return new ColorPolynomial<C>(g, r, w); 441 } 442 443 444 /** 445 * ColorPolynomial multiplication by coefficient. 446 * @param s Coefficient. 447 * @return this * (s). 448 */ 449 public ColorPolynomial<C> multiply(GenPolynomial<C> s) { 450 GenPolynomial<GenPolynomial<C>> g, r, w; 451 // coefficients commute 452 g = green.multiply(s); 453 r = red.multiply(s); 454 w = white.multiply(s); 455 return new ColorPolynomial<C>(g, r, w); 456 } 457 458 459 /** 460 * ColorPolynomial division by coefficient. 461 * @param s Coefficient. 462 * @return this / (s). 463 */ 464 public ColorPolynomial<C> divide(GenPolynomial<C> s) { 465 GenPolynomial<GenPolynomial<C>> g, r, w; 466 g = green.divide(s); 467 r = red.divide(s); 468 w = white.divide(s); 469 return new ColorPolynomial<C>(g, r, w); 470 } 471 472 473}