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