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