001    /*
002     * $Id: PolynomialList.java 3470 2011-01-06 19:19:11Z kredel $
003     */
004    
005    package edu.jas.poly;
006    
007    
008    import java.lang.Comparable;
009    import java.util.List;
010    import java.util.ArrayList;
011    import java.util.Map;
012    import java.io.Serializable;
013    
014    import org.apache.log4j.Logger;
015    
016    import edu.jas.structure.RingElem;
017    import edu.jas.kern.Scripting;
018    import edu.jas.poly.GenPolynomial;
019    import edu.jas.poly.GenSolvablePolynomial;
020    import edu.jas.poly.GenPolynomialRing;
021    import edu.jas.poly.GenSolvablePolynomialRing;
022    
023    
024    /**
025     * List of polynomials.
026     * Mainly for storage and printing / toString and 
027     * conversions to other representations.
028     * @author Heinz Kredel
029     */
030    
031    public class PolynomialList<C extends RingElem<C> > 
032        implements Comparable<PolynomialList<C>>, Serializable, Cloneable {
033    
034    
035        /** The factory for the solvable polynomial ring. 
036         */
037        public final GenPolynomialRing< C > ring;
038    
039    
040        /** The data structure is a List of polynomials. 
041         */
042        public final List< GenPolynomial<C> > list;
043    
044    
045        private static final Logger logger = Logger.getLogger(PolynomialList.class);
046    
047    
048        /**
049         * Constructor.
050         * @param r polynomial ring factory.
051         * @param l list of polynomials.
052         */
053        public PolynomialList( GenPolynomialRing< C > r,
054                               List<GenPolynomial< C >> l) {
055            ring = r;
056            list = l; 
057        }
058    
059    
060        /**
061         * Constructor.
062         * @param r solvable polynomial ring factory.
063         * @param l list of solvable polynomials.
064         */
065        public PolynomialList( GenSolvablePolynomialRing< C > r,
066                               List<GenSolvablePolynomial< C >> l) {
067            this( r, PolynomialList.<C>castToList(l) ); 
068        }
069    
070    
071        /**
072         * Clone this.
073         * @return a copy of this.
074         */
075        @Override
076        public PolynomialList<C> clone() {
077            return new PolynomialList<C>(ring,new ArrayList<GenPolynomial<C>>(list));
078        }
079    
080    
081        /** Comparison with any other object.
082         * @see java.lang.Object#equals(java.lang.Object)
083         */
084        @Override 
085        @SuppressWarnings("unchecked")
086        public boolean equals(Object p) {
087            if ( ! (p instanceof PolynomialList) ) {
088                System.out.println("no PolynomialList");
089                return false;
090            }
091            PolynomialList< C > pl = null;
092            try {
093                pl = (PolynomialList< C >)p;
094            } catch (ClassCastException ignored) {
095            }
096            if ( pl == null ) {
097               return false;
098            }
099            if ( ! ring.equals( pl.ring ) ) {
100                System.out.println("not same Ring " + ring.toScript() + ", " + pl.ring.toScript());
101                return false;
102            }
103            return ( compareTo(pl) == 0 );
104            // otherwise tables may be different
105        }
106    
107    
108        /** Polynomial list comparison.  
109         * @param L other PolynomialList.
110         * @return lexicographical comparison, sign of first different polynomials.
111         */
112        public int compareTo(PolynomialList<C> L) {
113            int si = L.list.size();
114            if ( list.size() < si ) { // minimum
115                si = list.size();
116            }
117            int s = 0;
118            List<GenPolynomial<C>> l1 = OrderedPolynomialList.<C>sort( ring, list );
119            List<GenPolynomial<C>> l2 = OrderedPolynomialList.<C>sort( ring, L.list );
120            for ( int i = 0; i < si; i++ ) {
121                GenPolynomial<C> a = l1.get(i);
122                GenPolynomial<C> b = l2.get(i);
123                s = a.compareTo(b);
124                if ( s != 0 ) {
125                   return s;
126                }
127            }
128            if ( list.size() > si ) { 
129                return 1;
130            }
131            if ( L.list.size() > si ) { 
132                return -1;
133            }
134            return s;
135        }
136    
137    
138        /** Hash code for this polynomial list.
139         * @see java.lang.Object#hashCode()
140         */
141        @Override
142        public int hashCode() { 
143           int h;
144           h = ring.hashCode();
145           h = 37 * h + ( list == null ? 0 : list.hashCode() );
146           return h;
147        }
148    
149    
150        /**
151         * String representation of the polynomial list.
152         * @see java.lang.Object#toString()
153         */
154        @Override
155        public String toString() {
156            StringBuffer erg = new StringBuffer();
157            String[] vars = null;
158            if ( ring != null ) {
159               erg.append( ring.toString() );
160               vars = ring.getVars();
161            }
162            boolean first = true;
163            erg.append("\n(\n");
164            String sa = null;
165            for ( GenPolynomial<C> oa: list ) {
166                if ( vars != null ) {
167                   sa = oa.toString(vars);
168                } else {
169                   sa = oa.toString();
170                }
171                if ( first ) {
172                   first = false;
173                } else {
174                   erg.append( ", " );
175                   if ( sa.length() > 10 ) {
176                      erg.append("\n");
177                   }
178                }
179                erg.append( "( " + sa + " )" );
180            }
181            erg.append("\n)");
182            return erg.toString();
183        }
184    
185    
186        /** Get a scripting compatible string representation.
187         * @return script compatible representation for this polynomial list.
188         */
189        public String toScript() {
190            StringBuffer s = new StringBuffer();
191            switch (Scripting.getLang() ) {
192            case Ruby:
193                s.append("Ideal.new(");
194                break;
195            case Python:
196            default:
197                s.append("Ideal(");
198            }
199            if ( ring != null ) {
200               s.append( ring.toScript() );
201            }
202            if ( list == null ) {
203                s.append(")");
204                return s.toString();
205            }
206            s.append(",list=[");
207            boolean first = true;
208            String sa = null;
209            for ( GenPolynomial<C> oa: list ) {
210                sa = oa.toScript();
211                if ( first ) {
212                   first = false;
213                } else {
214                   s.append( ", " );
215                }
216                s.append( "( " + sa + " )" );
217            }
218            s.append("])");
219            return s.toString();
220        }
221    
222    
223        /**
224         * Get ModuleList from PolynomialList.
225         * Extract module from polynomial ring. 
226         * @see edu.jas.poly.ModuleList
227         * @param i number of variables to be contract form the polynomials.
228         * @return module list corresponding to this.
229         */
230        @SuppressWarnings("unchecked")
231        public ModuleList<C> getModuleList(int i) {
232            GenPolynomialRing< C > pfac = ring.contract(i);
233            logger.debug("contracted ring = " + pfac);
234            //System.out.println("contracted ring = " + pfac);
235    
236            List<List<GenPolynomial<C>>> vecs = null;
237            if ( list == null ) { 
238               return new ModuleList<C>(pfac,vecs);
239            }
240            int rows = list.size();
241            vecs = new ArrayList<List<GenPolynomial<C>>>( rows );
242            if ( rows == 0 ) { // nothing to do
243               return new ModuleList<C>(pfac,vecs);
244            }
245    
246            ArrayList<GenPolynomial<C>> zr 
247                 = new ArrayList<GenPolynomial<C>>( i-1 );
248            GenPolynomial<C> zero = pfac.getZERO();
249            for ( int j = 0; j < i; j++ ) {
250                zr.add(j,zero);
251            }
252    
253            for ( GenPolynomial<C> p: list ) {
254                if ( p != null ) {
255                    Map<ExpVector,GenPolynomial<C>> r = null;
256                    r = p.contract( pfac );
257                    //System.out.println("r = " + r ); 
258                    List<GenPolynomial<C>> row 
259                        = (ArrayList<GenPolynomial<C>>)zr.clone();
260                    for ( ExpVector e: r.keySet() ) {
261                        int[] dov = e.dependencyOnVariables();
262                        int ix = 0;
263                        if ( dov.length > 1 ) {
264                           throw new IllegalArgumentException("wrong dependencyOnVariables " + e);
265                        } else if ( dov.length == 1 )  {
266                           ix = dov[0];
267                        }
268                        //ix = i-1 - ix; // revert
269                        //System.out.println("ix = " + ix ); 
270                        GenPolynomial<C> vi = r.get( e );
271                        row.set(ix,vi);
272                    }
273                    //System.out.println("row = " + row ); 
274                    vecs.add( row );
275                }
276            }
277            return new ModuleList<C>(pfac,vecs);
278        }
279    
280    
281        /**
282         * Get list as List of GenSolvablePolynomials.
283         * Required because no List casts allowed. Equivalent to 
284         * cast (List&lt;GenSolvablePolynomial&lt;C&gt;&gt;) list.
285         * @return solvable polynomial list from this.
286         */
287        public List< GenSolvablePolynomial<C> > castToSolvableList() {
288            return castToSolvableList(list);
289        }
290    
291    
292        /**
293         * Get list as List of GenSolvablePolynomials.
294         * Required because no List casts allowed. Equivalent to 
295         * cast (List&lt;GenSolvablePolynomial&lt;C&gt;&gt;) list.
296         * @param list list of extensions of polynomials.
297         * @return solvable polynomial list from this.
298         */
299        public static <C extends RingElem<C> > 
300               List< GenSolvablePolynomial<C> > castToSolvableList(List<GenPolynomial<C>> list) {
301            List< GenSolvablePolynomial<C> > slist = null;
302            if ( list == null ) {
303                return slist;
304            }
305            slist = new ArrayList< GenSolvablePolynomial<C> >( list.size() ); 
306            GenSolvablePolynomial<C> s;
307            for ( GenPolynomial<C> p: list ) {
308                if ( ! (p instanceof GenSolvablePolynomial) ) {
309                   throw new IllegalArgumentException("no solvable polynomial "+p);
310                }
311                s = (GenSolvablePolynomial<C>) p;
312                slist.add( s );
313            }
314            return slist;
315        }
316    
317    
318        /**
319         * Get list of list as List of List of GenSolvablePolynomials.
320         * Required because no List casts allowed. Equivalent to 
321         * cast (List&lt;GenSolvablePolynomial&lt;C&gt;&gt;) list.
322         * @param list list of extensions of polynomials.
323         * @return solvable polynomial list from this.
324         */
325        public static <C extends RingElem<C> > 
326               List<List< GenSolvablePolynomial<C> >> castToSolvableMatrix(List<List<GenPolynomial<C>>> list) {
327            List<List< GenSolvablePolynomial<C> >> slist = null;
328            if ( list == null ) {
329                return slist;
330            }
331            slist = new ArrayList< List<GenSolvablePolynomial<C>> >( list.size() ); 
332            List<GenSolvablePolynomial<C>> s;
333            for ( List<GenPolynomial<C>> p: list ) {
334                s = PolynomialList.<C>castToSolvableList(p);
335                slist.add( s );
336            }
337            return slist;
338        }
339    
340    
341        /**
342         * Get list of extensions of polynomials as List of GenPolynomials.
343         * Required because no List casts allowed. Equivalent to 
344         * cast (List&lt;GenPolynomial&lt;C&gt;&gt;) list.
345         * Mainly used for lists of GenSolvablePolynomials.
346         * @param slist list of extensions of polynomials.
347         * @return polynomial list from slist.
348         */
349        public static <C extends RingElem<C> > 
350               List< GenPolynomial<C> > 
351               castToList( List<? extends GenPolynomial<C>> slist) {
352            logger.warn("will lead to wrong method dispatch");
353            List< GenPolynomial<C> > list = null;
354            if ( slist == null ) {
355                return list;
356            }
357            list = new ArrayList< GenPolynomial<C> >( slist.size() ); 
358            for ( GenPolynomial<C> p: slist ) {
359                list.add( p );
360            }
361            return list;
362        }
363    
364    
365        /**
366         * Get list of list of extensions of polynomials as List of List of GenPolynomials.
367         * Required because no List casts allowed. Equivalent to 
368         * cast (List&lt;GenPolynomial&lt;C&gt;&gt;) list.
369         * Mainly used for lists of GenSolvablePolynomials.
370         * @param slist list of extensions of polynomials.
371         * @return polynomial list from slist.
372         */
373        public static <C extends RingElem<C> > 
374               List<List< GenPolynomial<C> >> 
375               castToMatrix( List<List<? extends GenPolynomial<C>>> slist) {
376            logger.warn("will lead to wrong method dispatch");
377            List<List< GenPolynomial<C> >> list = null;
378            if ( slist == null ) {
379                return list;
380            }
381            list = new ArrayList< List<GenPolynomial<C>> >( slist.size() ); 
382            for ( List<? extends GenPolynomial<C>> p: slist ) {
383                list.add( PolynomialList.<C>castToList(p) );
384            }
385            return list;
386        }
387    
388    
389      /**
390       * Test if list contains only ZEROs.
391       * @return true, if this is the 0 list, else false
392       */
393      public boolean isZERO() {
394          if ( list == null ) {
395              return true;
396          }
397          for ( GenPolynomial<C> p : list ) {
398              if ( p == null ) {
399                  continue;
400              }
401              if ( ! p.isZERO() ) {
402                 return false;
403              }
404          }
405          return true;
406      }
407    
408    
409      /**
410       * Test if list contains a ONE.
411       * @return true, if this contains 1, else false
412       */
413      public boolean isONE() {
414          if ( list == null ) {
415              return false;
416          }
417          for ( GenPolynomial<C> p : list ) {
418              if ( p == null ) {
419                  continue;
420              }
421              if ( p.isONE() ) {
422                 return true;
423              }
424          }
425          return false;
426      }
427    
428    }