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