001/*
002 * $Id: ResidueSolvableWordPolynomialRing.java 5284 2015-08-01 11:21:04Z kredel
003 * $
004 */
005
006package edu.jas.application;
007
008
009import java.io.IOException;
010import java.io.Reader;
011import java.io.StringReader;
012import java.math.BigInteger;
013import java.util.ArrayList;
014import java.util.List;
015import java.util.Map;
016import java.util.Random;
017
018import org.apache.log4j.Logger;
019
020import edu.jas.kern.PrettyPrint;
021import edu.jas.kern.Scripting;
022import edu.jas.poly.ExpVector;
023import edu.jas.poly.GenPolynomial;
024import edu.jas.poly.GenPolynomialRing;
025import edu.jas.poly.GenPolynomialTokenizer;
026import edu.jas.poly.GenSolvablePolynomial;
027import edu.jas.poly.GenSolvablePolynomialRing;
028import edu.jas.poly.GenWordPolynomial;
029import edu.jas.poly.RecSolvableWordPolynomial;
030import edu.jas.poly.RecSolvableWordPolynomialRing;
031import edu.jas.poly.RelationTable;
032import edu.jas.poly.TermOrder;
033import edu.jas.structure.GcdRingElem;
034import edu.jas.structure.RingElem;
035import edu.jas.structure.RingFactory;
036
037
038/**
039 * ResidueSolvableWordPolynomialRing solvable polynomial with word residue
040 * coefficients factory. It implements RingFactory and extends
041 * GenSolvablePolynomialRing factory. Factory for n-variate ordered solvable
042 * polynomials over non-commutative word residue coefficients. The
043 * non-commutative multiplication relations are maintained in a relation table
044 * and the non-commutative multiplication relations between the coefficients and
045 * the main variables are maintained in a coefficient relation table. Almost
046 * immutable object, except variable names and relation table contents.
047 * @param <C> base coefficient type.
048 * @author Heinz Kredel
049 */
050
051public class ResidueSolvableWordPolynomialRing<C extends GcdRingElem<C>> extends
052                GenSolvablePolynomialRing<WordResidue<C>> {
053
054
055    /*
056     * The solvable multiplication relations between variables and coefficients.
057     */
058    //public final RelationTable<WordResidue<C>> coeffTable;
059
060
061    /**
062     * Recursive solvable polynomial ring with polynomial coefficients.
063     */
064    public final RecSolvableWordPolynomialRing<C> polCoeff;
065
066
067    /**
068     * The constant polynomial 0 for this ring. Hides super ZERO.
069     */
070    public final ResidueSolvableWordPolynomial<C> ZERO;
071
072
073    /**
074     * The constant polynomial 1 for this ring. Hides super ONE.
075     */
076    public final ResidueSolvableWordPolynomial<C> ONE;
077
078
079    private static final Logger logger = Logger.getLogger(ResidueSolvableWordPolynomialRing.class);
080
081
082    private final boolean debug = logger.isDebugEnabled();
083
084
085    /**
086     * The constructor creates a solvable polynomial factory object with the
087     * default term order and commutative relations.
088     * @param cf factory for coefficients of type C.
089     * @param n number of variables.
090     */
091    public ResidueSolvableWordPolynomialRing(RingFactory<WordResidue<C>> cf, int n) {
092        this(cf, n, new TermOrder(), null, null);
093    }
094
095
096    /**
097     * The constructor creates a solvable polynomial factory object with the
098     * default term order.
099     * @param cf factory for coefficients of type C.
100     * @param n number of variables.
101     * @param rt solvable multiplication relations.
102     */
103    public ResidueSolvableWordPolynomialRing(RingFactory<WordResidue<C>> cf, int n,
104                    RelationTable<WordResidue<C>> rt) {
105        this(cf, n, new TermOrder(), null, rt);
106    }
107
108
109    /**
110     * The constructor creates a solvable polynomial factory object with the
111     * given term order and commutative relations.
112     * @param cf factory for coefficients of type C.
113     * @param n number of variables.
114     * @param t a term order.
115     */
116    public ResidueSolvableWordPolynomialRing(RingFactory<WordResidue<C>> cf, int n, TermOrder t) {
117        this(cf, n, t, null, null);
118    }
119
120
121    /**
122     * The constructor creates a solvable polynomial factory object with the
123     * given term order.
124     * @param cf factory for coefficients of type C.
125     * @param n number of variables.
126     * @param t a term order.
127     * @param rt solvable multiplication relations.
128     */
129    public ResidueSolvableWordPolynomialRing(RingFactory<WordResidue<C>> cf, int n, TermOrder t,
130                    RelationTable<WordResidue<C>> rt) {
131        this(cf, n, t, null, rt);
132    }
133
134
135    /**
136     * The constructor creates a solvable polynomial factory object with the
137     * given term order and commutative relations.
138     * @param cf factory for coefficients of type C.
139     * @param n number of variables.
140     * @param t a term order.
141     * @param v names for the variables.
142     */
143    public ResidueSolvableWordPolynomialRing(RingFactory<WordResidue<C>> cf, int n, TermOrder t, String[] v) {
144        this(cf, n, t, v, null);
145    }
146
147
148    /**
149     * The constructor creates a solvable polynomial factory object with the
150     * given term order and commutative relations.
151     * @param cf factory for coefficients of type C.
152     * @param t a term order.
153     * @param v names for the variables.
154     */
155    public ResidueSolvableWordPolynomialRing(RingFactory<WordResidue<C>> cf, TermOrder t, String[] v) {
156        this(cf, v.length, t, v, null);
157    }
158
159
160    /**
161     * The constructor creates a solvable polynomial factory object with the
162     * default term order.
163     * @param cf factory for coefficients of type C.
164     * @param v names for the variables.
165     */
166    public ResidueSolvableWordPolynomialRing(RingFactory<WordResidue<C>> cf, String[] v) {
167        this(cf, v.length, new TermOrder(), v, null);
168    }
169
170
171    /**
172     * The constructor creates a solvable polynomial factory object with the
173     * given term order.
174     * @param cf factory for coefficients of type C.
175     * @param n number of variables.
176     * @param t a term order.
177     * @param v names for the variables.
178     * @param rt solvable multiplication relations.
179     */
180    public ResidueSolvableWordPolynomialRing(RingFactory<WordResidue<C>> cf, int n, TermOrder t, String[] v,
181                    RelationTable<WordResidue<C>> rt) {
182        super(cf, n, t, v, rt);
183        //if (rt == null) { // handled in super }
184        WordResidueRing<C> cfring = (WordResidueRing<C>) cf; // == coFac
185        polCoeff = new RecSolvableWordPolynomialRing<C>(cfring.ring, n, t, v);
186        if (table.size() > 0) { // TODO
187            ExpVector e = null;
188            ExpVector f = null;
189            GenSolvablePolynomial<GenWordPolynomial<C>> p = null;
190            polCoeff.table.update(e, f, p); // from rt
191        }
192        //coeffTable = new RelationTable<WordResidue<C>>(this, true);
193        ZERO = new ResidueSolvableWordPolynomial<C>(this);
194        WordResidue<C> coeff = coFac.getONE();
195        //evzero = ExpVector.create(nvar); // from super
196        ONE = new ResidueSolvableWordPolynomial<C>(this, coeff, evzero);
197    }
198
199
200    /**
201     * The constructor creates a solvable polynomial factory object with the the
202     * same term order, number of variables and variable names as the given
203     * polynomial factory, only the coefficient factories differ and the
204     * solvable multiplication relations are <b>empty</b>.
205     * @param cf factory for coefficients of type C.
206     * @param o other solvable polynomial ring.
207     */
208    public ResidueSolvableWordPolynomialRing(RingFactory<WordResidue<C>> cf,
209                    ResidueSolvableWordPolynomialRing o) {
210        this(cf, o.nvar, o.tord, o.getVars(), null);
211    }
212
213
214    /**
215     * Get the String representation.
216     * @see java.lang.Object#toString()
217     */
218    @Override
219    public String toString() {
220        String res = super.toString();
221        if (PrettyPrint.isTrue()) {
222            //res += "\n" + table.toString(vars);
223            res += "\n" + polCoeff.coeffTable.toString(vars);
224        } else {
225            res += ", #rel = " + table.size() + " + " + polCoeff.coeffTable.size();
226        }
227        return res;
228    }
229
230
231    /**
232     * Get a scripting compatible string representation.
233     * @return script compatible representation for this Element.
234     * @see edu.jas.structure.Element#toScript()
235     */
236    @Override
237    public String toScript() {
238        StringBuffer s = new StringBuffer();
239        switch (Scripting.getLang()) {
240        case Ruby:
241            s.append("SolvPolyRing.new(");
242            break;
243        case Python:
244        default:
245            s.append("SolvPolyRing(");
246        }
247        if (coFac instanceof RingElem) {
248            s.append(((RingElem<WordResidue<C>>) coFac).toScriptFactory());
249        } else {
250            s.append(coFac.toScript().trim());
251        }
252        s.append(",\"" + varsToString() + "\",");
253        String to = tord.toString();
254        if (tord.getEvord() == TermOrder.INVLEX) {
255            to = "PolyRing.lex";
256        }
257        if (tord.getEvord() == TermOrder.IGRLEX) {
258            to = "PolyRing.grad";
259        }
260        s.append(to);
261        if (table.size() > 0) {
262            String rel = table.toScript();
263            s.append(",rel=");
264            s.append(rel);
265        }
266        if (polCoeff.coeffTable.size() > 0) {
267            String rel = polCoeff.coeffTable.toScript();
268            s.append(",coeffrel=");
269            s.append(rel);
270        }
271        s.append(")");
272        return s.toString();
273    }
274
275
276    /**
277     * Comparison with any other object.
278     * @see java.lang.Object#equals(java.lang.Object)
279     */
280    @Override
281    @SuppressWarnings("unchecked")
282    public boolean equals(Object other) {
283        if (other == null) {
284            return false;
285        }
286        if (!(other instanceof ResidueSolvableWordPolynomialRing)) {
287            return false;
288        }
289        // do a super.equals( )
290        if (!super.equals(other)) {
291            return false;
292        }
293        ResidueSolvableWordPolynomialRing<C> oring = (ResidueSolvableWordPolynomialRing<C>) other;
294        // check same base relations done in super
295        if (!polCoeff.coeffTable.equals(oring.polCoeff.coeffTable)) {
296            return false;
297        }
298        return true;
299    }
300
301
302    /**
303     * Hash code for this polynomial ring.
304     * @see java.lang.Object#hashCode()
305     */
306    @Override
307    public int hashCode() {
308        int h;
309        h = super.hashCode();
310        h = 37 * h + table.hashCode(); // may be different after some computations
311        h = 37 * h + polCoeff.coeffTable.hashCode(); // may be different
312        return h;
313    }
314
315
316    /**
317     * Get the zero element.
318     * @return 0 as ResidueSolvableWordPolynomial<C>.
319     */
320    @Override
321    public ResidueSolvableWordPolynomial<C> getZERO() {
322        return ZERO;
323    }
324
325
326    /**
327     * Get the one element.
328     * @return 1 as ResidueSolvableWordPolynomial<C>.
329     */
330    @Override
331    public ResidueSolvableWordPolynomial<C> getONE() {
332        return ONE;
333    }
334
335
336    /**
337     * Query if this ring is commutative.
338     * @return true if this ring is commutative, else false.
339     */
340    @Override
341    public boolean isCommutative() {
342        if (polCoeff.coeffTable.isEmpty()) {
343            return super.isCommutative();
344        }
345        return false;
346    }
347
348
349    /**
350     * Query if this ring is associative. Test if the relations between the mian
351     * variables and the coefficient generators define an associative solvable
352     * ring.
353     * @return true, if this ring is associative, else false.
354     */
355    @SuppressWarnings("unused")
356    @Override
357    public boolean isAssociative() {
358        if (!coFac.isAssociative()) {
359            return false;
360        }
361        ResidueSolvableWordPolynomial<C> Xi, Xj, Xk, p, q;
362        List<GenPolynomial<WordResidue<C>>> gens = generators();
363        //System.out.println("Rec word gens = " + gens);
364        int ngen = gens.size();
365        for (int i = 0; i < ngen; i++) {
366            Xi = (ResidueSolvableWordPolynomial<C>) gens.get(i);
367            if (Xi.isONE()) {
368                continue;
369            }
370            for (int j = i + 1; j < ngen; j++) {
371                Xj = (ResidueSolvableWordPolynomial<C>) gens.get(j);
372                for (int k = j + 1; k < ngen; k++) {
373                    Xk = (ResidueSolvableWordPolynomial<C>) gens.get(k);
374                    try {
375                        p = Xk.multiply(Xj).multiply(Xi);
376                        q = Xk.multiply(Xj.multiply(Xi));
377                        if (!p.equals(q)) {
378                            if (true || debug) {
379                                logger.info("Xk = " + Xk + ", Xj = " + Xj + ", Xi = " + Xi);
380                                logger.info("p = ( Xk * Xj ) * Xi = " + p);
381                                logger.info("q = Xk * ( Xj * Xi ) = " + q);
382                            }
383                            return false;
384                        }
385                    } catch (RuntimeException e) {
386                        e.printStackTrace();
387                        System.out.println("Xk = " + Xk + ", Xj = " + Xj + ", Xi = " + Xi);
388                    }
389                }
390            }
391        }
392        return true;
393    }
394
395
396    /**
397     * Get a (constant) ResidueSolvableWordPolynomial&lt;C&gt; element from a
398     * coefficient value.
399     * @param a coefficient.
400     * @return a ResidueSolvableWordPolynomial&lt;C&gt;.
401     */
402    @Override
403    public ResidueSolvableWordPolynomial<C> valueOf(WordResidue<C> a) {
404        return new ResidueSolvableWordPolynomial<C>(this, a, evzero);
405    }
406
407
408    /**
409     * Get a ResidueSolvableWordPolynomial&lt;C&gt; element from an ExpVector.
410     * @param e exponent vector.
411     * @return a ResidueSolvableWordPolynomial&lt;C&gt;.
412     */
413    @Override
414    public ResidueSolvableWordPolynomial<C> valueOf(ExpVector e) {
415        return valueOf(coFac.getONE(), e);
416    }
417
418
419    /**
420     * Get a ResidueSolvableWordPolynomial&lt;C&gt; element from a coeffcient
421     * and an ExpVector.
422     * @param a coefficient.
423     * @param e exponent vector.
424     * @return a ResidueSolvableWordPolynomial&lt;C&gt;.
425     */
426    @Override
427    public ResidueSolvableWordPolynomial<C> valueOf(WordResidue<C> a, ExpVector e) {
428        return new ResidueSolvableWordPolynomial<C>(this, a, e);
429    }
430
431
432    /**
433     * Get a (constant) ResidueSolvableWordPolynomial&lt;C&gt; element from a
434     * long value.
435     * @param a long.
436     * @return a ResidueSolvableWordPolynomial&lt;C&gt;.
437     */
438    @Override
439    public ResidueSolvableWordPolynomial<C> fromInteger(long a) {
440        return new ResidueSolvableWordPolynomial<C>(this, coFac.fromInteger(a), evzero);
441    }
442
443
444    /**
445     * Get a (constant) ResidueSolvableWordPolynomial&lt;C&gt; element from a
446     * BigInteger value.
447     * @param a BigInteger.
448     * @return a ResidueSolvableWordPolynomial&lt;C&gt;.
449     */
450    @Override
451    public ResidueSolvableWordPolynomial<C> fromInteger(BigInteger a) {
452        return new ResidueSolvableWordPolynomial<C>(this, coFac.fromInteger(a), evzero);
453    }
454
455
456    /**
457     * Random solvable polynomial. Generates a random solvable polynomial with k
458     * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
459     * @param n number of terms.
460     * @return a random solvable polynomial.
461     */
462    @Override
463    public ResidueSolvableWordPolynomial<C> random(int n) {
464        return random(n, random);
465    }
466
467
468    /**
469     * Random solvable polynomial. Generates a random solvable polynomial with k
470     * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
471     * @param n number of terms.
472     * @param rnd is a source for random bits.
473     * @return a random solvable polynomial.
474     */
475    @Override
476    public ResidueSolvableWordPolynomial<C> random(int n, Random rnd) {
477        if (nvar == 1) {
478            return random(5, n, n, 0.7f, rnd);
479        }
480        return random(5, n, 3, 0.3f, rnd);
481    }
482
483
484    /**
485     * Generate a random solvable polynomial.
486     * @param k bitsize of random coefficients.
487     * @param l number of terms.
488     * @param d maximal degree in each variable.
489     * @param q density of nozero exponents.
490     * @return a random solvable polynomial.
491     */
492    @Override
493    public ResidueSolvableWordPolynomial<C> random(int k, int l, int d, float q) {
494        return random(k, l, d, q, random);
495    }
496
497
498    /**
499     * Random solvable polynomial.
500     * @param k size of random coefficients.
501     * @param l number of terms.
502     * @param d maximal degree in each variable.
503     * @param q density of nozero exponents.
504     * @param rnd is a source for random bits.
505     * @return a random solvable polynomial.
506     */
507    @Override
508    public ResidueSolvableWordPolynomial<C> random(int k, int l, int d, float q, Random rnd) {
509        ResidueSolvableWordPolynomial<C> r = getZERO(); // copy( ZERO ); 
510        ExpVector e;
511        WordResidue<C> a;
512        // add random coeffs and exponents
513        for (int i = 0; i < l; i++) {
514            e = ExpVector.EVRAND(nvar, d, q, rnd);
515            a = coFac.random(k, rnd);
516            r = (ResidueSolvableWordPolynomial<C>) r.sum(a, e);
517            // somewhat inefficient but clean
518        }
519        return r;
520    }
521
522
523    /**
524     * Copy polynomial c.
525     * @param c
526     * @return a copy of c.
527     */
528    public ResidueSolvableWordPolynomial<C> copy(ResidueSolvableWordPolynomial<C> c) {
529        return new ResidueSolvableWordPolynomial<C>(this, c.getMap());
530    }
531
532
533    /**
534     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
535     * @param s String.
536     * @return ResidueSolvableWordPolynomial from s.
537     */
538    @Override
539    public ResidueSolvableWordPolynomial<C> parse(String s) {
540        return parse(new StringReader(s));
541    }
542
543
544    /**
545     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
546     * @param r Reader.
547     * @return next ResidueSolvableWordPolynomial from r.
548     */
549    @Override
550    @SuppressWarnings("unchecked")
551    public ResidueSolvableWordPolynomial<C> parse(Reader r) {
552        GenPolynomialTokenizer pt = new GenPolynomialTokenizer(this, r);
553        ResidueSolvableWordPolynomial<C> p = null;
554        try {
555            GenSolvablePolynomial<WordResidue<C>> s = pt.nextSolvablePolynomial();
556            p = new ResidueSolvableWordPolynomial<C>(this, s);
557        } catch (IOException e) {
558            logger.error(e.toString() + " parse " + this);
559            p = ZERO;
560        }
561        return p;
562    }
563
564
565    /**
566     * Generate univariate solvable polynomial in a given variable.
567     * @param i the index of the variable.
568     * @return X_i as solvable univariate polynomial.
569     */
570    @Override
571    public ResidueSolvableWordPolynomial<C> univariate(int i) {
572        return (ResidueSolvableWordPolynomial<C>) super.univariate(i);
573    }
574
575
576    /**
577     * Generate univariate solvable polynomial in a given variable with given
578     * exponent.
579     * @param i the index of the variable.
580     * @param e the exponent of the variable.
581     * @return X_i^e as solvable univariate polynomial.
582     */
583    @Override
584    public ResidueSolvableWordPolynomial<C> univariate(int i, long e) {
585        return (ResidueSolvableWordPolynomial<C>) super.univariate(i, e);
586    }
587
588
589    /**
590     * Generate univariate solvable polynomial in a given variable with given
591     * exponent.
592     * @param modv number of module variables.
593     * @param i the index of the variable.
594     * @param e the exponent of the variable.
595     * @return X_i^e as solvable univariate polynomial.
596     */
597    @Override
598    public ResidueSolvableWordPolynomial<C> univariate(int modv, int i, long e) {
599        return (ResidueSolvableWordPolynomial<C>) super.univariate(modv, i, e);
600    }
601
602
603    /**
604     * Generate list of univariate polynomials in all variables.
605     * @return List(X_1,...,X_n) a list of univariate polynomials.
606     */
607    //todo Override
608    @SuppressWarnings("unchecked")
609    public List<ResidueSolvableWordPolynomial<C>> recUnivariateList() {
610        //return castToSolvableList( super.univariateList() );
611        return (List<ResidueSolvableWordPolynomial<C>>) (Object) univariateList(0, 1L);
612    }
613
614
615    /**
616     * Generate list of univariate polynomials in all variables.
617     * @param modv number of module variables.
618     * @return List(X_1,...,X_n) a list of univariate polynomials.
619     */
620    //todo Override
621    @SuppressWarnings("unchecked")
622    public List<ResidueSolvableWordPolynomial<C>> recUnivariateList(int modv) {
623        return (List<ResidueSolvableWordPolynomial<C>>) (Object) univariateList(modv, 1L);
624    }
625
626
627    /**
628     * Generate list of univariate polynomials in all variables with given
629     * exponent.
630     * @param modv number of module variables.
631     * @param e the exponent of the variables.
632     * @return List(X_1^e,...,X_n^e) a list of univariate polynomials.
633     */
634    //todo Override
635    public List<ResidueSolvableWordPolynomial<C>> recUnivariateList(int modv, long e) {
636        List<ResidueSolvableWordPolynomial<C>> pols = new ArrayList<ResidueSolvableWordPolynomial<C>>(nvar);
637        int nm = nvar - modv;
638        for (int i = 0; i < nm; i++) {
639            ResidueSolvableWordPolynomial<C> p = univariate(modv, nm - 1 - i, e);
640            pols.add(p);
641        }
642        return pols;
643    }
644
645
646    /*
647     * Generate list of univariate polynomials in all variables with given exponent.
648     * @param modv number of module variables.
649     * @param e the exponent of the variables.
650     * @return List(X_1^e,...,X_n^e) a list of univariate polynomials.
651     @Override
652     public List<ResidueSolvableWordPolynomial<C>> univariateList(int modv, long e) {
653        List<GenPolynomial<C>> pol = super.univariateList(modv,e);
654        UnaryFunctor<GenPolynomial<C>,ResidueSolvableWordPolynomial<C>> fc 
655          = new UnaryFunctor<GenPolynomial<C>,ResidueSolvableWordPolynomial<C>>() {
656               public ResidueSolvableWordPolynomial<C> eval(GenPolynomial<C> p) {
657                  if ( ! (p instanceof ResidueSolvableWordPolynomial) ) {
658                      throw new RuntimeException("no solvable polynomial "+p);
659                  }
660                  return (ResidueSolvableWordPolynomial<C>) p;
661               }
662            };
663        List<ResidueSolvableWordPolynomial<C>> pols 
664           = ListUtil.<GenPolynomial<C>,ResidueSolvableWordPolynomial<C>>map(this,pol,fc);
665        return pols;
666     }
667     */
668
669
670    /**
671     * Extend variables. Used e.g. in module embedding. Extend number of
672     * variables by i.
673     * @param i number of variables to extend.
674     * @return extended solvable polynomial ring factory.
675     */
676    @Override
677    public ResidueSolvableWordPolynomialRing<C> extend(int i) {
678        GenSolvablePolynomialRing<WordResidue<C>> pfac = super.extend(i);
679        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
680                        pfac.nvar, pfac.tord, pfac.getVars());
681        spfac.table.extend(this.table); 
682        spfac.polCoeff.coeffTable.extend(this.polCoeff.coeffTable);
683        return spfac;
684    }
685
686
687    /**
688     * Extend variables. Used e.g. in module embedding. Extend number of
689     * variables by length(vn). New variables commute with the exiting
690     * variables.
691     * @param vs names for extended variables.
692     * @return extended polynomial ring factory.
693     */
694    @Override
695    public ResidueSolvableWordPolynomialRing<C> extend(String[] vs) {
696        GenSolvablePolynomialRing<WordResidue<C>> pfac = super.extend(vs);
697        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
698                        pfac.nvar, pfac.tord, pfac.getVars());
699        spfac.table.extend(this.table); 
700        spfac.polCoeff.coeffTable.extend(this.polCoeff.coeffTable);
701        return spfac;
702    }
703
704
705    /**
706     * Contract variables. Used e.g. in module embedding. Contract number of
707     * variables by i.
708     * @param i number of variables to remove.
709     * @return contracted solvable polynomial ring factory.
710     */
711    @Override
712    public ResidueSolvableWordPolynomialRing<C> contract(int i) {
713        GenPolynomialRing<WordResidue<C>> pfac = super.contract(i);
714        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
715                        pfac.nvar, pfac.tord, pfac.getVars()); 
716        spfac.table.contract(this.table);
717        spfac.polCoeff.coeffTable.contract(this.polCoeff.coeffTable);
718        return spfac;
719    }
720
721
722    /**
723     * Reverse variables. Used e.g. in opposite rings.
724     * @return solvable polynomial ring factory with reversed variables.
725     */
726    @Override
727    public ResidueSolvableWordPolynomialRing<C> reverse() {
728        return reverse(false);
729    }
730
731
732    /**
733     * Reverse variables. Used e.g. in opposite rings.
734     * @param partial true for partialy reversed term orders.
735     * @return solvable polynomial ring factory with reversed variables.
736     */
737    @Override
738    public ResidueSolvableWordPolynomialRing<C> reverse(boolean partial) {
739        GenPolynomialRing<WordResidue<C>> pfac = super.reverse(partial);
740        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
741                        pfac.nvar, pfac.tord, pfac.getVars()); //, pfac.table);
742        spfac.partial = partial;
743        spfac.table.reverse(this.table);
744        spfac.polCoeff.coeffTable.reverse(this.polCoeff.coeffTable);
745        return spfac;
746    }
747
748
749    /* not possible:
750     * Distributive representation as polynomial with all main variables.
751     * @return distributive polynomial ring factory.
752    @SuppressWarnings({"cast","unchecked"})
753    public static <C extends RingElem<C>> // must be static because of types
754       GenSolvablePolynomialRing<C> distribute(ResidueSolvableWordPolynomialRing<C> rf) {
755    }
756     */
757
758
759    /**
760     * Permutation of polynomial ring variables.
761     * @param P permutation.
762     * @return P(this).
763     */
764    @Override
765    public GenSolvablePolynomialRing<WordResidue<C>> permutation(List<Integer> P) {
766        if (!polCoeff.coeffTable.isEmpty()) {
767            throw new UnsupportedOperationException("permutation with coeff relations: " + this);
768        }
769        GenSolvablePolynomialRing<WordResidue<C>> pfac = (GenSolvablePolynomialRing<WordResidue<C>>) super
770                        .permutation(P);
771        return pfac;
772    }
773
774
775    /**
776     * Word residue coefficients from integral word polynomial coefficients.
777     * Represent as polynomial with type WordResidue<C> coefficients.
778     * @param A polynomial with integral word polynomial coefficients to be
779     *            converted.
780     * @return polynomial with type WordResidue<C> coefficients.
781     */
782    public ResidueSolvableWordPolynomial<C> fromPolyCoefficients(GenSolvablePolynomial<GenWordPolynomial<C>> A) {
783        ResidueSolvableWordPolynomial<C> B = getZERO().copy();
784        if (A == null || A.isZERO()) {
785            return B;
786        }
787        RingFactory<WordResidue<C>> cfac = coFac;
788        WordResidueRing<C> qfac = (WordResidueRing<C>) cfac;
789        for (Map.Entry<ExpVector, GenWordPolynomial<C>> y : A.getMap().entrySet()) {
790            ExpVector e = y.getKey();
791            GenWordPolynomial<C> a = y.getValue();
792            WordResidue<C> p = new WordResidue<C>(qfac, a); // can be zero
793            if (!p.isZERO()) {
794                //B = B.sum( p, e ); // inefficient
795                B.doPutToMap(e, p);
796            }
797        }
798        return B;
799    }
800
801
802    /**
803     * Integral word function from word residue coefficients. Represent as
804     * polynomial with type GenWordPolynomial<C> coefficients.
805     * @param A polynomial with word residue coefficients to be converted.
806     * @return polynomial with type GenWordPolynomial<C> coefficients.
807     */
808    public RecSolvableWordPolynomial<C> toPolyCoefficients(ResidueSolvableWordPolynomial<C> A) {
809        RecSolvableWordPolynomial<C> B = polCoeff.getZERO().copy();
810        if (A == null || A.isZERO()) {
811            return B;
812        }
813        for (Map.Entry<ExpVector, WordResidue<C>> y : A.getMap().entrySet()) {
814            ExpVector e = y.getKey();
815            WordResidue<C> a = y.getValue();
816            GenWordPolynomial<C> p = a.val; // can not be zero
817            if (!p.isZERO()) {
818                //B = B.sum( p, e ); // inefficient
819                B.doPutToMap(e, p);
820            }
821        }
822        return B;
823    }
824
825
826    /**
827     * Integral word function from word residue coefficients. Represent as
828     * polynomial with type GenWordPolynomial<C> coefficients.
829     * @param A polynomial with word residue coefficients to be converted.
830     * @return polynomial with type GenWordPolynomial<C> coefficients.
831     */
832    public RecSolvableWordPolynomial<C> toPolyCoefficients(GenPolynomial<WordResidue<C>> A) {
833        RecSolvableWordPolynomial<C> B = polCoeff.getZERO().copy();
834        if (A == null || A.isZERO()) {
835            return B;
836        }
837        for (Map.Entry<ExpVector, WordResidue<C>> y : A.getMap().entrySet()) {
838            ExpVector e = y.getKey();
839            WordResidue<C> a = y.getValue();
840            GenWordPolynomial<C> p = a.val; // can not be zero
841            if (!p.isZERO()) {
842                //B = B.sum( p, e ); // inefficient
843                B.doPutToMap(e, p);
844            }
845        }
846        return B;
847    }
848}