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 * 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 * Hash code for this polynomial. 148 * @see java.lang.Object#hashCode() 149 */ 150 @Override 151 public int hashCode() { 152 return super.hashCode(); 153 } 154 155 156 /** 157 * RecSolvableWordPolynomial multiplication. 158 * @param Bp RecSolvableWordPolynomial. 159 * @return this*Bp, where * denotes solvable multiplication. 160 */ 161 // cannot @Override, @NoOverride 162 public RecSolvableWordPolynomial<C> multiply(RecSolvableWordPolynomial<C> Bp) { 163 if (Bp == null || Bp.isZERO()) { 164 return ring.getZERO(); 165 } 166 if (this.isZERO()) { 167 return this; 168 } 169 assert (ring.nvar == Bp.ring.nvar); 170 if (debug) { 171 logger.info("ring = " + ring.toScript()); 172 } 173 final boolean commute = ring.table.isEmpty(); 174 final boolean commuteCoeff = ring.coeffTable.isEmpty(); 175 //GenWordPolynomialRing<C> cfac = (GenWordPolynomialRing<C>) ring.coFac; 176 RecSolvableWordPolynomial<C> Dp = ring.getZERO().copy(); 177 RecSolvableWordPolynomial<C> zero = ring.getZERO(); //.copy(); not needed 178 ExpVector Z = ring.evzero; 179 //Word Zc = cfac.wone; 180 GenWordPolynomial<C> one = ring.getONECoefficient(); 181 182 RecSolvableWordPolynomial<C> C1 = null; 183 RecSolvableWordPolynomial<C> C2 = null; 184 Map<ExpVector, GenWordPolynomial<C>> A = val; 185 Map<ExpVector, GenWordPolynomial<C>> B = Bp.val; 186 Set<Map.Entry<ExpVector, GenWordPolynomial<C>>> Bk = B.entrySet(); 187 if (debug) 188 logger.info("input A = " + this); 189 for (Map.Entry<ExpVector, GenWordPolynomial<C>> y : A.entrySet()) { 190 GenWordPolynomial<C> a = y.getValue(); 191 ExpVector e = y.getKey(); 192 if (debug) 193 logger.info("e = " + e + ", a = " + a); 194 int[] ep = e.dependencyOnVariables(); 195 int el1 = ring.nvar + 1; 196 if (ep.length > 0) { 197 el1 = ep[0]; 198 } 199 //int el1s = ring.nvar + 1 - el1; 200 if (debug) 201 logger.info("input B = " + Bp); 202 for (Map.Entry<ExpVector, GenWordPolynomial<C>> x : Bk) { 203 GenWordPolynomial<C> b = x.getValue(); 204 ExpVector f = x.getKey(); 205 if (debug) 206 logger.info("f = " + f + ", b = " + b); 207 int[] fp = f.dependencyOnVariables(); 208 int fl1 = 0; 209 if (fp.length > 0) { 210 fl1 = fp[fp.length - 1]; 211 } 212 int fl1s = ring.nvar + 1 - fl1; 213 // polynomial coefficient multiplication e*b = P_eb, for a*((e*b)*f) 214 RecSolvableWordPolynomial<C> Cps = ring.getZERO().copy(); 215 RecSolvableWordPolynomial<C> Cs = null; 216 if (commuteCoeff || b.isConstant() || e.isZERO()) { // symmetric 217 //Cps = (RecSolvableWordPolynomial<C>) zero.sum(b, e); 218 Cps.doAddTo(b, e); 219 if (debug) 220 logger.info("symmetric coeff, e*b: b = " + b + ", e = " + e); 221 } else { // unsymmetric 222 if (debug) 223 logger.info("unsymmetric coeff, e*b: b = " + b + ", e = " + e); 224 for (Map.Entry<Word, C> z : b.val.entrySet()) { 225 C c = z.getValue(); 226 GenWordPolynomial<C> cc = b.ring.getONE().multiply(c); 227 Word g = z.getKey(); 228 if (debug) 229 logger.info("g = " + g + ", c = " + c); 230 // split e = e1 * e2, g = g2 * g1 231 ExpVector g2 = g.leadingExpVector(); 232 Word g1 = g.reductum(); 233 //ExpVector g1; 234 //System.out.println("c = " + c + ", g = " + g + ", g1 = " + g1 + ", g1 == 1: " + g1.isONE()); 235 ExpVector e1 = e; 236 ExpVector e2 = Z; 237 if (!e.isZERO()) { 238 e1 = e.subst(el1, 0); 239 e2 = Z.subst(el1, e.getVal(el1)); 240 } 241 if (debug) { 242 logger.info("coeff, e1 = " + e1 + ", e2 = " + e2 + ", Cps = " + Cps); 243 logger.info("coeff, g2 = " + g2 + ", g1 = " + g1); 244 } 245 TableRelation<GenWordPolynomial<C>> crel = ring.coeffTable.lookup(e2, g2); 246 if (debug) 247 logger.info("coeff, crel = " + crel.p); 248 //System.out.println("coeff, e = " + e + ", g = " + g + ", crel = " + crel); 249 Cs = new RecSolvableWordPolynomial<C>(ring, crel.p); 250 // rest of multiplication and update relations 251 if (crel.f != null) { // process remaining right power 252 //GenWordPolynomial<C> c2 = b.ring.getONE().multiply(crel.f); 253 GenWordPolynomial<C> c2 = b.ring.valueOf(crel.f); 254 C2 = ring.valueOf(c2); //new RecSolvableWordPolynomial<C>(ring, c2, Z); 255 Cs = Cs.multiply(C2); 256 ExpVector e4; 257 if (crel.e == null) { 258 e4 = e2; 259 } else { 260 e4 = e2.subtract(crel.e); 261 } 262 ring.coeffTable.update(e4, g2, Cs); 263 } 264 if (crel.e != null) { // process remaining left power 265 C1 = ring.valueOf(crel.e); //new RecSolvableWordPolynomial<C>(ring, one, crel.e); 266 Cs = C1.multiply(Cs); 267 ring.coeffTable.update(e2, g2, Cs); 268 } 269 if (!g1.isONE()) { // process remaining right part 270 //GenWordPolynomial<C> c2 = b.ring.getONE().multiply(g1); 271 GenWordPolynomial<C> c2 = b.ring.valueOf(g1); 272 C2 = ring.valueOf(c2); //new RecSolvableWordPolynomial<C>(ring, c2, Z); 273 Cs = Cs.multiply(C2); 274 } 275 if (!e1.isZERO()) { // process remaining left part 276 C1 = ring.valueOf(e1); //new RecSolvableWordPolynomial<C>(ring, one, e1); 277 Cs = C1.multiply(Cs); 278 } 279 //System.out.println("e1*Cs*g1 = " + Cs); 280 Cs = Cs.multiplyLeft(cc); // assume c, coeff(cc) commutes with Cs 281 //Cps = (RecSolvableWordPolynomial<C>) Cps.sum(Cs); 282 Cps.doAddTo(Cs); 283 } // end b loop 284 if (debug) 285 logger.info("coeff, Cs = " + Cs + ", Cps = " + Cps); 286 //System.out.println("coeff loop end, Cs = " + Cs + ", Cps = " + Cps); 287 } 288 if (debug) 289 logger.info("coeff-poly: Cps = " + Cps); 290 // polynomial multiplication P_eb*f, for a*(P_eb*f) 291 RecSolvableWordPolynomial<C> Dps = ring.getZERO().copy(); 292 RecSolvableWordPolynomial<C> Ds = null; 293 RecSolvableWordPolynomial<C> D1, D2; 294 if (commute || Cps.isConstant() || f.isZERO()) { // symmetric 295 if (debug) 296 logger.info("symmetric poly, P_eb*f: Cps = " + Cps + ", f = " + f); 297 ExpVector g = e.sum(f); 298 if (Cps.isConstant()) { 299 Ds = ring.valueOf(Cps.leadingBaseCoefficient(), g); //new RecSolvableWordPolynomial<C>(ring, Cps.leadingBaseCoefficient(), g); // symmetric! 300 } else { 301 Ds = Cps.shift(f); // symmetric 302 } 303 } else { // eventually unsymmetric 304 if (debug) 305 logger.info("unsymmetric poly, P_eb*f: Cps = " + Cps + ", f = " + f); 306 for (Map.Entry<ExpVector, GenWordPolynomial<C>> z : Cps.val.entrySet()) { 307 // split g = g1 * g2, f = f1 * f2 308 GenWordPolynomial<C> c = z.getValue(); 309 ExpVector g = z.getKey(); 310 if (debug) 311 logger.info("g = " + g + ", c = " + c); 312 int[] gp = g.dependencyOnVariables(); 313 int gl1 = ring.nvar + 1; 314 if (gp.length > 0) { 315 gl1 = gp[0]; 316 } 317 int gl1s = ring.nvar + 1 - gl1; 318 if (gl1s <= fl1s) { // symmetric 319 ExpVector h = g.sum(f); 320 if (debug) 321 logger.info("disjoint poly: g = " + g + ", f = " + f + ", h = " + h); 322 Ds = (RecSolvableWordPolynomial<C>) zero.sum(one, h); // symmetric! 323 } else { 324 ExpVector g1 = g.subst(gl1, 0); 325 ExpVector g2 = Z.subst(gl1, g.getVal(gl1)); // bug el1, gl1 326 ExpVector g4; 327 ExpVector f1 = f.subst(fl1, 0); 328 ExpVector f2 = Z.subst(fl1, f.getVal(fl1)); 329 if (debug) { 330 logger.info("poly, g1 = " + g1 + ", f1 = " + f1 + ", Dps = " + Dps); 331 logger.info("poly, g2 = " + g2 + ", f2 = " + f2); 332 } 333 TableRelation<GenWordPolynomial<C>> rel = ring.table.lookup(g2, f2); 334 if (debug) 335 logger.info("poly, g = " + g + ", f = " + f + ", rel = " + rel); 336 Ds = new RecSolvableWordPolynomial<C>(ring, rel.p); //ring.copy(rel.p); 337 if (rel.f != null) { 338 D2 = ring.valueOf(rel.f); //new RecSolvableWordPolynomial<C>(ring, one, rel.f); 339 Ds = Ds.multiply(D2); 340 if (rel.e == null) { 341 g4 = g2; 342 } else { 343 g4 = g2.subtract(rel.e); 344 } 345 ring.table.update(g4, f2, Ds); 346 } 347 if (rel.e != null) { 348 D1 = ring.valueOf(rel.e); //new RecSolvableWordPolynomial<C>(ring, one, rel.e); 349 Ds = D1.multiply(Ds); 350 ring.table.update(g2, f2, Ds); 351 } 352 if (!f1.isZERO()) { 353 D2 = ring.valueOf(f1); //new RecSolvableWordPolynomial<C>(ring, one, f1); 354 Ds = Ds.multiply(D2); 355 //ring.table.update(?,f1,Ds) 356 } 357 if (!g1.isZERO()) { 358 D1 = ring.valueOf(g1); //new RecSolvableWordPolynomial<C>(ring, one, g1); 359 Ds = D1.multiply(Ds); 360 //ring.table.update(e1,?,Ds) 361 } 362 } 363 //System.out.println("main loop, Cs = " + Cs + ", c = " + c); 364 Ds = Ds.multiplyLeft(c); // assume c commutes with Cs 365 //Dps = (RecSolvableWordPolynomial<C>) Dps.sum(Ds); 366 Dps.doAddTo(Ds); 367 } // end Dps loop 368 Ds = Dps; 369 } 370 if (debug) { 371 logger.info("recursion+: Ds = " + Ds + ", a = " + a); 372 } 373 // polynomial coefficient multiplication a*(P_eb*f) = a*Ds 374 //System.out.println("main loop, Ds = " + Ds + ", a = " + a); 375 Ds = Ds.multiplyLeft(a); // multiply(a,b); // non-symmetric 376 if (debug) 377 logger.info("recursion-: Ds = " + Ds); 378 //Dp = (RecSolvableWordPolynomial<C>) Dp.sum(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 * RecSolvableWordPolynomial left and right multiplication. Product with two 392 * polynomials. 393 * @param S RecSolvableWordPolynomial. 394 * @param T RecSolvableWordPolynomial. 395 * @return S*this*T. 396 */ 397 // cannot @Override, @NoOverride 398 public RecSolvableWordPolynomial<C> multiply(RecSolvableWordPolynomial<C> S, 399 RecSolvableWordPolynomial<C> T) { 400 if (S.isZERO() || T.isZERO() || this.isZERO()) { 401 return ring.getZERO(); 402 } 403 if (S.isONE()) { 404 return multiply(T); 405 } 406 if (T.isONE()) { 407 return S.multiply(this); 408 } 409 return S.multiply(this).multiply(T); 410 } 411 412 413 /** 414 * RecSolvableWordPolynomial multiplication. Product with coefficient ring 415 * element. 416 * @param b coefficient polynomial. 417 * @return this*b, where * is coefficient multiplication. 418 */ 419 // cannot @Override 420 //public RecSolvableWordPolynomial<C> multiply(GenWordPolynomial<C> b) { 421 //public GenSolvablePolynomial<GenWordPolynomial<C>> multiply(GenWordPolynomial<C> b) { 422 public RecSolvableWordPolynomial<C> recMultiply(GenWordPolynomial<C> b) { 423 RecSolvableWordPolynomial<C> Cp = ring.getZERO().copy(); 424 if (b == null || b.isZERO()) { 425 return Cp; 426 } 427 Cp = new RecSolvableWordPolynomial<C>(ring, b, ring.evzero); 428 return multiply(Cp); 429 } 430 431 432 /** 433 * RecSolvableWordPolynomial 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 RecSolvableWordPolynomial<C> multiply(GenWordPolynomial<C> b, GenWordPolynomial<C> c) { 441 RecSolvableWordPolynomial<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 RecSolvableWordPolynomial<C> Cb = ring.valueOf(b); //new RecSolvableWordPolynomial<C>(ring, b, ring.evzero); 449 RecSolvableWordPolynomial<C> Cc = ring.valueOf(c); //new RecSolvableWordPolynomial<C>(ring, c, ring.evzero); 450 return Cb.multiply(this).multiply(Cc); 451 } 452 453 454 /* 455 * RecSolvableWordPolynomial multiplication. Product with coefficient ring 456 * element. 457 * @param b coefficient of coefficient. 458 * @return this*b, where * is coefficient multiplication. 459 */ 460 //@Override not possible, @NoOverride 461 //public RecSolvableWordPolynomial<C> multiply(C b) { ... } 462 463 464 /** 465 * RecSolvableWordPolynomial multiplication. Product with exponent vector. 466 * @param e exponent. 467 * @return this * x<sup>e</sup>, where * denotes solvable multiplication. 468 */ 469 @Override 470 public RecSolvableWordPolynomial<C> multiply(ExpVector e) { 471 if (e == null || e.isZERO()) { 472 return this; 473 } 474 GenWordPolynomial<C> b = ring.getONECoefficient(); 475 return multiply(b, e); 476 } 477 478 479 /** 480 * RecSolvableWordPolynomial left and right multiplication. Product with 481 * exponent vector. 482 * @param e exponent. 483 * @param f exponent. 484 * @return x<sup>e</sup> * this * x<sup>f</sup>, where * denotes solvable 485 * multiplication. 486 */ 487 @Override 488 public RecSolvableWordPolynomial<C> multiply(ExpVector e, ExpVector f) { 489 if (e == null || e.isZERO()) { 490 return this; 491 } 492 if (f == null || f.isZERO()) { 493 return this; 494 } 495 GenWordPolynomial<C> b = ring.getONECoefficient(); 496 return multiply(b, e, b, f); 497 } 498 499 500 /** 501 * RecSolvableWordPolynomial multiplication. Product with ring element and 502 * exponent vector. 503 * @param b coefficient polynomial. 504 * @param e exponent. 505 * @return this * b x<sup>e</sup>, where * denotes solvable multiplication. 506 */ 507 @Override 508 public RecSolvableWordPolynomial<C> multiply(GenWordPolynomial<C> b, ExpVector e) { 509 if (b == null || b.isZERO()) { 510 return ring.getZERO(); 511 } 512 RecSolvableWordPolynomial<C> Cp = ring.valueOf(b, e); //new RecSolvableWordPolynomial<C>(ring, b, e); 513 return multiply(Cp); 514 } 515 516 517 /** 518 * RecSolvableWordPolynomial left and right multiplication. Product with 519 * ring element and exponent vector. 520 * @param b coefficient polynomial. 521 * @param e exponent. 522 * @param c coefficient polynomial. 523 * @param f exponent. 524 * @return b x<sup>e</sup> * this * c x<sup>f</sup>, where * denotes 525 * solvable multiplication. 526 */ 527 @Override 528 public RecSolvableWordPolynomial<C> multiply(GenWordPolynomial<C> b, ExpVector e, GenWordPolynomial<C> c, 529 ExpVector f) { 530 if (b == null || b.isZERO()) { 531 return ring.getZERO(); 532 } 533 if (c == null || c.isZERO()) { 534 return ring.getZERO(); 535 } 536 RecSolvableWordPolynomial<C> Cp = ring.valueOf(b, e); //new RecSolvableWordPolynomial<C>(ring, b, e); 537 RecSolvableWordPolynomial<C> Dp = ring.valueOf(c, f); //new RecSolvableWordPolynomial<C>(ring, c, f); 538 return multiply(Cp, Dp); 539 } 540 541 542 /** 543 * RecSolvableWordPolynomial multiplication. Left product with ring element 544 * and exponent vector. 545 * @param b coefficient polynomial. 546 * @param e exponent. 547 * @return b x<sup>e</sup> * this, where * denotes solvable multiplication. 548 */ 549 @Override 550 public RecSolvableWordPolynomial<C> multiplyLeft(GenWordPolynomial<C> b, ExpVector e) { 551 if (b == null || b.isZERO()) { 552 return ring.getZERO(); 553 } 554 RecSolvableWordPolynomial<C> Cp = ring.valueOf(b, e); //new RecSolvableWordPolynomial<C>(ring, b, e); 555 return Cp.multiply(this); 556 } 557 558 559 /** 560 * RecSolvableWordPolynomial multiplication. Left product with exponent 561 * vector. 562 * @param e exponent. 563 * @return x<sup>e</sup> * this, where * denotes solvable multiplication. 564 */ 565 @Override 566 public RecSolvableWordPolynomial<C> multiplyLeft(ExpVector e) { 567 if (e == null || e.isZERO()) { 568 return this; 569 } 570 //GenWordPolynomial<C> b = ring.getONECoefficient(); 571 RecSolvableWordPolynomial<C> Cp = ring.valueOf(e); //new RecSolvableWordPolynomial<C>(ring, b, e); 572 return Cp.multiply(this); 573 } 574 575 576 /** 577 * RecSolvableWordPolynomial multiplication. Left product with coefficient 578 * ring element. 579 * @param b coefficient polynomial. 580 * @return b*this, where * is coefficient multiplication. 581 */ 582 @Override 583 public RecSolvableWordPolynomial<C> multiplyLeft(GenWordPolynomial<C> b) { 584 RecSolvableWordPolynomial<C> Cp = ring.getZERO().copy(); 585 if (b == null || b.isZERO()) { 586 return Cp; 587 } 588 Map<ExpVector, GenWordPolynomial<C>> Cm = Cp.val; //getMap(); 589 Map<ExpVector, GenWordPolynomial<C>> Am = val; 590 GenWordPolynomial<C> c; 591 for (Map.Entry<ExpVector, GenWordPolynomial<C>> y : Am.entrySet()) { 592 ExpVector e = y.getKey(); 593 GenWordPolynomial<C> a = y.getValue(); 594 c = b.multiply(a); 595 if (!c.isZERO()) { 596 Cm.put(e, c); 597 } 598 } 599 return Cp; 600 } 601 602 603 /** 604 * RecSolvableWordPolynomial multiplication. Left product with 'monomial'. 605 * @param m 'monomial'. 606 * @return m * this, where * denotes solvable multiplication. 607 */ 608 @Override 609 public RecSolvableWordPolynomial<C> multiplyLeft(Map.Entry<ExpVector, GenWordPolynomial<C>> m) { 610 if (m == null) { 611 return ring.getZERO(); 612 } 613 return multiplyLeft(m.getValue(), m.getKey()); 614 } 615 616 617 /** 618 * RecSolvableWordPolynomial multiplication. Product with 'monomial'. 619 * @param m 'monomial'. 620 * @return this * m, where * denotes solvable multiplication. 621 */ 622 @Override 623 public RecSolvableWordPolynomial<C> multiply(Map.Entry<ExpVector, GenWordPolynomial<C>> m) { 624 if (m == null) { 625 return ring.getZERO(); 626 } 627 return multiply(m.getValue(), m.getKey()); 628 } 629 630 631 /** 632 * RecSolvableWordPolynomial multiplication. Commutative product with 633 * exponent vector. 634 * @param f exponent vector. 635 * @return B*f, where * is commutative multiplication. 636 */ 637 protected RecSolvableWordPolynomial<C> shift(ExpVector f) { 638 RecSolvableWordPolynomial<C> C = ring.getZERO().copy(); 639 if (this.isZERO()) { 640 return C; 641 } 642 if (f == null || f.isZERO()) { 643 return this; 644 } 645 Map<ExpVector, GenWordPolynomial<C>> Cm = C.val; 646 Map<ExpVector, GenWordPolynomial<C>> Bm = this.val; 647 for (Map.Entry<ExpVector, GenWordPolynomial<C>> y : Bm.entrySet()) { 648 ExpVector e = y.getKey(); 649 GenWordPolynomial<C> a = y.getValue(); 650 ExpVector d = e.sum(f); 651 if (!a.isZERO()) { 652 Cm.put(d, a); 653 } 654 } 655 return C; 656 } 657 658}