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