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