001/*
002 * $Id$
003 */
004
005package edu.jas.poly;
006
007
008import java.io.IOException;
009import java.io.Reader;
010import java.io.StringReader;
011import java.math.BigInteger;
012import java.util.ArrayList;
013import java.util.List;
014import java.util.Map;
015import java.util.Random;
016import java.util.SortedMap;
017
018import org.apache.logging.log4j.LogManager;
019import org.apache.logging.log4j.Logger;
020
021import edu.jas.kern.PreemptStatus;
022import edu.jas.kern.Scripting;
023import edu.jas.structure.RingElem;
024import edu.jas.structure.RingFactory;
025import edu.jas.vector.GenMatrix;
026import edu.jas.vector.GenVector;
027
028
029/**
030 * GenExteriorPolynomialRing generic antisymmetric polynomial factory
031 * implementing RingFactory; Factory for antisymmetric polynomials (in fact
032 * vectors) over C. Objects of this class are intended to be immutable. Only the
033 * coefficients are modeled with generic types, the "exponents" are fixed to
034 * IndexList. C can also be a non integral domain, e.g. a ModInteger, i.e. it
035 * may contain zero divisors, since multiply() does check for zero coefficients
036 * and index lists.
037 * @see "masnc.DIPE.mi from SAC2/MAS"
038 * @param <C> coefficient type
039 * @author Heinz Kredel
040 */
041
042public final class GenExteriorPolynomialRing<C extends RingElem<C>>
043                implements RingFactory<GenExteriorPolynomial<C>> {
044    /*, Iterable<GenExteriorPolynomial<C>>*/
045
046
047    /**
048     * The factory for the coefficients.
049     */
050    public final RingFactory<C> coFac;
051
052
053    /**
054     * The factory for the IndexList.
055     */
056    public final IndexFactory ixfac;
057
058
059    /**
060     * The constant polynomial 0 for this ring.
061     */
062    public final GenExteriorPolynomial<C> ZERO;
063
064
065    /**
066     * The constant polynomial 1 for this ring.
067     */
068    public final GenExteriorPolynomial<C> ONE;
069
070
071    /**
072     * The constant empty index lists exponent for this ring.
073     */
074    public final IndexList wone;
075
076
077    /**
078     * A default random sequence generator.
079     */
080    final static Random random = new Random();
081
082
083    /**
084     * Indicator if this ring is a field.
085     */
086    private int isField = -1; // initially unknown
087
088
089    /**
090     * Log4j logger object.
091     */
092    private static final Logger logger = LogManager.getLogger(GenExteriorPolynomialRing.class);
093
094
095    /**
096     * Flag to enable if preemptive interrupt is checked.
097     */
098    final boolean checkPreempt = PreemptStatus.isAllowed();
099
100
101    /**
102     * The constructor creates a polynomial factory object with the default term
103     * order.
104     * @param cf factory for coefficients of type C.
105     * @param wf factory for index list.
106     */
107    public GenExteriorPolynomialRing(RingFactory<C> cf, IndexFactory wf) {
108        coFac = cf;
109        ixfac = wf;
110        ZERO = new GenExteriorPolynomial<C>(this);
111        C coeff = coFac.getONE();
112        wone = ixfac.getONE();
113        ONE = new GenExteriorPolynomial<C>(this, coeff, wone);
114    }
115
116
117    /**
118     * The constructor creates a polynomial factory object.
119     * @param cf factory for coefficients of type C.
120     * @param s array of variable names.
121     */
122    public GenExteriorPolynomialRing(RingFactory<C> cf, String[] s) {
123        this(cf, new IndexFactory(s.length));
124    }
125
126
127    /**
128     * The constructor creates a polynomial factory object.
129     * @param cf factory for coefficients of type C.
130     * @param s string of single letter variable names.
131     */
132    public GenExteriorPolynomialRing(RingFactory<C> cf, String s) {
133        this(cf, new IndexFactory(s.length())); // todo
134    }
135
136
137    /**
138     * The constructor creates a polynomial factory object.
139     * @param cf factory for coefficients of type C.
140     * @param o other polynomial ring.
141     */
142    public GenExteriorPolynomialRing(RingFactory<C> cf, GenExteriorPolynomialRing o) {
143        this(cf, o.ixfac);
144    }
145
146
147    /**
148     * The constructor creates a polynomial factory object.
149     * @param fac polynomial ring.
150     */
151    public GenExteriorPolynomialRing(GenPolynomialRing<C> fac) {
152        this(fac.coFac, new IndexFactory(fac.nvar));
153    }
154
155
156    /**
157     * Copy this factory.
158     * @return a clone of this.
159     */
160    public GenExteriorPolynomialRing<C> copy() {
161        return new GenExteriorPolynomialRing<C>(coFac, this);
162    }
163
164
165    /**
166     * Get the String representation.
167     * @see java.lang.Object#toString()
168     */
169    @Override
170    public String toString() {
171        StringBuffer s = new StringBuffer();
172        s.append("ExteriorPolyRing(");
173        if (coFac instanceof RingElem) {
174            s.append(((RingElem<C>) coFac).toScriptFactory());
175        } else {
176            s.append(coFac.toString().trim());
177        }
178        s.append(", \"");
179        s.append(ixfac.toString());
180        s.append("\")");
181        return s.toString();
182    }
183
184
185    /**
186     * Get a scripting compatible string representation.
187     * @return script compatible representation for this Element.
188     * @see edu.jas.structure.Element#toScript()
189     */
190    @Override
191    public String toScript() {
192        StringBuffer s = new StringBuffer();
193        switch (Scripting.getLang()) {
194        case Ruby:
195            s.append("ExtPolyRing.new(");
196            break;
197        case Python:
198        default:
199            s.append("ExtPolyRing(");
200        }
201        if (coFac instanceof RingElem) {
202            s.append(((RingElem<C>) coFac).toScriptFactory());
203        } else {
204            s.append(coFac.toScript().trim());
205        }
206        s.append(", \"");
207        s.append(ixfac.toScript());
208        s.append("\")");
209        return s.toString();
210    }
211
212
213    /**
214     * Comparison with any other object.
215     * @see java.lang.Object#equals(java.lang.Object)
216     */
217    @Override
218    @SuppressWarnings("unchecked")
219    public boolean equals(Object other) {
220        if (other == null) {
221            return false;
222        }
223        if (!(other instanceof GenExteriorPolynomialRing)) {
224            return false;
225        }
226        GenExteriorPolynomialRing<C> oring = (GenExteriorPolynomialRing<C>) other;
227        if (!coFac.equals(oring.coFac)) {
228            return false;
229        }
230        if (!ixfac.equals(oring.ixfac)) {
231            return false;
232        }
233        return true;
234    }
235
236
237    /**
238     * Hash code for this polynomial ring.
239     * @see java.lang.Object#hashCode()
240     */
241    @Override
242    public int hashCode() {
243        int h;
244        h = (coFac.hashCode() << 11);
245        h += ixfac.hashCode();
246        return h;
247    }
248
249
250    /*
251     * Get the variable names.
252     * @return vars.
253    public String[] getVars() {
254        return ixfac.getVars(); // Java-5: Arrays.copyOf(vars,vars.length);
255    }
256     */
257
258
259    /**
260     * Get the zero element from the coefficients.
261     * @return 0 as C.
262     */
263    public C getZEROCoefficient() {
264        return coFac.getZERO();
265    }
266
267
268    /**
269     * Get the one element from the coefficients.
270     * @return 1 as C.
271     */
272    public C getONECoefficient() {
273        return coFac.getONE();
274    }
275
276
277    /**
278     * Get the zero element.
279     * @return 0 as GenExteriorPolynomial<C>.
280     */
281    public GenExteriorPolynomial<C> getZERO() {
282        return ZERO;
283    }
284
285
286    /**
287     * Get the one element.
288     * @return 1 as GenExteriorPolynomial<C>.
289     */
290    public GenExteriorPolynomial<C> getONE() {
291        return ONE;
292    }
293
294
295    /**
296     * Query if this ring is commutative.
297     * @return true if this ring is commutative, else false.
298     */
299    public boolean isCommutative() {
300        return coFac.isCommutative() && ixfac.length() < 1;
301    }
302
303
304    /**
305     * Query if this ring is associative.
306     * @return true if this ring is associative, else false.
307     */
308    public boolean isAssociative() {
309        return coFac.isAssociative();
310    }
311
312
313    /**
314     * Is this structure finite or infinite.
315     * @return true if this structure is finite, else false.
316     * @see edu.jas.structure.ElemFactory#isFinite()
317     */
318    public boolean isFinite() {
319        return coFac.isFinite(); // ixfac.isFinite() is true
320    }
321
322
323    /**
324     * Query if this ring is a field.
325     * @return false.
326     */
327    public boolean isField() {
328        if (isField > 0) {
329            return true;
330        }
331        if (isField == 0) {
332            return false;
333        }
334        if (coFac.isField() && ixfac.length() < 1) {
335            isField = 1;
336            return true;
337        }
338        isField = 0;
339        return false;
340    }
341
342
343    /**
344     * Characteristic of this ring.
345     * @return characteristic of this ring.
346     */
347    public java.math.BigInteger characteristic() {
348        return coFac.characteristic();
349    }
350
351
352    /**
353     * Get a (constant) GenExteriorPolynomial element from a coefficient value.
354     * @param a coefficient.
355     * @return a constant GenExteriorPolynomial.
356     */
357    public GenExteriorPolynomial<C> valueOf(C a) {
358        return new GenExteriorPolynomial<C>(this, a);
359    }
360
361
362    /**
363     * Get a GenExteriorPolynomial element from a index list.
364     * @param e index list.
365     * @return a GenExteriorPolynomial.
366     */
367    public GenExteriorPolynomial<C> valueOf(IndexList e) {
368        return valueOf(coFac.getONE(), ixfac.valueOf(e));
369    }
370
371
372    /**
373     * Get a GenExteriorPolynomial from an ExpVector.
374     * @param e exponent vector.
375     * @return a GenExteriorPolynomial, if exponents are &gt; 1 return ZERO.
376     */
377    public GenExteriorPolynomial<C> valueOf(ExpVector e) {
378        return valueOf(coFac.getONE(), ixfac.valueOf(e));
379    }
380
381
382    /**
383     * Get a GenExteriorPolynomial from a coefficient and a IndexList.
384     * @param a coefficient.
385     * @param e word.
386     * @return a GenExteriorPolynomial.
387     */
388    public GenExteriorPolynomial<C> valueOf(C a, IndexList e) {
389        return new GenExteriorPolynomial<C>(this, a, e);
390    }
391
392
393    /**
394     * Get a GenExteriorPolynomial from a coefficient and an ExpVector.
395     * @param a coefficient.
396     * @param e exponent vector.
397     * @return a GenExteriorPolynomial, if exponents are &gt; 1 return ZERO.
398     */
399    public GenExteriorPolynomial<C> valueOf(C a, ExpVector e) {
400        return new GenExteriorPolynomial<C>(this, a, ixfac.valueOf(e));
401    }
402
403
404    /**
405     * Get a GenExteriorPolynomial from a multivariate GenPolynomial, terms with
406     * exponents &gt; 1 are set to zero.
407     * @param a multivariate GenPolynomial.
408     * @return multivariate a GenExteriorPolynomial.
409     */
410    public GenExteriorPolynomial<C> valueOf(GenPolynomial<C> a) {
411        if (a.isZERO()) {
412            return getZERO();
413        }
414        if (a.isONE()) {
415            return getONE();
416        }
417        GenExteriorPolynomial<C> p = this.getZERO().copy();
418        for (Map.Entry<ExpVector, C> m : a.val.entrySet()) {
419            C c = m.getValue();
420            ExpVector e = m.getKey();
421            IndexList w = ixfac.valueOf(e);
422            if (!w.isZERO()) {
423                p.doPutToMap(w, c);
424            }
425        }
426        return p;
427    }
428
429
430    /**
431     * Get a GenExteriorPolynomial from a GenExteriorPolynomial with conformant
432     * index lists.
433     * @param a GenExteriorPolynomial.
434     * @return a GenExteriorPolynomial with conformant index lists.
435     */
436    public GenExteriorPolynomial<C> valueOf(GenExteriorPolynomial<C> a) {
437        if (a.isZERO()) {
438            return getZERO();
439        }
440        if (a.isONE()) {
441            return getONE();
442        }
443        GenExteriorPolynomial<C> p = this.getZERO().copy();
444        for (Map.Entry<IndexList, C> m : a.val.entrySet()) {
445            C c = m.getValue();
446            IndexList e = m.getKey();
447            if (!e.isZERO()) {
448                IndexList w = ixfac.valueOf(e.val);
449                if (!w.isZERO()) {
450                    p.doPutToMap(w, c);
451                }
452            }
453        }
454        return p;
455    }
456
457
458    /**
459     * Get a list of GenExteriorPolynomials from a list of GenPolynomials.
460     * @param A GenPolynomial list.
461     * @return a GenExteriorPolynomial list.
462     */
463    public List<GenExteriorPolynomial<C>> valueOf(List<GenPolynomial<C>> A) {
464        List<GenExteriorPolynomial<C>> B = new ArrayList<GenExteriorPolynomial<C>>(A.size());
465        if (A.isEmpty()) {
466            return B;
467        }
468        for (GenPolynomial<C> a : A) {
469            GenExteriorPolynomial<C> b = valueOf(a);
470            B.add(b);
471        }
472        return B;
473    }
474
475
476    /**
477     * Get a GenExteriorPolynomial maximal index list element.
478     * @return a GenExteriorPolynomial with maximal index list.
479     */
480    public GenExteriorPolynomial<C> getIMAX() {
481        return valueOf(coFac.getONE(), ixfac.imax);
482    }
483
484
485    /**
486     * Get a (constant) GenExteriorPolynomial from a long value.
487     * @param a long.
488     * @return a GenExteriorPolynomial.
489     */
490    public GenExteriorPolynomial<C> fromInteger(long a) {
491        return new GenExteriorPolynomial<C>(this, coFac.fromInteger(a), wone);
492    }
493
494
495    /**
496     * Get a (constant) GenExteriorPolynomial from a BigInteger value.
497     * @param a BigInteger.
498     * @return a GenExteriorPolynomial&lt;C&gt;.
499     */
500    public GenExteriorPolynomial<C> fromInteger(BigInteger a) {
501        return new GenExteriorPolynomial<C>(this, coFac.fromInteger(a), wone);
502    }
503
504
505    /**
506     * Get a GenExteriorPolynomial from a GenVector.
507     * @param a GenVector.
508     * @return a GenExteriorPolynomial.
509     */
510    public GenExteriorPolynomial<C> fromVector(GenVector<C> a) {
511        if (a == null || a.isZERO()) {
512            return ZERO;
513        }
514        List<IndexList> gen = ixfac.generators();
515        //System.out.println("gen = " + gen);
516        GenExteriorPolynomial<C> ret = copy(ZERO);
517        SortedMap<IndexList, C> tm = ret.val;
518        int i = -1;
519        for (C m : a.val) {
520            i++;
521            if (m.isZERO()) {
522                continue;
523            }
524            IndexList ix = gen.get(i); //new IndexList(ixfac, new int[]{ i });
525            tm.put(ix, m);
526        }
527        return ret;
528    }
529
530
531    /**
532     * Get a list of GenExteriorPolynomials from a GenMatrix.
533     * @param A GenMatrix
534     * @return a list of GenExteriorPolynomials.
535     */
536    public List<GenExteriorPolynomial<C>> fromMatrix(GenMatrix<C> A) {
537        List<GenExteriorPolynomial<C>> L = new ArrayList<GenExteriorPolynomial<C>>();
538        if (A == null || A.isZERO()) { //|| A.isZERO()
539            return L;
540        }
541        for (int i = 0; i < A.ring.rows; i++) {
542            GenVector<C> v = A.getRow(i);
543            if (v.isZERO()) {
544                continue;
545            }
546            GenExteriorPolynomial<C> ep = fromVector(v);
547            //System.out.println("ep = " + ep);
548            L.add(ep);
549        }
550        return L;
551    }
552
553
554    /**
555     * Determinant form exterior polynomial / matrix.
556     * @param A list of GenExteriorPolynomials
557     * @return determinant of 'matrix' A.
558     */
559    public C determinant(List<GenExteriorPolynomial<C>> A) {
560        C det = coFac.getZERO();
561        if (A == null || A.isEmpty()) {
562            return det;
563        }
564        GenExteriorPolynomial<C> p = getONE();
565        for (GenExteriorPolynomial<C> ep : A) {
566            if (ep.isZERO()) {
567                return det;
568            }
569            p = p.multiply(ep);
570            //System.out.println("p = " + p);
571            if (p.isZERO()) {
572                return det;
573            }
574        }
575        if (p.length() > 1) {
576            return det;
577        }
578        det = p.leadingBaseCoefficient();
579        // IndexList di = p.leadingIndexList();
580        // if (di.equals(ixfac.imax)) { // to big
581        //     det = p.leadingBaseCoefficient();
582        // } else {
583        //     System.out.println("p in det = " + p);
584        // }
585        return det;
586    }
587
588
589    /**
590     * Get a GenExteriorPolynomial from a univariate GenPolynomial. Different
591     * exponents are converted to different indexes.
592     * @param a univariate GenPolynomial.
593     * @return a multivariate GenExteriorPolynomial.
594     */
595    @SuppressWarnings("unchecked")
596    public GenExteriorPolynomial<C> fromPolynomial(GenPolynomial<C> a) {
597        if (a == null || a.isZERO()) {
598            return ZERO;
599        }
600        if (a.ring.nvar != 1) {
601            throw new IllegalArgumentException("no univariate polynomial");
602        }
603        int deg = (int) a.degree();
604        if (deg > ixfac.imax.maxDeg()) {
605            throw new IllegalArgumentException(
606                            "ensure deg <= ixfax.maxDeg: " + deg + " > " + ixfac.imax.maxDeg());
607        }
608        if (ixfac.imax.minDeg() > 0) {
609            throw new IllegalArgumentException("ensure ixfax.minDeg == 0: " + ixfac.imax.minDeg());
610        }
611        List<IndexList> gen = ixfac.generators();
612        //System.out.println("gen = " + gen);
613        GenExteriorPolynomial<C> ret = copy(ZERO);
614        SortedMap<IndexList, C> tm = ret.val;
615        for (Monomial m : a) {
616            int e = (int) m.e.getVal(0);
617            IndexList ix = gen.get(e); //new IndexList(ixfac, new int[]{ e });
618            C co = (C) m.c;
619            tm.put(ix, co);
620        }
621        return ret;
622    }
623
624
625    /**
626     * Resultant of two commutative polynaomials.
627     * @param A GenPolynomial
628     * @param B GenPolynomial
629     * @return res(A,B).
630     */
631    public C resultant(GenPolynomial<C> A, GenPolynomial<C> B) {
632        C det = coFac.getZERO();
633        if (A == null || A.isZERO() || B == null || B.isZERO()) {
634            return det;
635        }
636        int m = (int) A.degree();
637        int n = (int) B.degree();
638        GenExteriorPolynomial<C> a, b;
639        a = fromPolynomial(A);
640        b = fromPolynomial(B);
641        if (m < n) {
642            GenExteriorPolynomial<C> c = a;
643            a = b;
644            b = c;
645            int t = m;
646            m = n;
647            n = t;
648        }
649        //System.out.println("a = " + a);
650        //System.out.println("b = " + b);
651        List<GenExteriorPolynomial<C>> mat = new ArrayList<GenExteriorPolynomial<C>>(m + n);
652        for (int i = n - 1; i >= 0; i--) {
653            GenExteriorPolynomial<C> c = a.shiftIndex(i);
654            mat.add(c);
655        }
656        for (int i = m - 1; i >= 0; i--) {
657            GenExteriorPolynomial<C> c = b.shiftIndex(i);
658            mat.add(c);
659        }
660        //System.out.println("mat = " + mat);
661        det = determinant(mat);
662        return det;
663    }
664
665
666    /**
667     * Random polynomial. Generates a random polynomial.
668     * @param n number of terms.
669     * @return a random polynomial.
670     */
671    public GenExteriorPolynomial<C> random(int n) {
672        return random(n, random);
673    }
674
675
676    /**
677     * Random polynomial. Generates a random polynomial with k = 5, l = n, d =
678     * 3.
679     * @param n number of terms.
680     * @param rnd is a source for random bits.
681     * @return a random polynomial.
682     */
683    public GenExteriorPolynomial<C> random(int n, Random rnd) {
684        return random(5, n, 3, rnd);
685    }
686
687
688    /**
689     * Generate a random polynomial.
690     * @param k bitsize of random coefficients.
691     * @param l number of terms.
692     * @param d maximal length of a random word.
693     * @return a random polynomial.
694     */
695    public GenExteriorPolynomial<C> random(int k, int l, int d) {
696        return random(k, l, d, random);
697    }
698
699
700    /**
701     * Generate a random polynomial.
702     * @param k bitsize of random coefficients.
703     * @param l number of terms.
704     * @param d maximal length of a random word.
705     * @param rnd is a source for random bits.
706     * @return a random polynomial.
707     */
708    public GenExteriorPolynomial<C> random(int k, int l, int d, Random rnd) {
709        GenExteriorPolynomial<C> r = getZERO(); //.clone() or copy( ZERO );
710        // add l random coeffs and words of maximal length d
711        int dm = Math.min(d, ixfac.imaxlength); //length());
712        for (int i = 0; i < l; i++) {
713            int di = Math.abs(rnd.nextInt() % dm);
714            IndexList e = ixfac.random(di, 0.5f, rnd).abs(); // s only = 0, 1
715            //System.out.println("e++ = " + e);
716            C a = coFac.random(k, rnd);
717            //System.out.println("e = " + e + " a = " + a);
718            r = r.sum(a, e); // somewhat inefficient but clean
719        }
720        return r;
721    }
722
723
724    /**
725     * Generate a random k-form polynomial.
726     * @param kl bitsize of random coefficients.
727     * @param l number of terms.
728     * @param k length of any random word.
729     * @return a random k-form polynomial.
730     */
731    public GenExteriorPolynomial<C> randomForm(int kl, int l, int k) {
732        return randomForm(kl, l, k, random);
733    }
734
735
736    /**
737     * Generate a random k-form polynomial.
738     * @param kl bitsize of random coefficients.
739     * @param l number of terms.
740     * @param k length of any random word.
741     * @param rnd is a source for random bits.
742     * @return a random k-form polynomial.
743     */
744    public GenExteriorPolynomial<C> randomForm(int kl, int l, int k, Random rnd) {
745        GenExteriorPolynomial<C> r = getZERO(); //.copy(); // or copy( ZERO );
746        // add l random coeffs and index lists of length k
747        if (k > ixfac.imaxlength || k < 0) {
748            return r;
749        }
750        if (k == 0) {
751            return getZERO();
752        }
753        for (int i = 0; i < l; i++) {
754            IndexList e = ixfac.random(k, 0.5f, rnd).abs(); // s only = 0, 1
755            //System.out.println("e_k = " + e);
756            if (e.length() != k) {
757                continue;
758            }
759            C a = coFac.random(kl, rnd);
760            //System.out.println("e = " + e + " a = " + a);
761            r = r.sum(a, e); // somewhat inefficient but clean
762        }
763        return r;
764    }
765
766
767    /**
768     * Copy polynomial c.
769     * @param c polynomial to copy.
770     * @return a copy of c.
771     */
772    public GenExteriorPolynomial<C> copy(GenExteriorPolynomial<C> c) {
773        return new GenExteriorPolynomial<C>(this, c.val);
774    }
775
776
777    /**
778     * Parse a polynomial with the use of GenExteriorPolynomialTokenizer.
779     * @param s String.
780     * @return GenExteriorPolynomial from s.
781     */
782    public GenExteriorPolynomial<C> parse(String s) {
783        String val = s;
784        if (!s.contains("|")) {
785            val = val.replace("{", "").replace("}", "");
786        }
787        return parse(new StringReader(val));
788    }
789
790
791    /**
792     * Parse a polynomial with the use of GenPolynomialTokenizer.
793     * @param r Reader.
794     * @return next GenExteriorPolynomial from r.
795     */
796    @SuppressWarnings("unchecked")
797    public GenExteriorPolynomial<C> parse(Reader r) {
798        GenPolynomialTokenizer tok = new GenPolynomialTokenizer(r);
799        GenExteriorPolynomial<C> a;
800        try {
801            a = tok.nextExteriorPolynomial(this);
802        } catch (IOException e) {
803            a = null;
804            e.printStackTrace();
805            logger.error("{} parse {}", e, this);
806        }
807        return a;
808        //throw new UnsupportedOperationException("not implemented");
809    }
810
811
812    /**
813     * Generate univariate polynomial in a given variable.
814     * @param i the index of the variable.
815     * @return X_i as univariate polynomial.
816     */
817    public GenExteriorPolynomial<C> univariate(int i) {
818        GenExteriorPolynomial<C> p = getZERO();
819        List<IndexList> wgen = ixfac.generators();
820        if (0 <= i && i < wgen.size()) {
821            C one = coFac.getONE();
822            IndexList f = wgen.get(i);
823            p = p.sum(one, f);
824        }
825        return p;
826    }
827
828
829    /**
830     * Generate list of univariate polynomials in all variables.
831     * @return List(X_1,...,X_n) a list of univariate polynomials.
832     */
833    public List<GenExteriorPolynomial<C>> univariateList() {
834        int n = ixfac.length();
835        List<GenExteriorPolynomial<C>> pols = new ArrayList<GenExteriorPolynomial<C>>(n);
836        for (int i = 0; i < n; i++) {
837            GenExteriorPolynomial<C> p = univariate(i);
838            pols.add(p);
839        }
840        return pols;
841    }
842
843
844    /**
845     * Get the generating elements <b>excluding</b> the generators for the
846     * coefficient ring.
847     * @return a list of generating elements for this ring.
848     */
849    public List<GenExteriorPolynomial<C>> getGenerators() {
850        List<GenExteriorPolynomial<C>> univs = univariateList();
851        List<GenExteriorPolynomial<C>> gens = new ArrayList<GenExteriorPolynomial<C>>(univs.size() + 1);
852        gens.add(getONE());
853        gens.addAll(univs);
854        return gens;
855    }
856
857
858    /**
859     * Get a list of all generating elements.
860     * @return list of generators for the algebraic structure.
861     * @see edu.jas.structure.ElemFactory#generators()
862     */
863    public List<GenExteriorPolynomial<C>> generators() {
864        List<C> cogens = coFac.generators();
865        List<GenExteriorPolynomial<C>> univs = univariateList();
866        List<GenExteriorPolynomial<C>> gens = new ArrayList<GenExteriorPolynomial<C>>(
867                        univs.size() + cogens.size());
868        for (C c : cogens) {
869            gens.add(getONE().multiply(c));
870        }
871        gens.addAll(univs);
872        return gens;
873    }
874
875}