001 /* 002 * $Id: ModuleList.java 3654 2011-06-02 18:19:30Z kredel $ 003 */ 004 005 package edu.jas.poly; 006 007 import java.util.List; 008 import java.util.ArrayList; 009 import java.io.Serializable; 010 011 import org.apache.log4j.Logger; 012 013 import edu.jas.kern.Scripting; 014 import edu.jas.structure.RingElem; 015 import edu.jas.vector.GenVector; 016 import edu.jas.vector.GenVectorModul; 017 018 019 /** 020 * List of vectors of polynomials. 021 * Mainly for storage and printing / toString and 022 * conversions to other representations. 023 * @author Heinz Kredel 024 */ 025 026 public class ModuleList<C extends RingElem<C> > implements Serializable { 027 028 029 /** The factory for the solvable polynomial ring. 030 */ 031 public final GenPolynomialRing< C > ring; 032 033 034 /** The data structure is a List of Lists of polynomials. 035 */ 036 public final List< List< GenPolynomial<C> > > list; 037 038 039 /** Number of rows in the data structure. 040 */ 041 public final int rows; // -1 is undefined 042 043 044 /** Number of columns in the data structure. 045 */ 046 public final int cols; // -1 is undefined 047 048 049 private static final Logger logger = Logger.getLogger(ModuleList.class); 050 051 052 /** 053 * Constructor. 054 * @param r polynomial ring factory. 055 * @param l list of list of polynomials. 056 */ 057 public ModuleList( GenPolynomialRing< C > r, 058 List< List<GenPolynomial< C >>> l) { 059 ring = r; 060 list = ModuleList.<C>padCols(r,l); 061 if ( list == null ) { 062 rows = -1; 063 cols = -1; 064 } else { 065 rows = list.size(); 066 if ( rows > 0 ) { 067 cols = list.get(0).size(); 068 } else { 069 cols = -1; 070 } 071 } 072 } 073 074 075 /** 076 * Constructor. 077 * @param r solvable polynomial ring factory. 078 * @param l list of list of solvable polynomials. 079 */ 080 public ModuleList( GenSolvablePolynomialRing< C > r, 081 List< List<GenSolvablePolynomial< C >>> l) { 082 this( r, ModuleList.<C>castToList(l) ); 083 } 084 085 086 /** 087 * Constructor. 088 * @param r polynomial ring factory. 089 * @param l list of vectors of polynomials. 090 */ 091 public ModuleList( GenVectorModul<GenPolynomial<C>> r, 092 List< GenVector<GenPolynomial< C >>> l) { 093 this( (GenPolynomialRing<C>)r.coFac, ModuleList.<C>vecToList(l) ); 094 } 095 096 097 /** Comparison with any other object. 098 * @see java.lang.Object#equals(java.lang.Object) 099 */ 100 @Override 101 @SuppressWarnings("unchecked") // not jet working 102 public boolean equals(Object m) { 103 if ( ! (m instanceof ModuleList) ) { 104 //System.out.println("ModuleList"); 105 return false; 106 } 107 ModuleList<C> ml = null; 108 try { 109 ml = (ModuleList<C>)m; 110 } catch (ClassCastException ignored) { 111 } 112 if ( ml == null ) { 113 return false; 114 } 115 if ( ! ring.equals( ml.ring ) ) { 116 //System.out.println("Ring"); 117 return false; 118 } 119 if ( list == ml.list ) { 120 return true; 121 } 122 if ( list == null && ml.list != null ) { 123 //System.out.println("List, null"); 124 return false; 125 } 126 if ( list != null && ml.list == null ) { 127 //System.out.println("List, null"); 128 return false; 129 } 130 if ( list.size() != ml.list.size() ) { 131 //System.out.println("List, size"); 132 return false; 133 } 134 // compare sorted lists 135 List otl = OrderedModuleList.sort( ring, list ); 136 List oml = OrderedModuleList.sort( ring, ml.list ); 137 if ( ! otl.equals(oml) ) { 138 return false; 139 } 140 return true; 141 } 142 143 144 /** Hash code for this module list. 145 * @see java.lang.Object#hashCode() 146 */ 147 @Override 148 public int hashCode() { 149 int h; 150 h = ring.hashCode(); 151 h = 37 * h + ( list == null ? 0 : list.hashCode() ); 152 return h; 153 } 154 155 156 /** 157 * String representation of the module list. 158 * @see java.lang.Object#toString() 159 */ 160 @Override 161 //@SuppressWarnings("unchecked") 162 public String toString() { 163 StringBuffer erg = new StringBuffer(); 164 String[] vars = null; 165 if ( ring != null ) { 166 erg.append( ring.toString() ); 167 vars = ring.getVars(); 168 } 169 if ( list == null ) { 170 erg.append(")"); 171 return erg.toString(); 172 } 173 boolean first = true; 174 erg.append("(\n"); 175 for ( List< GenPolynomial<C> > row: list ) { 176 if ( first ) { 177 first = false; 178 } else { 179 erg.append( ",\n" ); 180 } 181 boolean ifirst = true; 182 erg.append(" ( "); 183 String os; 184 for ( GenPolynomial<C> oa: row ) { 185 if ( oa == null ) { 186 os = "0"; 187 } else if ( vars != null ) { 188 os = oa.toString(vars); 189 } else { 190 os = oa.toString(); 191 } 192 if ( ifirst ) { 193 ifirst = false; 194 } else { 195 erg.append( ", " ); 196 if ( os.length() > 100 ) { 197 erg.append("\n"); 198 } 199 } 200 erg.append( os ); 201 } 202 erg.append(" )"); 203 } 204 erg.append("\n)"); 205 return erg.toString(); 206 } 207 208 209 /** Get a scripting compatible string representation. 210 * @return script compatible representation for this ModuleList. 211 */ 212 public String toScript() { 213 StringBuffer s = new StringBuffer(); 214 if ( ring instanceof GenSolvablePolynomialRing ) { 215 s.append("Solvable"); 216 } 217 switch (Scripting.getLang() ) { 218 case Ruby: 219 s.append("SubModule.new("); 220 break; 221 case Python: 222 default: 223 s.append("SubModule("); 224 } 225 if ( ring != null ) { 226 s.append( ring.toScript() ); 227 } 228 if ( list == null ) { 229 s.append(")"); 230 return s.toString(); 231 } 232 s.append(",list=["); 233 boolean first = true; 234 for ( List< GenPolynomial<C> > row: list ) { 235 if ( first ) { 236 first = false; 237 } else { 238 s.append( "," ); 239 } 240 boolean ifirst = true; 241 s.append(" ( "); 242 String os; 243 for ( GenPolynomial<C> oa: row ) { 244 if ( oa == null ) { 245 os = "0"; 246 } else { 247 os = oa.toScript(); 248 } 249 if ( ifirst ) { 250 ifirst = false; 251 } else { 252 s.append( ", " ); 253 } 254 s.append( os ); 255 } 256 s.append(" )"); 257 } 258 s.append(" ])"); 259 return s.toString(); 260 } 261 262 263 /** 264 * Pad columns and remove zero rows. 265 * Make all rows have the same number of columns. 266 * @param ring polynomial ring factory. 267 * @param l list of list of polynomials. 268 * @return list of list of polynomials with same number of colums. 269 */ 270 public static <C extends RingElem<C> > 271 List< List<GenPolynomial< C >>> 272 padCols(GenPolynomialRing< C > ring, 273 List< List<GenPolynomial< C >>> l) { 274 if ( l == null ) { 275 return l; 276 } 277 int mcols = 0; 278 int rs = 0; 279 for ( List< GenPolynomial<C> > row: l ) { 280 if ( row != null ) { 281 rs++; 282 if ( row.size() > mcols ) { 283 mcols = row.size(); 284 } 285 } 286 } 287 List< List<GenPolynomial<C>> > norm 288 = new ArrayList< List<GenPolynomial<C>> >( rs ); 289 for ( List< GenPolynomial<C> > row: l ) { 290 if ( row != null ) { 291 List<GenPolynomial<C>> rn 292 = new ArrayList<GenPolynomial<C>>( row ); 293 while ( rn.size() < mcols ) { 294 rn.add( ring.getZERO() ); 295 } 296 norm.add( rn ); 297 } 298 } 299 return norm; 300 } 301 302 303 304 /** 305 * Get PolynomialList. 306 * Embed module in a polynomial ring. 307 * @see edu.jas.poly.PolynomialList 308 * @return polynomial list corresponding to this. 309 */ 310 public PolynomialList<C> getPolynomialList() { 311 GenPolynomialRing< C > pfac = ring.extend(cols); 312 logger.debug("extended ring = " + pfac); 313 //System.out.println("extended ring = " + pfac); 314 315 List<GenPolynomial<C>> pols = null; 316 if ( list == null ) { // rows < 0 317 return new PolynomialList<C>(pfac,pols); 318 } 319 pols = new ArrayList<GenPolynomial<C>>( rows ); 320 if ( rows == 0 ) { // nothing to do 321 return new PolynomialList<C>(pfac,pols); 322 } 323 324 GenPolynomial<C> zero = pfac.getZERO(); 325 GenPolynomial<C> d = null; 326 for ( List<GenPolynomial<C>> r: list ) { 327 GenPolynomial<C> ext = zero; 328 //int m = cols-1; 329 int m = 0; 330 for ( GenPolynomial<C> c: r ) { 331 d = c.extend( pfac, m, 1l ); 332 ext = ext.sum(d); 333 m++; 334 } 335 pols.add( ext ); 336 } 337 return new PolynomialList<C>(pfac, pols); 338 } 339 340 341 /** 342 * Get list as List of GenSolvablePolynomials. 343 * Required because no List casts allowed. Equivalent to 344 * cast (List<List<GenSolvablePolynomial<C>>>) list. 345 * @return list of solvable polynomial lists from this. 346 */ 347 public List< List< GenSolvablePolynomial<C> > > castToSolvableList() { 348 List< List<GenSolvablePolynomial<C>> > slist = null; 349 if ( list == null ) { 350 return slist; 351 } 352 slist = new ArrayList< List<GenSolvablePolynomial<C>> >( list.size() ); 353 for ( List< GenPolynomial<C>> row: list ) { 354 List< GenSolvablePolynomial<C> > srow 355 = new ArrayList< GenSolvablePolynomial<C> >( row.size() ); 356 for ( GenPolynomial<C> p: row ) { 357 if ( ! (p instanceof GenSolvablePolynomial) ) { 358 throw new RuntimeException("no solvable polynomial "+p); 359 } 360 GenSolvablePolynomial<C> s 361 = (GenSolvablePolynomial<C>) p; 362 srow.add( s ); 363 } 364 slist.add( srow ); 365 } 366 return slist; 367 } 368 369 370 /** 371 * Get a solvable polynomials list as List of GenPolynomials. 372 * Required because no List casts allowed. Equivalent to 373 * cast (List<List<GenPolynomial<C>>>) list. 374 * @param slist list of solvable polynomial lists. 375 * @return list of polynomial lists from slist. 376 */ 377 public static <C extends RingElem<C> > 378 List< List< GenPolynomial<C> > > 379 castToList( List< List<GenSolvablePolynomial<C>> > slist ) { 380 List< List<GenPolynomial<C>> > list = null; 381 if ( slist == null ) { 382 return list; 383 } 384 list = new ArrayList< List<GenPolynomial<C>> >( slist.size() ); 385 for ( List< GenSolvablePolynomial<C>> srow: slist ) { 386 List< GenPolynomial<C> > row 387 = new ArrayList< GenPolynomial<C> >( srow.size() ); 388 for ( GenSolvablePolynomial<C> s: srow ) { 389 row.add( s ); 390 } 391 list.add( row ); 392 } 393 return list; 394 } 395 396 397 /** 398 * Get a list of vectors as List of list of GenPolynomials. 399 * @param vlist list of vectors of polynomials. 400 * @return list of polynomial lists from vlist. 401 */ 402 public static <C extends RingElem<C> > 403 List< List< GenPolynomial<C> > > 404 vecToList( List< GenVector<GenPolynomial<C>> > vlist ) { 405 List< List<GenPolynomial<C>> > list = null; 406 if ( vlist == null ) { 407 return list; 408 } 409 list = new ArrayList< List<GenPolynomial<C>> >( vlist.size() ); 410 for ( GenVector< GenPolynomial<C>> srow: vlist ) { 411 List< GenPolynomial<C> > row = srow.val; 412 list.add( row ); 413 } 414 return list; 415 } 416 417 }