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