001/* 002 * $Id: ColorPolynomial.java 5868 2018-07-20 15:44:13Z kredel $ 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.Logger; 016import org.apache.logging.log4j.LogManager; 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, 063 GenPolynomial<GenPolynomial<C>> r, 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) > LT(white). 172 * @return true, if all ordering invariants are met, else false. 173 */ 174 public boolean checkInvariant() { 175 boolean t = true; 176 ExpVector ttg, ltr, ttr, ltw; 177 Comparator<ExpVector> cmp; 178 if (green.isZERO() && red.isZERO() && white.isZERO()) { 179 return true; 180 } 181 if (green.isZERO() && red.isZERO()) { 182 return true; 183 } 184 if (red.isZERO() && white.isZERO()) { 185 return true; 186 } 187 188 if (!green.isZERO() && !red.isZERO()) { 189 ttg = green.trailingExpVector(); 190 ltr = red.leadingExpVector(); 191 cmp = green.ring.tord.getDescendComparator(); 192 t = t && (cmp.compare(ttg, ltr) < 0); 193 } 194 if (!red.isZERO() && !white.isZERO()) { 195 ttr = red.trailingExpVector(); 196 ltw = white.leadingExpVector(); 197 cmp = white.ring.tord.getDescendComparator(); 198 t = t && (cmp.compare(ttr, ltw) < 0); 199 } 200 if (red.isZERO() && !green.isZERO() && !white.isZERO()) { 201 ttg = green.trailingExpVector(); 202 ltw = white.leadingExpVector(); 203 cmp = white.ring.tord.getDescendComparator(); 204 t = t && (cmp.compare(ttg, ltw) < 0); 205 } 206 if (!t) { 207 System.out.println("not invariant " + this); 208 // throw new RuntimeException("test"); 209 } 210 return t; 211 } 212 213 214 /** 215 * Get zero condition on coefficients. 216 * @return green coefficients. 217 */ 218 public List<GenPolynomial<C>> getGreenCoefficients() { 219 Collection<GenPolynomial<C>> c = green.getMap().values(); 220 return new ArrayList<GenPolynomial<C>>(c); 221 } 222 223 224 /** 225 * Get non zero condition on coefficients. 226 * @return red coefficients. 227 */ 228 public List<GenPolynomial<C>> getRedCoefficients() { 229 Collection<GenPolynomial<C>> c = red.getMap().values(); 230 return new ArrayList<GenPolynomial<C>>(c); 231 } 232 233 234 /** 235 * Get full polynomial. 236 * @return sum of all parts. 237 */ 238 public GenPolynomial<GenPolynomial<C>> getPolynomial() { 239 GenPolynomial<GenPolynomial<C>> f = green.sum(red).sum(white); 240 int s = green.length() + red.length() + white.length(); 241 int t = f.length(); 242 if (t != s) { 243 throw new RuntimeException("illegal coloring state " + s + " != " + t); 244 } 245 return f; 246 } 247 248 249 /** 250 * Get essential polynomial. 251 * @return sum of red and white parts. 252 */ 253 public GenPolynomial<GenPolynomial<C>> getEssentialPolynomial() { 254 GenPolynomial<GenPolynomial<C>> f = red.sum(white); 255 int s = red.length() + white.length(); 256 int t = f.length(); 257 if (t != s) { 258 logger.warn("incomplete coloring state " + s + " != " + t); 259 logger.info("f = " + f + ", red = " + red + ", white = " + white); 260 //throw new RuntimeException("illegal coloring state " + s + " != " + t); 261 } 262 return f; 263 } 264 265 266 /** 267 * Length of red and white parts. 268 * @return length of essential parts. 269 */ 270 public int length() { 271 int s = red.length() + white.length(); 272 return s; 273 } 274 275 276 /** 277 * Get leading exponent vector. 278 * @return LT of red or white parts. 279 */ 280 public ExpVector leadingExpVector() { 281 if (!red.isZERO()) { 282 return red.leadingExpVector(); 283 } 284 return white.leadingExpVector(); 285 } 286 287 288 /** 289 * Get leading monomial. 290 * @return LM of red or white parts. 291 */ 292 public Map.Entry<ExpVector, GenPolynomial<C>> leadingMonomial() { 293 if (!red.isZERO()) { 294 return red.leadingMonomial(); 295 } 296 return white.leadingMonomial(); 297 } 298 299 300 /** 301 * ColorPolynomial absolute value. 302 * @return abs(this). 303 */ 304 public ColorPolynomial<C> abs() { 305 GenPolynomial<GenPolynomial<C>> g, r, w; 306 int s = green.signum(); 307 if (s > 0) { 308 return this; 309 } 310 if (s < 0) { 311 g = green.negate(); 312 r = red.negate(); 313 w = white.negate(); 314 return new ColorPolynomial<C>(g, r, w); 315 } 316 // green == 0 317 g = green; 318 s = red.signum(); 319 if (s > 0) { 320 return this; 321 } 322 if (s < 0) { 323 r = red.negate(); 324 w = white.negate(); 325 return new ColorPolynomial<C>(g, r, w); 326 } 327 // red == 0 328 r = red; 329 s = white.signum(); 330 if (s > 0) { 331 return this; 332 } 333 if (s < 0) { 334 w = white.negate(); 335 return new ColorPolynomial<C>(g, r, w); 336 } 337 // white == 0 338 w = white; 339 return new ColorPolynomial<C>(g, r, w); 340 } 341 342 343 /** 344 * ColorPolynomial summation. <b>Note:</b> green coefficients stay green, 345 * all others become white. 346 * @param S ColorPolynomial. 347 * @return this+S. 348 */ 349 public ColorPolynomial<C> sum(ColorPolynomial<C> S) { 350 GenPolynomial<GenPolynomial<C>> g, r, w; 351 g = green.sum(S.green); 352 r = red.ring.getZERO(); 353 w = getEssentialPolynomial().sum(S.getEssentialPolynomial()); 354 return new ColorPolynomial<C>(g, r, w); 355 } 356 357 358 /** 359 * ColorPolynomial summation. 360 * @param s GenPolynomial. 361 * @param e exponent vector. 362 * @return this+(c e). 363 */ 364 public ColorPolynomial<C> sum(GenPolynomial<C> s, ExpVector e) { 365 GenPolynomial<GenPolynomial<C>> g, r, w; 366 g = green; 367 r = red; 368 w = white; 369 if (green.getMap().keySet().contains(e)) { 370 g = green.sum(s, e); 371 } else if (red.getMap().keySet().contains(e)) { 372 r = red.sum(s, e); 373 } else { 374 w = white.sum(s, e); 375 } 376 return new ColorPolynomial<C>(g, r, w); 377 } 378 379 380 /** 381 * ColorPolynomial subtraction. <b>Note:</b> green coefficients stay green, 382 * all others become white. 383 * @param S ColorPolynomial. 384 * @return this-S. 385 */ 386 public ColorPolynomial<C> subtract(ColorPolynomial<C> S) { 387 GenPolynomial<GenPolynomial<C>> g, r, w; 388 g = green.subtract(S.green); 389 r = red.ring.getZERO(); 390 w = getEssentialPolynomial().subtract(S.getEssentialPolynomial()); 391 return new ColorPolynomial<C>(g, r, w); 392 } 393 394 395 /** 396 * ColorPolynomial subtract. 397 * @param s GenPolynomial. 398 * @param e exponent vector. 399 * @return this-(c e). 400 */ 401 public ColorPolynomial<C> subtract(GenPolynomial<C> s, ExpVector e) { 402 GenPolynomial<GenPolynomial<C>> g, r, w; 403 g = green; 404 r = red; 405 w = white; 406 if (green.getMap().keySet().contains(e)) { 407 g = green.subtract(s, e); 408 } else if (red.getMap().keySet().contains(e)) { 409 r = red.subtract(s, e); 410 } else { 411 w = white.subtract(s, e); 412 } 413 return new ColorPolynomial<C>(g, r, w); 414 } 415 416 417 /** 418 * ColorPolynomial multiplication by monomial. 419 * @param s Coefficient. 420 * @param e Expvector. 421 * @return this * (c t). 422 */ 423 public ColorPolynomial<C> multiply(GenPolynomial<C> s, ExpVector e) { 424 GenPolynomial<GenPolynomial<C>> g, r, w; 425 if (green instanceof GenSolvablePolynomial) { 426 logger.info("use left multiplication"); 427 GenSolvablePolynomial<GenPolynomial<C>> gs, rs, ws; 428 gs = (GenSolvablePolynomial<GenPolynomial<C>>) green; 429 rs = (GenSolvablePolynomial<GenPolynomial<C>>) red; 430 ws = (GenSolvablePolynomial<GenPolynomial<C>>) white; 431 g = gs.multiplyLeft(s, e); 432 r = rs.multiplyLeft(s, e); 433 w = ws.multiplyLeft(s, e); 434 } else { 435 g = green.multiply(s, e); 436 r = red.multiply(s, e); 437 w = white.multiply(s, e); 438 } 439 return new ColorPolynomial<C>(g, r, w); 440 } 441 442 443 /** 444 * ColorPolynomial multiplication by coefficient. 445 * @param s Coefficient. 446 * @return this * (s). 447 */ 448 public ColorPolynomial<C> multiply(GenPolynomial<C> s) { 449 GenPolynomial<GenPolynomial<C>> g, r, w; 450 // coefficients commute 451 g = green.multiply(s); 452 r = red.multiply(s); 453 w = white.multiply(s); 454 return new ColorPolynomial<C>(g, r, w); 455 } 456 457 458 /** 459 * ColorPolynomial division by coefficient. 460 * @param s Coefficient. 461 * @return this / (s). 462 */ 463 public ColorPolynomial<C> divide(GenPolynomial<C> s) { 464 GenPolynomial<GenPolynomial<C>> g, r, w; 465 g = green.divide(s); 466 r = red.divide(s); 467 w = white.divide(s); 468 return new ColorPolynomial<C>(g, r, w); 469 } 470 471 472}