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