001/* 002 * $Id: PolynomialList.java 5913 2018-08-27 21:27:23Z kredel $ 003 */ 004 005package edu.jas.poly; 006 007 008import java.io.Serializable; 009import java.util.ArrayList; 010import java.util.List; 011import java.util.Map; 012import java.util.SortedSet; 013import java.util.TreeSet; 014 015import org.apache.logging.log4j.Logger; 016import org.apache.logging.log4j.LogManager; 017 018import edu.jas.kern.Scripting; 019import edu.jas.structure.RingElem; 020 021 022/** 023 * List of polynomials. Mainly for storage and printing / toString and 024 * conversions to other representations. 025 * @author Heinz Kredel 026 */ 027 028public class PolynomialList<C extends RingElem<C>> implements Comparable<PolynomialList<C>>, Serializable { 029 030 031 /** 032 * The factory for the solvable polynomial ring. 033 */ 034 public final GenPolynomialRing<C> ring; 035 036 037 /** 038 * The data structure is a List of polynomials. 039 */ 040 public final List<GenPolynomial<C>> list; 041 042 043 private static final Logger logger = LogManager.getLogger(PolynomialList.class); 044 045 046 /** 047 * Constructor. 048 * @param r polynomial ring factory. 049 * @param l list of polynomials. 050 */ 051 public PolynomialList(GenPolynomialRing<C> r, List<GenPolynomial<C>> l) { 052 ring = r; 053 list = l; 054 } 055 056 057 /** 058 * Constructor. 059 * @param r solvable polynomial ring factory. 060 * @param l list of solvable polynomials. 061 */ 062 public PolynomialList(GenSolvablePolynomialRing<C> r, List<GenSolvablePolynomial<C>> l) { 063 this(r, PolynomialList.<C> castToList(l)); 064 } 065 066 067 /** 068 * Copy this. 069 * @return a copy of this. 070 */ 071 public PolynomialList<C> copy() { 072 return new PolynomialList<C>(ring, new ArrayList<GenPolynomial<C>>(list)); 073 } 074 075 076 /** 077 * Comparison with any other object. 078 * @see java.lang.Object#equals(java.lang.Object) 079 */ 080 @Override 081 @SuppressWarnings("unchecked") 082 public boolean equals(Object p) { 083 if (p == null) { 084 return false; 085 } 086 if (!(p instanceof PolynomialList)) { 087 System.out.println("no PolynomialList"); 088 return false; 089 } 090 PolynomialList<C> pl = (PolynomialList<C>) p; 091 if (!ring.equals(pl.ring)) { 092 System.out.println("not same Ring " + ring.toScript() + ", " + pl.ring.toScript()); 093 return false; 094 } 095 return (compareTo(pl) == 0); 096 // otherwise tables may be different 097 } 098 099 100 /** 101 * Polynomial list comparison. 102 * @param L other PolynomialList. 103 * @return lexicographical comparison, sign of first different polynomials. 104 */ 105 public int compareTo(PolynomialList<C> L) { 106 int si = L.list.size(); 107 if (list.size() < si) { // minimum 108 si = list.size(); 109 } 110 int s = 0; 111 List<GenPolynomial<C>> l1 = OrderedPolynomialList.<C> sort(ring, list); 112 List<GenPolynomial<C>> l2 = OrderedPolynomialList.<C> sort(ring, L.list); 113 for (int i = 0; i < si; i++) { 114 GenPolynomial<C> a = l1.get(i); 115 GenPolynomial<C> b = l2.get(i); 116 s = a.compareTo(b); 117 if (s != 0) { 118 return s; 119 } 120 } 121 if (list.size() > si) { 122 return 1; 123 } 124 if (L.list.size() > si) { 125 return -1; 126 } 127 return s; 128 } 129 130 131 /** 132 * Hash code for this polynomial list. 133 * @see java.lang.Object#hashCode() 134 */ 135 @Override 136 public int hashCode() { 137 int h; 138 h = ring.hashCode(); 139 h = 37 * h + (list == null ? 0 : list.hashCode()); 140 return h; 141 } 142 143 144 /** 145 * Test if list is empty. 146 * @return true if this is empty, alse false. 147 */ 148 public boolean isEmpty() { 149 if (list == null) { 150 return true; 151 } 152 return list.isEmpty(); 153 } 154 155 156 /** 157 * String representation of the polynomial list. 158 * @see java.lang.Object#toString() 159 */ 160 @Override 161 public String toString() { 162 StringBuffer erg = new StringBuffer(); 163 String[] vars = null; 164 if (ring != null) { 165 erg.append(ring.toString()); 166 vars = ring.getVars(); 167 } 168 boolean first = true; 169 erg.append("\n(\n"); 170 String sa = null; 171 for (GenPolynomial<C> oa : list) { 172 if (vars != null) { 173 sa = oa.toString(vars); 174 } else { 175 sa = oa.toString(); 176 } 177 if (first) { 178 first = false; 179 } else { 180 erg.append(", "); 181 if (sa.length() > 10) { 182 erg.append("\n"); 183 } 184 } 185 erg.append("( " + sa + " )"); 186 } 187 erg.append("\n)"); 188 return erg.toString(); 189 } 190 191 192 /** 193 * Get a scripting compatible string representation. 194 * @return script compatible representation for this polynomial list. 195 */ 196 public String toScript() { 197 StringBuffer s = new StringBuffer(); 198 if (ring instanceof GenSolvablePolynomialRing) { 199 switch (Scripting.getLang()) { 200 case Ruby: 201 s.append("SolvIdeal.new("); 202 break; 203 case Python: 204 default: 205 s.append("SolvableIdeal("); 206 } 207 } else { 208 switch (Scripting.getLang()) { 209 case Ruby: 210 s.append("SimIdeal.new("); 211 break; 212 case Python: 213 default: 214 s.append("Ideal("); 215 } 216 } 217 if (ring != null) { 218 s.append(ring.toScript()); 219 } 220 if (list == null) { 221 s.append(")"); 222 return s.toString(); 223 } 224 switch (Scripting.getLang()) { 225 case Ruby: 226 s.append(",\"\",["); 227 break; 228 case Python: 229 default: 230 s.append(",list=["); 231 } 232 boolean first = true; 233 String sa = null; 234 for (GenPolynomial<C> oa : list) { 235 sa = oa.toScript(); 236 if (first) { 237 first = false; 238 } else { 239 s.append(", "); 240 } 241 //s.append("( " + sa + " )"); 242 s.append(sa); 243 } 244 s.append("])"); 245 return s.toString(); 246 } 247 248 249 /** 250 * Get ModuleList from PolynomialList. Extract module from polynomial ring. 251 * @see edu.jas.poly.ModuleList 252 * @param i number of variables to be contract form the polynomials. 253 * @return module list corresponding to this. 254 */ 255 @SuppressWarnings("unchecked") 256 public ModuleList<C> getModuleList(int i) { 257 GenPolynomialRing<C> pfac = ring.contract(i); 258 logger.debug("contracted ring = " + pfac); 259 //System.out.println("contracted ring = " + pfac); 260 261 List<List<GenPolynomial<C>>> vecs = null; 262 if (list == null) { 263 return new ModuleList<C>(pfac, vecs); 264 } 265 int rows = list.size(); 266 vecs = new ArrayList<List<GenPolynomial<C>>>(rows); 267 if (rows == 0) { // nothing to do 268 return new ModuleList<C>(pfac, vecs); 269 } 270 271 ArrayList<GenPolynomial<C>> zr = new ArrayList<GenPolynomial<C>>(i - 1); 272 GenPolynomial<C> zero = pfac.getZERO(); 273 for (int j = 0; j < i; j++) { 274 zr.add(j, zero); 275 } 276 277 for (GenPolynomial<C> p : list) { 278 if (p != null) { 279 Map<ExpVector, GenPolynomial<C>> r = p.contract(pfac); 280 //System.out.println("r = " + r ); 281 List<GenPolynomial<C>> row = new ArrayList<GenPolynomial<C>>(zr); //zr.clone(); 282 for (Map.Entry<ExpVector, GenPolynomial<C>> me : r.entrySet()) { 283 ExpVector e = me.getKey(); 284 int[] dov = e.dependencyOnVariables(); 285 int ix = 0; 286 if (dov.length > 1) { 287 throw new IllegalArgumentException("wrong dependencyOnVariables " + e); 288 } else if (dov.length == 1) { 289 ix = dov[0]; 290 } 291 //ix = i-1 - ix; // revert 292 //System.out.println("ix = " + ix ); 293 GenPolynomial<C> vi = me.getValue(); //r.get( e ); 294 row.set(ix, vi); 295 } 296 //System.out.println("row = " + row ); 297 vecs.add(row); 298 } 299 } 300 return new ModuleList<C>(pfac, vecs); 301 } 302 303 304 /** 305 * Get list. 306 * @return list from this. 307 */ 308 public List<GenPolynomial<C>> getList() { 309 return list; 310 } 311 312 313 /** 314 * Get list as List of GenSolvablePolynomials. Required because no List 315 * casts allowed. Equivalent to cast 316 * (List<GenSolvablePolynomial<C>>) list. 317 * @return solvable polynomial list from this. 318 */ 319 public List<GenSolvablePolynomial<C>> castToSolvableList() { 320 return castToSolvableList(list); 321 } 322 323 324 /** 325 * Get list as List of GenSolvablePolynomials. Required because no List 326 * casts allowed. Equivalent to cast 327 * (List<GenSolvablePolynomial<C>>) list. 328 * @return solvable polynomial list from this. 329 */ 330 public List<GenSolvablePolynomial<C>> getSolvableList() { 331 return castToSolvableList(list); 332 } 333 334 335 /** 336 * Get ring as GenSolvablePolynomialRing. 337 * @return solvable polynomial ring list from this. 338 */ 339 public GenSolvablePolynomialRing<C> getSolvableRing() { 340 return (GenSolvablePolynomialRing<C>) ring; 341 } 342 343 344 /** 345 * Get list as List of GenSolvablePolynomials. Required because no List 346 * casts allowed. Equivalent to cast 347 * (List<GenSolvablePolynomial<C>>) list. 348 * @param list list of extensions of polynomials. 349 * @return solvable polynomial list from this. 350 */ 351 public static <C extends RingElem<C>> List<GenSolvablePolynomial<C>> castToSolvableList( 352 List<GenPolynomial<C>> list) { 353 List<GenSolvablePolynomial<C>> slist = null; 354 if (list == null) { 355 return slist; 356 } 357 slist = new ArrayList<GenSolvablePolynomial<C>>(list.size()); 358 GenSolvablePolynomial<C> s; 359 for (GenPolynomial<C> p : list) { 360 if (!(p instanceof GenSolvablePolynomial)) { 361 throw new IllegalArgumentException("no solvable polynomial " + p); 362 } 363 s = (GenSolvablePolynomial<C>) p; 364 slist.add(s); 365 } 366 return slist; 367 } 368 369 370 /** 371 * Get list of list as List of List of GenSolvablePolynomials. Required 372 * because no List casts allowed. Equivalent to cast 373 * (List<GenSolvablePolynomial<C>>) list. 374 * @param list list of extensions of polynomials. 375 * @return solvable polynomial list from this. 376 */ 377 public static <C extends RingElem<C>> List<List<GenSolvablePolynomial<C>>> castToSolvableMatrix( 378 List<List<GenPolynomial<C>>> list) { 379 List<List<GenSolvablePolynomial<C>>> slist = null; 380 if (list == null) { 381 return slist; 382 } 383 slist = new ArrayList<List<GenSolvablePolynomial<C>>>(list.size()); 384 List<GenSolvablePolynomial<C>> s; 385 for (List<GenPolynomial<C>> p : list) { 386 s = PolynomialList.<C> castToSolvableList(p); 387 slist.add(s); 388 } 389 return slist; 390 } 391 392 393 /** 394 * Get list of extensions of polynomials as List of GenPolynomials. Required 395 * because no List casts allowed. Equivalent to cast 396 * (List<GenPolynomial<C>>) list. Mainly used for lists of 397 * GenSolvablePolynomials. 398 * @param slist list of extensions of polynomials. 399 * @return polynomial list from slist. 400 */ 401 public static <C extends RingElem<C>> List<GenPolynomial<C>> castToList( 402 List<? extends GenPolynomial<C>> slist) { 403 logger.debug("warn: can lead to wrong method dispatch"); 404 List<GenPolynomial<C>> list = null; 405 if (slist == null) { 406 return list; 407 } 408 list = new ArrayList<GenPolynomial<C>>(slist.size()); 409 for (GenPolynomial<C> p : slist) { 410 list.add(p); 411 } 412 return list; 413 } 414 415 416 /** 417 * Get list of list of extensions of polynomials as List of List of 418 * GenPolynomials. Required because no List casts allowed. Equivalent to 419 * cast (List<GenPolynomial<C>>) list. Mainly used for lists of 420 * GenSolvablePolynomials. 421 * @param slist list of extensions of polynomials. 422 * @return polynomial list from slist. 423 */ 424 public static <C extends RingElem<C>> List<List<GenPolynomial<C>>> castToMatrix( 425 List<List<? extends GenPolynomial<C>>> slist) { 426 logger.debug("warn: can lead to wrong method dispatch"); 427 List<List<GenPolynomial<C>>> list = null; 428 if (slist == null) { 429 return list; 430 } 431 list = new ArrayList<List<GenPolynomial<C>>>(slist.size()); 432 for (List<? extends GenPolynomial<C>> p : slist) { 433 list.add(PolynomialList.<C> castToList(p)); 434 } 435 return list; 436 } 437 438 439 /** 440 * Test if list contains only ZEROs. 441 * @return true, if this is the 0 list, else false 442 */ 443 public boolean isZERO() { 444 if (list == null) { 445 return true; 446 } 447 for (GenPolynomial<C> p : list) { 448 if (p == null) { 449 continue; 450 } 451 if (!p.isZERO()) { 452 return false; 453 } 454 } 455 return true; 456 } 457 458 459 /** 460 * Test if list contains a ONE. 461 * @return true, if this contains 1, else false 462 */ 463 public boolean isONE() { 464 if (list == null) { 465 return false; 466 } 467 for (GenPolynomial<C> p : list) { 468 if (p == null) { 469 continue; 470 } 471 if (p.isONE()) { 472 return true; 473 } 474 } 475 return false; 476 } 477 478 479 /** 480 * Make homogeneous. 481 * @return polynomial list of homogeneous polynomials. 482 */ 483 public PolynomialList<C> homogenize() { 484 GenPolynomialRing<C> pfac = ring.extend(1); 485 List<GenPolynomial<C>> hom = new ArrayList<GenPolynomial<C>>(list.size()); 486 for (GenPolynomial<C> p : list) { 487 GenPolynomial<C> h = p.homogenize(pfac); 488 hom.add(h); 489 } 490 return new PolynomialList<C>(pfac, hom); 491 } 492 493 494 /** 495 * Dehomogenize. 496 * @return polynomial list of de-homogenized polynomials. 497 */ 498 public PolynomialList<C> deHomogenize() { 499 GenPolynomialRing<C> pfac = ring.contract(1); 500 List<GenPolynomial<C>> dehom = new ArrayList<GenPolynomial<C>>(list.size()); 501 for (GenPolynomial<C> p : list) { 502 GenPolynomial<C> h = p.deHomogenize(pfac); 503 dehom.add(h); 504 } 505 return new PolynomialList<C>(pfac, dehom); 506 } 507 508 509 /** 510 * Test if all polynomials are homogeneous. 511 * @return true, if all polynomials are homogeneous, else false 512 */ 513 public boolean isHomogeneous() { 514 if (list == null) { 515 return true; 516 } 517 for (GenPolynomial<C> p : list) { 518 if (p == null) { 519 continue; 520 } 521 if (!p.isHomogeneous()) { 522 return false; 523 } 524 } 525 return true; 526 } 527 528 529 /** 530 * Union of the delta of exponent vectors of all polynomials. 531 * @return list of u-v, where u = lt() and v != u in p in list. 532 */ 533 public SortedSet<ExpVector> deltaExpVectors() { 534 SortedSet<ExpVector> de = new TreeSet<ExpVector>(ring.tord.getAscendComparator()); 535 if (list.isEmpty()) { 536 return de; 537 } 538 for (GenPolynomial<C> p : list) { 539 List<ExpVector> pe = p.deltaExpVectors(); 540 de.addAll(pe); 541 } 542 return de; 543 } 544 545 546 /** 547 * Union of the delta of exponent vectors of all polynomials. 548 * @param mark list of marked exp vectors of polynomials. 549 * @return list of u-v, where u in mark and v != u in p.expVectors in list. 550 */ 551 public SortedSet<ExpVector> deltaExpVectors(List<ExpVector> mark) { 552 SortedSet<ExpVector> de = new TreeSet<ExpVector>(ring.tord.getAscendComparator()); 553 if (list.isEmpty()) { 554 return de; 555 } 556 if (mark.isEmpty()) { 557 return deltaExpVectors(); 558 } 559 if (list.size() != mark.size()) { 560 throw new IllegalArgumentException("#list != #mark"); 561 } 562 int i = 0; 563 for (GenPolynomial<C> p : list) { 564 ExpVector u = mark.get(i); 565 List<ExpVector> pe = p.deltaExpVectors(u); 566 de.addAll(pe); 567 i++; 568 } 569 return de; 570 } 571 572 573 /** 574 * Leading weight polynomials. 575 * @return list of polynomials with terms of maximal weight degree. 576 */ 577 public List<GenPolynomial<C>> leadingWeightPolynomials() { 578 List<GenPolynomial<C>> lw = new ArrayList<GenPolynomial<C>>(list.size()); 579 if (list.isEmpty()) { 580 return lw; 581 } 582 for (GenPolynomial<C> p : list) { 583 GenPolynomial<C> pw = p.leadingWeightPolynomial(); 584 lw.add(pw); 585 } 586 return lw; 587 } 588 589}