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