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 }