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