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 * @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 = LogManager.getLogger(ResidueSolvableWordPolynomialRing.class);
080
081
082    private static 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.toScript();
254        s.append(to);
255        if (table.size() > 0) {
256            String rel = table.toScript();
257            s.append(",rel=");
258            s.append(rel);
259        }
260        if (polCoeff.coeffTable.size() > 0) {
261            String rel = polCoeff.coeffTable.toScript();
262            s.append(",coeffrel=");
263            s.append(rel);
264        }
265        s.append(")");
266        return s.toString();
267    }
268
269
270    /**
271     * Comparison with any other object.
272     * @see java.lang.Object#equals(java.lang.Object)
273     */
274    @Override
275    @SuppressWarnings("unchecked")
276    public boolean equals(Object other) {
277        if (other == null) {
278            return false;
279        }
280        if (!(other instanceof ResidueSolvableWordPolynomialRing)) {
281            return false;
282        }
283        // do a super.equals( )
284        if (!super.equals(other)) {
285            return false;
286        }
287        ResidueSolvableWordPolynomialRing<C> oring = (ResidueSolvableWordPolynomialRing<C>) other;
288        // check same base relations done in super
289        if (!polCoeff.coeffTable.equals(oring.polCoeff.coeffTable)) {
290            return false;
291        }
292        return true;
293    }
294
295
296    /**
297     * Hash code for this polynomial ring.
298     * @see java.lang.Object#hashCode()
299     */
300    @Override
301    public int hashCode() {
302        int h;
303        h = super.hashCode();
304        h = 37 * h + table.hashCode(); // may be different after some computations
305        h = 37 * h + polCoeff.coeffTable.hashCode(); // may be different
306        return h;
307    }
308
309
310    /**
311     * Get the zero element.
312     * @return 0 as ResidueSolvableWordPolynomial<C>.
313     */
314    @Override
315    public ResidueSolvableWordPolynomial<C> getZERO() {
316        return ZERO;
317    }
318
319
320    /**
321     * Get the one element.
322     * @return 1 as ResidueSolvableWordPolynomial<C>.
323     */
324    @Override
325    public ResidueSolvableWordPolynomial<C> getONE() {
326        return ONE;
327    }
328
329
330    /**
331     * Query if this ring is commutative.
332     * @return true if this ring is commutative, else false.
333     */
334    @Override
335    public boolean isCommutative() {
336        if (polCoeff.coeffTable.isEmpty()) {
337            return super.isCommutative();
338        }
339        return false;
340    }
341
342
343    /**
344     * Query if this ring is associative. Test if the relations between the mian
345     * variables and the coefficient generators define an associative solvable
346     * ring.
347     * @return true, if this ring is associative, else false.
348     */
349    @SuppressWarnings("unused")
350    @Override
351    public boolean isAssociative() {
352        if (!coFac.isAssociative()) {
353            return false;
354        }
355        ResidueSolvableWordPolynomial<C> Xi, Xj, Xk, p, q;
356        List<GenPolynomial<WordResidue<C>>> gens = generators();
357        //System.out.println("Rec word gens = " + gens);
358        int ngen = gens.size();
359        for (int i = 0; i < ngen; i++) {
360            Xi = (ResidueSolvableWordPolynomial<C>) gens.get(i);
361            if (Xi.isONE()) {
362                continue;
363            }
364            for (int j = i + 1; j < ngen; j++) {
365                Xj = (ResidueSolvableWordPolynomial<C>) gens.get(j);
366                for (int k = j + 1; k < ngen; k++) {
367                    Xk = (ResidueSolvableWordPolynomial<C>) gens.get(k);
368                    try {
369                        p = Xk.multiply(Xj).multiply(Xi);
370                        q = Xk.multiply(Xj.multiply(Xi));
371                        if (!p.equals(q)) {
372                            logger.info("Xk = {}, Xj = {}, Xi = {}", Xk, Xj, Xi);
373                            logger.info("p = ( Xk * Xj ) * Xi = {}", p);
374                            logger.info("q = Xk * ( Xj * Xi ) = {}", q);
375                            return false;
376                        }
377                    } catch (RuntimeException e) {
378                        e.printStackTrace();
379                        System.out.println("Xk = " + Xk + ", Xj = " + Xj + ", Xi = " + Xi);
380                    }
381                }
382            }
383        }
384        return true;
385    }
386
387
388    /**
389     * Get a (constant) ResidueSolvableWordPolynomial&lt;C&gt; element from a
390     * coefficient value.
391     * @param a coefficient.
392     * @return a ResidueSolvableWordPolynomial&lt;C&gt;.
393     */
394    @Override
395    public ResidueSolvableWordPolynomial<C> valueOf(WordResidue<C> a) {
396        return new ResidueSolvableWordPolynomial<C>(this, a, evzero);
397    }
398
399
400    /**
401     * Get a ResidueSolvableWordPolynomial&lt;C&gt; element from an ExpVector.
402     * @param e exponent vector.
403     * @return a ResidueSolvableWordPolynomial&lt;C&gt;.
404     */
405    @Override
406    public ResidueSolvableWordPolynomial<C> valueOf(ExpVector e) {
407        return valueOf(coFac.getONE(), e);
408    }
409
410
411    /**
412     * Get a ResidueSolvableWordPolynomial&lt;C&gt; element from a coeffcient
413     * and an ExpVector.
414     * @param a coefficient.
415     * @param e exponent vector.
416     * @return a ResidueSolvableWordPolynomial&lt;C&gt;.
417     */
418    @Override
419    public ResidueSolvableWordPolynomial<C> valueOf(WordResidue<C> a, ExpVector e) {
420        return new ResidueSolvableWordPolynomial<C>(this, a, e);
421    }
422
423
424    /**
425     * Get a (constant) ResidueSolvableWordPolynomial&lt;C&gt; element from a
426     * long value.
427     * @param a long.
428     * @return a ResidueSolvableWordPolynomial&lt;C&gt;.
429     */
430    @Override
431    public ResidueSolvableWordPolynomial<C> fromInteger(long a) {
432        return new ResidueSolvableWordPolynomial<C>(this, coFac.fromInteger(a), evzero);
433    }
434
435
436    /**
437     * Get a (constant) ResidueSolvableWordPolynomial&lt;C&gt; element from a
438     * BigInteger value.
439     * @param a BigInteger.
440     * @return a ResidueSolvableWordPolynomial&lt;C&gt;.
441     */
442    @Override
443    public ResidueSolvableWordPolynomial<C> fromInteger(BigInteger a) {
444        return new ResidueSolvableWordPolynomial<C>(this, coFac.fromInteger(a), evzero);
445    }
446
447
448    /**
449     * Random solvable polynomial. Generates a random solvable polynomial with k
450     * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
451     * @param n number of terms.
452     * @return a random solvable polynomial.
453     */
454    @Override
455    public ResidueSolvableWordPolynomial<C> random(int n) {
456        return random(n, random);
457    }
458
459
460    /**
461     * Random solvable polynomial. Generates a random solvable polynomial with k
462     * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
463     * @param n number of terms.
464     * @param rnd is a source for random bits.
465     * @return a random solvable polynomial.
466     */
467    @Override
468    public ResidueSolvableWordPolynomial<C> random(int n, Random rnd) {
469        if (nvar == 1) {
470            return random(5, n, n, 0.7f, rnd);
471        }
472        return random(5, n, 3, 0.3f, rnd);
473    }
474
475
476    /**
477     * Generate a random solvable polynomial.
478     * @param k bitsize of random coefficients.
479     * @param l number of terms.
480     * @param d maximal degree in each variable.
481     * @param q density of nozero exponents.
482     * @return a random solvable polynomial.
483     */
484    @Override
485    public ResidueSolvableWordPolynomial<C> random(int k, int l, int d, float q) {
486        return random(k, l, d, q, random);
487    }
488
489
490    /**
491     * Random solvable polynomial.
492     * @param k size of random coefficients.
493     * @param l number of terms.
494     * @param d maximal degree in each variable.
495     * @param q density of nozero exponents.
496     * @param rnd is a source for random bits.
497     * @return a random solvable polynomial.
498     */
499    @Override
500    public ResidueSolvableWordPolynomial<C> random(int k, int l, int d, float q, Random rnd) {
501        ResidueSolvableWordPolynomial<C> r = getZERO(); // copy( ZERO ); 
502        ExpVector e;
503        WordResidue<C> a;
504        // add random coeffs and exponents
505        for (int i = 0; i < l; i++) {
506            e = ExpVector.random(nvar, d, q, rnd);
507            a = coFac.random(k, rnd);
508            r = (ResidueSolvableWordPolynomial<C>) r.sum(a, e);
509            // somewhat inefficient but clean
510        }
511        return r;
512    }
513
514
515    /**
516     * Copy polynomial c.
517     * @param c
518     * @return a copy of c.
519     */
520    public ResidueSolvableWordPolynomial<C> copy(ResidueSolvableWordPolynomial<C> c) {
521        return new ResidueSolvableWordPolynomial<C>(this, c.getMap());
522    }
523
524
525    /**
526     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
527     * @param s String.
528     * @return ResidueSolvableWordPolynomial from s.
529     */
530    @Override
531    public ResidueSolvableWordPolynomial<C> parse(String s) {
532        return parse(new StringReader(s));
533    }
534
535
536    /**
537     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
538     * @param r Reader.
539     * @return next ResidueSolvableWordPolynomial from r.
540     */
541    @Override
542    @SuppressWarnings("unchecked")
543    public ResidueSolvableWordPolynomial<C> parse(Reader r) {
544        GenPolynomialTokenizer pt = new GenPolynomialTokenizer(this, r);
545        ResidueSolvableWordPolynomial<C> p = null;
546        try {
547            GenSolvablePolynomial<WordResidue<C>> s = pt.nextSolvablePolynomial();
548            p = new ResidueSolvableWordPolynomial<C>(this, s);
549        } catch (IOException e) {
550            logger.error(e.toString() + " parse {}", this);
551            p = ZERO;
552        }
553        return p;
554    }
555
556
557    /**
558     * Generate univariate solvable polynomial in a given variable.
559     * @param i the index of the variable.
560     * @return X_i as solvable univariate polynomial.
561     */
562    @Override
563    public ResidueSolvableWordPolynomial<C> univariate(int i) {
564        return (ResidueSolvableWordPolynomial<C>) super.univariate(i);
565    }
566
567
568    /**
569     * Generate univariate solvable polynomial in a given variable with given
570     * exponent.
571     * @param i the index of the variable.
572     * @param e the exponent of the variable.
573     * @return X_i^e as solvable univariate polynomial.
574     */
575    @Override
576    public ResidueSolvableWordPolynomial<C> univariate(int i, long e) {
577        return (ResidueSolvableWordPolynomial<C>) super.univariate(i, e);
578    }
579
580
581    /**
582     * Generate univariate solvable polynomial in a given variable with given
583     * exponent.
584     * @param modv number of module variables.
585     * @param i the index of the variable.
586     * @param e the exponent of the variable.
587     * @return X_i^e as solvable univariate polynomial.
588     */
589    @Override
590    public ResidueSolvableWordPolynomial<C> univariate(int modv, int i, long e) {
591        return (ResidueSolvableWordPolynomial<C>) super.univariate(modv, i, e);
592    }
593
594
595    /**
596     * Generate list of univariate polynomials in all variables.
597     * @return List(X_1,...,X_n) a list of univariate polynomials.
598     */
599    @Override
600    public List<ResidueSolvableWordPolynomial<C>> univariateList() {
601        return univariateList(0, 1L);
602    }
603
604
605    /**
606     * Generate list of univariate polynomials in all variables.
607     * @param modv number of module variables.
608     * @return List(X_1,...,X_n) a list of univariate polynomials.
609     */
610    @Override
611    public List<ResidueSolvableWordPolynomial<C>> univariateList(int modv) {
612        return univariateList(modv, 1L);
613    }
614
615
616    /**
617     * Generate list of univariate polynomials in all variables with given
618     * exponent.
619     * @param modv number of module variables.
620     * @param e the exponent of the variables.
621     * @return List(X_1^e,...,X_n^e) a list of univariate polynomials.
622     */
623    @Override
624    public List<ResidueSolvableWordPolynomial<C>> univariateList(int modv, long e) {
625        List<ResidueSolvableWordPolynomial<C>> pols = new ArrayList<ResidueSolvableWordPolynomial<C>>(nvar);
626        int nm = nvar - modv;
627        for (int i = 0; i < nm; i++) {
628            ResidueSolvableWordPolynomial<C> p = univariate(modv, nm - 1 - i, e);
629            pols.add(p);
630        }
631        return pols;
632    }
633
634
635    /**
636     * Extend variables. Used e.g. in module embedding. Extend number of
637     * variables by i.
638     * @param i number of variables to extend.
639     * @return extended solvable polynomial ring factory.
640     */
641    @Override
642    public ResidueSolvableWordPolynomialRing<C> extend(int i) {
643        return extend(i, false);
644    }
645
646    
647    /**
648     * Extend variables. Used e.g. in module embedding. Extend number of
649     * variables by i.
650     * @param i number of variables to extend.
651     * @param top true for TOP term order, false for POT term order.
652     * @return extended solvable polynomial ring factory.
653     */
654    @Override
655    public ResidueSolvableWordPolynomialRing<C> extend(int i, boolean top) {
656        GenSolvablePolynomialRing<WordResidue<C>> pfac = super.extend(i, top);
657        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
658                        pfac.nvar, pfac.tord, pfac.getVars());
659        spfac.table.extend(this.table); 
660        spfac.polCoeff.coeffTable.extend(this.polCoeff.coeffTable);
661        return spfac;
662    }
663
664
665    /**
666     * Extend variables. Used e.g. in module embedding. Extend number of
667     * variables by length(vn). New variables commute with the exiting
668     * variables.
669     * @param vs names for extended variables.
670     * @return extended polynomial ring factory.
671     */
672    @Override
673    public ResidueSolvableWordPolynomialRing<C> extend(String[] vs) {
674        return extend(vs, false);
675    }
676
677    
678    /**
679     * Extend variables. Used e.g. in module embedding. Extend number of
680     * variables by length(vn). New variables commute with the exiting
681     * variables.
682     * @param vs names for extended variables.
683     * @param top true for TOP term order, false for POT term order.
684     * @return extended polynomial ring factory.
685     */
686    @Override
687    public ResidueSolvableWordPolynomialRing<C> extend(String[] vs, boolean top) {
688        GenSolvablePolynomialRing<WordResidue<C>> pfac = super.extend(vs, top);
689        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
690                        pfac.nvar, pfac.tord, pfac.getVars());
691        spfac.table.extend(this.table); 
692        spfac.polCoeff.coeffTable.extend(this.polCoeff.coeffTable);
693        return spfac;
694    }
695
696
697    /**
698     * Contract variables. Used e.g. in module embedding. Contract number of
699     * variables by i.
700     * @param i number of variables to remove.
701     * @return contracted solvable polynomial ring factory.
702     */
703    @Override
704    public ResidueSolvableWordPolynomialRing<C> contract(int i) {
705        GenPolynomialRing<WordResidue<C>> pfac = super.contract(i);
706        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
707                        pfac.nvar, pfac.tord, pfac.getVars()); 
708        spfac.table.contract(this.table);
709        spfac.polCoeff.coeffTable.contract(this.polCoeff.coeffTable);
710        return spfac;
711    }
712
713
714    /**
715     * Reverse variables. Used e.g. in opposite rings.
716     * @return solvable polynomial ring factory with reversed variables.
717     */
718    @Override
719    public ResidueSolvableWordPolynomialRing<C> reverse() {
720        return reverse(false);
721    }
722
723
724    /**
725     * Reverse variables. Used e.g. in opposite rings.
726     * @param partial true for partialy reversed term orders.
727     * @return solvable polynomial ring factory with reversed variables.
728     */
729    @Override
730    public ResidueSolvableWordPolynomialRing<C> reverse(boolean partial) {
731        GenPolynomialRing<WordResidue<C>> pfac = super.reverse(partial);
732        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
733                        pfac.nvar, pfac.tord, pfac.getVars()); //, pfac.table);
734        spfac.partial = partial;
735        spfac.table.reverse(this.table);
736        spfac.polCoeff.coeffTable.reverse(this.polCoeff.coeffTable);
737        return spfac;
738    }
739
740
741    /* not possible:
742     * Distributive representation as polynomial with all main variables.
743     * @return distributive polynomial ring factory.
744    @SuppressWarnings({"cast","unchecked"})
745    public static <C extends RingElem<C>> // must be static because of types
746       GenSolvablePolynomialRing<C> distribute(ResidueSolvableWordPolynomialRing<C> rf) {
747    }
748     */
749
750
751    /**
752     * Permutation of polynomial ring variables.
753     * @param P permutation.
754     * @return P(this).
755     */
756    @Override
757    public GenSolvablePolynomialRing<WordResidue<C>> permutation(List<Integer> P) {
758        if (!polCoeff.coeffTable.isEmpty()) {
759            throw new UnsupportedOperationException("permutation with coeff relations: " + this);
760        }
761        GenSolvablePolynomialRing<WordResidue<C>> pfac = (GenSolvablePolynomialRing<WordResidue<C>>) super
762                        .permutation(P);
763        return pfac;
764    }
765
766
767    /**
768     * Word residue coefficients from integral word polynomial coefficients.
769     * Represent as polynomial with type WordResidue<C> coefficients.
770     * @param A polynomial with integral word polynomial coefficients to be
771     *            converted.
772     * @return polynomial with type WordResidue<C> coefficients.
773     */
774    public ResidueSolvableWordPolynomial<C> fromPolyCoefficients(GenSolvablePolynomial<GenWordPolynomial<C>> A) {
775        ResidueSolvableWordPolynomial<C> B = getZERO().copy();
776        if (A == null || A.isZERO()) {
777            return B;
778        }
779        RingFactory<WordResidue<C>> cfac = coFac;
780        WordResidueRing<C> qfac = (WordResidueRing<C>) cfac;
781        for (Map.Entry<ExpVector, GenWordPolynomial<C>> y : A.getMap().entrySet()) {
782            ExpVector e = y.getKey();
783            GenWordPolynomial<C> a = y.getValue();
784            WordResidue<C> p = new WordResidue<C>(qfac, a); // can be zero
785            if (!p.isZERO()) {
786                //B = B.sum( p, e ); // inefficient
787                B.doPutToMap(e, p);
788            }
789        }
790        return B;
791    }
792
793
794    /**
795     * Integral word function from word residue coefficients. Represent as
796     * polynomial with type GenWordPolynomial<C> coefficients.
797     * @param A polynomial with word residue coefficients to be converted.
798     * @return polynomial with type GenWordPolynomial<C> coefficients.
799     */
800    public RecSolvableWordPolynomial<C> toPolyCoefficients(ResidueSolvableWordPolynomial<C> A) {
801        RecSolvableWordPolynomial<C> B = polCoeff.getZERO().copy();
802        if (A == null || A.isZERO()) {
803            return B;
804        }
805        for (Map.Entry<ExpVector, WordResidue<C>> y : A.getMap().entrySet()) {
806            ExpVector e = y.getKey();
807            WordResidue<C> a = y.getValue();
808            GenWordPolynomial<C> p = a.val; // can not be zero
809            if (!p.isZERO()) {
810                //B = B.sum( p, e ); // inefficient
811                B.doPutToMap(e, p);
812            }
813        }
814        return B;
815    }
816
817
818    /**
819     * Integral word function from word residue coefficients. Represent as
820     * polynomial with type GenWordPolynomial<C> coefficients.
821     * @param A polynomial with word residue coefficients to be converted.
822     * @return polynomial with type GenWordPolynomial<C> coefficients.
823     */
824    public RecSolvableWordPolynomial<C> toPolyCoefficients(GenPolynomial<WordResidue<C>> A) {
825        RecSolvableWordPolynomial<C> B = polCoeff.getZERO().copy();
826        if (A == null || A.isZERO()) {
827            return B;
828        }
829        for (Map.Entry<ExpVector, WordResidue<C>> y : A.getMap().entrySet()) {
830            ExpVector e = y.getKey();
831            WordResidue<C> a = y.getValue();
832            GenWordPolynomial<C> p = a.val; // can not be zero
833            if (!p.isZERO()) {
834                //B = B.sum( p, e ); // inefficient
835                B.doPutToMap(e, p);
836            }
837        }
838        return B;
839    }
840}