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