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