001/* 002 * $Id: RecSolvableWordPolynomial.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 * RecSolvableWordPolynomial generic recursive solvable polynomials implementing 020 * RingElem. n-variate ordered solvable polynomials over non-commutative word 021 * polynomial coefficients. Objects of this class are intended to be immutable. 022 * The implementation is based on TreeMap respectively SortedMap from exponents 023 * to coefficients by extension of GenPolynomial. 024 * @param <C> base coefficient type 025 * @author Heinz Kredel 026 */ 027 028public class RecSolvableWordPolynomial<C extends RingElem<C>> extends 029 GenSolvablePolynomial<GenWordPolynomial<C>> { 030 031 032 /** 033 * The factory for the recursive solvable polynomial ring. Hides super.ring. 034 */ 035 public final RecSolvableWordPolynomialRing<C> ring; 036 037 038 private static final Logger logger = LogManager.getLogger(RecSolvableWordPolynomial.class); 039 040 041 private static final boolean debug = logger.isDebugEnabled(); 042 043 044 /** 045 * Constructor for zero RecSolvableWordPolynomial. 046 * @param r solvable polynomial ring factory. 047 */ 048 public RecSolvableWordPolynomial(RecSolvableWordPolynomialRing<C> r) { 049 super(r); 050 ring = r; 051 } 052 053 054 /** 055 * Constructor for RecSolvableWordPolynomial. 056 * @param r solvable polynomial ring factory. 057 * @param e exponent. 058 */ 059 public RecSolvableWordPolynomial(RecSolvableWordPolynomialRing<C> r, ExpVector e) { 060 this(r); 061 val.put(e, ring.getONECoefficient()); 062 } 063 064 065 /** 066 * Constructor for RecSolvableWordPolynomial. 067 * @param r solvable polynomial ring factory. 068 * @param c coefficient polynomial. 069 * @param e exponent. 070 */ 071 public RecSolvableWordPolynomial(RecSolvableWordPolynomialRing<C> r, GenWordPolynomial<C> c, ExpVector e) { 072 this(r); 073 if (c != null && !c.isZERO()) { 074 val.put(e, c); 075 } 076 } 077 078 079 /** 080 * Constructor for RecSolvableWordPolynomial. 081 * @param r solvable polynomial ring factory. 082 * @param c coefficient polynomial. 083 */ 084 public RecSolvableWordPolynomial(RecSolvableWordPolynomialRing<C> r, GenWordPolynomial<C> c) { 085 this(r, c, r.evzero); 086 } 087 088 089 /** 090 * Constructor for RecSolvableWordPolynomial. 091 * @param r solvable polynomial ring factory. 092 * @param S solvable polynomial. 093 */ 094 public RecSolvableWordPolynomial(RecSolvableWordPolynomialRing<C> r, 095 GenSolvablePolynomial<GenWordPolynomial<C>> S) { 096 this(r, S.val); 097 } 098 099 100 /** 101 * Constructor for RecSolvableWordPolynomial. 102 * @param r solvable polynomial ring factory. 103 * @param v the SortedMap of some other (solvable) polynomial. 104 */ 105 protected RecSolvableWordPolynomial(RecSolvableWordPolynomialRing<C> r, 106 SortedMap<ExpVector, GenWordPolynomial<C>> v) { 107 this(r); 108 val.putAll(v); // assume no zero coefficients 109 } 110 111 112 /** 113 * Get the corresponding element factory. 114 * @return factory for this Element. 115 * @see edu.jas.structure.Element#factory() 116 */ 117 @Override 118 public RecSolvableWordPolynomialRing<C> factory() { 119 return ring; 120 } 121 122 123 /** 124 * Clone this RecSolvableWordPolynomial. 125 * @see java.lang.Object#clone() 126 */ 127 @Override 128 public RecSolvableWordPolynomial<C> copy() { 129 return new RecSolvableWordPolynomial<C>(ring, this.val); 130 } 131 132 133 /** 134 * Comparison with any other object. 135 * @see java.lang.Object#equals(java.lang.Object) 136 */ 137 @Override 138 public boolean equals(Object B) { 139 if (!(B instanceof RecSolvableWordPolynomial)) { 140 return false; 141 } 142 return super.equals(B); 143 } 144 145 146 /** 147 * RecSolvableWordPolynomial multiplication. 148 * @param Bp RecSolvableWordPolynomial. 149 * @return this*Bp, where * denotes solvable multiplication. 150 */ 151 // cannot @Override, @NoOverride 152 public RecSolvableWordPolynomial<C> multiply(RecSolvableWordPolynomial<C> Bp) { 153 if (Bp == null || Bp.isZERO()) { 154 return ring.getZERO(); 155 } 156 if (this.isZERO()) { 157 return this; 158 } 159 assert (ring.nvar == Bp.ring.nvar); 160 if (debug) { 161 logger.info("ring = " + ring.toScript()); 162 } 163 final boolean commute = ring.table.isEmpty(); 164 final boolean commuteCoeff = ring.coeffTable.isEmpty(); 165 //GenWordPolynomialRing<C> cfac = (GenWordPolynomialRing<C>) ring.coFac; 166 RecSolvableWordPolynomial<C> Dp = ring.getZERO().copy(); 167 RecSolvableWordPolynomial<C> zero = ring.getZERO(); //.copy(); not needed 168 ExpVector Z = ring.evzero; 169 //Word Zc = cfac.wone; 170 GenWordPolynomial<C> one = ring.getONECoefficient(); 171 172 RecSolvableWordPolynomial<C> C1 = null; 173 RecSolvableWordPolynomial<C> C2 = null; 174 Map<ExpVector, GenWordPolynomial<C>> A = val; 175 Map<ExpVector, GenWordPolynomial<C>> B = Bp.val; 176 Set<Map.Entry<ExpVector, GenWordPolynomial<C>>> Bk = B.entrySet(); 177 if (debug) 178 logger.info("input A = " + this); 179 for (Map.Entry<ExpVector, GenWordPolynomial<C>> y : A.entrySet()) { 180 GenWordPolynomial<C> a = y.getValue(); 181 ExpVector e = y.getKey(); 182 if (debug) 183 logger.info("e = " + e + ", a = " + a); 184 int[] ep = e.dependencyOnVariables(); 185 int el1 = ring.nvar + 1; 186 if (ep.length > 0) { 187 el1 = ep[0]; 188 } 189 //int el1s = ring.nvar + 1 - el1; 190 if (debug) 191 logger.info("input B = " + Bp); 192 for (Map.Entry<ExpVector, GenWordPolynomial<C>> x : Bk) { 193 GenWordPolynomial<C> b = x.getValue(); 194 ExpVector f = x.getKey(); 195 if (debug) 196 logger.info("f = " + f + ", b = " + b); 197 int[] fp = f.dependencyOnVariables(); 198 int fl1 = 0; 199 if (fp.length > 0) { 200 fl1 = fp[fp.length - 1]; 201 } 202 int fl1s = ring.nvar + 1 - fl1; 203 // polynomial coefficient multiplication e*b = P_eb, for a*((e*b)*f) 204 RecSolvableWordPolynomial<C> Cps = ring.getZERO().copy(); 205 RecSolvableWordPolynomial<C> Cs = null; 206 if (commuteCoeff || b.isConstant() || e.isZERO()) { // symmetric 207 //Cps = (RecSolvableWordPolynomial<C>) zero.sum(b, e); 208 Cps.doAddTo(b, e); 209 if (debug) 210 logger.info("symmetric coeff, e*b: b = " + b + ", e = " + e); 211 } else { // unsymmetric 212 if (debug) 213 logger.info("unsymmetric coeff, e*b: b = " + b + ", e = " + e); 214 for (Map.Entry<Word, C> z : b.val.entrySet()) { 215 C c = z.getValue(); 216 GenWordPolynomial<C> cc = b.ring.getONE().multiply(c); 217 Word g = z.getKey(); 218 if (debug) 219 logger.info("g = " + g + ", c = " + c); 220 // split e = e1 * e2, g = g2 * g1 221 ExpVector g2 = g.leadingExpVector(); 222 Word g1 = g.reductum(); 223 //ExpVector g1; 224 //System.out.println("c = " + c + ", g = " + g + ", g1 = " + g1 + ", g1 == 1: " + g1.isONE()); 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 if (debug) { 232 logger.info("coeff, e1 = " + e1 + ", e2 = " + e2 + ", Cps = " + Cps); 233 logger.info("coeff, g2 = " + g2 + ", g1 = " + g1); 234 } 235 TableRelation<GenWordPolynomial<C>> crel = ring.coeffTable.lookup(e2, g2); 236 if (debug) 237 logger.info("coeff, crel = " + crel.p); 238 //System.out.println("coeff, e = " + e + ", g = " + g + ", crel = " + crel); 239 Cs = new RecSolvableWordPolynomial<C>(ring, crel.p); 240 // rest of multiplication and update relations 241 if (crel.f != null) { // process remaining right power 242 //GenWordPolynomial<C> c2 = b.ring.getONE().multiply(crel.f); 243 GenWordPolynomial<C> c2 = b.ring.valueOf(crel.f); 244 C2 = ring.valueOf(c2); //new RecSolvableWordPolynomial<C>(ring, c2, Z); 245 Cs = Cs.multiply(C2); 246 ExpVector e4; 247 if (crel.e == null) { 248 e4 = e2; 249 } else { 250 e4 = e2.subtract(crel.e); 251 } 252 ring.coeffTable.update(e4, g2, Cs); 253 } 254 if (crel.e != null) { // process remaining left power 255 C1 = ring.valueOf(crel.e); //new RecSolvableWordPolynomial<C>(ring, one, crel.e); 256 Cs = C1.multiply(Cs); 257 ring.coeffTable.update(e2, g2, Cs); 258 } 259 if (!g1.isONE()) { // process remaining right part 260 //GenWordPolynomial<C> c2 = b.ring.getONE().multiply(g1); 261 GenWordPolynomial<C> c2 = b.ring.valueOf(g1); 262 C2 = ring.valueOf(c2); //new RecSolvableWordPolynomial<C>(ring, c2, Z); 263 Cs = Cs.multiply(C2); 264 } 265 if (!e1.isZERO()) { // process remaining left part 266 C1 = ring.valueOf(e1); //new RecSolvableWordPolynomial<C>(ring, one, e1); 267 Cs = C1.multiply(Cs); 268 } 269 //System.out.println("e1*Cs*g1 = " + Cs); 270 Cs = Cs.multiplyLeft(cc); // assume c, coeff(cc) commutes with Cs 271 //Cps = (RecSolvableWordPolynomial<C>) Cps.sum(Cs); 272 Cps.doAddTo(Cs); 273 } // end b loop 274 if (debug) 275 logger.info("coeff, Cs = " + Cs + ", Cps = " + Cps); 276 //System.out.println("coeff loop end, Cs = " + Cs + ", Cps = " + Cps); 277 } 278 if (debug) 279 logger.info("coeff-poly: Cps = " + Cps); 280 // polynomial multiplication P_eb*f, for a*(P_eb*f) 281 RecSolvableWordPolynomial<C> Dps = ring.getZERO().copy(); 282 RecSolvableWordPolynomial<C> Ds = null; 283 RecSolvableWordPolynomial<C> D1, D2; 284 if (commute || Cps.isConstant() || f.isZERO()) { // symmetric 285 if (debug) 286 logger.info("symmetric poly, P_eb*f: Cps = " + Cps + ", f = " + f); 287 ExpVector g = e.sum(f); 288 if (Cps.isConstant()) { 289 Ds = ring.valueOf(Cps.leadingBaseCoefficient(), g); //new RecSolvableWordPolynomial<C>(ring, Cps.leadingBaseCoefficient(), g); // symmetric! 290 } else { 291 Ds = Cps.shift(f); // symmetric 292 } 293 } else { // eventually unsymmetric 294 if (debug) 295 logger.info("unsymmetric poly, P_eb*f: Cps = " + Cps + ", f = " + f); 296 for (Map.Entry<ExpVector, GenWordPolynomial<C>> z : Cps.val.entrySet()) { 297 // split g = g1 * g2, f = f1 * f2 298 GenWordPolynomial<C> c = z.getValue(); 299 ExpVector g = z.getKey(); 300 if (debug) 301 logger.info("g = " + g + ", c = " + c); 302 int[] gp = g.dependencyOnVariables(); 303 int gl1 = ring.nvar + 1; 304 if (gp.length > 0) { 305 gl1 = gp[0]; 306 } 307 int gl1s = ring.nvar + 1 - gl1; 308 if (gl1s <= fl1s) { // symmetric 309 ExpVector h = g.sum(f); 310 if (debug) 311 logger.info("disjoint poly: g = " + g + ", f = " + f + ", h = " + h); 312 Ds = (RecSolvableWordPolynomial<C>) zero.sum(one, h); // symmetric! 313 } else { 314 ExpVector g1 = g.subst(gl1, 0); 315 ExpVector g2 = Z.subst(gl1, g.getVal(gl1)); // bug el1, gl1 316 ExpVector g4; 317 ExpVector f1 = f.subst(fl1, 0); 318 ExpVector f2 = Z.subst(fl1, f.getVal(fl1)); 319 if (debug) { 320 logger.info("poly, g1 = " + g1 + ", f1 = " + f1 + ", Dps = " + Dps); 321 logger.info("poly, g2 = " + g2 + ", f2 = " + f2); 322 } 323 TableRelation<GenWordPolynomial<C>> rel = ring.table.lookup(g2, f2); 324 if (debug) 325 logger.info("poly, g = " + g + ", f = " + f + ", rel = " + rel); 326 Ds = new RecSolvableWordPolynomial<C>(ring, rel.p); //ring.copy(rel.p); 327 if (rel.f != null) { 328 D2 = ring.valueOf(rel.f); //new RecSolvableWordPolynomial<C>(ring, one, rel.f); 329 Ds = Ds.multiply(D2); 330 if (rel.e == null) { 331 g4 = g2; 332 } else { 333 g4 = g2.subtract(rel.e); 334 } 335 ring.table.update(g4, f2, Ds); 336 } 337 if (rel.e != null) { 338 D1 = ring.valueOf(rel.e); //new RecSolvableWordPolynomial<C>(ring, one, rel.e); 339 Ds = D1.multiply(Ds); 340 ring.table.update(g2, f2, Ds); 341 } 342 if (!f1.isZERO()) { 343 D2 = ring.valueOf(f1); //new RecSolvableWordPolynomial<C>(ring, one, f1); 344 Ds = Ds.multiply(D2); 345 //ring.table.update(?,f1,Ds) 346 } 347 if (!g1.isZERO()) { 348 D1 = ring.valueOf(g1); //new RecSolvableWordPolynomial<C>(ring, one, g1); 349 Ds = D1.multiply(Ds); 350 //ring.table.update(e1,?,Ds) 351 } 352 } 353 //System.out.println("main loop, Cs = " + Cs + ", c = " + c); 354 Ds = Ds.multiplyLeft(c); // assume c commutes with Cs 355 //Dps = (RecSolvableWordPolynomial<C>) Dps.sum(Ds); 356 Dps.doAddTo(Ds); 357 } // end Dps loop 358 Ds = Dps; 359 } 360 if (debug) { 361 logger.info("recursion+: Ds = " + Ds + ", a = " + a); 362 } 363 // polynomial coefficient multiplication a*(P_eb*f) = a*Ds 364 //System.out.println("main loop, Ds = " + Ds + ", a = " + a); 365 Ds = Ds.multiplyLeft(a); // multiply(a,b); // non-symmetric 366 if (debug) 367 logger.info("recursion-: Ds = " + Ds); 368 //Dp = (RecSolvableWordPolynomial<C>) Dp.sum(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 * RecSolvableWordPolynomial left and right multiplication. Product with two 382 * polynomials. 383 * @param S RecSolvableWordPolynomial. 384 * @param T RecSolvableWordPolynomial. 385 * @return S*this*T. 386 */ 387 // cannot @Override, @NoOverride 388 public RecSolvableWordPolynomial<C> multiply(RecSolvableWordPolynomial<C> S, 389 RecSolvableWordPolynomial<C> T) { 390 if (S.isZERO() || T.isZERO() || this.isZERO()) { 391 return ring.getZERO(); 392 } 393 if (S.isONE()) { 394 return multiply(T); 395 } 396 if (T.isONE()) { 397 return S.multiply(this); 398 } 399 return S.multiply(this).multiply(T); 400 } 401 402 403 /** 404 * RecSolvableWordPolynomial multiplication. Product with coefficient ring 405 * element. 406 * @param b coefficient polynomial. 407 * @return this*b, where * is coefficient multiplication. 408 */ 409 // cannot @Override 410 //public RecSolvableWordPolynomial<C> multiply(GenWordPolynomial<C> b) { 411 //public GenSolvablePolynomial<GenWordPolynomial<C>> multiply(GenWordPolynomial<C> b) { 412 public RecSolvableWordPolynomial<C> recMultiply(GenWordPolynomial<C> b) { 413 RecSolvableWordPolynomial<C> Cp = ring.getZERO().copy(); 414 if (b == null || b.isZERO()) { 415 return Cp; 416 } 417 Cp = new RecSolvableWordPolynomial<C>(ring, b, ring.evzero); 418 return multiply(Cp); 419 } 420 421 422 /** 423 * RecSolvableWordPolynomial left and right multiplication. Product with 424 * coefficient ring element. 425 * @param b coefficient polynomial. 426 * @param c coefficient polynomial. 427 * @return b*this*c, where * is coefficient multiplication. 428 */ 429 @Override 430 public RecSolvableWordPolynomial<C> multiply(GenWordPolynomial<C> b, GenWordPolynomial<C> c) { 431 RecSolvableWordPolynomial<C> Cp = ring.getZERO().copy(); 432 if (b == null || b.isZERO()) { 433 return Cp; 434 } 435 if (c == null || c.isZERO()) { 436 return Cp; 437 } 438 RecSolvableWordPolynomial<C> Cb = ring.valueOf(b); //new RecSolvableWordPolynomial<C>(ring, b, ring.evzero); 439 RecSolvableWordPolynomial<C> Cc = ring.valueOf(c); //new RecSolvableWordPolynomial<C>(ring, c, ring.evzero); 440 return Cb.multiply(this).multiply(Cc); 441 } 442 443 444 /* 445 * RecSolvableWordPolynomial multiplication. Product with coefficient ring 446 * element. 447 * @param b coefficient of coefficient. 448 * @return this*b, where * is coefficient multiplication. 449 */ 450 //@Override not possible, @NoOverride 451 //public RecSolvableWordPolynomial<C> multiply(C b) { ... } 452 453 454 /** 455 * RecSolvableWordPolynomial multiplication. Product with exponent vector. 456 * @param e exponent. 457 * @return this * x<sup>e</sup>, where * denotes solvable multiplication. 458 */ 459 @Override 460 public RecSolvableWordPolynomial<C> multiply(ExpVector e) { 461 if (e == null || e.isZERO()) { 462 return this; 463 } 464 GenWordPolynomial<C> b = ring.getONECoefficient(); 465 return multiply(b, e); 466 } 467 468 469 /** 470 * RecSolvableWordPolynomial left and right multiplication. Product with 471 * exponent vector. 472 * @param e exponent. 473 * @param f exponent. 474 * @return x<sup>e</sup> * this * x<sup>f</sup>, where * denotes solvable 475 * multiplication. 476 */ 477 @Override 478 public RecSolvableWordPolynomial<C> multiply(ExpVector e, ExpVector f) { 479 if (e == null || e.isZERO()) { 480 return this; 481 } 482 if (f == null || f.isZERO()) { 483 return this; 484 } 485 GenWordPolynomial<C> b = ring.getONECoefficient(); 486 return multiply(b, e, b, f); 487 } 488 489 490 /** 491 * RecSolvableWordPolynomial multiplication. Product with ring element and 492 * exponent vector. 493 * @param b coefficient polynomial. 494 * @param e exponent. 495 * @return this * b x<sup>e</sup>, where * denotes solvable multiplication. 496 */ 497 @Override 498 public RecSolvableWordPolynomial<C> multiply(GenWordPolynomial<C> b, ExpVector e) { 499 if (b == null || b.isZERO()) { 500 return ring.getZERO(); 501 } 502 RecSolvableWordPolynomial<C> Cp = ring.valueOf(b, e); //new RecSolvableWordPolynomial<C>(ring, b, e); 503 return multiply(Cp); 504 } 505 506 507 /** 508 * RecSolvableWordPolynomial left and right multiplication. Product with 509 * ring element and exponent vector. 510 * @param b coefficient polynomial. 511 * @param e exponent. 512 * @param c coefficient polynomial. 513 * @param f exponent. 514 * @return b x<sup>e</sup> * this * c x<sup>f</sup>, where * denotes 515 * solvable multiplication. 516 */ 517 @Override 518 public RecSolvableWordPolynomial<C> multiply(GenWordPolynomial<C> b, ExpVector e, GenWordPolynomial<C> c, 519 ExpVector f) { 520 if (b == null || b.isZERO()) { 521 return ring.getZERO(); 522 } 523 if (c == null || c.isZERO()) { 524 return ring.getZERO(); 525 } 526 RecSolvableWordPolynomial<C> Cp = ring.valueOf(b, e); //new RecSolvableWordPolynomial<C>(ring, b, e); 527 RecSolvableWordPolynomial<C> Dp = ring.valueOf(c, f); //new RecSolvableWordPolynomial<C>(ring, c, f); 528 return multiply(Cp, Dp); 529 } 530 531 532 /** 533 * RecSolvableWordPolynomial multiplication. Left product with ring element 534 * and exponent vector. 535 * @param b coefficient polynomial. 536 * @param e exponent. 537 * @return b x<sup>e</sup> * this, where * denotes solvable multiplication. 538 */ 539 @Override 540 public RecSolvableWordPolynomial<C> multiplyLeft(GenWordPolynomial<C> b, ExpVector e) { 541 if (b == null || b.isZERO()) { 542 return ring.getZERO(); 543 } 544 RecSolvableWordPolynomial<C> Cp = ring.valueOf(b, e); //new RecSolvableWordPolynomial<C>(ring, b, e); 545 return Cp.multiply(this); 546 } 547 548 549 /** 550 * RecSolvableWordPolynomial multiplication. Left product with exponent 551 * vector. 552 * @param e exponent. 553 * @return x<sup>e</sup> * this, where * denotes solvable multiplication. 554 */ 555 @Override 556 public RecSolvableWordPolynomial<C> multiplyLeft(ExpVector e) { 557 if (e == null || e.isZERO()) { 558 return this; 559 } 560 //GenWordPolynomial<C> b = ring.getONECoefficient(); 561 RecSolvableWordPolynomial<C> Cp = ring.valueOf(e); //new RecSolvableWordPolynomial<C>(ring, b, e); 562 return Cp.multiply(this); 563 } 564 565 566 /** 567 * RecSolvableWordPolynomial multiplication. Left product with coefficient 568 * ring element. 569 * @param b coefficient polynomial. 570 * @return b*this, where * is coefficient multiplication. 571 */ 572 @Override 573 public RecSolvableWordPolynomial<C> multiplyLeft(GenWordPolynomial<C> b) { 574 RecSolvableWordPolynomial<C> Cp = ring.getZERO().copy(); 575 if (b == null || b.isZERO()) { 576 return Cp; 577 } 578 Map<ExpVector, GenWordPolynomial<C>> Cm = Cp.val; //getMap(); 579 Map<ExpVector, GenWordPolynomial<C>> Am = val; 580 GenWordPolynomial<C> c; 581 for (Map.Entry<ExpVector, GenWordPolynomial<C>> y : Am.entrySet()) { 582 ExpVector e = y.getKey(); 583 GenWordPolynomial<C> a = y.getValue(); 584 c = b.multiply(a); 585 if (!c.isZERO()) { 586 Cm.put(e, c); 587 } 588 } 589 return Cp; 590 } 591 592 593 /** 594 * RecSolvableWordPolynomial multiplication. Left product with 'monomial'. 595 * @param m 'monomial'. 596 * @return m * this, where * denotes solvable multiplication. 597 */ 598 @Override 599 public RecSolvableWordPolynomial<C> multiplyLeft(Map.Entry<ExpVector, GenWordPolynomial<C>> m) { 600 if (m == null) { 601 return ring.getZERO(); 602 } 603 return multiplyLeft(m.getValue(), m.getKey()); 604 } 605 606 607 /** 608 * RecSolvableWordPolynomial multiplication. Product with 'monomial'. 609 * @param m 'monomial'. 610 * @return this * m, where * denotes solvable multiplication. 611 */ 612 @Override 613 public RecSolvableWordPolynomial<C> multiply(Map.Entry<ExpVector, GenWordPolynomial<C>> m) { 614 if (m == null) { 615 return ring.getZERO(); 616 } 617 return multiply(m.getValue(), m.getKey()); 618 } 619 620 621 /** 622 * RecSolvableWordPolynomial multiplication. Commutative product with 623 * exponent vector. 624 * @param f exponent vector. 625 * @return B*f, where * is commutative multiplication. 626 */ 627 protected RecSolvableWordPolynomial<C> shift(ExpVector f) { 628 RecSolvableWordPolynomial<C> C = ring.getZERO().copy(); 629 if (this.isZERO()) { 630 return C; 631 } 632 if (f == null || f.isZERO()) { 633 return this; 634 } 635 Map<ExpVector, GenWordPolynomial<C>> Cm = C.val; 636 Map<ExpVector, GenWordPolynomial<C>> Bm = this.val; 637 for (Map.Entry<ExpVector, GenWordPolynomial<C>> y : Bm.entrySet()) { 638 ExpVector e = y.getKey(); 639 GenWordPolynomial<C> a = y.getValue(); 640 ExpVector d = e.sum(f); 641 if (!a.isZERO()) { 642 Cm.put(d, a); 643 } 644 } 645 return C; 646 } 647 648}