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