001/* 002 * $Id: CReductionSeq.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.Collections; 011import java.util.LinkedList; 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.GenPolynomialRing; 021import edu.jas.structure.GcdRingElem; 022import edu.jas.structure.RingFactory; 023import edu.jas.ufd.GCDFactory; 024import edu.jas.ufd.GreatestCommonDivisor; 025 026 027/** 028 * Polynomial parametric ring reduction sequential use algorithm. Implements 029 * normalform, condition construction and polynomial determination. 030 * @param <C> coefficient type 031 * @author Heinz Kredel 032 */ 033public class CReductionSeq<C extends GcdRingElem<C>> implements Serializable 034/* extends ReductionAbstract<C> */ 035/* implements CReduction<C> */{ 036 037 038 private static final Logger logger = LogManager.getLogger(CReductionSeq.class); 039 040 041 //private static final boolean debug = logger.isDebugEnabled(); 042 043 044 private final boolean info = logger.isInfoEnabled(); 045 046 047 /** 048 * Greatest common divisor engine. 049 */ 050 protected final GreatestCommonDivisor<C> engine; 051 052 053 /** 054 * Polynomial coefficient ring factory. 055 */ 056 protected final RingFactory<C> cofac; 057 058 059 /** 060 * Flag if top-reduction only should be used. 061 */ 062 protected boolean top = true; // false; 063 064 065 /** 066 * Constructor. 067 * @param rf coefficient factory. 068 */ 069 public CReductionSeq(RingFactory<C> rf) { 070 cofac = rf; 071 // System.out.println("cofac = " + cofac); 072 engine = GCDFactory.<C> getImplementation(cofac); 073 } 074 075 076 /** 077 * S-Polynomial. 078 * @param Ap polynomial. 079 * @param Bp polynomial. 080 * @return spol(Ap,Bp) the S-polynomial of Ap and Bp. 081 */ 082 public ColorPolynomial<C> SPolynomial(ColorPolynomial<C> Ap, ColorPolynomial<C> Bp) { 083 if (Bp == null || Bp.isZERO()) { 084 return Bp; 085 } 086 if (Ap == null || Ap.isZERO()) { 087 return Ap; 088 } 089 090 Map.Entry<ExpVector, GenPolynomial<C>> ma = Ap.red.leadingMonomial(); 091 Map.Entry<ExpVector, GenPolynomial<C>> mb = Bp.red.leadingMonomial(); 092 093 ExpVector e = ma.getKey(); 094 ExpVector f = mb.getKey(); 095 096 ExpVector g = e.lcm(f); // EVLCM(e,f); 097 ExpVector e1 = g.subtract(e); // EVDIF(g,e); 098 ExpVector f1 = g.subtract(f); // EVDIF(g,f); 099 100 GenPolynomial<C> a = ma.getValue(); 101 GenPolynomial<C> b = mb.getValue(); 102 103 GenPolynomial<C> c = engine.gcd(a, b); 104 if (!c.isONE()) { 105 // System.out.println("gcd =s " + c); 106 a = a.divide(c); 107 b = b.divide(c); 108 } 109 110 ColorPolynomial<C> App = Ap.multiply(b, e1); // multiplyLeft in poly 111 ColorPolynomial<C> Bpp = Bp.multiply(a, f1); // multiplyLeft in poly 112 ColorPolynomial<C> Cp = App.subtract(Bpp); 113 assert (! g.equals(Cp.getEssentialPolynomial().leadingExpVector())) : "g == lt(Cp)"; 114 return Cp; 115 } 116 117 118 /** 119 * Is top reducible. 120 * @param A polynomial. 121 * @param P polynomial list. 122 * @return true if A is top reducible with respect to P. 123 */ 124 public boolean isTopReducible(List<ColorPolynomial<C>> P, ColorPolynomial<C> A) { 125 if (P == null || P.isEmpty()) { 126 return false; 127 } 128 if (A == null || A.isZERO()) { 129 return false; 130 } 131 boolean mt = false; 132 ExpVector e = A.leadingExpVector(); 133 for (ColorPolynomial<C> p : P) { 134 if (p == null) { 135 return false; 136 } 137 ExpVector f = p.leadingExpVector(); 138 if (f == null) { 139 return false; 140 } 141 if (e == null) { 142 return false; 143 } 144 mt = e.multipleOf(f); // EVMT( e, p.leadingExpVector() ); 145 if (mt) { 146 return true; 147 } 148 } 149 return false; 150 } 151 152 153 /** 154 * Is reducible. 155 * @param Ap polynomial. 156 * @param Pp polynomial list. 157 * @return true if Ap is reducible with respect to Pp. 158 */ 159 public boolean isReducible(List<ColorPolynomial<C>> Pp, ColorPolynomial<C> Ap) { 160 return !isNormalform(Pp, Ap); 161 } 162 163 164 /** 165 * Is in Normalform. 166 * @param Ap polynomial. 167 * @param Pp polynomial list. 168 * @return true if Ap is in normalform with respect to Pp. 169 */ 170 @SuppressWarnings("unchecked") 171 public boolean isNormalform(List<ColorPolynomial<C>> Pp, ColorPolynomial<C> Ap) { 172 if (Pp == null || Pp.isEmpty()) { 173 return true; 174 } 175 if (Ap == null || Ap.isZERO()) { 176 return true; 177 } 178 int l; 179 ColorPolynomial<C>[] P; 180 synchronized (Pp) { 181 l = Pp.size(); 182 P = new ColorPolynomial[l]; 183 // P = Pp.toArray(); 184 for (int i = 0; i < Pp.size(); i++) { 185 P[i] = Pp.get(i); 186 } 187 } 188 ExpVector[] htl = new ExpVector[l]; 189 ColorPolynomial<C>[] p = new ColorPolynomial[l]; 190 Map.Entry<ExpVector, GenPolynomial<C>> m; 191 int i; 192 int j = 0; 193 for (i = 0; i < l; i++) { 194 p[i] = P[i]; 195 m = p[i].red.leadingMonomial(); 196 if (m != null) { 197 p[j] = p[i]; 198 htl[j] = m.getKey(); 199 j++; 200 } 201 } 202 l = j; 203 boolean mt = false; 204 for (ExpVector e : Ap.red.getMap().keySet()) { 205 for (i = 0; i < l; i++) { 206 mt = e.multipleOf(htl[i]); // EVMT( e, htl[i] ); 207 if (mt) { 208 System.out.println("not normalform " + Ap + ", P[i] = " + P[i]); 209 return false; 210 } 211 } 212 if (top) { 213 return true; 214 } 215 } 216 for (ExpVector e : Ap.white.getMap().keySet()) { 217 for (i = 0; i < l; i++) { 218 mt = e.multipleOf(htl[i]); // EVMT( e, htl[i] ); 219 if (mt) { 220 System.out.println("not normalform " + Ap + ", P[i] = " + P[i]); 221 return false; 222 } 223 } 224 if (top) { 225 return true; 226 } 227 } 228 return true; 229 } 230 231 232 /** 233 * Is in Normalform. 234 * @param Pp polynomial list. 235 * @return true if each Ap in Pp is in normalform with respect to Pp\{Ap}. 236 */ 237 public boolean isNormalform(List<ColorPolynomial<C>> Pp) { 238 if (Pp == null || Pp.isEmpty()) { 239 return true; 240 } 241 ColorPolynomial<C> Ap; 242 List<ColorPolynomial<C>> P = new LinkedList<ColorPolynomial<C>>(Pp); 243 int s = P.size(); 244 for (int i = 0; i < s; i++) { 245 Ap = P.remove(i); 246 if (!isNormalform(P, Ap)) { 247 return false; 248 } 249 P.add(Ap); 250 } 251 return true; 252 } 253 254 255 /** 256 * Normalform. 257 * @param Ap polynomial. 258 * @param Pp polynomial list. 259 * @param cond condition for these polynomials. 260 * @return nf(Ap) with respect to Pp. 261 */ 262 @SuppressWarnings("unchecked") 263 public ColorPolynomial<C> normalform(Condition<C> cond, List<ColorPolynomial<C>> Pp, ColorPolynomial<C> Ap) { 264 if (Pp == null || Pp.isEmpty()) { 265 return Ap; 266 } 267 if (Ap == null || Ap.isZERO()) { 268 return Ap; 269 } 270 Map.Entry<ExpVector, GenPolynomial<C>> m; 271 int l; 272 ColorPolynomial<C>[] P; 273 synchronized (Pp) { 274 l = Pp.size(); 275 P = new ColorPolynomial[l]; 276 // P = Pp.toArray(); 277 for (int i = 0; i < Pp.size(); i++) { 278 P[i] = Pp.get(i); 279 } 280 } 281 ExpVector[] htl = new ExpVector[l]; 282 Object[] lbc = new Object[l]; // want C[] 283 ColorPolynomial<C>[] p = new ColorPolynomial[l]; 284 int i; 285 int j = 0; 286 for (i = 0; i < l; i++) { 287 if (P[i] == null) { 288 continue; 289 } 290 p[i] = P[i]; 291 m = p[i].red.leadingMonomial(); 292 if (m != null) { 293 p[j] = p[i]; 294 htl[j] = m.getKey(); 295 lbc[j] = m.getValue(); 296 j++; 297 } 298 } 299 l = j; 300 ExpVector e, f; 301 GenPolynomial<C> a; 302 boolean mt = false; 303 GenPolynomial<GenPolynomial<C>> zero = p[0].red.ring.getZERO(); 304 ColorPolynomial<C> R = new ColorPolynomial<C>(zero, zero, zero); 305 306 // ColorPolynomial<C> T = null; 307 ColorPolynomial<C> Q = null; 308 ColorPolynomial<C> S = Ap; 309 while (S.length() > 0) { 310 m = S.leadingMonomial(); 311 e = m.getKey(); 312 a = m.getValue(); 313 Condition.Color col = cond.color(a); 314 if (col == Condition.Color.GREEN) { // move to green terms 315 GenPolynomial<GenPolynomial<C>> g = S.green.sum(a, e); 316 GenPolynomial<GenPolynomial<C>> r = S.red; 317 GenPolynomial<GenPolynomial<C>> w = S.white; 318 if (S.red.isZERO()) { 319 w = w.subtract(a, e); 320 } else { // only in minimalGB 321 logger.info("green_red = " + zero.sum(a, e)); 322 r = r.subtract(a, e); 323 } 324 S = new ColorPolynomial<C>(g, r, w); 325 continue; 326 } 327 //if (col == Condition.Color.WHITE) { // refine condition 328 // System.out.println("white = " + zero.sum(a,e)); 329 // return S; // return for new case distinction 330 //} 331 // System.out.println("NF, e = " + e); 332 for (i = 0; i < l; i++) { 333 mt = e.multipleOf(htl[i]); // EVMT( e, htl[i] ); 334 if (mt) 335 break; 336 } 337 if (!mt) { 338 // logger.debug("irred"); 339 if (top) { 340 return S; 341 } 342 R = R.sum(a, e); 343 S = S.subtract(a, e); 344 // System.out.println(" S = " + S); 345 } else { 346 f = e; 347 e = e.subtract(htl[i]); // EVDIF( e, htl[i] ); 348 // logger.info("red div = " + e); 349 GenPolynomial<C> c = (GenPolynomial<C>) lbc[i]; 350 GenPolynomial<C> g = engine.gcd(a, c); 351 if (!g.isONE()) { 352 // System.out.println("gcd = " + g); 353 a = a.divide(g); 354 c = c.divide(g); 355 } 356 S = S.multiply(c); 357 R = R.multiply(c); 358 Q = p[i].multiply(a, e); // multiplyLeft in poly 359 S = S.subtract(Q); 360 assert (! f.equals(S.getEssentialPolynomial().leadingExpVector()) ) : "f == lt(S)"; 361 } 362 } 363 return R; 364 } 365 366 367 /* 368 * -------- coloring and condition stuff ------------------------------ 369 */ 370 371 /** 372 * Case distinction conditions of parametric polynomial list. The returned 373 * condition determines the polynomial list. 374 * @param L list of parametric polynomials. 375 * @return list of conditions as case distinction. 376 */ 377 public List<Condition<C>> caseDistinction(List<GenPolynomial<GenPolynomial<C>>> L) { 378 List<Condition<C>> cd = new ArrayList<Condition<C>>(); 379 if (L == null || L.size() == 0) { 380 return cd; 381 } 382 for (GenPolynomial<GenPolynomial<C>> A : L) { 383 if (A != null && !A.isZERO()) { 384 cd = caseDistinction(cd, A); 385 } 386 } 387 // System.out.println("cd = " + cd); 388 return cd; 389 } 390 391 392 /** 393 * Case distinction conditions of parametric polynomial list. 394 * @param cd a list of conditions. 395 * @param A a parametric polynomial. 396 * @return list of conditions as case distinction extending the conditions 397 * in cd. 398 */ 399 public List<Condition<C>> caseDistinction(List<Condition<C>> cd, GenPolynomial<GenPolynomial<C>> A) { 400 if (A == null || A.isZERO()) { 401 return cd; 402 } 403 if (cd == null) { 404 cd = new ArrayList<Condition<C>>(); 405 } 406 if (cd.size() == 0) { // construct empty condition 407 RingFactory<GenPolynomial<C>> crfac = A.ring.coFac; 408 GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) crfac; 409 Condition<C> sc = new Condition<C>(cfac); 410 cd.add(sc); 411 } 412 GenPolynomial<GenPolynomial<C>> Ap; 413 GenPolynomial<GenPolynomial<C>> Bp; 414 415 List<Condition<C>> C = new ArrayList<Condition<C>>( /* leer! */); 416 for (Condition<C> cond : cd) { 417 // System.out.println("caseDist: " + cond); 418 Condition<C> cz = cond; 419 Ap = A; 420 while (!Ap.isZERO()) { 421 GenPolynomial<C> c = Ap.leadingBaseCoefficient(); 422 Bp = Ap.reductum(); 423 //System.out.println("to color: " + c); 424 switch (cz.color(c)) { 425 case GREEN: 426 // System.out.println("color green: " + c); 427 Ap = Bp; 428 continue; 429 case RED: 430 // System.out.println("color red: " + c); 431 C.add(cz); 432 // wrong: return C; 433 Ap = A.ring.getZERO(); 434 continue; 435 // break; 436 case WHITE: 437 default: 438 // System.out.println("color white: " + c); 439 Condition<C> nc = cz.extendNonZero(c); 440 if (nc != null) { // no contradiction 441 if (!cz.equals(nc)) { 442 C.add(nc); 443 } else { 444 cz = null; 445 Ap = A.ring.getZERO(); 446 continue; 447 } 448 } else { // contradiction rechecked in determine(c) 449 //System.out.println("this should not be printed, c = " + c); 450 //System.out.println("this should not be printed, cz = " + cz); 451 } 452 Condition<C> ez = cz.extendZero(c); 453 if (ez != null) { 454 cz = ez; 455 } else { // contradiction 456 cz = null; 457 Ap = A.ring.getZERO(); 458 continue; 459 } 460 Ap = Bp; 461 } 462 } 463 // System.out.println("cond cz: " + cz); 464 if (cz == null || cz.isContradictory() || C.contains(cz)) { 465 // System.out.println("not added entry " + cz); 466 } else { 467 C.add(cz); 468 } 469 } 470 // System.out.println("C = " + C); 471 return C; 472 } 473 474 475 /** 476 * Case distinction conditions of parametric polynomial list. 477 * @param A a parametric polynomial. 478 * @param cond a condition. 479 * @return list of case distinction conditions. 480 */ 481 public List<Condition<C>> caseDistinction(Condition<C> cond, GenPolynomial<GenPolynomial<C>> A) { 482 List<Condition<C>> cd = new ArrayList<Condition<C>>(); 483 if (A == null || A.isZERO()) { 484 return cd; 485 } 486 cd.add(cond); 487 cd = caseDistinction(cd, A); 488 if (info) { 489 StringBuffer s = new StringBuffer("extending condition: " + cond + "\n"); 490 s.append("case distinctions: [ \n"); 491 for (Condition<C> c : cd) { 492 s.append(c.toString() + "\n"); 493 } 494 s.append("]"); 495 logger.info(s.toString()); 496 } 497 return cd; 498 } 499 500 501 /** 502 * Determine polynomial list. 503 * @param H polynomial list. 504 * @return new determined list of colored systems. 505 */ 506 public List<ColoredSystem<C>> determine(List<GenPolynomial<GenPolynomial<C>>> H) { 507 if (H == null || H.size() == 0) { 508 List<ColoredSystem<C>> CS = new ArrayList<ColoredSystem<C>>(); 509 return CS; 510 } 511 //System.out.println("of determine = " + H); 512 Collections.reverse(H); 513 List<Condition<C>> cd = caseDistinction(H); 514 //System.out.println("case Distinction = " + cd); 515 //System.out.println("of determine = " + H); 516 return determine(cd, H); 517 } 518 519 520 /** 521 * Determine polynomial list. 522 * @param H polynomial list. 523 * @param cd case distiction, a condition list. 524 * @return new determined list of colored systems. 525 */ 526 public List<ColoredSystem<C>> determine(List<Condition<C>> cd, List<GenPolynomial<GenPolynomial<C>>> H) { 527 List<ColoredSystem<C>> CS = new ArrayList<ColoredSystem<C>>(); 528 if (H == null || H.size() == 0) { 529 return CS; 530 } 531 for (Condition<C> cond : cd) { 532 logger.info("determine wrt cond = " + cond); 533 if (cond.zero.isONE()) { // should not happen 534 System.out.println("ideal is one = " + cond.zero); 535 // continue; // can treat all coeffs as green 536 } 537 // if ( cond.isEmpty() ) { // do not use this code 538 // continue; // can skip condition (?) 539 // } 540 List<ColorPolynomial<C>> S = cond.determine(H); 541 ColoredSystem<C> cs = new ColoredSystem<C>(cond, S); 542 CS.add(cs); 543 } 544 return CS; 545 } 546 547}