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&lt;List&lt;GenSolvablePolynomial&lt;C&gt;&gt;&gt;) 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&lt;List&lt;GenPolynomial&lt;C&gt;&gt;&gt;) 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}