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