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