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