001/*
002 * $Id: ResidueSolvableWordPolynomialRing.java 5284 2015-08-01 11:21:04Z kredel
003 * $
004 */
005
006package edu.jas.application;
007
008
009import java.io.IOException;
010import java.io.Reader;
011import java.io.StringReader;
012import java.math.BigInteger;
013import java.util.ArrayList;
014import java.util.List;
015import java.util.Map;
016import java.util.Random;
017
018import org.apache.log4j.Logger;
019
020import edu.jas.kern.PrettyPrint;
021import edu.jas.kern.Scripting;
022import edu.jas.poly.ExpVector;
023import edu.jas.poly.GenPolynomial;
024import edu.jas.poly.GenPolynomialRing;
025import edu.jas.poly.GenPolynomialTokenizer;
026import edu.jas.poly.GenSolvablePolynomial;
027import edu.jas.poly.GenSolvablePolynomialRing;
028import edu.jas.poly.GenWordPolynomial;
029import edu.jas.poly.RecSolvableWordPolynomial;
030import edu.jas.poly.RecSolvableWordPolynomialRing;
031import edu.jas.poly.RelationTable;
032import edu.jas.poly.TermOrder;
033import edu.jas.structure.GcdRingElem;
034import edu.jas.structure.RingElem;
035import edu.jas.structure.RingFactory;
036
037
038/**
039 * ResidueSolvableWordPolynomialRing solvable polynomial with word residue
040 * coefficients factory. It implements RingFactory and extends
041 * GenSolvablePolynomialRing factory. Factory for n-variate ordered solvable
042 * polynomials over non-commutative word residue coefficients. The
043 * non-commutative multiplication relations are maintained in a relation table
044 * and the non-commutative multiplication relations between the coefficients and
045 * the main variables are maintained in a coefficient relation table. Almost
046 * immutable object, except variable names and relation table contents.
047 * @param <C> base coefficient type.
048 * @author Heinz Kredel
049 */
050
051public class ResidueSolvableWordPolynomialRing<C extends GcdRingElem<C>> extends
052                GenSolvablePolynomialRing<WordResidue<C>> {
053
054
055    /*
056     * The solvable multiplication relations between variables and coefficients.
057     */
058    //public final RelationTable<WordResidue<C>> coeffTable;
059
060
061    /**
062     * Recursive solvable polynomial ring with polynomial coefficients.
063     */
064    public final RecSolvableWordPolynomialRing<C> polCoeff;
065
066
067    /**
068     * The constant polynomial 0 for this ring. Hides super ZERO.
069     */
070    public final ResidueSolvableWordPolynomial<C> ZERO;
071
072
073    /**
074     * The constant polynomial 1 for this ring. Hides super ONE.
075     */
076    public final ResidueSolvableWordPolynomial<C> ONE;
077
078
079    private static final Logger logger = Logger.getLogger(ResidueSolvableWordPolynomialRing.class);
080
081
082    private 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 (true || debug) {
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.EVRAND(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        GenSolvablePolynomialRing<WordResidue<C>> pfac = super.extend(i);
646        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
647                        pfac.nvar, pfac.tord, pfac.getVars());
648        spfac.table.extend(this.table); 
649        spfac.polCoeff.coeffTable.extend(this.polCoeff.coeffTable);
650        return spfac;
651    }
652
653
654    /**
655     * Extend variables. Used e.g. in module embedding. Extend number of
656     * variables by length(vn). New variables commute with the exiting
657     * variables.
658     * @param vs names for extended variables.
659     * @return extended polynomial ring factory.
660     */
661    @Override
662    public ResidueSolvableWordPolynomialRing<C> extend(String[] vs) {
663        GenSolvablePolynomialRing<WordResidue<C>> pfac = super.extend(vs);
664        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
665                        pfac.nvar, pfac.tord, pfac.getVars());
666        spfac.table.extend(this.table); 
667        spfac.polCoeff.coeffTable.extend(this.polCoeff.coeffTable);
668        return spfac;
669    }
670
671
672    /**
673     * Contract variables. Used e.g. in module embedding. Contract number of
674     * variables by i.
675     * @param i number of variables to remove.
676     * @return contracted solvable polynomial ring factory.
677     */
678    @Override
679    public ResidueSolvableWordPolynomialRing<C> contract(int i) {
680        GenPolynomialRing<WordResidue<C>> pfac = super.contract(i);
681        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
682                        pfac.nvar, pfac.tord, pfac.getVars()); 
683        spfac.table.contract(this.table);
684        spfac.polCoeff.coeffTable.contract(this.polCoeff.coeffTable);
685        return spfac;
686    }
687
688
689    /**
690     * Reverse variables. Used e.g. in opposite rings.
691     * @return solvable polynomial ring factory with reversed variables.
692     */
693    @Override
694    public ResidueSolvableWordPolynomialRing<C> reverse() {
695        return reverse(false);
696    }
697
698
699    /**
700     * Reverse variables. Used e.g. in opposite rings.
701     * @param partial true for partialy reversed term orders.
702     * @return solvable polynomial ring factory with reversed variables.
703     */
704    @Override
705    public ResidueSolvableWordPolynomialRing<C> reverse(boolean partial) {
706        GenPolynomialRing<WordResidue<C>> pfac = super.reverse(partial);
707        ResidueSolvableWordPolynomialRing<C> spfac = new ResidueSolvableWordPolynomialRing<C>(pfac.coFac,
708                        pfac.nvar, pfac.tord, pfac.getVars()); //, pfac.table);
709        spfac.partial = partial;
710        spfac.table.reverse(this.table);
711        spfac.polCoeff.coeffTable.reverse(this.polCoeff.coeffTable);
712        return spfac;
713    }
714
715
716    /* not possible:
717     * Distributive representation as polynomial with all main variables.
718     * @return distributive polynomial ring factory.
719    @SuppressWarnings({"cast","unchecked"})
720    public static <C extends RingElem<C>> // must be static because of types
721       GenSolvablePolynomialRing<C> distribute(ResidueSolvableWordPolynomialRing<C> rf) {
722    }
723     */
724
725
726    /**
727     * Permutation of polynomial ring variables.
728     * @param P permutation.
729     * @return P(this).
730     */
731    @Override
732    public GenSolvablePolynomialRing<WordResidue<C>> permutation(List<Integer> P) {
733        if (!polCoeff.coeffTable.isEmpty()) {
734            throw new UnsupportedOperationException("permutation with coeff relations: " + this);
735        }
736        GenSolvablePolynomialRing<WordResidue<C>> pfac = (GenSolvablePolynomialRing<WordResidue<C>>) super
737                        .permutation(P);
738        return pfac;
739    }
740
741
742    /**
743     * Word residue coefficients from integral word polynomial coefficients.
744     * Represent as polynomial with type WordResidue<C> coefficients.
745     * @param A polynomial with integral word polynomial coefficients to be
746     *            converted.
747     * @return polynomial with type WordResidue<C> coefficients.
748     */
749    public ResidueSolvableWordPolynomial<C> fromPolyCoefficients(GenSolvablePolynomial<GenWordPolynomial<C>> A) {
750        ResidueSolvableWordPolynomial<C> B = getZERO().copy();
751        if (A == null || A.isZERO()) {
752            return B;
753        }
754        RingFactory<WordResidue<C>> cfac = coFac;
755        WordResidueRing<C> qfac = (WordResidueRing<C>) cfac;
756        for (Map.Entry<ExpVector, GenWordPolynomial<C>> y : A.getMap().entrySet()) {
757            ExpVector e = y.getKey();
758            GenWordPolynomial<C> a = y.getValue();
759            WordResidue<C> p = new WordResidue<C>(qfac, a); // can be zero
760            if (!p.isZERO()) {
761                //B = B.sum( p, e ); // inefficient
762                B.doPutToMap(e, p);
763            }
764        }
765        return B;
766    }
767
768
769    /**
770     * Integral word function from word residue coefficients. Represent as
771     * polynomial with type GenWordPolynomial<C> coefficients.
772     * @param A polynomial with word residue coefficients to be converted.
773     * @return polynomial with type GenWordPolynomial<C> coefficients.
774     */
775    public RecSolvableWordPolynomial<C> toPolyCoefficients(ResidueSolvableWordPolynomial<C> A) {
776        RecSolvableWordPolynomial<C> B = polCoeff.getZERO().copy();
777        if (A == null || A.isZERO()) {
778            return B;
779        }
780        for (Map.Entry<ExpVector, WordResidue<C>> y : A.getMap().entrySet()) {
781            ExpVector e = y.getKey();
782            WordResidue<C> a = y.getValue();
783            GenWordPolynomial<C> p = a.val; // can not 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(GenPolynomial<WordResidue<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}