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