001/*
002 * $Id: QLRSolvablePolynomialRing.java 5835 2018-05-18 19:12:07Z 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.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 static 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    @SuppressWarnings("unchecked")
200    public QLRSolvablePolynomialRing(RingFactory<C> cf, int n, TermOrder t, String[] v,
201                    RelationTable<C> rt) {
202        super(cf, n, t, v, rt);
203        //if (rt == null) { // handled in super }
204        qpfac = (QuotPairFactory<GenPolynomial<D>,C>) cf; // crucial part of type
205        RingFactory<GenPolynomial<D>> cfring = qpfac.pairFactory(); // == coFac.ring
206        polCoeff = new RecSolvablePolynomialRing<D>(cfring, n, t, v);
207        if (table.size() > 0) { // TODO
208            ExpVector e = null;
209            ExpVector f = null;
210            GenSolvablePolynomial<GenPolynomial<D>> p = null;
211            polCoeff.table.update(e, f, p); // from rt
212            throw new RuntimeException("TODO");
213        }
214        ZERO = new QLRSolvablePolynomial<C,D>(this);
215        C coeff = coFac.getONE();
216        ONE = new QLRSolvablePolynomial<C,D>(this, coeff, evzero);
217    }
218
219
220    /**
221     * Get the String representation.
222     * @see java.lang.Object#toString()
223     */
224    @Override
225    public String toString() {
226        String res = super.toString();
227        if (PrettyPrint.isTrue()) {
228            res += "\n" + polCoeff.coeffTable.toString(vars);
229            res += "\n" + polCoeff.table.toString(vars);
230        } else {
231            res += ", #rel = " + table.size() + " + " + polCoeff.coeffTable.size() + " + " + polCoeff.table.size();
232        }
233        return res;
234    }
235
236
237    /**
238     * Get a scripting compatible string representation.
239     * @return script compatible representation for this Element.
240     * @see edu.jas.structure.Element#toScript()
241     */
242    @Override
243    public String toScript() {
244        StringBuffer s = new StringBuffer();
245        switch (Scripting.getLang()) {
246        case Ruby:
247            s.append("SolvPolyRing.new(");
248            break;
249        case Python:
250        default:
251            s.append("SolvPolyRing(");
252        }
253        if (coFac instanceof RingElem) {
254            s.append(((RingElem<C>) coFac).toScriptFactory());
255        } else {
256            s.append(coFac.toScript().trim());
257        }
258        s.append(",\"" + varsToString() + "\",");
259        String to = tord.toScript();
260        s.append(to);
261        String rel = "";
262        if (table.size() > 0) {
263            rel = table.toScript();
264            s.append(",rel=");
265            s.append(rel);
266        }
267        if (polCoeff.coeffTable.size() > 0) {
268            String crel = polCoeff.coeffTable.toScript();
269            s.append(",coeffrel=");
270            s.append(crel);
271        }
272        if (polCoeff.table.size() > 0) { // should not be printed
273            String polrel = polCoeff.table.toScript();
274            if (!rel.equals(polrel)) {
275                s.append(",polrel=");
276                s.append(polrel);
277            }
278        }
279        s.append(")");
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("Xk = " + Xk + ", Xj = " + Xj + ", Xi = " + Xi);
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
451     * BigInteger 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.EVRAND(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(e.toString() + " parse " + 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        GenPolynomialRing<C> pfac = super.extend(i);
661        QLRSolvablePolynomialRing<C,D> spfac = new QLRSolvablePolynomialRing<C,D>(pfac.coFac, pfac.nvar,
662                        pfac.tord, pfac.getVars());
663        spfac.table.extend(this.table);
664        spfac.polCoeff.coeffTable.extend(this.polCoeff.coeffTable);
665        return spfac;
666    }
667
668
669    /**
670     * Contract variables. Used e.g. in module embedding. Contract number of
671     * variables by i.
672     * @param i number of variables to remove.
673     * @return contracted solvable polynomial ring factory.
674     */
675    @Override
676    public QLRSolvablePolynomialRing<C,D> contract(int i) {
677        GenPolynomialRing<C> pfac = super.contract(i);
678        QLRSolvablePolynomialRing<C,D> spfac = new QLRSolvablePolynomialRing<C,D>(pfac.coFac, pfac.nvar,
679                        pfac.tord, pfac.getVars());
680        spfac.table.contract(this.table);
681        spfac.polCoeff.coeffTable.contract(this.polCoeff.coeffTable);
682        return spfac;
683    }
684
685
686    /**
687     * Reverse variables. Used e.g. in opposite rings.
688     * @return solvable polynomial ring factory with reversed variables.
689     */
690    @Override
691    public QLRSolvablePolynomialRing<C,D> reverse() {
692        return reverse(false);
693    }
694
695
696    /**
697     * Reverse variables. Used e.g. in opposite rings.
698     * @param partial true for partialy reversed term orders.
699     * @return solvable polynomial ring factory with reversed variables.
700     */
701    @Override
702    public QLRSolvablePolynomialRing<C,D> reverse(boolean partial) {
703        GenPolynomialRing<C> pfac = super.reverse(partial);
704        QLRSolvablePolynomialRing<C,D> spfac = new QLRSolvablePolynomialRing<C,D>(pfac.coFac, pfac.nvar,
705                        pfac.tord, pfac.getVars());
706        spfac.partial = partial;
707        spfac.table.reverse(this.table);
708        spfac.polCoeff.coeffTable.reverse(this.polCoeff.coeffTable);
709        return spfac;
710    }
711
712
713    /**
714     * Rational function from integral polynomial coefficients. Represent as
715     * polynomial with type C coefficients.
716     * @param A polynomial with integral polynomial coefficients to be
717     *            converted.
718     * @return polynomial with type C coefficients.
719     */
720    public QLRSolvablePolynomial<C,D> fromPolyCoefficients(GenSolvablePolynomial<GenPolynomial<D>> A) {
721        QLRSolvablePolynomial<C,D> B = getZERO().copy();
722        if (A == null || A.isZERO()) {
723            return B;
724        }
725        for (Map.Entry<ExpVector, GenPolynomial<D>> y : A.getMap().entrySet()) {
726            ExpVector e = y.getKey();
727            GenSolvablePolynomial<D> a = (GenSolvablePolynomial<D>) y.getValue();
728            //C p = new C(qfac, a); 
729            C p = qpfac.create(a); 
730            if (!p.isZERO()) {
731                B.doPutToMap(e, p);
732            }
733        }
734        return B;
735    }
736
737
738    /**
739     * Integral function from rational polynomial coefficients. Represent as
740     * polynomial with type GenSolvablePolynomial<C> coefficients.
741     * @param A polynomial with rational polynomial coefficients to be
742     *            converted.
743     * @return polynomial with type GenSolvablePolynomial<C> coefficients.
744     */
745    public RecSolvablePolynomial<D> toPolyCoefficients(QLRSolvablePolynomial<C,D> A) {
746        RecSolvablePolynomial<D> B = polCoeff.getZERO().copy();
747        if (A == null || A.isZERO()) {
748            return B;
749        }
750        for (Map.Entry<ExpVector, C> y : A.getMap().entrySet()) {
751            ExpVector e = y.getKey();
752            C a = y.getValue();
753            if (!a.denominator().isONE()) {
754                throw new IllegalArgumentException("den != 1 not supported: " + a);
755            }
756            GenPolynomial<D> p = a.numerator(); // can not be zero
757            if (!p.isZERO()) {
758                B.doPutToMap(e, p);
759            }
760        }
761        return B;
762    }
763
764
765    /**
766     * Integral function from rational polynomial coefficients. Represent as
767     * polynomial with type GenSolvablePolynomial coefficients.
768     * @param A polynomial with rational polynomial coefficients to be
769     *            converted.
770     * @return polynomial with type GenSolvablePolynomial coefficients.
771     */
772    public RecSolvablePolynomial<D> toPolyCoefficients(GenPolynomial<C> A) {
773        RecSolvablePolynomial<D> B = polCoeff.getZERO().copy();
774        if (A == null || A.isZERO()) {
775            return B;
776        }
777        for (Map.Entry<ExpVector, C> y : A.getMap().entrySet()) {
778            ExpVector e = y.getKey();
779            C a = y.getValue();
780            if (!a.denominator().isONE()) {
781                throw new IllegalArgumentException("den != 1 not supported: " + a);
782            }
783            GenPolynomial<D> p = a.numerator(); // can not be zero
784            if (!p.isZERO()) {
785                B.doPutToMap(e, p);
786            }
787        }
788        return B;
789    }
790
791}