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 = new ArrayList<GenSolvablePolynomial<GenPolynomial<C>>>();
187            for (GenSolvablePolynomial<SolvableQuotient<C>> q : table.relationList()) {
188                nt.add(this.toPolyCoefficients(q)); // only with den == 1
189            }
190            polCoeff.table.addSolvRelations(nt);
191        }
192        ZERO = new QuotSolvablePolynomial<C>(this);
193        SolvableQuotient<C> coeff = coFac.getONE();
194        //evzero = ExpVector.create(nvar); // from super
195        ONE = new QuotSolvablePolynomial<C>(this, coeff, evzero);
196    }
197
198
199    /**
200     * The constructor creates a solvable polynomial factory object with the the
201     * same term order, number of variables and variable names as the given
202     * polynomial factory, only the coefficient factories differ and the
203     * solvable multiplication relations are <b>empty</b>.
204     * @param cf factory for coefficients of type C.
205     * @param o other solvable polynomial ring.
206     */
207    public QuotSolvablePolynomialRing(RingFactory<SolvableQuotient<C>> cf, GenSolvablePolynomialRing o) {
208        this(cf, o.nvar, o.tord, o.getVars(), null);
209    }
210
211
212    /**
213     * The constructor creates a solvable polynomial factory object with the the
214     * same term order, number of variables and variable names as the given
215     * polynomial factory, only the coefficient factories differ and the
216     * solvable multiplication relations are <b>empty</b>.
217     * @param cf factory for coefficients of type C.
218     * @param o other solvable polynomial ring.
219     */
220    public QuotSolvablePolynomialRing(RingFactory<SolvableQuotient<C>> cf, QuotSolvablePolynomialRing o) {
221        this(cf, (GenSolvablePolynomialRing) o);
222    }
223
224
225    /**
226     * Get the String representation.
227     * @see java.lang.Object#toString()
228     */
229    @Override
230    public String toString() {
231        String res = super.toString();
232        if (PrettyPrint.isTrue()) {
233            //res += "\n" + table.toString(vars);
234            res += "\n" + polCoeff.coeffTable.toString(vars);
235        } else {
236            res += ", #rel = " + table.size() + " + " + polCoeff.coeffTable.size();
237        }
238        return res;
239    }
240
241
242    /**
243     * Get a scripting compatible string representation.
244     * @return script compatible representation for this Element.
245     * @see edu.jas.structure.Element#toScript()
246     */
247    @Override
248    public String toScript() {
249        StringBuffer s = new StringBuffer();
250        switch (Scripting.getLang()) {
251        case Ruby:
252            s.append("SolvPolyRing.new(");
253            break;
254        case Python:
255        default:
256            s.append("SolvPolyRing(");
257        }
258        if (coFac instanceof RingElem) {
259            s.append(((RingElem<SolvableQuotient<C>>) coFac).toScriptFactory());
260        } else {
261            s.append(coFac.toScript().trim());
262        }
263        s.append(",\"" + varsToString() + "\",");
264        String to = tord.toScript();
265        s.append(to);
266        if (table.size() > 0) {
267            String rel = table.toScript();
268            s.append(",rel=");
269            s.append(rel);
270        }
271        if (polCoeff.coeffTable.size() > 0) {
272            String rel = polCoeff.coeffTable.toScript();
273            s.append(",coeffrel=");
274            s.append(rel);
275        }
276        s.append(")");
277        return s.toString();
278    }
279
280
281    /**
282     * Comparison with any other object.
283     * @see java.lang.Object#equals(java.lang.Object)
284     */
285    @Override
286    @SuppressWarnings("unchecked")
287    public boolean equals(Object other) {
288        if (other == null) {
289            return false;
290        }
291        if (!(other instanceof QuotSolvablePolynomialRing)) {
292            return false;
293        }
294        QuotSolvablePolynomialRing<C> oring = (QuotSolvablePolynomialRing<C>) other;
295        // do a super.equals( )
296        if (!super.equals(other)) {
297            return false;
298        }
299        // check same base relations
300        //if ( ! table.equals(oring.table) ) { // done in super
301        //    return false;
302        //}
303        if (!polCoeff.coeffTable.equals(oring.polCoeff.coeffTable)) {
304            return false;
305        }
306        return true;
307    }
308
309
310    /**
311     * Hash code for this polynomial ring.
312     * @see java.lang.Object#hashCode()
313     */
314    @Override
315    public int hashCode() {
316        int h;
317        h = super.hashCode();
318        h = 37 * h + table.hashCode(); // may be different after some computations
319        h = 37 * h + polCoeff.coeffTable.hashCode(); // may be different
320        return h;
321    }
322
323
324    /**
325     * Get the zero element.
326     * @return 0 as QuotSolvablePolynomial<C>.
327     */
328    @Override
329    public QuotSolvablePolynomial<C> getZERO() {
330        if (ZERO == null || !ZERO.isZERO()) { // happened since May 5 2022
331            // Name        : java-11-openjdk-headless, java-17-openjdk-headless
332            // Version     : 11.0.15.0, 17.0.4
333            // Release     : 150000.3.80.1, 150400.3.3.1
334            throw new RuntimeException("zero not 0: " + ZERO);
335        }
336        return ZERO;
337    }
338
339
340    /**
341     * Get the one element.
342     * @return 1 as QuotSolvablePolynomial<C>.
343     */
344    @Override
345    public QuotSolvablePolynomial<C> getONE() {
346        if (ONE == null || !ONE.isONE()) {
347            throw new RuntimeException("one not 1: " + ONE);
348        }
349        return ONE;
350    }
351
352
353    /**
354     * Query if this ring is commutative.
355     * @return true if this ring is commutative, else false.
356     */
357    @Override
358    public boolean isCommutative() {
359        if (polCoeff.coeffTable.size() == 0) {
360            return super.isCommutative();
361        }
362        // check structure of relations?
363        return false;
364    }
365
366
367    /**
368     * Query if this ring is associative. Test if the relations between the mian
369     * variables and the coefficient generators define an associative solvable
370     * ring.
371     * @return true, if this ring is associative, else false.
372     */
373    @Override
374    public boolean isAssociative() {
375        if (!coFac.isAssociative()) {
376            return false;
377        }
378        QuotSolvablePolynomial<C> Xi, Xj, Xk, p, q;
379        List<GenPolynomial<SolvableQuotient<C>>> gens = generators();
380        int ngen = gens.size();
381        for (int i = 0; i < ngen; i++) {
382            Xi = (QuotSolvablePolynomial<C>) gens.get(i);
383            for (int j = i + 1; j < ngen; j++) {
384                Xj = (QuotSolvablePolynomial<C>) gens.get(j);
385                for (int k = j + 1; k < ngen; k++) {
386                    Xk = (QuotSolvablePolynomial<C>) gens.get(k);
387                    p = Xk.multiply(Xj).multiply(Xi);
388                    q = Xk.multiply(Xj.multiply(Xi));
389                    if (!p.equals(q)) {
390                        logger.info("Xk = {}, Xj = {}, Xi = {}", Xk, Xj, Xi);
391                        logger.info("p = ( Xk * Xj ) * Xi = {}", p);
392                        logger.info("q = Xk * ( Xj * Xi ) = {}", q);
393                        logger.info("q-p = {}", p.subtract(q));
394                        return false;
395                    }
396                }
397            }
398        }
399        return true; //coFac.isAssociative();
400    }
401
402
403    /**
404     * Get a (constant) QuotSolvablePolynomial&lt;C&gt; element from a long
405     * value.
406     * @param a long.
407     * @return a QuotSolvablePolynomial&lt;C&gt;.
408     */
409    @Override
410    public QuotSolvablePolynomial<C> fromInteger(long a) {
411        return new QuotSolvablePolynomial<C>(this, coFac.fromInteger(a), evzero);
412    }
413
414
415    /**
416     * Get a (constant) QuotSolvablePolynomial&lt;C&gt; element from a
417     * BigInteger value.
418     * @param a BigInteger.
419     * @return a QuotSolvablePolynomial&lt;C&gt;.
420     */
421    @Override
422    public QuotSolvablePolynomial<C> fromInteger(BigInteger a) {
423        return new QuotSolvablePolynomial<C>(this, coFac.fromInteger(a), evzero);
424    }
425
426
427    /**
428     * Random solvable polynomial. Generates a random solvable polynomial with k
429     * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
430     * @param n number of terms.
431     * @return a random solvable polynomial.
432     */
433    @Override
434    public QuotSolvablePolynomial<C> random(int n) {
435        return random(n, random);
436    }
437
438
439    /**
440     * Random solvable polynomial. Generates a random solvable polynomial with k
441     * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
442     * @param n number of terms.
443     * @param rnd is a source for random bits.
444     * @return a random solvable polynomial.
445     */
446    @Override
447    public QuotSolvablePolynomial<C> random(int n, Random rnd) {
448        if (nvar == 1) {
449            return random(5, n, n, 0.7f, rnd);
450        }
451        return random(5, n, 3, 0.3f, rnd);
452    }
453
454
455    /**
456     * Generate a random solvable polynomial.
457     * @param k bitsize of random coefficients.
458     * @param l number of terms.
459     * @param d maximal degree in each variable.
460     * @param q density of nozero exponents.
461     * @return a random solvable polynomial.
462     */
463    @Override
464    public QuotSolvablePolynomial<C> random(int k, int l, int d, float q) {
465        return random(k, l, d, q, random);
466    }
467
468
469    /**
470     * Random solvable polynomial.
471     * @param k size of random coefficients.
472     * @param l number of terms.
473     * @param d maximal degree in each variable.
474     * @param q density of nozero exponents.
475     * @param rnd is a source for random bits.
476     * @return a random solvable polynomial.
477     */
478    @Override
479    public QuotSolvablePolynomial<C> random(int k, int l, int d, float q, Random rnd) {
480        QuotSolvablePolynomial<C> r = getZERO(); // copy( ZERO ); 
481        ExpVector e;
482        SolvableQuotient<C> a;
483        // add random coeffs and exponents
484        for (int i = 0; i < l; i++) {
485            e = ExpVector.random(nvar, d, q, rnd);
486            a = coFac.random(k, rnd);
487            r = (QuotSolvablePolynomial<C>) r.sum(a, e);
488            // somewhat inefficient but clean
489        }
490        return r;
491    }
492
493
494    /**
495     * Copy polynomial c.
496     * @param c
497     * @return a copy of c.
498     */
499    public QuotSolvablePolynomial<C> copy(QuotSolvablePolynomial<C> c) {
500        return new QuotSolvablePolynomial<C>(this, c.getMap());
501    }
502
503
504    /**
505     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
506     * @param s String.
507     * @return QuotSolvablePolynomial from s.
508     */
509    @Override
510    public QuotSolvablePolynomial<C> parse(String s) {
511        return parse(new StringReader(s));
512    }
513
514
515    /**
516     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
517     * @param r Reader.
518     * @return next QuotSolvablePolynomial from r.
519     */
520    @Override
521    @SuppressWarnings("unchecked")
522    public QuotSolvablePolynomial<C> parse(Reader r) {
523        GenPolynomialTokenizer pt = new GenPolynomialTokenizer(this, r);
524        QuotSolvablePolynomial<C> p = null;
525        try {
526            GenSolvablePolynomial<SolvableQuotient<C>> s = pt.nextSolvablePolynomial();
527            p = new QuotSolvablePolynomial<C>(this, s);
528        } catch (IOException e) {
529            logger.error("{} parse {}", e, this);
530            p = ZERO;
531        }
532        return p;
533    }
534
535
536    /**
537     * Generate univariate solvable polynomial in a given variable.
538     * @param i the index of the variable.
539     * @return X_i as solvable univariate polynomial.
540     */
541    @Override
542    public QuotSolvablePolynomial<C> univariate(int i) {
543        return (QuotSolvablePolynomial<C>) super.univariate(i);
544    }
545
546
547    /**
548     * Generate univariate solvable polynomial in a given variable with given
549     * exponent.
550     * @param i the index of the variable.
551     * @param e the exponent of the variable.
552     * @return X_i^e as solvable univariate polynomial.
553     */
554    @Override
555    public QuotSolvablePolynomial<C> univariate(int i, long e) {
556        return (QuotSolvablePolynomial<C>) super.univariate(i, e);
557    }
558
559
560    /**
561     * Generate univariate solvable polynomial in a given variable with given
562     * exponent.
563     * @param modv number of module variables.
564     * @param i the index of the variable.
565     * @param e the exponent of the variable.
566     * @return X_i^e as solvable univariate polynomial.
567     */
568    @Override
569    public QuotSolvablePolynomial<C> univariate(int modv, int i, long e) {
570        return (QuotSolvablePolynomial<C>) super.univariate(modv, i, e);
571    }
572
573
574    /**
575     * Generate list of univariate polynomials in all variables.
576     * @return List(X_1,...,X_n) a list of univariate polynomials.
577     */
578    @Override
579    public List<QuotSolvablePolynomial<C>> univariateList() {
580        return univariateList(0, 1L);
581    }
582
583
584    /**
585     * Generate list of univariate polynomials in all variables.
586     * @param modv number of module variables.
587     * @return List(X_1,...,X_n) a list of univariate polynomials.
588     */
589    @Override
590    public List<QuotSolvablePolynomial<C>> univariateList(int modv) {
591        return univariateList(modv, 1L);
592    }
593
594
595    /**
596     * Generate list of univariate polynomials in all variables with given
597     * exponent.
598     * @param modv number of module variables.
599     * @param e the exponent of the variables.
600     * @return List(X_1^e,...,X_n^e) a list of univariate polynomials.
601     */
602    @Override
603    public List<QuotSolvablePolynomial<C>> univariateList(int modv, long e) {
604        List<QuotSolvablePolynomial<C>> pols = new ArrayList<QuotSolvablePolynomial<C>>(nvar);
605        int nm = nvar - modv;
606        for (int i = 0; i < nm; i++) {
607            QuotSolvablePolynomial<C> p = univariate(modv, nm - 1 - i, e);
608            pols.add(p);
609        }
610        return pols;
611    }
612
613
614    /**
615     * Extend variables. Used e.g. in module embedding. Extend number of
616     * variables by i.
617     * @param i number of variables to extend.
618     * @return extended solvable polynomial ring factory.
619     */
620    @Override
621    public QuotSolvablePolynomialRing<C> extend(int i) {
622        return extend(i, false);
623    }
624
625
626    /**
627     * Extend variables. Used e.g. in module embedding. Extend number of
628     * variables by i.
629     * @param i number of variables to extend.
630     * @param top true for TOP term order, false for POT term order.
631     * @return extended solvable polynomial ring factory.
632     */
633    @Override
634    public QuotSolvablePolynomialRing<C> extend(int i, boolean top) {
635        GenPolynomialRing<SolvableQuotient<C>> pfac = super.extend(i, top);
636        QuotSolvablePolynomialRing<C> spfac = new QuotSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
637                        pfac.tord, pfac.getVars());
638        spfac.table.extend(this.table);
639        spfac.polCoeff.coeffTable.extend(this.polCoeff.coeffTable);
640        return spfac;
641    }
642
643
644    /**
645     * Extend variables. Used e.g. in module embedding. Extend number of
646     * variables by i.
647     * @param vn names for extended variables.
648     * @return extended solvable polynomial ring factory.
649     */
650    @Override
651    public QuotSolvablePolynomialRing<C> extend(String[] vn) {
652        return extend(vn, false);
653    }
654
655
656    /**
657     * Extend variables. Used e.g. in module embedding. Extend number of
658     * variables by i.
659     * @param vn names for extended variables.
660     * @param top true for TOP term order, false for POT term order.
661     * @return extended solvable polynomial ring factory.
662     */
663    @Override
664    public QuotSolvablePolynomialRing<C> extend(String[] vn, boolean top) {
665        GenPolynomialRing<SolvableQuotient<C>> pfac = super.extend(vn, top);
666        QuotSolvablePolynomialRing<C> spfac = new QuotSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
667                        pfac.tord, pfac.getVars());
668        spfac.table.extend(this.table);
669        spfac.polCoeff.coeffTable.extend(this.polCoeff.coeffTable);
670        return spfac;
671    }
672
673
674    /**
675     * Contract variables. Used e.g. in module embedding. Contract number of
676     * variables by i.
677     * @param i number of variables to remove.
678     * @return contracted solvable polynomial ring factory.
679     */
680    @Override
681    public QuotSolvablePolynomialRing<C> contract(int i) {
682        GenPolynomialRing<SolvableQuotient<C>> pfac = super.contract(i);
683        QuotSolvablePolynomialRing<C> spfac = new QuotSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
684                        pfac.tord, pfac.getVars());
685        spfac.table.contract(this.table);
686        spfac.polCoeff.coeffTable.contract(this.polCoeff.coeffTable);
687        return spfac;
688    }
689
690
691    /**
692     * Reverse variables. Used e.g. in opposite rings.
693     * @return solvable polynomial ring factory with reversed variables.
694     */
695    @Override
696    public QuotSolvablePolynomialRing<C> reverse() {
697        return reverse(false);
698    }
699
700
701    /**
702     * Reverse variables. Used e.g. in opposite rings.
703     * @param partial true for partially reversed term orders.
704     * @return solvable polynomial ring factory with reversed variables.
705     */
706    @Override
707    public QuotSolvablePolynomialRing<C> reverse(boolean partial) {
708        GenPolynomialRing<SolvableQuotient<C>> pfac = super.reverse(partial);
709        QuotSolvablePolynomialRing<C> spfac = new QuotSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
710                        pfac.tord, pfac.getVars());
711        spfac.partial = partial;
712        spfac.table.reverse(this.table);
713        spfac.polCoeff.coeffTable.reverse(this.polCoeff.coeffTable);
714        return spfac;
715    }
716
717
718    /**
719     * Rational function from integral polynomial coefficients. Represent as
720     * polynomial with type SolvableQuotient<C> coefficients.
721     * @param A polynomial with integral polynomial coefficients to be
722     *            converted.
723     * @return polynomial with type SolvableQuotient<C> coefficients.
724     */
725    public QuotSolvablePolynomial<C> fromPolyCoefficients(GenSolvablePolynomial<GenPolynomial<C>> A) {
726        QuotSolvablePolynomial<C> B = getZERO().copy();
727        if (A == null || A.isZERO()) {
728            return B;
729        }
730        RingFactory<SolvableQuotient<C>> cfac = coFac;
731        SolvableQuotientRing<C> qfac = (SolvableQuotientRing<C>) cfac;
732        for (Map.Entry<ExpVector, GenPolynomial<C>> y : A.getMap().entrySet()) {
733            ExpVector e = y.getKey();
734            GenSolvablePolynomial<C> a = (GenSolvablePolynomial<C>) y.getValue();
735            SolvableQuotient<C> p = new SolvableQuotient<C>(qfac, a); // can not be zero
736            if (!p.isZERO()) {
737                //B = B.sum( p, e ); // inefficient
738                B.doPutToMap(e, p);
739            }
740        }
741        return B;
742    }
743
744
745    /**
746     * Integral function from rational polynomial coefficients. Represent as
747     * polynomial with type GenSolvablePolynomial<C> coefficients.
748     * @param A polynomial with rational polynomial coefficients to be
749     *            converted.
750     * @return polynomial with type GenSolvablePolynomial<C> coefficients.
751     */
752    public RecSolvablePolynomial<C> toPolyCoefficients(QuotSolvablePolynomial<C> A) {
753        RecSolvablePolynomial<C> B = polCoeff.getZERO().copy();
754        if (A == null || A.isZERO()) {
755            return B;
756        }
757        for (Map.Entry<ExpVector, SolvableQuotient<C>> y : A.getMap().entrySet()) {
758            ExpVector e = y.getKey();
759            SolvableQuotient<C> a = y.getValue();
760            if (!a.den.isONE()) {
761                throw new IllegalArgumentException("den != 1 not supported: " + a);
762            }
763            GenPolynomial<C> p = a.num; // can not be zero
764            if (!p.isZERO()) {
765                //B = B.sum( p, e ); // inefficient
766                B.doPutToMap(e, p);
767            }
768        }
769        return B;
770    }
771
772
773    /**
774     * Integral function from rational polynomial coefficients. Represent as
775     * polynomial with type GenSolvablePolynomial<C> coefficients.
776     * @param A polynomial with rational polynomial coefficients to be
777     *            converted.
778     * @return polynomial with type GenSolvablePolynomial<C> coefficients.
779     */
780    public RecSolvablePolynomial<C> toPolyCoefficients(GenPolynomial<SolvableQuotient<C>> A) {
781        RecSolvablePolynomial<C> B = polCoeff.getZERO().copy();
782        if (A == null || A.isZERO()) {
783            return B;
784        }
785        for (Map.Entry<ExpVector, SolvableQuotient<C>> y : A.getMap().entrySet()) {
786            ExpVector e = y.getKey();
787            SolvableQuotient<C> a = y.getValue();
788            if (!a.den.isONE()) {
789                throw new IllegalArgumentException("den != 1 not supported: " + a);
790            }
791            GenPolynomial<C> p = a.num; // can not be zero
792            if (!p.isZERO()) {
793                //B = B.sum( p, e ); // inefficient
794                B.doPutToMap(e, p);
795            }
796        }
797        return B;
798    }
799
800}