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