001/* 002 * $Id: RecSolvablePolynomial.java 5872 2018-07-20 16:01:46Z kredel $ 003 */ 004 005package edu.jas.poly; 006 007 008import java.util.Map; 009import java.util.Set; 010import java.util.SortedMap; 011 012import org.apache.logging.log4j.Logger; 013import org.apache.logging.log4j.LogManager; 014 015import edu.jas.structure.RingElem; 016 017 018/** 019 * RecSolvablePolynomial generic recursive solvable polynomials implementing 020 * RingElem. n-variate ordered solvable polynomials over solvable polynomial 021 * coefficients. Objects of this class are intended to be immutable. The 022 * implementation is based on TreeMap respectively SortedMap from exponents to 023 * coefficients by extension of GenPolynomial. 024 * @param <C> coefficient type 025 * @author Heinz Kredel 026 */ 027 028public class RecSolvablePolynomial<C extends RingElem<C>> extends GenSolvablePolynomial<GenPolynomial<C>> { 029 030 031 /** 032 * The factory for the recursive solvable polynomial ring. Hides super.ring. 033 */ 034 public final RecSolvablePolynomialRing<C> ring; 035 036 037 private static final Logger logger = LogManager.getLogger(RecSolvablePolynomial.class); 038 039 040 private static final boolean debug = logger.isDebugEnabled(); 041 042 043 /** 044 * Constructor for zero RecSolvablePolynomial. 045 * @param r solvable polynomial ring factory. 046 */ 047 public RecSolvablePolynomial(RecSolvablePolynomialRing<C> r) { 048 super(r); 049 ring = r; 050 } 051 052 053 /** 054 * Constructor for RecSolvablePolynomial. 055 * @param r solvable polynomial ring factory. 056 * @param e exponent. 057 */ 058 public RecSolvablePolynomial(RecSolvablePolynomialRing<C> r, ExpVector e) { 059 this(r); 060 val.put(e, ring.getONECoefficient()); 061 } 062 063 064 /** 065 * Constructor for RecSolvablePolynomial. 066 * @param r solvable polynomial ring factory. 067 * @param c coefficient polynomial. 068 * @param e exponent. 069 */ 070 public RecSolvablePolynomial(RecSolvablePolynomialRing<C> r, GenPolynomial<C> c, ExpVector e) { 071 this(r); 072 if (c != null && !c.isZERO()) { 073 val.put(e, c); 074 } 075 } 076 077 078 /** 079 * Constructor for RecSolvablePolynomial. 080 * @param r solvable polynomial ring factory. 081 * @param c coefficient polynomial. 082 */ 083 public RecSolvablePolynomial(RecSolvablePolynomialRing<C> r, GenPolynomial<C> c) { 084 this(r, c, r.evzero); 085 } 086 087 088 /** 089 * Constructor for RecSolvablePolynomial. 090 * @param r solvable polynomial ring factory. 091 * @param S solvable polynomial. 092 */ 093 public RecSolvablePolynomial(RecSolvablePolynomialRing<C> r, GenSolvablePolynomial<GenPolynomial<C>> S) { 094 this(r, S.val); 095 } 096 097 098 /** 099 * Constructor for RecSolvablePolynomial. 100 * @param r solvable polynomial ring factory. 101 * @param v the SortedMap of some other (solvable) polynomial. 102 */ 103 protected RecSolvablePolynomial(RecSolvablePolynomialRing<C> r, SortedMap<ExpVector, GenPolynomial<C>> v) { 104 this(r); 105 val.putAll(v); // assume no zero coefficients 106 } 107 108 109 /** 110 * Get the corresponding element factory. 111 * @return factory for this Element. 112 * @see edu.jas.structure.Element#factory() 113 */ 114 @Override 115 public RecSolvablePolynomialRing<C> factory() { 116 return ring; 117 } 118 119 120 /** 121 * Clone this RecSolvablePolynomial. 122 * @see java.lang.Object#clone() 123 */ 124 @Override 125 public RecSolvablePolynomial<C> copy() { 126 return new RecSolvablePolynomial<C>(ring, this.val); 127 } 128 129 130 /** 131 * Comparison with any other object. 132 * @see java.lang.Object#equals(java.lang.Object) 133 */ 134 @Override 135 public boolean equals(Object B) { 136 if (!(B instanceof RecSolvablePolynomial)) { 137 return false; 138 } 139 // compare also coeffTable? 140 return super.equals(B); 141 } 142 143 144 /** 145 * RecSolvablePolynomial multiplication. 146 * @param Bp RecSolvablePolynomial. 147 * @return this*Bp, where * denotes solvable multiplication. 148 */ 149 // cannot @Override, @NoOverride 150 public RecSolvablePolynomial<C> multiply(RecSolvablePolynomial<C> Bp) { 151 if (Bp == null || Bp.isZERO()) { 152 return ring.getZERO(); 153 } 154 if (this.isZERO()) { 155 return this; 156 } 157 assert (ring.nvar == Bp.ring.nvar); 158 if (debug) { 159 logger.info("ring = " + ring.toScript()); 160 } 161 final boolean commute = ring.table.isEmpty(); 162 final boolean commuteCoeff = ring.coeffTable.isEmpty(); 163 GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) ring.coFac; 164 RecSolvablePolynomial<C> Dp = ring.getZERO().copy(); 165 ExpVector Z = ring.evzero; 166 ExpVector Zc = cfac.evzero; 167 GenPolynomial<C> one = ring.getONECoefficient(); 168 169 RecSolvablePolynomial<C> C1 = null; 170 RecSolvablePolynomial<C> C2 = null; 171 Map<ExpVector, GenPolynomial<C>> A = val; 172 Map<ExpVector, GenPolynomial<C>> B = Bp.val; 173 Set<Map.Entry<ExpVector, GenPolynomial<C>>> Bk = B.entrySet(); 174 if (debug) 175 logger.info("input A = " + this); 176 for (Map.Entry<ExpVector, GenPolynomial<C>> y : A.entrySet()) { 177 GenPolynomial<C> a = y.getValue(); 178 ExpVector e = y.getKey(); 179 if (debug) 180 logger.info("e = " + e + ", a = " + a); 181 int[] ep = e.dependencyOnVariables(); 182 int el1 = ring.nvar + 1; 183 if (ep.length > 0) { 184 el1 = ep[0]; 185 } 186 //int el1s = ring.nvar + 1 - el1; 187 if (debug) 188 logger.info("input B = " + Bp); 189 for (Map.Entry<ExpVector, GenPolynomial<C>> x : Bk) { 190 GenPolynomial<C> b = x.getValue(); 191 ExpVector f = x.getKey(); 192 if (debug) 193 logger.info("f = " + f + ", b = " + b); 194 int[] fp = f.dependencyOnVariables(); 195 int fl1 = 0; 196 if (fp.length > 0) { 197 fl1 = fp[fp.length - 1]; 198 } 199 int fl1s = ring.nvar + 1 - fl1; 200 // polynomial coefficient multiplication e*b = P_eb, for a*((e*b)*f) 201 RecSolvablePolynomial<C> Cps = ring.getZERO().copy(); 202 RecSolvablePolynomial<C> Cs = null; 203 if (commuteCoeff || b.isConstant() || e.isZERO()) { // symmetric 204 Cps.doAddTo(b, e); 205 if (debug) 206 logger.info("symmetric coeff, e*b: b = " + b + ", e = " + e); 207 } else { // unsymmetric 208 if (debug) 209 logger.info("unsymmetric coeff, e*b: b = " + b + ", e = " + e); 210 for (Map.Entry<ExpVector, C> z : b.val.entrySet()) { 211 C c = z.getValue(); 212 GenPolynomial<C> cc = b.ring.valueOf(c); 213 ExpVector g = z.getKey(); 214 if (debug) 215 logger.info("g = " + g + ", c = " + c); 216 int[] gp = g.dependencyOnVariables(); 217 int gl1 = 0; 218 if (gp.length > 0) { 219 gl1 = gp[gp.length - 1]; 220 } 221 int gl1s = b.ring.nvar + 1 - gl1; 222 if (debug) { 223 logger.info("gl1s = " + gl1s); 224 } 225 // split e = e1 * e2, g = g2 * g1 (= g1 * g2) 226 ExpVector e1 = e; 227 ExpVector e2 = Z; 228 if (!e.isZERO()) { 229 e1 = e.subst(el1, 0); 230 e2 = Z.subst(el1, e.getVal(el1)); 231 } 232 ExpVector e4; 233 ExpVector g1 = g; 234 ExpVector g2 = Zc; 235 if (!g.isZERO()) { 236 g1 = g.subst(gl1, 0); 237 g2 = Zc.subst(gl1, g.getVal(gl1)); 238 } 239 if (debug) { 240 logger.info("coeff, e1 = " + e1 + ", e2 = " + e2 + ", Cps = " + Cps); 241 logger.info("coeff, g1 = " + g1 + ", g2 = " + g2); 242 } 243 TableRelation<GenPolynomial<C>> crel = ring.coeffTable.lookup(e2, g2); 244 if (debug) 245 logger.info("coeff, crel = " + crel.p); 246 //logger.info("coeff, e = " + e + " g, = " + g + ", crel = " + crel); 247 Cs = new RecSolvablePolynomial<C>(ring, crel.p); 248 // rest of multiplication and update relations 249 if (crel.f != null) { // process remaining right power 250 GenPolynomial<C> c2 = b.ring.valueOf(crel.f); 251 C2 = new RecSolvablePolynomial<C>(ring, c2, Z); 252 Cs = Cs.multiply(C2); 253 if (crel.e == null) { 254 e4 = e2; 255 } else { 256 e4 = e2.subtract(crel.e); 257 } 258 ring.coeffTable.update(e4, g2, Cs); 259 } 260 if (crel.e != null) { // process remaining left power 261 C1 = new RecSolvablePolynomial<C>(ring, one, crel.e); 262 Cs = C1.multiply(Cs); 263 ring.coeffTable.update(e2, g2, Cs); 264 } 265 if (!g1.isZERO()) { // process remaining right part 266 GenPolynomial<C> c2 = b.ring.valueOf(g1); 267 C2 = new RecSolvablePolynomial<C>(ring, c2, Z); 268 Cs = Cs.multiply(C2); 269 } 270 if (!e1.isZERO()) { // process remaining left part 271 C1 = new RecSolvablePolynomial<C>(ring, one, e1); 272 Cs = C1.multiply(Cs); 273 } 274 //System.out.println("e1*Cs*g1 = " + Cs); 275 Cs = Cs.multiplyLeft(cc); // assume c, coeff(cc) commutes with Cs 276 //Cps = (RecSolvablePolynomial<C>) Cps.sum(Cs); 277 Cps.doAddTo(Cs); 278 } // end b loop 279 if (debug) 280 logger.info("coeff, Cs = " + Cs + ", Cps = " + Cps); 281 } 282 if (debug) 283 logger.info("coeff-poly: Cps = " + Cps); 284 // polynomial multiplication P_eb*f, for a*(P_eb*f) 285 RecSolvablePolynomial<C> Dps = ring.getZERO().copy(); 286 RecSolvablePolynomial<C> Ds = null; 287 RecSolvablePolynomial<C> D1, D2; 288 if (commute || Cps.isConstant() || f.isZERO()) { // symmetric 289 if (debug) 290 logger.info("symmetric poly, P_eb*f: Cps = " + Cps + ", f = " + f); 291 ExpVector g = e.sum(f); 292 if (Cps.isConstant()) { 293 Ds = new RecSolvablePolynomial<C>(ring, Cps.leadingBaseCoefficient(), g); // symmetric! 294 } else { 295 Ds = Cps.shift(f); // symmetric 296 } 297 } else { // eventually unsymmetric 298 if (debug) 299 logger.info("unsymmetric poly, P_eb*f: Cps = " + Cps + ", f = " + f); 300 for (Map.Entry<ExpVector, GenPolynomial<C>> z : Cps.val.entrySet()) { 301 // split g = g1 * g2, f = f1 * f2 302 GenPolynomial<C> c = z.getValue(); 303 ExpVector g = z.getKey(); 304 if (debug) 305 logger.info("g = " + g + ", c = " + c); 306 int[] gp = g.dependencyOnVariables(); 307 int gl1 = ring.nvar + 1; 308 if (gp.length > 0) { 309 gl1 = gp[0]; 310 } 311 int gl1s = ring.nvar + 1 - gl1; 312 if (gl1s <= fl1s) { // symmetric 313 ExpVector h = g.sum(f); 314 if (debug) 315 logger.info("disjoint poly: g = " + g + ", f = " + f + ", h = " + h); 316 Ds = ring.valueOf(h); // symmetric! 317 } else { 318 ExpVector g1 = g.subst(gl1, 0); 319 ExpVector g2 = Z.subst(gl1, g.getVal(gl1)); // bug el1, gl1 320 ExpVector g4; 321 ExpVector f1 = f.subst(fl1, 0); 322 ExpVector f2 = Z.subst(fl1, f.getVal(fl1)); 323 if (debug) { 324 logger.info("poly, g1 = " + g1 + ", f1 = " + f1 + ", Dps = " + Dps); 325 logger.info("poly, g2 = " + g2 + ", f2 = " + f2); 326 } 327 TableRelation<GenPolynomial<C>> rel = ring.table.lookup(g2, f2); 328 if (debug) 329 logger.info("poly, g = " + g + ", f = " + f + ", rel = " + rel); 330 Ds = new RecSolvablePolynomial<C>(ring, rel.p); //ring.copy(rel.p); 331 if (rel.f != null) { 332 D2 = ring.valueOf(rel.f); 333 Ds = Ds.multiply(D2); 334 if (rel.e == null) { 335 g4 = g2; 336 } else { 337 g4 = g2.subtract(rel.e); 338 } 339 ring.table.update(g4, f2, Ds); 340 } 341 if (rel.e != null) { 342 D1 = ring.valueOf(rel.e); 343 Ds = D1.multiply(Ds); 344 ring.table.update(g2, f2, Ds); 345 } 346 if (!f1.isZERO()) { 347 D2 = ring.valueOf(f1); 348 Ds = Ds.multiply(D2); 349 //ring.table.update(?,f1,Ds) 350 } 351 if (!g1.isZERO()) { 352 D1 = ring.valueOf(g1); 353 Ds = D1.multiply(Ds); 354 //ring.table.update(e1,?,Ds) 355 } 356 } 357 Ds = Ds.multiplyLeft(c); // assume c commutes with Cs 358 Dps.doAddTo(Ds); 359 } // end Dps loop 360 Ds = Dps; 361 } 362 if (debug) { 363 logger.info("recursion+: Ds = " + Ds + ", a = " + a); 364 } 365 // polynomial coefficient multiplication a*(P_eb*f) = a*Ds 366 Ds = Ds.multiplyLeft(a); // multiply(a,b); // non-symmetric 367 if (debug) 368 logger.info("recursion-: Ds = " + Ds); 369 Dp.doAddTo(Ds); 370 if (debug) 371 logger.info("end B loop: Dp = " + Dp); 372 } // end B loop 373 if (debug) 374 logger.info("end A loop: Dp = " + Dp); 375 } // end A loop 376 return Dp; 377 } 378 379 380 /** 381 * RecSolvablePolynomial left and right multiplication. Product with two 382 * polynomials. 383 * @param S RecSolvablePolynomial. 384 * @param T RecSolvablePolynomial. 385 * @return S*this*T. 386 */ 387 // cannot @Override, @NoOverride 388 public RecSolvablePolynomial<C> multiply(RecSolvablePolynomial<C> S, RecSolvablePolynomial<C> T) { 389 if (S.isZERO() || T.isZERO() || this.isZERO()) { 390 return ring.getZERO(); 391 } 392 if (S.isONE()) { 393 return multiply(T); 394 } 395 if (T.isONE()) { 396 return S.multiply(this); 397 } 398 return S.multiply(this).multiply(T); 399 } 400 401 402 /** 403 * RecSolvablePolynomial multiplication. Product with coefficient ring 404 * element. 405 * @param b coefficient polynomial. 406 * @return this*b, where * is coefficient multiplication. 407 */ 408 // cannot @Override 409 //public RecSolvablePolynomial<C> multiply(GenPolynomial<C> b) { 410 //public GenSolvablePolynomial<GenPolynomial<C>> multiply(GenPolynomial<C> b) { 411 public RecSolvablePolynomial<C> recMultiply(GenPolynomial<C> b) { 412 RecSolvablePolynomial<C> Cp = ring.getZERO().copy(); 413 if (b == null || b.isZERO()) { 414 return Cp; 415 } 416 Cp = new RecSolvablePolynomial<C>(ring, b, ring.evzero); 417 return multiply(Cp); 418 // wrong: 419 // Map<ExpVector, GenPolynomial<C>> Cm = Cp.val; //getMap(); 420 // Map<ExpVector, GenPolynomial<C>> Am = val; 421 // for (Map.Entry<ExpVector, GenPolynomial<C>> y : Am.entrySet()) { 422 // ExpVector e = y.getKey(); 423 // GenPolynomial<C> a = y.getValue(); 424 // GenPolynomial<C> c = a.multiply(b); 425 // if (!c.isZERO()) { 426 // Cm.put(e, c); 427 // } 428 // } 429 // return Cp; 430 } 431 432 433 /** 434 * RecSolvablePolynomial left and right multiplication. Product with 435 * coefficient ring element. 436 * @param b coefficient polynomial. 437 * @param c coefficient polynomial. 438 * @return b*this*c, where * is coefficient multiplication. 439 */ 440 @Override 441 public RecSolvablePolynomial<C> multiply(GenPolynomial<C> b, GenPolynomial<C> c) { 442 RecSolvablePolynomial<C> Cp = ring.getZERO().copy(); 443 if (b == null || b.isZERO()) { 444 return Cp; 445 } 446 if (c == null || c.isZERO()) { 447 return Cp; 448 } 449 RecSolvablePolynomial<C> Cb = ring.valueOf(b); 450 RecSolvablePolynomial<C> Cc = ring.valueOf(c); 451 return Cb.multiply(this).multiply(Cc); 452 // wrong: 453 // Map<ExpVector, GenPolynomial<C>> Cm = Cp.val; //getMap(); 454 // Map<ExpVector, GenPolynomial<C>> Am = val; 455 // for (Map.Entry<ExpVector, GenPolynomial<C>> y : Am.entrySet()) { 456 // ExpVector e = y.getKey(); 457 // GenPolynomial<C> a = y.getValue(); 458 // GenPolynomial<C> d = b.multiply(a).multiply(c); 459 // if (!d.isZERO()) { 460 // Cm.put(e, d); 461 // } 462 // } 463 // return Cp; 464 } 465 466 467 /* 468 * RecSolvablePolynomial multiplication. Product with coefficient ring 469 * element. 470 * @param b coefficient of coefficient. 471 * @return this*b, where * is coefficient multiplication. 472 */ 473 //@Override not possible, @NoOverride 474 //public RecSolvablePolynomial<C> multiply(C b) { ... } 475 476 477 /** 478 * RecSolvablePolynomial multiplication. Product with exponent vector. 479 * @param e exponent. 480 * @return this * x<sup>e</sup>, where * denotes solvable multiplication. 481 */ 482 @Override 483 public RecSolvablePolynomial<C> multiply(ExpVector e) { 484 if (e == null || e.isZERO()) { 485 return this; 486 } 487 GenPolynomial<C> b = ring.getONECoefficient(); 488 return multiply(b, e); 489 } 490 491 492 /** 493 * RecSolvablePolynomial left and right multiplication. Product with 494 * exponent vector. 495 * @param e exponent. 496 * @param f exponent. 497 * @return x<sup>e</sup> * this * x<sup>f</sup>, where * denotes solvable 498 * multiplication. 499 */ 500 @Override 501 public RecSolvablePolynomial<C> multiply(ExpVector e, ExpVector f) { 502 if (e == null || e.isZERO()) { 503 return this; 504 } 505 if (f == null || f.isZERO()) { 506 return this; 507 } 508 GenPolynomial<C> b = ring.getONECoefficient(); 509 return multiply(b, e, b, f); 510 } 511 512 513 /** 514 * RecSolvablePolynomial multiplication. Product with ring element and 515 * exponent vector. 516 * @param b coefficient polynomial. 517 * @param e exponent. 518 * @return this * b x<sup>e</sup>, where * denotes solvable multiplication. 519 */ 520 @Override 521 public RecSolvablePolynomial<C> multiply(GenPolynomial<C> b, ExpVector e) { 522 if (b == null || b.isZERO()) { 523 return ring.getZERO(); 524 } 525 RecSolvablePolynomial<C> Cp = ring.valueOf(b, e); 526 return multiply(Cp); 527 } 528 529 530 /** 531 * RecSolvablePolynomial left and right multiplication. Product with ring 532 * element and exponent vector. 533 * @param b coefficient polynomial. 534 * @param e exponent. 535 * @param c coefficient polynomial. 536 * @param f exponent. 537 * @return b x<sup>e</sup> * this * c x<sup>f</sup>, where * denotes 538 * solvable multiplication. 539 */ 540 @Override 541 public RecSolvablePolynomial<C> multiply(GenPolynomial<C> b, ExpVector e, GenPolynomial<C> c, ExpVector f) { 542 if (b == null || b.isZERO()) { 543 return ring.getZERO(); 544 } 545 if (c == null || c.isZERO()) { 546 return ring.getZERO(); 547 } 548 RecSolvablePolynomial<C> Cp = ring.valueOf(b, e); 549 RecSolvablePolynomial<C> Dp = ring.valueOf(c, f); 550 return multiply(Cp, Dp); 551 } 552 553 554 /** 555 * RecSolvablePolynomial multiplication. Left product with ring element and 556 * exponent vector. 557 * @param b coefficient polynomial. 558 * @param e exponent. 559 * @return b x<sup>e</sup> * this, where * denotes solvable multiplication. 560 */ 561 @Override 562 public RecSolvablePolynomial<C> multiplyLeft(GenPolynomial<C> b, ExpVector e) { 563 if (b == null || b.isZERO()) { 564 return ring.getZERO(); 565 } 566 RecSolvablePolynomial<C> Cp = ring.valueOf(b, e); 567 return Cp.multiply(this); 568 } 569 570 571 /** 572 * RecSolvablePolynomial multiplication. Left product with exponent vector. 573 * @param e exponent. 574 * @return x<sup>e</sup> * this, where * denotes solvable multiplication. 575 */ 576 @Override 577 public RecSolvablePolynomial<C> multiplyLeft(ExpVector e) { 578 if (e == null || e.isZERO()) { 579 return this; 580 } 581 RecSolvablePolynomial<C> Cp = ring.valueOf(e); 582 return Cp.multiply(this); 583 } 584 585 586 /** 587 * RecSolvablePolynomial multiplication. Left product with coefficient ring 588 * element. 589 * @param b coefficient polynomial. 590 * @return b*this, where * is coefficient multiplication. 591 */ 592 @Override 593 public RecSolvablePolynomial<C> multiplyLeft(GenPolynomial<C> b) { 594 RecSolvablePolynomial<C> Cp = ring.getZERO().copy(); 595 if (b == null || b.isZERO()) { 596 return Cp; 597 } 598 GenSolvablePolynomial<C> bb = null; 599 if (b instanceof GenSolvablePolynomial) { 600 //throw new RuntimeException("wrong method dispatch in JRE "); 601 logger.debug("warn: wrong method dispatch in JRE multiply(b) - trying to fix"); 602 bb = (GenSolvablePolynomial<C>) b; 603 } 604 Map<ExpVector, GenPolynomial<C>> Cm = Cp.val; //getMap(); 605 Map<ExpVector, GenPolynomial<C>> Am = val; 606 GenPolynomial<C> c; 607 for (Map.Entry<ExpVector, GenPolynomial<C>> y : Am.entrySet()) { 608 ExpVector e = y.getKey(); 609 GenPolynomial<C> a = y.getValue(); 610 if (bb != null) { 611 GenSolvablePolynomial<C> aa = (GenSolvablePolynomial<C>) a; 612 c = bb.multiply(aa); 613 } else { 614 c = b.multiply(a); 615 } 616 if (!c.isZERO()) { 617 Cm.put(e, c); 618 } 619 } 620 return Cp; 621 } 622 623 624 /** 625 * RecSolvablePolynomial multiplication. Left product with 'monomial'. 626 * @param m 'monomial'. 627 * @return m * this, where * denotes solvable multiplication. 628 */ 629 @Override 630 public RecSolvablePolynomial<C> multiplyLeft(Map.Entry<ExpVector, GenPolynomial<C>> m) { 631 if (m == null) { 632 return ring.getZERO(); 633 } 634 return multiplyLeft(m.getValue(), m.getKey()); 635 } 636 637 638 /** 639 * RecSolvablePolynomial multiplication. Product with 'monomial'. 640 * @param m 'monomial'. 641 * @return this * m, where * denotes solvable multiplication. 642 */ 643 @Override 644 public RecSolvablePolynomial<C> multiply(Map.Entry<ExpVector, GenPolynomial<C>> m) { 645 if (m == null) { 646 return ring.getZERO(); 647 } 648 return multiply(m.getValue(), m.getKey()); 649 } 650 651 652 /** 653 * RecSolvablePolynomial multiplication. Commutative product with exponent 654 * vector. 655 * @param f exponent vector. 656 * @return B*f, where * is commutative multiplication. 657 */ 658 public RecSolvablePolynomial<C> shift(ExpVector f) { 659 RecSolvablePolynomial<C> C = ring.getZERO().copy(); 660 if (this.isZERO()) { 661 return C; 662 } 663 if (f == null || f.isZERO()) { 664 return this; 665 } 666 Map<ExpVector, GenPolynomial<C>> Cm = C.val; 667 Map<ExpVector, GenPolynomial<C>> Bm = this.val; 668 for (Map.Entry<ExpVector, GenPolynomial<C>> y : Bm.entrySet()) { 669 ExpVector e = y.getKey(); 670 GenPolynomial<C> a = y.getValue(); 671 ExpVector d = e.sum(f); 672 if (!a.isZERO()) { 673 Cm.put(d, a); 674 } 675 } 676 return C; 677 } 678 679 680 /** 681 * RecSolvablePolynomial multiplication. Commutative product with 682 * coefficient. 683 * @param b coefficient. 684 * @return B*b, where * is commutative multiplication with respect to main variables. 685 */ 686 public RecSolvablePolynomial<C> multiplyRightComm(GenPolynomial<C> b) { 687 RecSolvablePolynomial<C> C = ring.getZERO().copy(); 688 if (this.isZERO()) { 689 return C; 690 } 691 if (b == null || b.isZERO()) { 692 return this; 693 } 694 Map<ExpVector, GenPolynomial<C>> Cm = C.val; 695 Map<ExpVector, GenPolynomial<C>> Bm = this.val; 696 for (Map.Entry<ExpVector, GenPolynomial<C>> y : Bm.entrySet()) { 697 ExpVector e = y.getKey(); 698 GenPolynomial<C> a = y.getValue(); 699 a = a.multiply(b); 700 if (!a.isZERO()) { 701 Cm.put(e, a); 702 } 703 } 704 return C; 705 } 706 707 708 /** 709 * RecSolvablePolynomial right coefficients from left coefficients. 710 * <b>Note:</b> R is represented as a polynomial with left coefficients, the 711 * implementation can at the moment not distinguish between left and right 712 * coefficients. 713 * @return R = sum( X<sup>i</sup> b<sub>i</sub> ), with this = 714 * sum(a<sub>i</sub> X<sup>i</sup> ) and eval(sum(X<sup>i</sup> 715 * b<sub>i</sub>)) == sum(a<sub>i</sub> X<sup>i</sup>) 716 */ 717 @SuppressWarnings("cast") 718 @Override 719 public GenSolvablePolynomial<GenPolynomial<C>> rightRecursivePolynomial() { 720 if (this.isZERO()) { 721 return this; 722 } 723 if (!(this instanceof RecSolvablePolynomial)) { 724 return this; 725 } 726 RecSolvablePolynomialRing<C> rfac = (RecSolvablePolynomialRing<C>) ring; 727 if (rfac.coeffTable.isEmpty()) { 728 return this; 729 } 730 RecSolvablePolynomial<C> R = rfac.getZERO().copy(); 731 RecSolvablePolynomial<C> p = this; 732 RecSolvablePolynomial<C> r; 733 while (!p.isZERO()) { 734 ExpVector f = p.leadingExpVector(); 735 GenPolynomial<C> a = p.leadingBaseCoefficient(); 736 //r = h.multiply(a); // wrong method dispatch // right: f*a 737 //okay: r = onep.multiply(one, f, a, zero); // right: (1 f) * 1 * (a zero) 738 r = rfac.valueOf(f).multiply(rfac.valueOf(a)); // right: (1 f) * 1 * (a zero) 739 //System.out.println("a,f = " + a + ", " + f); // + ", h.ring = " + h.ring.toScript()); 740 //System.out.println("f*a = " + r); // + ", r.ring = " + r.ring.toScript()); 741 p = (RecSolvablePolynomial<C>) p.subtract(r); 742 R = (RecSolvablePolynomial<C>) R.sum(a, f); 743 //R.doPutToMap(f, a); 744 } 745 return R; 746 } 747 748 749 /** 750 * Evaluate RecSolvablePolynomial as right coefficients polynomial. 751 * <b>Note:</b> R is represented as a polynomial with left coefficients, the 752 * implementation can at the moment not distinguish between left and right 753 * coefficients. 754 * @return this as evaluated polynomial R. R = sum( X<sup>i</sup> 755 * b<sub>i</sub> ), this = sum(a<sub>i</sub> X<sup>i</sup> ) = 756 * eval(sum(X<sup>i</sup> b<sub>i</sub>)) 757 */ 758 @SuppressWarnings("cast") 759 @Override 760 public GenSolvablePolynomial<GenPolynomial<C>> evalAsRightRecursivePolynomial() { 761 if (this.isONE() || this.isZERO()) { 762 return this; 763 } 764 if (!(this instanceof RecSolvablePolynomial)) { 765 return this; 766 } 767 RecSolvablePolynomialRing<C> rfac = (RecSolvablePolynomialRing<C>) ring; 768 if (rfac.coeffTable.isEmpty()) { 769 return this; 770 } 771 RecSolvablePolynomial<C> q = rfac.getZERO(); 772 RecSolvablePolynomial<C> s; 773 RecSolvablePolynomial<C> r = (RecSolvablePolynomial<C>) this; 774 for (Map.Entry<ExpVector, GenPolynomial<C>> y : r.getMap().entrySet()) { 775 ExpVector f = y.getKey(); 776 GenPolynomial<C> a = y.getValue(); 777 // f.multiply(a); // wrong method dispatch // right: f*a 778 // onep.multiply(f).multiply(a) // should do now 779 //okay: s = onep.multiply(one, f, a, zero); // right: (1 f) * 1 * (a zero) 780 s = rfac.valueOf(f).multiply(rfac.valueOf(a)); // right: (1 f) * 1 * (a zero) 781 q = (RecSolvablePolynomial<C>) q.sum(s); 782 } 783 return q; 784 } 785 786 787 /** 788 * Test RecSolvablePolynomial right coefficients polynomial. <b>Note:</b> R 789 * is represented as a polynomial with left coefficients, the implementation 790 * can at the moment not distinguish between left and right coefficients. 791 * @param R GenSolvablePolynomial with right coefficients. 792 * @return true, if R is polynomial with right coefficients of this. R = 793 * sum( X<sup>i</sup> b<sub>i</sub> ), with this = sum(a<sub>i</sub> 794 * X<sup>i</sup> ) and eval(sum(X<sup>i</sup> b<sub>i</sub>)) == 795 * sum(a<sub>i</sub> X<sup>i</sup>) 796 */ 797 @SuppressWarnings("cast") 798 @Override 799 public boolean isRightRecursivePolynomial(GenSolvablePolynomial<GenPolynomial<C>> R) { 800 if (this.isZERO()) { 801 return R.isZERO(); 802 } 803 if (this.isONE()) { 804 return R.isONE(); 805 } 806 if (!(this instanceof RecSolvablePolynomial)) { 807 return !(R instanceof RecSolvablePolynomial); 808 } 809 if (!(R instanceof RecSolvablePolynomial)) { 810 return false; 811 } 812 RecSolvablePolynomialRing<C> rfac = (RecSolvablePolynomialRing<C>) ring; 813 if (rfac.coeffTable.isEmpty()) { 814 RecSolvablePolynomialRing<C> rf = (RecSolvablePolynomialRing<C>) R.ring; 815 return rf.coeffTable.isEmpty(); 816 } 817 RecSolvablePolynomial<C> p = (RecSolvablePolynomial<C>) this; 818 RecSolvablePolynomial<C> q = (RecSolvablePolynomial<C>) R.evalAsRightRecursivePolynomial(); 819 p = (RecSolvablePolynomial<C>) PolyUtil.<C> monic(p); 820 q = (RecSolvablePolynomial<C>) PolyUtil.<C> monic(q); 821 return p.equals(q); 822 } 823 824}