001/* 002 * $Id: ModuleList.java 3992 2012-07-14 21:32:18Z kredel $ 003 */ 004 005package edu.jas.poly; 006 007import java.util.List; 008import java.util.ArrayList; 009import java.io.Serializable; 010 011import org.apache.log4j.Logger; 012 013import edu.jas.kern.Scripting; 014import edu.jas.structure.RingElem; 015import edu.jas.vector.GenVector; 016import 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 026public 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.size() != ml.list.size() ) { 127 //System.out.println("List, size"); 128 return false; 129 } 130 // compare sorted lists 131 List otl = OrderedModuleList.sort( ring, list ); 132 List oml = OrderedModuleList.sort( ring, ml.list ); 133 if ( ! otl.equals(oml) ) { 134 return false; 135 } 136 return true; 137 } 138 139 140 /** Hash code for this module list. 141 * @see java.lang.Object#hashCode() 142 */ 143 @Override 144 public int hashCode() { 145 int h; 146 h = ring.hashCode(); 147 h = 37 * h + ( list == null ? 0 : list.hashCode() ); 148 return h; 149 } 150 151 152 /** 153 * String representation of the module list. 154 * @see java.lang.Object#toString() 155 */ 156 @Override 157 //@SuppressWarnings("unchecked") 158 public String toString() { 159 StringBuffer erg = new StringBuffer(); 160 String[] vars = null; 161 if ( ring != null ) { 162 erg.append( ring.toString() ); 163 vars = ring.getVars(); 164 } 165 if ( list == null ) { 166 erg.append(")"); 167 return erg.toString(); 168 } 169 boolean first = true; 170 erg.append("(\n"); 171 for ( List< GenPolynomial<C> > row: list ) { 172 if ( first ) { 173 first = false; 174 } else { 175 erg.append( ",\n" ); 176 } 177 boolean ifirst = true; 178 erg.append(" ( "); 179 String os; 180 for ( GenPolynomial<C> oa: row ) { 181 if ( oa == null ) { 182 os = "0"; 183 } else if ( vars != null ) { 184 os = oa.toString(vars); 185 } else { 186 os = oa.toString(); 187 } 188 if ( ifirst ) { 189 ifirst = false; 190 } else { 191 erg.append( ", " ); 192 if ( os.length() > 100 ) { 193 erg.append("\n"); 194 } 195 } 196 erg.append( os ); 197 } 198 erg.append(" )"); 199 } 200 erg.append("\n)"); 201 return erg.toString(); 202 } 203 204 205 /** Get a scripting compatible string representation. 206 * @return script compatible representation for this ModuleList. 207 */ 208 public String toScript() { 209 StringBuffer s = new StringBuffer(); 210 if ( ring instanceof GenSolvablePolynomialRing ) { 211 s.append("Solvable"); 212 } 213 switch (Scripting.getLang() ) { 214 case Ruby: 215 s.append("SubModule.new("); 216 break; 217 case Python: 218 default: 219 s.append("SubModule("); 220 } 221 if ( ring != null ) { 222 s.append( ring.toScript() ); 223 } 224 if ( list == null ) { 225 s.append(")"); 226 return s.toString(); 227 } 228 switch (Scripting.getLang() ) { 229 case Ruby: 230 s.append(",\"\",["); 231 break; 232 case Python: 233 default: 234 s.append(",list=["); 235 } 236 boolean first = true; 237 for ( List< GenPolynomial<C> > row: list ) { 238 if ( first ) { 239 first = false; 240 } else { 241 s.append( "," ); 242 } 243 boolean ifirst = true; 244 s.append(" ( "); 245 String os; 246 for ( GenPolynomial<C> oa: row ) { 247 if ( oa == null ) { 248 os = "0"; 249 } else { 250 os = oa.toScript(); 251 } 252 if ( ifirst ) { 253 ifirst = false; 254 } else { 255 s.append( ", " ); 256 } 257 s.append( os ); 258 } 259 s.append(" )"); 260 } 261 s.append(" ])"); 262 return s.toString(); 263 } 264 265 266 /** 267 * Pad columns and remove zero rows. 268 * Make all rows have the same number of columns. 269 * @param ring polynomial ring factory. 270 * @param l list of list of polynomials. 271 * @return list of list of polynomials with same number of colums. 272 */ 273 public static <C extends RingElem<C> > 274 List< List<GenPolynomial< C >>> 275 padCols(GenPolynomialRing< C > ring, 276 List< List<GenPolynomial< C >>> l) { 277 if ( l == null ) { 278 return l; 279 } 280 int mcols = 0; 281 int rs = 0; 282 for ( List< GenPolynomial<C> > row: l ) { 283 if ( row != null ) { 284 rs++; 285 if ( row.size() > mcols ) { 286 mcols = row.size(); 287 } 288 } 289 } 290 List< List<GenPolynomial<C>> > norm 291 = new ArrayList< List<GenPolynomial<C>> >( rs ); 292 for ( List< GenPolynomial<C> > row: l ) { 293 if ( row != null ) { 294 List<GenPolynomial<C>> rn 295 = new ArrayList<GenPolynomial<C>>( row ); 296 while ( rn.size() < mcols ) { 297 rn.add( ring.getZERO() ); 298 } 299 norm.add( rn ); 300 } 301 } 302 return norm; 303 } 304 305 306 307 /** 308 * Get PolynomialList. 309 * Embed module in a polynomial ring. 310 * @see edu.jas.poly.PolynomialList 311 * @return polynomial list corresponding to this. 312 */ 313 public PolynomialList<C> getPolynomialList() { 314 GenPolynomialRing< C > pfac = ring.extend(cols); 315 logger.debug("extended ring = " + pfac); 316 //System.out.println("extended ring = " + pfac); 317 318 List<GenPolynomial<C>> pols = null; 319 if ( list == null ) { // rows < 0 320 return new PolynomialList<C>(pfac,pols); 321 } 322 pols = new ArrayList<GenPolynomial<C>>( rows ); 323 if ( rows == 0 ) { // nothing to do 324 return new PolynomialList<C>(pfac,pols); 325 } 326 327 GenPolynomial<C> zero = pfac.getZERO(); 328 GenPolynomial<C> d = null; 329 for ( List<GenPolynomial<C>> r: list ) { 330 GenPolynomial<C> ext = zero; 331 //int m = cols-1; 332 int m = 0; 333 for ( GenPolynomial<C> c: r ) { 334 d = c.extend( pfac, m, 1l ); 335 ext = ext.sum(d); 336 m++; 337 } 338 pols.add( ext ); 339 } 340 return new PolynomialList<C>(pfac, pols); 341 } 342 343 344 /** 345 * Get list as List of GenSolvablePolynomials. 346 * Required because no List casts allowed. Equivalent to 347 * cast (List<List<GenSolvablePolynomial<C>>>) list. 348 * @return list of solvable polynomial lists from this. 349 */ 350 public List< List< GenSolvablePolynomial<C> > > castToSolvableList() { 351 List< List<GenSolvablePolynomial<C>> > slist = null; 352 if ( list == null ) { 353 return slist; 354 } 355 slist = new ArrayList< List<GenSolvablePolynomial<C>> >( list.size() ); 356 for ( List< GenPolynomial<C>> row: list ) { 357 List< GenSolvablePolynomial<C> > srow 358 = new ArrayList< GenSolvablePolynomial<C> >( row.size() ); 359 for ( GenPolynomial<C> p: row ) { 360 if ( ! (p instanceof GenSolvablePolynomial) ) { 361 throw new RuntimeException("no solvable polynomial "+p); 362 } 363 GenSolvablePolynomial<C> s 364 = (GenSolvablePolynomial<C>) p; 365 srow.add( s ); 366 } 367 slist.add( srow ); 368 } 369 return slist; 370 } 371 372 373 /** 374 * Get a solvable polynomials list as List of GenPolynomials. 375 * Required because no List casts allowed. Equivalent to 376 * cast (List<List<GenPolynomial<C>>>) list. 377 * @param slist list of solvable polynomial lists. 378 * @return list of polynomial lists from slist. 379 */ 380 public static <C extends RingElem<C> > 381 List< List< GenPolynomial<C> > > 382 castToList( List< List<GenSolvablePolynomial<C>> > slist ) { 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< GenSolvablePolynomial<C>> srow: slist ) { 389 List< GenPolynomial<C> > row 390 = new ArrayList< GenPolynomial<C> >( srow.size() ); 391 for ( GenSolvablePolynomial<C> s: srow ) { 392 row.add( s ); 393 } 394 list.add( row ); 395 } 396 return list; 397 } 398 399 400 /** 401 * Get a list of vectors as List of list of GenPolynomials. 402 * @param vlist list of vectors of polynomials. 403 * @return list of polynomial lists from vlist. 404 */ 405 public static <C extends RingElem<C> > 406 List< List< GenPolynomial<C> > > 407 vecToList( List< GenVector<GenPolynomial<C>> > vlist ) { 408 List< List<GenPolynomial<C>> > list = null; 409 if ( vlist == null ) { 410 return list; 411 } 412 list = new ArrayList< List<GenPolynomial<C>> >( vlist.size() ); 413 for ( GenVector< GenPolynomial<C>> srow: vlist ) { 414 List< GenPolynomial<C> > row = srow.val; 415 list.add( row ); 416 } 417 return list; 418 } 419 420}