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