001/*
002 * $Id$
003 */
004
005package edu.jas.application;
006
007
008import java.util.ArrayList;
009import java.util.Arrays;
010import java.util.List;
011import java.util.Map;
012import java.util.SortedMap;
013import java.util.TreeMap;
014
015import org.apache.logging.log4j.Logger;
016import org.apache.logging.log4j.LogManager; 
017
018import edu.jas.arith.BigDecimal;
019import edu.jas.arith.BigRational;
020import edu.jas.arith.Product;
021import edu.jas.arith.ProductRing;
022import edu.jas.arith.Rational;
023import edu.jas.poly.AlgebraicNumber;
024import edu.jas.poly.AlgebraicNumberRing;
025import edu.jas.poly.Complex;
026import edu.jas.poly.ComplexRing;
027import edu.jas.poly.ExpVector;
028import edu.jas.poly.GenPolynomial;
029import edu.jas.poly.GenPolynomialRing;
030import edu.jas.poly.PolyUtil;
031import edu.jas.poly.PolynomialList;
032import edu.jas.poly.TermOrder;
033import edu.jas.root.ComplexRoots;
034import edu.jas.root.ComplexRootsAbstract;
035import edu.jas.root.ComplexRootsSturm;
036import edu.jas.root.Interval;
037import edu.jas.root.InvalidBoundaryException;
038import edu.jas.root.RealAlgebraicNumber;
039import edu.jas.root.RealAlgebraicRing;
040import edu.jas.root.RealRootTuple;
041import edu.jas.root.RealRootsAbstract;
042import edu.jas.root.RealRootsSturm;
043import edu.jas.root.Rectangle;
044import edu.jas.root.RootFactory;
045import edu.jas.structure.GcdRingElem;
046import edu.jas.structure.RingElem;
047import edu.jas.structure.RingFactory;
048import edu.jas.structure.UnaryFunctor;
049import edu.jas.util.ListUtil;
050
051
052/**
053 * Polynomial utilities for applications, for example conversion ExpVector to
054 * Product or zero dimensional ideal root computation.
055 * @param <C> coefficient type
056 * @author Heinz Kredel
057 */
058public class PolyUtilApp<C extends RingElem<C>> {
059
060
061    private static final Logger logger = LogManager.getLogger(PolyUtilApp.class);
062
063
064    private static final boolean debug = logger.isDebugEnabled();
065
066
067    /**
068     * Product representation.
069     * @param <C> coefficient type.
070     * @param pfac polynomial ring factory.
071     * @param L list of polynomials to be represented.
072     * @return Product represenation of L in the polynomial ring pfac.
073     */
074    public static <C extends GcdRingElem<C>> List<GenPolynomial<Product<Residue<C>>>> toProductRes(
075                    GenPolynomialRing<Product<Residue<C>>> pfac, List<GenPolynomial<GenPolynomial<C>>> L) {
076
077        List<GenPolynomial<Product<Residue<C>>>> list = new ArrayList<GenPolynomial<Product<Residue<C>>>>();
078        if (L == null || L.size() == 0) {
079            return list;
080        }
081        GenPolynomial<Product<Residue<C>>> b;
082        for (GenPolynomial<GenPolynomial<C>> a : L) {
083            b = toProductRes(pfac, a);
084            list.add(b);
085        }
086        return list;
087    }
088
089
090    /**
091     * Product representation.
092     * @param <C> coefficient type.
093     * @param pfac polynomial ring factory.
094     * @param A polynomial to be represented.
095     * @return Product represenation of A in the polynomial ring pfac.
096     */
097    public static <C extends GcdRingElem<C>> GenPolynomial<Product<Residue<C>>> toProductRes(
098                    GenPolynomialRing<Product<Residue<C>>> pfac, GenPolynomial<GenPolynomial<C>> A) {
099
100        GenPolynomial<Product<Residue<C>>> P = pfac.getZERO().copy();
101        if (A == null || A.isZERO()) {
102            return P;
103        }
104        RingFactory<Product<Residue<C>>> rpfac = pfac.coFac;
105        ProductRing<Residue<C>> fac = (ProductRing<Residue<C>>) rpfac;
106        Product<Residue<C>> p;
107        for (Map.Entry<ExpVector, GenPolynomial<C>> y : A.getMap().entrySet()) {
108            ExpVector e = y.getKey();
109            GenPolynomial<C> a = y.getValue();
110            p = toProductRes(fac, a);
111            if (!p.isZERO()) {
112                P.doPutToMap(e, p);
113            }
114        }
115        return P;
116    }
117
118
119    /**
120     * Product representation.
121     * @param <C> coefficient type.
122     * @param pfac product ring factory.
123     * @param c coefficient to be represented.
124     * @return Product represenation of c in the ring pfac.
125     */
126    public static <C extends GcdRingElem<C>> Product<Residue<C>> toProductRes(ProductRing<Residue<C>> pfac,
127                    GenPolynomial<C> c) {
128
129        SortedMap<Integer, Residue<C>> elem = new TreeMap<Integer, Residue<C>>();
130        for (int i = 0; i < pfac.length(); i++) {
131            RingFactory<Residue<C>> rfac = pfac.getFactory(i);
132            ResidueRing<C> fac = (ResidueRing<C>) rfac;
133            Residue<C> u = new Residue<C>(fac, c);
134            //fac.fromInteger( c.getVal() );
135            if (!u.isZERO()) {
136                elem.put(i, u);
137            }
138        }
139        return new Product<Residue<C>>(pfac, elem);
140    }
141
142
143    /**
144     * Product residue representation.
145     * @param <C> coefficient type.
146     * @param CS list of ColoredSystems from comprehensive GB system.
147     * @return Product residue represenation of CS.
148     */
149    public static <C extends GcdRingElem<C>> List<GenPolynomial<Product<Residue<C>>>> toProductRes(
150                    List<ColoredSystem<C>> CS) {
151
152        List<GenPolynomial<Product<Residue<C>>>> list = new ArrayList<GenPolynomial<Product<Residue<C>>>>();
153        if (CS == null || CS.isEmpty()) {
154            return list;
155        }
156        GenPolynomialRing<GenPolynomial<C>> pr = null;
157        List<RingFactory<Residue<C>>> rrl = new ArrayList<RingFactory<Residue<C>>>(CS.size());
158        for (ColoredSystem<C> cs : CS) {
159            Ideal<C> id = cs.condition.zero;
160            ResidueRing<C> r = new ResidueRing<C>(id);
161            if (!rrl.contains(r)) {
162                rrl.add(r);
163            }
164            if (pr == null) {
165                if (cs.list.size() > 0) {
166                    pr = cs.list.get(0).green.ring;
167                }
168            }
169        }
170        if (pr == null) {
171            throw new IllegalArgumentException("no polynomial ring found");
172        }
173        ProductRing<Residue<C>> pfac;
174        pfac = new ProductRing<Residue<C>>(rrl);
175        //System.out.println("pfac = " + pfac);
176        GenPolynomialRing<Product<Residue<C>>> rf = new GenPolynomialRing<Product<Residue<C>>>(pfac, pr.nvar,
177                        pr.tord, pr.getVars());
178        GroebnerSystem<C> gs = new GroebnerSystem<C>(CS);
179        List<GenPolynomial<GenPolynomial<C>>> F = gs.getCGB();
180        list = PolyUtilApp.<C> toProductRes(rf, F);
181        return list;
182    }
183
184
185    /**
186     * Residue coefficient representation.
187     * @param pfac polynomial ring factory.
188     * @param L list of polynomials to be represented.
189     * @return Represenation of L in the polynomial ring pfac.
190     */
191    public static <C extends GcdRingElem<C>> List<GenPolynomial<Residue<C>>> toResidue(
192                    GenPolynomialRing<Residue<C>> pfac, List<GenPolynomial<GenPolynomial<C>>> L) {
193        List<GenPolynomial<Residue<C>>> list = new ArrayList<GenPolynomial<Residue<C>>>();
194        if (L == null || L.size() == 0) {
195            return list;
196        }
197        GenPolynomial<Residue<C>> b;
198        for (GenPolynomial<GenPolynomial<C>> a : L) {
199            b = toResidue(pfac, a);
200            if (!b.isZERO()) {
201                list.add(b);
202            }
203        }
204        return list;
205    }
206
207
208    /**
209     * Residue coefficient representation.
210     * @param pfac polynomial ring factory.
211     * @param A polynomial to be represented.
212     * @return Represenation of A in the polynomial ring pfac.
213     */
214    public static <C extends GcdRingElem<C>> GenPolynomial<Residue<C>> toResidue(
215                    GenPolynomialRing<Residue<C>> pfac, GenPolynomial<GenPolynomial<C>> A) {
216        GenPolynomial<Residue<C>> P = pfac.getZERO().copy();
217        if (A == null || A.isZERO()) {
218            return P;
219        }
220        RingFactory<Residue<C>> rpfac = pfac.coFac;
221        ResidueRing<C> fac = (ResidueRing<C>) rpfac;
222        Residue<C> p;
223        for (Map.Entry<ExpVector, GenPolynomial<C>> y : A.getMap().entrySet()) {
224            ExpVector e = y.getKey();
225            GenPolynomial<C> a = y.getValue();
226            p = new Residue<C>(fac, a);
227            if (!p.isZERO()) {
228                P.doPutToMap(e, p);
229            }
230        }
231        return P;
232    }
233
234
235    /**
236     * Product slice.
237     * @param <C> coefficient type.
238     * @param L list of polynomials with product coefficients.
239     * @return Slices represenation of L.
240     */
241    public static <C extends GcdRingElem<C>> Map<Ideal<C>, PolynomialList<GenPolynomial<C>>> productSlice(
242                    PolynomialList<Product<Residue<C>>> L) {
243
244        Map<Ideal<C>, PolynomialList<GenPolynomial<C>>> map;
245        RingFactory<Product<Residue<C>>> fpr = L.ring.coFac;
246        ProductRing<Residue<C>> pr = (ProductRing<Residue<C>>) fpr;
247        int s = pr.length();
248        map = new TreeMap<Ideal<C>, PolynomialList<GenPolynomial<C>>>();
249        List<GenPolynomial<GenPolynomial<C>>> slist;
250
251        List<GenPolynomial<Product<Residue<C>>>> plist = L.list;
252        PolynomialList<GenPolynomial<C>> spl;
253
254        for (int i = 0; i < s; i++) {
255            RingFactory<Residue<C>> r = pr.getFactory(i);
256            ResidueRing<C> rr = (ResidueRing<C>) r;
257            Ideal<C> id = rr.ideal;
258            GenPolynomialRing<C> cof = rr.ring;
259            GenPolynomialRing<GenPolynomial<C>> pfc;
260            pfc = new GenPolynomialRing<GenPolynomial<C>>(cof, L.ring);
261            slist = fromProduct(pfc, plist, i);
262            spl = new PolynomialList<GenPolynomial<C>>(pfc, slist);
263            PolynomialList<GenPolynomial<C>> d = map.get(id);
264            if (d != null) {
265                throw new RuntimeException("ideal exists twice " + id);
266            }
267            map.put(id, spl);
268        }
269        return map;
270    }
271
272
273    /**
274     * Product slice at i.
275     * @param <C> coefficient type.
276     * @param L list of polynomials with product coeffients.
277     * @param i index of slice.
278     * @return Slice of of L at i.
279     */
280    public static <C extends GcdRingElem<C>> PolynomialList<GenPolynomial<C>> productSlice(
281                    PolynomialList<Product<Residue<C>>> L, int i) {
282
283        RingFactory<Product<Residue<C>>> fpr = L.ring.coFac;
284        ProductRing<Residue<C>> pr = (ProductRing<Residue<C>>) fpr;
285        List<GenPolynomial<GenPolynomial<C>>> slist;
286
287        List<GenPolynomial<Product<Residue<C>>>> plist = L.list;
288        PolynomialList<GenPolynomial<C>> spl;
289
290        RingFactory<Residue<C>> r = pr.getFactory(i);
291        ResidueRing<C> rr = (ResidueRing<C>) r;
292        GenPolynomialRing<C> cof = rr.ring;
293        GenPolynomialRing<GenPolynomial<C>> pfc;
294        pfc = new GenPolynomialRing<GenPolynomial<C>>(cof, L.ring);
295        slist = fromProduct(pfc, plist, i);
296        spl = new PolynomialList<GenPolynomial<C>>(pfc, slist);
297        return spl;
298    }
299
300
301    /**
302     * From product representation.
303     * @param <C> coefficient type.
304     * @param pfac polynomial ring factory.
305     * @param L list of polynomials to be converted from product representation.
306     * @param i index of product representation to be taken.
307     * @return Represenation of i-slice of L in the polynomial ring pfac.
308     */
309    public static <C extends GcdRingElem<C>> List<GenPolynomial<GenPolynomial<C>>> fromProduct(
310                    GenPolynomialRing<GenPolynomial<C>> pfac, List<GenPolynomial<Product<Residue<C>>>> L,
311                    int i) {
312
313        List<GenPolynomial<GenPolynomial<C>>> list = new ArrayList<GenPolynomial<GenPolynomial<C>>>();
314
315        if (L == null || L.size() == 0) {
316            return list;
317        }
318        GenPolynomial<GenPolynomial<C>> b;
319        for (GenPolynomial<Product<Residue<C>>> a : L) {
320            b = fromProduct(pfac, a, i);
321            if (!b.isZERO()) {
322                b = b.abs();
323                if (!list.contains(b)) {
324                    list.add(b);
325                }
326            }
327        }
328        return list;
329    }
330
331
332    /**
333     * From product representation.
334     * @param <C> coefficient type.
335     * @param pfac polynomial ring factory.
336     * @param P polynomial to be converted from product representation.
337     * @param i index of product representation to be taken.
338     * @return Represenation of i-slice of P in the polynomial ring pfac.
339     */
340    public static <C extends GcdRingElem<C>> GenPolynomial<GenPolynomial<C>> fromProduct(
341                    GenPolynomialRing<GenPolynomial<C>> pfac, GenPolynomial<Product<Residue<C>>> P, int i) {
342
343        GenPolynomial<GenPolynomial<C>> b = pfac.getZERO().copy();
344        if (P == null || P.isZERO()) {
345            return b;
346        }
347
348        for (Map.Entry<ExpVector, Product<Residue<C>>> y : P.getMap().entrySet()) {
349            ExpVector e = y.getKey();
350            Product<Residue<C>> a = y.getValue();
351            Residue<C> r = a.get(i);
352            if (r != null && !r.isZERO()) {
353                GenPolynomial<C> p = r.val;
354                if (!p.isZERO()) {
355                    b.doPutToMap(e, p);
356                }
357            }
358        }
359        return b;
360    }
361
362
363    /**
364     * Product slice to String.
365     * @param <C> coefficient type.
366     * @param L list of polynomials with to be represented.
367     * @return Product represenation of L in the polynomial ring pfac.
368     */
369    public static <C extends GcdRingElem<C>> String productSliceToString(
370                    Map<Ideal<C>, PolynomialList<GenPolynomial<C>>> L) {
371        //Set<GenPolynomial<GenPolynomial<C>>> sl = new TreeSet<GenPolynomial<GenPolynomial<C>>>();
372        PolynomialList<GenPolynomial<C>> pl = null;
373        StringBuffer sb = new StringBuffer(); //"\nproductSlice ----------------- begin");
374        for (Map.Entry<Ideal<C>, PolynomialList<GenPolynomial<C>>> en : L.entrySet()) {
375            sb.append("\n\ncondition == 0:\n");
376            sb.append(en.getKey().list.toScript());
377            pl = en.getValue(); //L.get(id);
378            //sl.addAll(pl.list);
379            sb.append("\ncorresponding ideal:\n");
380            sb.append(pl.toScript());
381        }
382        //List<GenPolynomial<GenPolynomial<C>>> sll 
383        //   = new ArrayList<GenPolynomial<GenPolynomial<C>>>( sl );
384        //pl = new PolynomialList<GenPolynomial<C>>(pl.ring,sll);
385        // sb.append("\nunion = " + pl.toString());
386        //sb.append("\nproductSlice ------------------------- end\n");
387        return sb.toString();
388    }
389
390
391    /**
392     * Product slice to String.
393     * @param <C> coefficient type.
394     * @param L list of polynomials with product coefficients.
395     * @return string represenation of slices of L.
396     */
397    public static <C extends GcdRingElem<C>> String productToString(PolynomialList<Product<Residue<C>>> L) {
398        Map<Ideal<C>, PolynomialList<GenPolynomial<C>>> M;
399        M = productSlice(L);
400        String s = productSliceToString(M);
401        return s;
402    }
403
404
405    /**
406     * Construct superset of complex roots for zero dimensional ideal(G).
407     * @param I zero dimensional ideal.
408     * @param eps desired precision.
409     * @return list of coordinates of complex roots for ideal(G)
410     */
411    public static <D extends GcdRingElem<D> & Rational> List<List<Complex<BigDecimal>>> complexRootTuples(
412                    Ideal<D> I, BigRational eps) {
413        List<GenPolynomial<D>> univs = I.constructUnivariate();
414        logger.info("univs = {}", univs);
415        return complexRoots(I, univs, eps);
416    }
417
418
419    /**
420     * Construct superset of complex roots for zero dimensional ideal(G).
421     * @param I zero dimensional ideal.
422     * @param univs list of univariate polynomials.
423     * @param eps desired precision.
424     * @return list of coordinates of complex roots for ideal(G)
425     */
426    public static <D extends GcdRingElem<D> & Rational> List<List<Complex<BigDecimal>>> complexRoots(
427                    Ideal<D> I, List<GenPolynomial<D>> univs, BigRational eps) {
428        List<List<Complex<BigDecimal>>> croots = new ArrayList<List<Complex<BigDecimal>>>();
429        RingFactory<D> cf = I.list.ring.coFac;
430        ComplexRing<D> cr = new ComplexRing<D>(cf);
431        ComplexRootsAbstract<D> cra = new ComplexRootsSturm<D>(cr);
432        List<GenPolynomial<Complex<D>>> cunivs = new ArrayList<GenPolynomial<Complex<D>>>();
433        for (GenPolynomial<D> p : univs) {
434            GenPolynomialRing<Complex<D>> pfac = new GenPolynomialRing<Complex<D>>(cr, p.ring);
435            //System.out.println("pfac = " + pfac.toScript());
436            GenPolynomial<Complex<D>> cp = PolyUtil.<D> toComplex(pfac, p);
437            cunivs.add(cp);
438            //System.out.println("cp = " + cp);
439        }
440        for (int i = 0; i < I.list.ring.nvar; i++) {
441            List<Complex<BigDecimal>> cri = cra.approximateRoots(cunivs.get(i), eps);
442            //System.out.println("cri = " + cri);
443            croots.add(cri);
444        }
445        croots = ListUtil.<Complex<BigDecimal>> tupleFromList(croots);
446        return croots;
447    }
448
449
450    /**
451     * Construct superset of complex roots for zero dimensional ideal(G).
452     * @param Il list of zero dimensional ideals with univariate polynomials.
453     * @param eps desired precision.
454     * @return list of coordinates of complex roots for ideal(cap_i(G_i))
455     */
456    public static <D extends GcdRingElem<D> & Rational> List<List<Complex<BigDecimal>>> complexRootTuples(
457                    List<IdealWithUniv<D>> Il, BigRational eps) {
458        List<List<Complex<BigDecimal>>> croots = new ArrayList<List<Complex<BigDecimal>>>();
459        for (IdealWithUniv<D> I : Il) {
460            List<List<Complex<BigDecimal>>> cr = complexRoots(I.ideal, I.upolys, eps);
461            croots.addAll(cr);
462        }
463        return croots;
464    }
465
466
467    /**
468     * Construct superset of complex roots for zero dimensional ideal(G).
469     * @param Il list of zero dimensional ideals with univariate polynomials.
470     * @param eps desired precision.
471     * @return list of ideals with coordinates of complex roots for
472     *         ideal(cap_i(G_i))
473     */
474    public static <D extends GcdRingElem<D> & Rational> List<IdealWithComplexRoots<D>> complexRoots(
475                    List<IdealWithUniv<D>> Il, BigRational eps) {
476        List<IdealWithComplexRoots<D>> Ic = new ArrayList<IdealWithComplexRoots<D>>(Il.size());
477        for (IdealWithUniv<D> I : Il) {
478            List<List<Complex<BigDecimal>>> cr = complexRoots(I.ideal, I.upolys, eps);
479            IdealWithComplexRoots<D> ic = new IdealWithComplexRoots<D>(I, cr);
480            Ic.add(ic);
481        }
482        return Ic;
483    }
484
485
486    /**
487     * Construct superset of complex roots for zero dimensional ideal(G).
488     * @param G list of polynomials of a of zero dimensional ideal.
489     * @param eps desired precision.
490     * @return list of ideals with coordinates of complex roots for ideal(G)
491     */
492    public static <D extends GcdRingElem<D> & Rational> List<IdealWithComplexRoots<D>> complexRoots(
493                    Ideal<D> G, BigRational eps) {
494        List<IdealWithUniv<D>> Il = G.zeroDimDecomposition();
495        return complexRoots(Il, eps);
496    }
497
498
499    /**
500     * Construct superset of real roots for zero dimensional ideal(G).
501     * @param I zero dimensional ideal.
502     * @param eps desired precision.
503     * @return list of coordinates of real roots for ideal(G)
504     */
505    public static <D extends GcdRingElem<D> & Rational> List<List<BigDecimal>> realRootTuples(Ideal<D> I,
506                    BigRational eps) {
507        List<GenPolynomial<D>> univs = I.constructUnivariate();
508        logger.info("univs = {}", univs);
509        return realRoots(I, univs, eps);
510    }
511
512
513    /**
514     * Construct superset of real roots for zero dimensional ideal(G).
515     * @param I zero dimensional ideal.
516     * @param univs list of univariate polynomials.
517     * @param eps desired precision.
518     * @return list of coordinates of real roots for ideal(G)
519     */
520    public static <D extends GcdRingElem<D> & Rational> List<List<BigDecimal>> realRoots(Ideal<D> I,
521                    List<GenPolynomial<D>> univs, BigRational eps) {
522        List<List<BigDecimal>> roots = new ArrayList<List<BigDecimal>>();
523        //RingFactory<D> cf = (RingFactory<D>) I.list.ring.coFac;
524        RealRootsAbstract<D> rra = new RealRootsSturm<D>();
525        for (int i = 0; i < I.list.ring.nvar; i++) {
526            List<BigDecimal> rri = rra.approximateRoots(univs.get(i), eps);
527            //System.out.println("rri = " + rri);
528            roots.add(rri);
529        }
530        //System.out.println("roots-1 = " + roots);
531        roots = ListUtil.<BigDecimal> tupleFromList(roots);
532        //System.out.println("roots-2 = " + roots);
533        return roots;
534    }
535
536
537    /**
538     * Construct superset of real roots for zero dimensional ideal(G).
539     * @param Il list of zero dimensional ideals with univariate polynomials.
540     * @param eps desired precision.
541     * @return list of coordinates of real roots for ideal(cap_i(G_i))
542     */
543    public static <D extends GcdRingElem<D> & Rational> List<List<BigDecimal>> realRootTuples(
544                    List<IdealWithUniv<D>> Il, BigRational eps) {
545        List<List<BigDecimal>> rroots = new ArrayList<List<BigDecimal>>();
546        for (IdealWithUniv<D> I : Il) {
547            List<List<BigDecimal>> rr = realRoots(I.ideal, I.upolys, eps);
548            rroots.addAll(rr);
549        }
550        return rroots;
551    }
552
553
554    /**
555     * Construct superset of real roots for zero dimensional ideal(G).
556     * @param Il list of zero dimensional ideals with univariate polynomials.
557     * @param eps desired precision.
558     * @return list of ideals with coordinates of real roots for
559     *         ideal(cap_i(G_i))
560     */
561    public static <D extends GcdRingElem<D> & Rational> List<IdealWithRealRoots<D>> realRoots(
562                    List<IdealWithUniv<D>> Il, BigRational eps) {
563        List<IdealWithRealRoots<D>> Ir = new ArrayList<IdealWithRealRoots<D>>(Il.size());
564        for (IdealWithUniv<D> I : Il) {
565            List<List<BigDecimal>> rr = realRoots(I.ideal, I.upolys, eps);
566            IdealWithRealRoots<D> ir = new IdealWithRealRoots<D>(I, rr);
567            Ir.add(ir);
568        }
569        return Ir;
570    }
571
572
573    /**
574     * Construct superset of real roots for zero dimensional ideal(G).
575     * @param G list of polynomials of a of zero dimensional ideal.
576     * @param eps desired precision.
577     * @return list of ideals with coordinates of real roots for ideal(G)
578     */
579    public static <D extends GcdRingElem<D> & Rational> List<IdealWithRealRoots<D>> realRoots(Ideal<D> G,
580                    BigRational eps) {
581        List<IdealWithUniv<D>> Il = G.zeroDimDecomposition();
582        return realRoots(Il, eps);
583    }
584
585
586    /**
587     * Test for real roots of zero dimensional ideal(L).
588     * @param L list of polynomials.
589     * @param roots list of real roots for ideal(G).
590     * @param eps desired precision.
591     * @return true if root is a list of coordinates of real roots for ideal(L)
592     */
593    public static boolean isRealRoots(List<GenPolynomial<BigDecimal>> L, List<List<BigDecimal>> roots,
594                    BigDecimal eps) {
595        if (L == null || L.size() == 0) {
596            return true;
597        }
598        // polynomials with decimal coefficients
599        BigDecimal dc = BigDecimal.ONE;
600        //GenPolynomialRing<BigDecimal> dfac = L.get(0).ring;
601        //System.out.println("dfac = " + dfac);
602        for (GenPolynomial<BigDecimal> dp : L) {
603            //System.out.println("dp = " + dp);
604            for (List<BigDecimal> r : roots) {
605                //System.out.println("r = " + r);
606                BigDecimal ev = PolyUtil.<BigDecimal> evaluateAll(dc, dp, r);
607                if (ev.abs().compareTo(eps) > 0) {
608                    System.out.println("ev = " + ev);
609                    return false;
610                }
611            }
612        }
613        return true;
614    }
615
616
617    /**
618     * Test for complex roots of zero dimensional ideal(L).
619     * @param L list of polynomials.
620     * @param roots list of real roots for ideal(G).
621     * @param eps desired precision.
622     * @return true if root is a list of coordinates of complex roots for
623     *         ideal(L)
624     */
625    public static boolean isComplexRoots(List<GenPolynomial<Complex<BigDecimal>>> L,
626                    List<List<Complex<BigDecimal>>> roots, BigDecimal eps) {
627        if (L == null || L.size() == 0) {
628            return true;
629        }
630        // polynomials with decimal coefficients
631        BigDecimal dc = BigDecimal.ONE;
632        ComplexRing<BigDecimal> dcc = new ComplexRing<BigDecimal>(dc);
633        //GenPolynomialRing<Complex<BigDecimal>> dfac = L.get(0).ring;
634        //System.out.println("dfac = " + dfac);
635        for (GenPolynomial<Complex<BigDecimal>> dp : L) {
636            //System.out.println("dp = " + dp);
637            for (List<Complex<BigDecimal>> r : roots) {
638                //System.out.println("r = " + r);
639                Complex<BigDecimal> ev = PolyUtil.<Complex<BigDecimal>> evaluateAll(dcc, dp, r);
640                if (ev.norm().getRe().compareTo(eps) > 0) {
641                    System.out.println("ev = " + ev);
642                    return false;
643                }
644            }
645        }
646        return true;
647    }
648
649
650    /**
651     * Construct real roots for zero dimensional ideal(G).
652     * @param I zero dimensional ideal with univariate irreducible polynomials
653     *            and bi-variate polynomials.
654     * @return real algebraic roots for ideal(G)
655     */
656    public static <D extends GcdRingElem<D> & Rational> IdealWithRealAlgebraicRoots<D> realAlgebraicRoots(
657                    IdealWithUniv<D> I) {
658        List<List<RealAlgebraicNumber<D>>> ran = new ArrayList<List<RealAlgebraicNumber<D>>>();
659        if (I == null) {
660            throw new IllegalArgumentException("null ideal not permitted");
661        }
662        if (I.ideal == null || I.upolys == null) {
663            throw new IllegalArgumentException("null ideal components not permitted " + I);
664        }
665        if (I.ideal.isZERO() || I.upolys.size() == 0) {
666            return new IdealWithRealAlgebraicRoots<D>(I, ran);
667        }
668        GenPolynomialRing<D> fac = I.ideal.list.ring;
669        // case i == 0:
670        GenPolynomial<D> p0 = I.upolys.get(0);
671        GenPolynomial<D> p0p = PolyUtil.<D> selectWithVariable(I.ideal.list.list, fac.nvar - 1);
672        if (p0p == null) {
673            throw new RuntimeException("no polynomial found in " + (fac.nvar - 1) + " of  " + I.ideal);
674        }
675        //System.out.println("p0  = " + p0);
676        logger.info("p0p = {}", p0p);
677        int[] dep0 = p0p.degreeVector().dependencyOnVariables();
678        //System.out.println("dep0 = " + Arrays.toString(dep0));
679        if (dep0.length != 1) {
680            throw new RuntimeException("wrong number of variables " + Arrays.toString(dep0));
681        }
682        List<RealAlgebraicNumber<D>> rra = RootFactory.<D> realAlgebraicNumbersIrred(p0);
683        if (logger.isInfoEnabled()) {
684            List<Interval<D>> il = new ArrayList<Interval<D>>();
685            for (RealAlgebraicNumber<D> rr : rra) {
686                il.add(rr.ring.getRoot());
687            }
688            logger.info("roots(p0) = {}", il);
689        }
690        for (RealAlgebraicNumber<D> rr : rra) {
691            List<RealAlgebraicNumber<D>> rl = new ArrayList<RealAlgebraicNumber<D>>();
692            rl.add(rr);
693            ran.add(rl);
694        }
695        // case i > 0:
696        for (int i = 1; i < I.upolys.size(); i++) {
697            List<List<RealAlgebraicNumber<D>>> rn = new ArrayList<List<RealAlgebraicNumber<D>>>();
698            GenPolynomial<D> pi = I.upolys.get(i);
699            GenPolynomial<D> pip = PolyUtil.selectWithVariable(I.ideal.list.list, fac.nvar - 1 - i);
700            if (pip == null) {
701                throw new RuntimeException(
702                                "no polynomial found in " + (fac.nvar - 1 - i) + " of  " + I.ideal);
703            }
704            //System.out.println("i   = " + i);
705            //System.out.println("pi  = " + pi);
706            logger.info("pi  = {}, pip = {}", pi, pip);
707            int[] depi = pip.degreeVector().dependencyOnVariables();
708            //System.out.println("depi = " + Arrays.toString(depi));
709            if (depi.length < 1 || depi.length > 2) {
710                throw new RuntimeException("wrong number of variables " + Arrays.toString(depi));
711            }
712            rra = RootFactory.<D> realAlgebraicNumbersIrred(pi);
713            if (logger.isInfoEnabled()) {
714                List<Interval<D>> il = new ArrayList<Interval<D>>();
715                for (RealAlgebraicNumber<D> rr : rra) {
716                    il.add(rr.ring.getRoot());
717                }
718                logger.info("roots(pi) = {}", il);
719            }
720            if (depi.length == 1) {
721                // all combinations are roots of the ideal I
722                for (RealAlgebraicNumber<D> rr : rra) {
723                    //System.out.println("rr.ring = " + rr.ring);
724                    for (List<RealAlgebraicNumber<D>> rx : ran) {
725                        //System.out.println("rx = " + rx);
726                        List<RealAlgebraicNumber<D>> ry = new ArrayList<RealAlgebraicNumber<D>>();
727                        ry.addAll(rx);
728                        ry.add(rr);
729                        rn.add(ry);
730                    }
731                }
732            } else { // depi.length == 2
733                // select roots of the ideal I
734                GenPolynomial<D> pip2 = PolyUtil.<D> removeUnusedUpperVariables(pip);
735                //System.out.println("pip2 = " + pip2.ring);
736                GenPolynomialRing<D> ufac = pip2.ring.contract(1);
737                TermOrder to = new TermOrder(TermOrder.INVLEX);
738                GenPolynomialRing<GenPolynomial<D>> rfac = new GenPolynomialRing<GenPolynomial<D>>(ufac, 1,
739                                                                                                   to); // new vars
740                GenPolynomial<GenPolynomial<D>> pip2r = PolyUtil.<D> recursive(rfac, pip2);
741                int ix = fac.nvar - 1 - depi[depi.length - 1];
742                //System.out.println("ix = " + ix);
743                for (RealAlgebraicNumber<D> rr : rra) {
744                    //System.out.println("rr.ring = " + rr.ring);
745                    Interval<D> rroot = rr.ring.getRoot();
746                    GenPolynomial<D> pip2el = PolyUtil.<D> evaluateMainRecursive(ufac, pip2r, rroot.left);
747                    GenPolynomial<D> pip2er = PolyUtil.<D> evaluateMainRecursive(ufac, pip2r, rroot.right);
748                    GenPolynomialRing<D> upfac = I.upolys.get(ix).ring;
749                    GenPolynomial<D> pip2elc = convert(upfac, pip2el);
750                    GenPolynomial<D> pip2erc = convert(upfac, pip2er);
751                    //System.out.println("pip2elc = " + pip2elc);
752                    //System.out.println("pip2erc = " + pip2erc);
753                    for (List<RealAlgebraicNumber<D>> rx : ran) {
754                        //System.out.println("rx = " + rx);
755                        RealAlgebraicRing<D> rar = rx.get(ix).ring;
756                        //System.out.println("rar = " + rar.toScript());
757                        RealAlgebraicNumber<D> rel = new RealAlgebraicNumber<D>(rar, pip2elc);
758                        RealAlgebraicNumber<D> rer = new RealAlgebraicNumber<D>(rar, pip2erc);
759                        int sl = rel.signum();
760                        int sr = rer.signum();
761                        //System.out.println("sl = " + sl + ", sr = " + sr + ", sl*sr = " + (sl*sr));
762                        if (sl * sr <= 0) {
763                            //System.out.println("sl * sr <= 0: rar = " + rar.toScript());
764                            List<RealAlgebraicNumber<D>> ry = new ArrayList<RealAlgebraicNumber<D>>();
765                            ry.addAll(rx);
766                            ry.add(rr);
767                            rn.add(ry);
768                        }
769                    }
770                }
771            }
772            ran = rn;
773        }
774        if (logger.isInfoEnabled()) {
775            for (List<RealAlgebraicNumber<D>> rz : ran) {
776                List<Interval<D>> il = new ArrayList<Interval<D>>();
777                for (RealAlgebraicNumber<D> rr : rz) {
778                    il.add(rr.ring.getRoot());
779                }
780                logger.info("root-tuple = {}", il);
781            }
782        }
783        IdealWithRealAlgebraicRoots<D> Ir = new IdealWithRealAlgebraicRoots<D>(I, ran);
784        return Ir;
785    }
786
787
788    /**
789     * Construct real roots for zero dimensional ideal(G).
790     * @param I list of zero dimensional ideal with univariate irreducible
791     *            polynomials and bi-variate polynomials.
792     * @return list of real algebraic roots for all ideal(I_i)
793     */
794    public static <D extends GcdRingElem<D> & Rational> List<IdealWithRealAlgebraicRoots<D>> realAlgebraicRoots(
795                    List<IdealWithUniv<D>> I) {
796        List<IdealWithRealAlgebraicRoots<D>> lir = new ArrayList<IdealWithRealAlgebraicRoots<D>>(I.size());
797        for (IdealWithUniv<D> iu : I) {
798            IdealWithRealAlgebraicRoots<D> iur = PolyUtilApp.<D> realAlgebraicRoots(iu);
799            //System.out.println("iur = " + iur);
800            lir.add(iur);
801        }
802        return lir;
803    }
804
805
806    /**
807     * Construct complex roots for zero dimensional ideal(G).
808     * @param I zero dimensional ideal with univariate irreducible polynomials
809     *            and bi-variate polynomials.
810     * @return complex algebraic roots for ideal(G) <b>Note:</b> implementation
811     *         contains errors, do not use.
812     */
813    public static <D extends GcdRingElem<D> & Rational> IdealWithComplexAlgebraicRoots<D> complexAlgebraicRootsWrong( // Wrong
814                    IdealWithUniv<D> I) {
815        List<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>> can;
816        can = new ArrayList<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>>();
817        if (I == null) {
818            throw new IllegalArgumentException("null ideal not permitted");
819        }
820        if (I.ideal == null || I.upolys == null) {
821            throw new IllegalArgumentException("null ideal components not permitted " + I);
822        }
823        if (I.ideal.isZERO() || I.upolys.size() == 0) {
824            return new IdealWithComplexAlgebraicRoots<D>(I, can);
825        }
826        GenPolynomialRing<D> fac = I.ideal.list.ring;
827        if (fac.nvar == 0) {
828            return new IdealWithComplexAlgebraicRoots<D>(I, can);
829        }
830        if (fac.nvar != I.upolys.size()) {
831            throw new IllegalArgumentException("ideal not zero dimnsional: " + I);
832        }
833        // case i == 0:
834        GenPolynomial<D> p0 = I.upolys.get(0);
835        GenPolynomial<D> p0p = PolyUtil.<D> selectWithVariable(I.ideal.list.list, fac.nvar - 1);
836        if (p0p == null) {
837            throw new RuntimeException("no polynomial found in " + (fac.nvar - 1) + " of  " + I.ideal);
838        }
839        logger.info("p0  = {}, p0p = {}", p0, p0p);
840        int[] dep0 = p0p.degreeVector().dependencyOnVariables();
841        //System.out.println("dep0 = " + Arrays.toString(dep0));
842        if (dep0.length != 1) {
843            throw new RuntimeException("wrong number of variables " + Arrays.toString(dep0));
844        }
845        RingFactory<D> cfac = p0.ring.coFac;
846        ComplexRing<D> ccfac = new ComplexRing<D>(cfac);
847        GenPolynomialRing<Complex<D>> facc = new GenPolynomialRing<Complex<D>>(ccfac, p0.ring);
848        GenPolynomial<Complex<D>> p0c = PolyUtil.<D> complexFromAny(facc, p0);
849        List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cra;
850        cra = edu.jas.application.RootFactoryApp.<D> complexAlgebraicNumbersSquarefree(p0c);
851        logger.info("#roots(p0c) = {}", cra.size());
852        if (debug) {
853            boolean t = edu.jas.application.RootFactoryApp.<D> isRoot(p0c, cra);
854            if (!t) {
855                throw new RuntimeException("no roots of " + p0c);
856            }
857        }
858        for (Complex<edu.jas.application.RealAlgebraicNumber<D>> cr : cra) {
859            List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cl;
860            cl = new ArrayList<Complex<edu.jas.application.RealAlgebraicNumber<D>>>();
861            cl.add(cr);
862            can.add(cl);
863        }
864        if (fac.nvar == 1) {
865            return new IdealWithComplexAlgebraicRoots<D>(I, can);
866        }
867        // case i > 0:
868        for (int i = 1; i < I.upolys.size(); i++) {
869            List<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>> cn;
870            cn = new ArrayList<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>>();
871            GenPolynomial<D> pi = I.upolys.get(i);
872            GenPolynomial<D> pip = PolyUtil.selectWithVariable(I.ideal.list.list, fac.nvar - 1 - i);
873            if (pip == null) {
874                throw new RuntimeException(
875                                "no polynomial found in " + (fac.nvar - 1 - i) + " of  " + I.ideal);
876            }
877            logger.info("pi({}) = {}", i, pi);
878            logger.info("pip  = {}", pip);
879            facc = new GenPolynomialRing<Complex<D>>(ccfac, pi.ring);
880            GenPolynomial<Complex<D>> pic = PolyUtil.<D> complexFromAny(facc, pi);
881            int[] depi = pip.degreeVector().dependencyOnVariables();
882            //System.out.println("depi = " + Arrays.toString(depi));
883            if (depi.length < 1 || depi.length > 2) {
884                throw new RuntimeException(
885                                "wrong number of variables " + Arrays.toString(depi) + " for " + pip);
886            }
887            cra = edu.jas.application.RootFactoryApp.<D> complexAlgebraicNumbersSquarefree(pic);
888            logger.info("#roots(pic) = {}", cra.size());
889            if (debug) {
890                boolean t = edu.jas.application.RootFactoryApp.<D> isRoot(pic, cra);
891                if (!t) {
892                    throw new RuntimeException("no roots of " + pic);
893                }
894            }
895            if (depi.length == 1) {
896                // all combinations are roots of the ideal I
897                for (Complex<edu.jas.application.RealAlgebraicNumber<D>> cr : cra) {
898                    //System.out.println("cr.ring = " + cr.ring);
899                    for (List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cx : can) {
900                        //System.out.println("cx = " + cx);
901                        List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cy;
902                        cy = new ArrayList<Complex<edu.jas.application.RealAlgebraicNumber<D>>>();
903                        cy.addAll(cx);
904                        cy.add(cr);
905                        cn.add(cy);
906                    }
907                }
908            } else { // depi.length == 2
909                // select roots of the ideal I
910                GenPolynomial<D> pip2 = PolyUtil.<D> removeUnusedUpperVariables(pip);
911                GenPolynomialRing<GenPolynomial<D>> rfac = pip2.ring.recursive(1);
912                GenPolynomialRing<D> ufac = pip2.ring.contract(1);
913                GenPolynomialRing<Complex<D>> ucfac = new GenPolynomialRing<Complex<D>>(ccfac, ufac);
914                GenPolynomialRing<Complex<D>> c2fac = new GenPolynomialRing<Complex<D>>(ccfac, pip2.ring);
915                GenPolynomial<Complex<D>> pip2c = PolyUtil.<D> complexFromAny(c2fac, pip2);
916                //System.out.println("pip2c = " + pip2c);
917                GenPolynomialRing<GenPolynomial<Complex<D>>> rcfac;
918                rcfac = new GenPolynomialRing<GenPolynomial<Complex<D>>>(ucfac, rfac);
919                GenPolynomial<GenPolynomial<Complex<D>>> pip2cr = PolyUtil.<Complex<D>> recursive(rcfac,
920                                pip2c);
921                //System.out.println("pip2cr = " + pip2cr);
922
923                int ix = fac.nvar - 1 - depi[depi.length - 1];
924                //System.out.println("ix = " + ix);
925                for (Complex<edu.jas.application.RealAlgebraicNumber<D>> cr : cra) {
926                    System.out.println("cr = " + toString(cr)); // <----------------------------------
927                    edu.jas.application.RealAlgebraicRing<D> cring = (edu.jas.application.RealAlgebraicRing<D>) cr.ring.ring;
928                    RealRootTuple<D> rroot = cring.getRoot();
929                    List<RealAlgebraicNumber<D>> rlist = rroot.tuple;
930                    Interval<D> vr = rlist.get(0).ring.getRoot();
931                    Interval<D> vi = rlist.get(1).ring.getRoot();
932                    logger.info("vr = {}, vi = {}", vr, vi);
933                    if (vr.length().isZERO()) {
934                        D e = vr.left.factory().parse("1/2");
935                        D m = vr.left; //middle();
936                        vr = new Interval<D>(m.subtract(e), m.sum(e));
937                        logger.info("|vr| == 0: {}", vr);
938                    }
939                    if (vi.length().isZERO()) {
940                        D e = vi.left.factory().parse("1/2");
941                        D m = vi.left; //middle();
942                        vi = new Interval<D>(m.subtract(e), m.sum(e));
943                        logger.info("|vi| == 0: {}", vi);
944                    }
945                    Complex<D> sw = new Complex<D>(ccfac, vr.left, vi.left);
946                    Complex<D> ne = new Complex<D>(ccfac, vr.right, vi.right);
947                    logger.info("sw   = {}, ne   = {}", toString1(sw), toString1(ne));
948                    GenPolynomial<Complex<D>> pip2cesw, pip2cene;
949                    pip2cesw = PolyUtil.<Complex<D>> evaluateMainRecursive(ucfac, pip2cr, sw);
950                    pip2cene = PolyUtil.<Complex<D>> evaluateMainRecursive(ucfac, pip2cr, ne);
951                    GenPolynomialRing<D> upfac = I.upolys.get(ix).ring;
952                    GenPolynomialRing<Complex<D>> upcfac = new GenPolynomialRing<Complex<D>>(ccfac, upfac);
953                    //System.out.println("upfac = " + upfac);
954                    //System.out.println("upcfac = " + upcfac);
955                    GenPolynomial<Complex<D>> pip2eswc = convertComplexComplex(upcfac, pip2cesw);
956                    GenPolynomial<Complex<D>> pip2enec = convertComplexComplex(upcfac, pip2cene);
957                    //System.out.println("pip2eswc = " + pip2eswc);
958                    //System.out.println("pip2enec = " + pip2enec);
959                    for (List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cx : can) {
960                        //System.out.println("cxi = " + toString(cx.get(ix)));
961                        Complex<edu.jas.application.RealAlgebraicNumber<D>> cax = cx.get(ix);
962                        ComplexRing<edu.jas.application.RealAlgebraicNumber<D>> car = cax.ring;
963                        edu.jas.application.RealAlgebraicRing<D> rar = (edu.jas.application.RealAlgebraicRing<D>) car.ring;
964                        //System.out.println("car = " + car);
965                        //System.out.println("rar = " + rar);
966                        TermOrder to = new TermOrder(TermOrder.INVLEX);
967                        String vvr = rar.algebraic.ring.getVars()[0];
968                        String vvi = rar.algebraic.ring.getVars()[1];
969                        String[] vars = new String[] { vvr, vvi };
970                        GenPolynomialRing<Complex<D>> tfac = new GenPolynomialRing<Complex<D>>(ccfac, to,
971                                        vars);
972                        GenPolynomial<Complex<D>> t = tfac.univariate(1, 1L)
973                                        .sum(tfac.univariate(0, 1L).multiply(ccfac.getIMAG()));
974                        //System.out.println("t  = " + t); // t = x + i y
975                        GenPolynomialRing<D> rtfac = new GenPolynomialRing<D>(cfac, tfac);
976                        GenPolynomial<Complex<D>> su;
977                        GenPolynomial<D> re, im;
978                        su = PolyUtil.<Complex<D>> substituteUnivariate(pip2eswc, t);
979                        //su = su.monic(); not here
980                        re = PolyUtil.<D> realPartFromComplex(rtfac, su);
981                        im = PolyUtil.<D> imaginaryPartFromComplex(rtfac, su);
982                        //System.out.println("re = " + re);
983                        //System.out.println("im = " + im);
984                        edu.jas.application.RealAlgebraicNumber<D> resw, imsw, rene, imne;
985                        resw = new edu.jas.application.RealAlgebraicNumber<D>(rar, re);
986                        //System.out.println("resw = " + resw);
987                        int sswr = resw.signum();
988                        imsw = new edu.jas.application.RealAlgebraicNumber<D>(rar, im);
989                        //System.out.println("imsw = " + imsw);
990                        int sswi = imsw.signum();
991                        su = PolyUtil.<Complex<D>> substituteUnivariate(pip2enec, t);
992                        //su = su.monic(); not here
993                        re = PolyUtil.<D> realPartFromComplex(rtfac, su);
994                        im = PolyUtil.<D> imaginaryPartFromComplex(rtfac, su);
995                        //System.out.println("re = " + re);
996                        //System.out.println("im = " + im);
997                        rene = new edu.jas.application.RealAlgebraicNumber<D>(rar, re);
998                        //System.out.println("rene = " + rene);
999                        int sner = rene.signum();
1000                        imne = new edu.jas.application.RealAlgebraicNumber<D>(rar, im);
1001                        //System.out.println("imne = " + imne);
1002                        int snei = imne.signum();
1003                        //System.out.println("sswr = " + sswr + ", sswi = " + sswi);
1004                        //System.out.println("sner = " + sner + ", snei = " + snei);
1005                        if ((sswr * sner <= 0 && sswi * snei <= 0)) { // wrong !
1006                            logger.info("   hit, cxi = {}, cr = {}", toString(cx.get(ix)), toString(cr));
1007                            List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cy;
1008                            cy = new ArrayList<Complex<edu.jas.application.RealAlgebraicNumber<D>>>();
1009                            cy.addAll(cx);
1010                            cy.add(cr);
1011                            cn.add(cy);
1012                        } else {
1013                            logger.info("no hit, cxi = {}, cr = {}", toString(cx.get(ix)), toString(cr));
1014                        }
1015                    }
1016                }
1017            }
1018            can = cn;
1019        }
1020        IdealWithComplexAlgebraicRoots<D> Ic = new IdealWithComplexAlgebraicRoots<D>(I, can);
1021        return Ic;
1022    }
1023
1024
1025    /**
1026     * Construct complex roots for zero dimensional ideal(G).
1027     * @param I zero dimensional ideal with univariate irreducible polynomials
1028     *            and bi-variate polynomials.
1029     * @return complex algebraic roots for ideal(G) <b>Note:</b> not jet
1030     *         completed oin all cases.
1031     */
1032    public static <D extends GcdRingElem<D> & Rational> IdealWithComplexAlgebraicRoots<D> complexAlgebraicRoots(
1033                    IdealWithUniv<D> I) {
1034        List<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>> can;
1035        can = new ArrayList<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>>();
1036        if (I == null) {
1037            throw new IllegalArgumentException("null ideal not permitted");
1038        }
1039        if (I.ideal == null || I.upolys == null) {
1040            throw new IllegalArgumentException("null ideal components not permitted " + I);
1041        }
1042        if (I.ideal.isZERO() || I.upolys.size() == 0) {
1043            return new IdealWithComplexAlgebraicRoots<D>(I, can);
1044        }
1045        GenPolynomialRing<D> fac = I.ideal.list.ring;
1046        if (fac.nvar == 0) {
1047            return new IdealWithComplexAlgebraicRoots<D>(I, can);
1048        }
1049        if (fac.nvar != I.upolys.size()) {
1050            throw new IllegalArgumentException("ideal not zero dimnsional: " + I);
1051        }
1052        // case i == 0:
1053        GenPolynomial<D> p0 = I.upolys.get(0);
1054        GenPolynomial<D> p0p = PolyUtil.<D> selectWithVariable(I.ideal.list.list, fac.nvar - 1);
1055        if (p0p == null) {
1056            throw new RuntimeException("no polynomial found in " + (fac.nvar - 1) + " of  " + I.ideal);
1057        }
1058        logger.info("p0  = {}, p0p = {}", p0, p0p);
1059        int[] dep0 = p0p.degreeVector().dependencyOnVariables();
1060        //System.out.println("dep0 = " + Arrays.toString(dep0));
1061        if (dep0.length != 1) {
1062            throw new RuntimeException("wrong number of variables " + Arrays.toString(dep0));
1063        }
1064        RingFactory<D> cfac = p0.ring.coFac;
1065        ComplexRing<D> ccfac = new ComplexRing<D>(cfac);
1066        GenPolynomialRing<Complex<D>> facc = new GenPolynomialRing<Complex<D>>(ccfac, p0.ring);
1067        GenPolynomial<Complex<D>> p0c = PolyUtil.<D> complexFromAny(facc, p0);
1068        List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cra;
1069        cra = edu.jas.application.RootFactoryApp.<D> complexAlgebraicNumbersSquarefree(p0c);
1070        logger.info("#roots(p0c) = {}", cra.size());
1071        for (Complex<edu.jas.application.RealAlgebraicNumber<D>> cr : cra) {
1072            List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cl;
1073            cl = new ArrayList<Complex<edu.jas.application.RealAlgebraicNumber<D>>>();
1074            cl.add(cr);
1075            can.add(cl);
1076        }
1077        if (fac.nvar == 1) {
1078            return new IdealWithComplexAlgebraicRoots<D>(I, can);
1079        }
1080        // case i > 0:
1081        for (int i = 1; i < I.upolys.size(); i++) {
1082            List<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>> cn;
1083            cn = new ArrayList<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>>();
1084            GenPolynomial<D> pi = I.upolys.get(i);
1085            GenPolynomial<D> pip = PolyUtil.selectWithVariable(I.ideal.list.list, fac.nvar - 1 - i);
1086            if (pip == null) {
1087                throw new RuntimeException(
1088                                "no polynomial found in " + (fac.nvar - 1 - i) + " of  " + I.ideal);
1089            }
1090            if (logger.isInfoEnabled()) {
1091                logger.info("pi({}) = {}", i, pi);
1092                logger.info("pip  = {}", pip);
1093            }
1094            facc = new GenPolynomialRing<Complex<D>>(ccfac, pi.ring);
1095            GenPolynomial<Complex<D>> pic = PolyUtil.<D> complexFromAny(facc, pi);
1096            int[] depi = pip.degreeVector().dependencyOnVariables();
1097            //System.out.println("depi = " + Arrays.toString(depi));
1098            if (depi.length < 1 || depi.length > 2) {
1099                throw new RuntimeException(
1100                                "wrong number of variables " + Arrays.toString(depi) + " for " + pip);
1101            }
1102            cra = edu.jas.application.RootFactoryApp.<D> complexAlgebraicNumbersSquarefree(pic);
1103            logger.info("#roots(pic) = {}", cra.size());
1104            if (depi.length == 1) {
1105                // all combinations are roots of the ideal I
1106                for (Complex<edu.jas.application.RealAlgebraicNumber<D>> cr : cra) {
1107                    //System.out.println("cr.ring = " + cr.ring);
1108                    for (List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cx : can) {
1109                        //System.out.println("cx = " + cx);
1110                        List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cy;
1111                        cy = new ArrayList<Complex<edu.jas.application.RealAlgebraicNumber<D>>>();
1112                        cy.addAll(cx);
1113                        cy.add(cr);
1114                        cn.add(cy);
1115                    }
1116                }
1117            } else { // depi.length == 2
1118                // select roots of the ideal I
1119                GenPolynomial<D> pip2 = PolyUtil.<D> removeUnusedUpperVariables(pip);
1120                pip2 = PolyUtil.<D> removeUnusedLowerVariables(pip2);
1121                pip2 = PolyUtil.<D> removeUnusedMiddleVariables(pip2);
1122                GenPolynomialRing<GenPolynomial<D>> rfac = pip2.ring.recursive(1);
1123                GenPolynomialRing<D> ufac = pip2.ring.contract(1);
1124                GenPolynomialRing<Complex<D>> ucfac = new GenPolynomialRing<Complex<D>>(ccfac, ufac);
1125                GenPolynomialRing<Complex<D>> c2fac = new GenPolynomialRing<Complex<D>>(ccfac, pip2.ring);
1126                GenPolynomial<Complex<D>> pip2c = PolyUtil.<D> complexFromAny(c2fac, pip2);
1127                GenPolynomialRing<GenPolynomial<Complex<D>>> rcfac;
1128                rcfac = new GenPolynomialRing<GenPolynomial<Complex<D>>>(ucfac, rfac);
1129                GenPolynomial<GenPolynomial<Complex<D>>> pip2cr = PolyUtil.<Complex<D>> recursive(rcfac,
1130                                pip2c);
1131                //System.out.println("pip2cr = " + pip2cr);
1132                int ix = fac.nvar - 1 - depi[depi.length - 1];
1133                //System.out.println("ix = " + ix);
1134                for (Complex<edu.jas.application.RealAlgebraicNumber<D>> cr : cra) {
1135                    //System.out.println("cr = " + toString(cr)); 
1136                    edu.jas.application.RealAlgebraicRing<D> cring = (edu.jas.application.RealAlgebraicRing<D>) cr.ring.ring;
1137                    RealRootTuple<D> rroot = cring.getRoot();
1138                    List<RealAlgebraicNumber<D>> rlist = rroot.tuple;
1139                    //System.out.println("rlist = " + rlist);
1140                    Interval<D> vr = rlist.get(0).ring.getRoot();
1141                    Interval<D> vi = rlist.get(1).ring.getRoot();
1142                    //logger.info("vr = {}, vi = {}", vr, vi);
1143                    edu.jas.application.RealAlgebraicNumber<D> vrl, vil, vrr, vir;
1144                    vrl = new edu.jas.application.RealAlgebraicNumber<D>(cring, vr.left);
1145                    vil = new edu.jas.application.RealAlgebraicNumber<D>(cring, vi.left);
1146                    vrr = new edu.jas.application.RealAlgebraicNumber<D>(cring, vr.right);
1147                    vir = new edu.jas.application.RealAlgebraicNumber<D>(cring, vi.right);
1148                    ComplexRing<edu.jas.application.RealAlgebraicNumber<D>> crr;
1149                    crr = new ComplexRing<edu.jas.application.RealAlgebraicNumber<D>>(cring);
1150                    Complex<edu.jas.application.RealAlgebraicNumber<D>> csw, cne;
1151                    csw = new Complex<edu.jas.application.RealAlgebraicNumber<D>>(crr, vrl, vil);
1152                    cne = new Complex<edu.jas.application.RealAlgebraicNumber<D>>(crr, vrr, vir);
1153                    //logger.info("csw  = {}, cne  = {}", toString(csw), toString(cne));
1154                    Rectangle<edu.jas.application.RealAlgebraicNumber<D>> rec;
1155                    rec = new Rectangle<edu.jas.application.RealAlgebraicNumber<D>>(csw, cne);
1156                    //System.out.println("rec = " + rec);
1157                    for (List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cx : can) {
1158                        Complex<edu.jas.application.RealAlgebraicNumber<D>> cax = cx.get(ix);
1159                        //System.out.println("cax = " + toString(cax));
1160                        ComplexRing<edu.jas.application.RealAlgebraicNumber<D>> car = cax.ring;
1161                        //System.out.println("car = " + car);
1162                        GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<D>>> pcrfac;
1163                        pcrfac = new GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<D>>>(
1164                                        car, rcfac);
1165                        GenPolynomial<Complex<edu.jas.application.RealAlgebraicNumber<D>>> pcr;
1166                        pcr = evaluateToComplexRealCoefficients(pcrfac, pip2cr, cax);
1167                        //System.out.println("pcr = " + pcr);
1168                        ComplexRoots<edu.jas.application.RealAlgebraicNumber<D>> rengine;
1169                        rengine = new ComplexRootsSturm<edu.jas.application.RealAlgebraicNumber<D>>(car);
1170                        long nr = 0;
1171                        try {
1172                            nr = rengine.complexRootCount(rec, pcr);
1173                            //logger.info("rootCount = {}", nr);
1174                        } catch (InvalidBoundaryException e) {
1175                            e.printStackTrace();
1176                        }
1177                        if (nr == 1) { // one root
1178                            logger.info("   hit, cxi = {}, cr = {}", toString(cx.get(ix)), toString(cr));
1179                            List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cy;
1180                            cy = new ArrayList<Complex<edu.jas.application.RealAlgebraicNumber<D>>>();
1181                            cy.addAll(cx);
1182                            cy.add(cr);
1183                            cn.add(cy);
1184                        } else if (nr > 1) {
1185                            logger.error("to many roots, cxi = {}, cr = {}", toString(cx.get(ix)), toString(cr));
1186                        } else { // no root
1187                            logger.info("no hit, cxi = {}, cr = {}", toString(cx.get(ix)), toString(cr));
1188                        }
1189                    }
1190                }
1191            }
1192            can = cn;
1193        }
1194        IdealWithComplexAlgebraicRoots<D> Ic = new IdealWithComplexAlgebraicRoots<D>(I, can);
1195        return Ic;
1196    }
1197
1198
1199    /**
1200     * String representation of a deximal approximation of a complex number.
1201     * @param c compelx number.
1202     * @return String representation of c
1203     */
1204    public static <D extends GcdRingElem<D> & Rational> String toString(
1205                    Complex<edu.jas.application.RealAlgebraicNumber<D>> c) {
1206        edu.jas.application.RealAlgebraicNumber<D> re = c.getRe();
1207        edu.jas.application.RealAlgebraicNumber<D> im = c.getIm();
1208        String s = re.decimalMagnitude().toString();
1209        if (!im.isZERO()) {
1210            s = s + "i" + im.decimalMagnitude();
1211        }
1212        return s;
1213    }
1214
1215
1216    /**
1217     * String representation of a deximal approximation of a complex number.
1218     * @param c compelx number.
1219     * @return String representation of c
1220     */
1221    public static <D extends GcdRingElem<D> & Rational> String toString1(Complex<D> c) {
1222        D re = c.getRe();
1223        D im = c.getIm();
1224        String s = new BigDecimal(re.getRational()).toString();
1225        if (!im.isZERO()) {
1226            s = s + "i" + new BigDecimal(im.getRational());
1227        }
1228        return s;
1229    }
1230
1231
1232    /**
1233     * Construct complex roots for zero dimensional ideal(G).
1234     * @param I list of zero dimensional ideal with univariate irreducible
1235     *            polynomials and bi-variate polynomials.
1236     * @return list of complex algebraic roots for ideal(G)
1237     */
1238    public static <D extends GcdRingElem<D> & Rational> List<IdealWithComplexAlgebraicRoots<D>> complexAlgebraicRoots(
1239                    List<IdealWithUniv<D>> I) {
1240        List<IdealWithComplexAlgebraicRoots<D>> lic = new ArrayList<IdealWithComplexAlgebraicRoots<D>>();
1241        for (IdealWithUniv<D> iu : I) {
1242            IdealWithComplexAlgebraicRoots<D> iuc = PolyUtilApp.<D> complexAlgebraicRoots(iu);
1243            //System.out.println("iuc = " + iuc);
1244            lic.add(iuc);
1245        }
1246        return lic;
1247    }
1248
1249
1250    /**
1251     * Construct exact set of complex roots for zero dimensional ideal(G).
1252     * @param I zero dimensional ideal.
1253     * @return list of coordinates of complex roots for ideal(G)
1254     */
1255    public static <D extends GcdRingElem<D> & Rational> List<IdealWithComplexAlgebraicRoots<D>> complexAlgebraicRoots(
1256                    Ideal<D> I) {
1257        List<IdealWithUniv<D>> Ir = I.zeroDimRootDecomposition();
1258        //System.out.println("Ir = " + Ir);
1259        List<IdealWithComplexAlgebraicRoots<D>> roots = PolyUtilApp.<D> complexAlgebraicRoots(Ir);
1260        return roots;
1261    }
1262
1263
1264    /*
1265     * Convert to a polynomial in given ring.
1266     * @param fac result polynomial ring.
1267     * @param p polynomial.
1268     * @return polynomial in ring fac <b>Note: </b> if p can not be represented
1269     *         in fac then the results are unpredictable.
1270     */
1271    static <C extends RingElem<C>> GenPolynomial<C> convert(GenPolynomialRing<C> fac, GenPolynomial<C> p) {
1272        if (fac.equals(p.factory())) {
1273            return p;
1274        }
1275        GenPolynomial<C> q = fac.parse(p.toString());
1276        if (!q.toString().equals(p.toString())) {
1277            throw new RuntimeException("convert(" + p + ") = " + q);
1278        }
1279        return q;
1280    }
1281
1282
1283    /*
1284     * Convert to a polynomial in given ring.
1285     * @param fac result polynomial ring.
1286     * @param p polynomial.
1287     * @return polynomial in ring fac <b>Note: </b> if p can not be represented
1288     *         in fac then the results are unpredictable.
1289     */
1290    static <C extends RingElem<C>> GenPolynomial<Complex<C>> convertComplex(GenPolynomialRing<Complex<C>> fac,
1291                    GenPolynomial<C> p) {
1292        GenPolynomial<Complex<C>> q = fac.parse(p.toString());
1293        if (!q.toString().equals(p.toString())) {
1294            throw new RuntimeException("convert(" + p + ") = " + q);
1295        }
1296        return q;
1297    }
1298
1299
1300    /*
1301     * Convert to a polynomial in given ring.
1302     * @param fac result polynomial ring.
1303     * @param p complex polynomial.
1304     * @return polynomial in ring fac <b>Note: </b> if p can not be represented
1305     *         in fac then the results are unpredictable.
1306     */
1307    static <C extends RingElem<C>> GenPolynomial<Complex<C>> convertComplexComplex(
1308                    GenPolynomialRing<Complex<C>> fac, GenPolynomial<Complex<C>> p) {
1309        if (fac.equals(p.factory())) {
1310            return p;
1311        }
1312        GenPolynomial<Complex<C>> q = fac.parse(p.toString());
1313        if (!q.toString().equals(p.toString())) {
1314            throw new RuntimeException("convert(" + p + ") = " + q);
1315        }
1316        return q;
1317    }
1318
1319
1320    /**
1321     * Construct exact set of real roots for zero dimensional ideal(G).
1322     * @param I zero dimensional ideal.
1323     * @return list of coordinates of real roots for ideal(G)
1324     */
1325    public static <D extends GcdRingElem<D> & Rational> List<IdealWithRealAlgebraicRoots<D>> realAlgebraicRoots(
1326                    Ideal<D> I) {
1327        List<IdealWithUniv<D>> Ir = I.zeroDimRootDecomposition();
1328        //System.out.println("Ir = " + Ir);
1329        List<IdealWithRealAlgebraicRoots<D>> roots = PolyUtilApp.<D> realAlgebraicRoots(Ir);
1330        return roots;
1331    }
1332
1333
1334    /**
1335     * Construct primitive element for double field extension.
1336     * @param a algebraic number ring with squarefree monic minimal polynomial
1337     * @param b algebraic number ring with squarefree monic minimal polynomial
1338     * @return primitive element container with algebraic number ring c, with
1339     *         Q(c) = Q(a,b)
1340     */
1341    public static <C extends GcdRingElem<C>> PrimitiveElement<C> primitiveElement(AlgebraicNumberRing<C> a,
1342                    AlgebraicNumberRing<C> b) {
1343        GenPolynomial<C> ap = a.modul;
1344        GenPolynomial<C> bp = b.modul;
1345
1346        // setup bivariate polynomial ring
1347        String[] cv = new String[2];
1348        cv[0] = ap.ring.getVars()[0];
1349        cv[1] = bp.ring.getVars()[0];
1350        TermOrder to = new TermOrder(TermOrder.INVLEX);
1351        GenPolynomialRing<C> cfac = new GenPolynomialRing<C>(ap.ring.coFac, 2, to, cv);
1352        GenPolynomial<C> as = ap.extendUnivariate(cfac, 0);
1353        GenPolynomial<C> bs = bp.extendUnivariate(cfac, 1);
1354        List<GenPolynomial<C>> L = new ArrayList<GenPolynomial<C>>(2);
1355        L.add(as);
1356        L.add(bs);
1357        List<GenPolynomial<C>> Op = new ArrayList<GenPolynomial<C>>();
1358
1359        Ideal<C> id = new Ideal<C>(cfac, L);
1360        //System.out.println("id = " + id);
1361        IdealWithUniv<C> iu = id.normalPositionFor(0, 1, Op);
1362        //System.out.println("iu = " + iu);
1363
1364        // extract result polynomials
1365        List<GenPolynomial<C>> Np = iu.ideal.getList();
1366        //System.out.println("Np = " + Np);
1367        as = PolyUtil.<C> selectWithVariable(Np, 1);
1368        bs = PolyUtil.<C> selectWithVariable(Np, 0);
1369        GenPolynomial<C> cs = PolyUtil.<C> selectWithVariable(Np, 2);
1370        //System.out.println("as = " + as);
1371        //System.out.println("bs = " + bs);
1372        //System.out.println("cs = " + cs);
1373        String[] ev = new String[] { cs.ring.getVars()[0] };
1374        GenPolynomialRing<C> efac = new GenPolynomialRing<C>(ap.ring.coFac, 1, to, ev);
1375        //System.out.println("efac = " + efac);
1376        cs = cs.contractCoeff(efac);
1377        //System.out.println("cs = " + cs);
1378        as = as.reductum().contractCoeff(efac);
1379        as = as.negate();
1380        //System.out.println("as = " + as);
1381        bs = bs.reductum().contractCoeff(efac);
1382        bs = bs.negate();
1383        //System.out.println("bs = " + bs);
1384        AlgebraicNumberRing<C> c = new AlgebraicNumberRing<C>(cs);
1385        AlgebraicNumber<C> ab = new AlgebraicNumber<C>(c, as);
1386        AlgebraicNumber<C> bb = new AlgebraicNumber<C>(c, bs);
1387        PrimitiveElement<C> pe = new PrimitiveElement<C>(c, ab, bb, a, b);
1388        logger.info("primitive element = {}", c);
1389        return pe;
1390    }
1391
1392
1393    /**
1394     * Convert to primitive element ring.
1395     * @param cfac primitive element ring.
1396     * @param A algebraic number representing the generating element of a in the
1397     *            new ring.
1398     * @param a algebraic number to convert.
1399     * @return a converted to the primitive element ring
1400     */
1401    public static <C extends GcdRingElem<C>> AlgebraicNumber<C> convertToPrimitiveElem(
1402                    AlgebraicNumberRing<C> cfac, AlgebraicNumber<C> A, AlgebraicNumber<C> a) {
1403        GenPolynomialRing<C> aufac = a.ring.ring;
1404        GenPolynomialRing<AlgebraicNumber<C>> ar = new GenPolynomialRing<AlgebraicNumber<C>>(cfac, aufac);
1405        GenPolynomial<AlgebraicNumber<C>> aps = PolyUtil.<C> convertToAlgebraicCoefficients(ar, a.val);
1406        AlgebraicNumber<C> ac = PolyUtil.<AlgebraicNumber<C>> evaluateMain(cfac, aps, A);
1407        return ac;
1408    }
1409
1410
1411    /**
1412     * Convert coefficients to primitive element ring.
1413     * @param cfac primitive element ring.
1414     * @param A algebraic number representing the generating element of a in the
1415     *            new ring.
1416     * @param a polynomial with coefficients algebraic number to convert.
1417     * @return a with coefficients converted to the primitive element ring
1418     */
1419    public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> convertToPrimitiveElem(
1420                    AlgebraicNumberRing<C> cfac, AlgebraicNumber<C> A, GenPolynomial<AlgebraicNumber<C>> a) {
1421        GenPolynomialRing<AlgebraicNumber<C>> cr = new GenPolynomialRing<AlgebraicNumber<C>>(cfac, a.ring);
1422        return PolyUtil.<AlgebraicNumber<C>, AlgebraicNumber<C>> map(cr, a, new CoeffConvertAlg<C>(cfac, A));
1423    }
1424
1425
1426    /**
1427     * Convert to primitive element ring.
1428     * @param cfac primitive element ring.
1429     * @param A algebraic number representing the generating element of a in the
1430     *            new ring.
1431     * @param a recursive algebraic number to convert.
1432     * @return a converted to the primitive element ring
1433     */
1434    public static <C extends GcdRingElem<C>> AlgebraicNumber<C> convertToPrimitiveElem(
1435                    AlgebraicNumberRing<C> cfac, AlgebraicNumber<C> A, AlgebraicNumber<C> B,
1436                    AlgebraicNumber<AlgebraicNumber<C>> a) {
1437        GenPolynomial<AlgebraicNumber<C>> aps = PolyUtilApp.<C> convertToPrimitiveElem(cfac, A, a.val);
1438        AlgebraicNumber<C> ac = PolyUtil.<AlgebraicNumber<C>> evaluateMain(cfac, aps, B);
1439        return ac;
1440    }
1441
1442
1443    /**
1444     * Construct primitive element for double field extension.
1445     * @param b algebraic number ring with squarefree monic minimal polynomial
1446     *            over Q(a)
1447     * @return primitive element container with algebraic number ring c, with
1448     *         Q(c) = Q(a)(b)
1449     */
1450    public static <C extends GcdRingElem<C>> PrimitiveElement<C> primitiveElement(
1451                    AlgebraicNumberRing<AlgebraicNumber<C>> b) {
1452        GenPolynomial<AlgebraicNumber<C>> bp = b.modul;
1453        AlgebraicNumberRing<C> a = (AlgebraicNumberRing<C>) b.ring.coFac;
1454        GenPolynomial<C> ap = a.modul;
1455
1456        // setup bivariate polynomial ring
1457        String[] cv = new String[2];
1458        cv[0] = ap.ring.getVars()[0];
1459        cv[1] = bp.ring.getVars()[0];
1460        TermOrder to = new TermOrder(TermOrder.INVLEX);
1461        GenPolynomialRing<C> cfac = new GenPolynomialRing<C>(ap.ring.coFac, 2, to, cv);
1462        GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(a.ring, 1,
1463                        bp.ring.getVars());
1464        GenPolynomial<C> as = ap.extendUnivariate(cfac, 0);
1465        GenPolynomial<GenPolynomial<C>> bss = PolyUtil.<C> fromAlgebraicCoefficients(rfac, bp);
1466        GenPolynomial<C> bs = PolyUtil.<C> distribute(cfac, bss);
1467        List<GenPolynomial<C>> L = new ArrayList<GenPolynomial<C>>(2);
1468        L.add(as);
1469        L.add(bs);
1470        List<GenPolynomial<C>> Op = new ArrayList<GenPolynomial<C>>();
1471
1472        Ideal<C> id = new Ideal<C>(cfac, L);
1473        //System.out.println("id = " + id);
1474        IdealWithUniv<C> iu = id.normalPositionFor(0, 1, Op);
1475        //System.out.println("iu = " + iu);
1476
1477        // extract result polynomials
1478        List<GenPolynomial<C>> Np = iu.ideal.getList();
1479        as = PolyUtil.<C> selectWithVariable(Np, 1);
1480        bs = PolyUtil.<C> selectWithVariable(Np, 0);
1481        GenPolynomial<C> cs = PolyUtil.<C> selectWithVariable(Np, 2);
1482        //System.out.println("as = " + as);
1483        //System.out.println("bs = " + bs);
1484        //System.out.println("cs = " + cs);
1485        String[] ev = new String[] { cs.ring.getVars()[0] };
1486        GenPolynomialRing<C> efac = new GenPolynomialRing<C>(ap.ring.coFac, 1, to, ev);
1487        // System.out.println("efac = " + efac);
1488        cs = cs.contractCoeff(efac);
1489        // System.out.println("cs = " + cs);
1490        as = as.reductum().contractCoeff(efac);
1491        as = as.negate();
1492        // System.out.println("as = " + as);
1493        bs = bs.reductum().contractCoeff(efac);
1494        bs = bs.negate();
1495        //System.out.println("bs = " + bs);
1496        AlgebraicNumberRing<C> c = new AlgebraicNumberRing<C>(cs);
1497        AlgebraicNumber<C> ab = new AlgebraicNumber<C>(c, as);
1498        AlgebraicNumber<C> bb = new AlgebraicNumber<C>(c, bs);
1499        PrimitiveElement<C> pe = new PrimitiveElement<C>(c, ab, bb); // missing ,a,b);
1500        logger.info("primitive element = {}", pe);
1501        return pe;
1502    }
1503
1504
1505    /**
1506     * Convert to primitive element ring.
1507     * @param cfac primitive element ring.
1508     * @param A algebraic number representing the generating element of a in the
1509     *            new ring.
1510     * @param a polynomial with recursive algebraic number coefficients to
1511     *            convert.
1512     * @return a converted to the primitive element ring
1513     */
1514    public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> convertToPrimitiveElem(
1515                    AlgebraicNumberRing<C> cfac, AlgebraicNumber<C> A, AlgebraicNumber<C> B,
1516                    GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>> a) {
1517        GenPolynomialRing<AlgebraicNumber<C>> cr = new GenPolynomialRing<AlgebraicNumber<C>>(cfac, a.ring);
1518        return PolyUtil.<AlgebraicNumber<AlgebraicNumber<C>>, AlgebraicNumber<C>> map(cr, a,
1519                        new CoeffRecConvertAlg<C>(cfac, A, B));
1520    }
1521
1522
1523    /**
1524     * Convert to RealAlgebraicNumber coefficients. Represent as polynomial with
1525     * RealAlgebraicNumber<C> coefficients from package
1526     * <code>edu.jas.root.</code>
1527     * @param afac result polynomial factory.
1528     * @param A polynomial with RealAlgebraicNumber&lt;C&gt; coefficients to be
1529     *            converted.
1530     * @return polynomial with RealAlgebraicNumber&lt;C&gt; coefficients.
1531     */
1532    public static <C extends GcdRingElem<C> & Rational> GenPolynomial<edu.jas.root.RealAlgebraicNumber<C>> realAlgFromRealCoefficients(
1533                    GenPolynomialRing<edu.jas.root.RealAlgebraicNumber<C>> afac,
1534                    GenPolynomial<edu.jas.application.RealAlgebraicNumber<C>> A) {
1535        edu.jas.root.RealAlgebraicRing<C> cfac = (edu.jas.root.RealAlgebraicRing<C>) afac.coFac;
1536        return PolyUtil.<edu.jas.application.RealAlgebraicNumber<C>, edu.jas.root.RealAlgebraicNumber<C>> map(
1537                        afac, A, new ReAlgFromRealCoeff<C>(cfac));
1538    }
1539
1540
1541    /**
1542     * Convert to RealAlgebraicNumber coefficients. Represent as polynomial with
1543     * RealAlgebraicNumber<C> coefficients from package
1544     * 
1545     * <pre>
1546     * edu.jas.application
1547     * </pre>
1548     * 
1549     * .
1550     * @param rfac result polynomial factory.
1551     * @param A polynomial with RealAlgebraicNumber&lt;C&gt; coefficients to be
1552     *            converted.
1553     * @return polynomial with RealAlgebraicNumber&lt;C&gt; coefficients.
1554     */
1555    public static <C extends GcdRingElem<C> & Rational> GenPolynomial<edu.jas.application.RealAlgebraicNumber<C>> realFromRealAlgCoefficients(
1556                    GenPolynomialRing<edu.jas.application.RealAlgebraicNumber<C>> rfac,
1557                    GenPolynomial<edu.jas.root.RealAlgebraicNumber<C>> A) {
1558        edu.jas.application.RealAlgebraicRing<C> cfac = (edu.jas.application.RealAlgebraicRing<C>) rfac.coFac;
1559        return PolyUtil.<edu.jas.root.RealAlgebraicNumber<C>, edu.jas.application.RealAlgebraicNumber<C>> map(
1560                        rfac, A, new RealFromReAlgCoeff<C>(cfac));
1561    }
1562
1563
1564    /**
1565     * Convert to Complex&lt;RealAlgebraicNumber&gt; coefficients. Represent as
1566     * polynomial with Complex&lt;RealAlgebraicNumber&gt; coefficients, C is
1567     * e.g. BigRational.
1568     * @param pfac result polynomial factory.
1569     * @param A polynomial with Complex coefficients to be converted.
1570     * @return polynomial with Complex&lt;RealAlgebraicNumber&gt; coefficients.
1571     */
1572    public static <C extends GcdRingElem<C> & Rational> GenPolynomial<Complex<edu.jas.application.RealAlgebraicNumber<C>>> convertToComplexRealCoefficients(
1573                    GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<C>>> pfac,
1574                    GenPolynomial<Complex<C>> A) {
1575        ComplexRing<edu.jas.application.RealAlgebraicNumber<C>> afac;
1576        afac = (ComplexRing<edu.jas.application.RealAlgebraicNumber<C>>) pfac.coFac;
1577        return PolyUtil.<Complex<C>, Complex<edu.jas.application.RealAlgebraicNumber<C>>> map(pfac, A,
1578                        new CoeffToComplexReal<C>(afac));
1579    }
1580
1581
1582    /**
1583     * Evaluate to Complex&lt;RealAlgebraicNumber&gt; coefficients. Represent as
1584     * polynomial with Complex&lt;RealAlgebraicNumber&gt; coefficients, C is
1585     * e.g. BigRational.
1586     * @param pfac result polynomial factory.
1587     * @param A = A(x,Y) a recursive polynomial with
1588     *            GenPolynomial&lt;Complex&gt; coefficients to be converted.
1589     * @param r Complex&lt;RealAlgebraicNumber&gt; to be evaluated at.
1590     * @return A(r,Y), a polynomial with Complex&lt;RealAlgebraicNumber&gt;
1591     *         coefficients.
1592     */
1593    public static <C extends GcdRingElem<C> & Rational> GenPolynomial<Complex<edu.jas.application.RealAlgebraicNumber<C>>> evaluateToComplexRealCoefficients(
1594                    GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<C>>> pfac,
1595                    GenPolynomial<GenPolynomial<Complex<C>>> A,
1596                    Complex<edu.jas.application.RealAlgebraicNumber<C>> r) {
1597        return PolyUtil.<GenPolynomial<Complex<C>>, Complex<edu.jas.application.RealAlgebraicNumber<C>>> map(
1598                        pfac, A, new EvaluateToComplexReal<C>(pfac, r));
1599    }
1600
1601
1602}
1603
1604
1605/**
1606 * Coefficient to convert algebriac functor.
1607 */
1608class CoeffConvertAlg<C extends GcdRingElem<C>>
1609                implements UnaryFunctor<AlgebraicNumber<C>, AlgebraicNumber<C>> {
1610
1611
1612    final protected AlgebraicNumberRing<C> afac;
1613
1614
1615    final protected AlgebraicNumber<C> A;
1616
1617
1618    public CoeffConvertAlg(AlgebraicNumberRing<C> fac, AlgebraicNumber<C> a) {
1619        if (fac == null || a == null) {
1620            throw new IllegalArgumentException("fac and a must not be null");
1621        }
1622        afac = fac;
1623        A = a;
1624    }
1625
1626
1627    public AlgebraicNumber<C> eval(AlgebraicNumber<C> c) {
1628        if (c == null) {
1629            return afac.getZERO();
1630        }
1631        return PolyUtilApp.<C> convertToPrimitiveElem(afac, A, c);
1632    }
1633}
1634
1635
1636/**
1637 * Coefficient recursive to convert algebriac functor.
1638 */
1639class CoeffRecConvertAlg<C extends GcdRingElem<C>>
1640                implements UnaryFunctor<AlgebraicNumber<AlgebraicNumber<C>>, AlgebraicNumber<C>> {
1641
1642
1643    final protected AlgebraicNumberRing<C> afac;
1644
1645
1646    final protected AlgebraicNumber<C> A;
1647
1648
1649    final protected AlgebraicNumber<C> B;
1650
1651
1652    public CoeffRecConvertAlg(AlgebraicNumberRing<C> fac, AlgebraicNumber<C> a, AlgebraicNumber<C> b) {
1653        if (fac == null || a == null || b == null) {
1654            throw new IllegalArgumentException("fac, a and b must not be null");
1655        }
1656        afac = fac;
1657        A = a;
1658        B = b;
1659    }
1660
1661
1662    public AlgebraicNumber<C> eval(AlgebraicNumber<AlgebraicNumber<C>> c) {
1663        if (c == null) {
1664            return afac.getZERO();
1665        }
1666        return PolyUtilApp.<C> convertToPrimitiveElem(afac, A, B, c);
1667    }
1668}
1669
1670
1671/**
1672 * Coefficient to real algebriac from real algebraic functor.
1673 */
1674class ReAlgFromRealCoeff<C extends GcdRingElem<C> & Rational> implements
1675                UnaryFunctor<edu.jas.application.RealAlgebraicNumber<C>, edu.jas.root.RealAlgebraicNumber<C>> {
1676
1677
1678    final protected edu.jas.root.RealAlgebraicRing<C> afac;
1679
1680
1681    public ReAlgFromRealCoeff(edu.jas.root.RealAlgebraicRing<C> fac) {
1682        if (fac == null) {
1683            throw new IllegalArgumentException("fac must not be null");
1684        }
1685        afac = fac;
1686    }
1687
1688
1689    @SuppressWarnings("unchecked")
1690    public edu.jas.root.RealAlgebraicNumber<C> eval(edu.jas.application.RealAlgebraicNumber<C> c) {
1691        if (c == null) {
1692            return afac.getZERO();
1693        }
1694        return (edu.jas.root.RealAlgebraicNumber<C>) (Object) c.number; // force ignore recursion
1695    }
1696}
1697
1698
1699/**
1700 * Coefficient to real algebriac from algebraic functor.
1701 */
1702class RealFromReAlgCoeff<C extends GcdRingElem<C> & Rational> implements
1703                UnaryFunctor<edu.jas.root.RealAlgebraicNumber<C>, edu.jas.application.RealAlgebraicNumber<C>> {
1704
1705
1706    final protected edu.jas.application.RealAlgebraicRing<C> rfac;
1707
1708
1709    public RealFromReAlgCoeff(edu.jas.application.RealAlgebraicRing<C> fac) {
1710        if (fac == null) {
1711            throw new IllegalArgumentException("fac must not be null");
1712        }
1713        rfac = fac;
1714    }
1715
1716
1717    @SuppressWarnings("unchecked")
1718    public edu.jas.application.RealAlgebraicNumber<C> eval(edu.jas.root.RealAlgebraicNumber<C> c) {
1719        if (c == null) {
1720            return rfac.getZERO();
1721        }
1722        edu.jas.root.RealAlgebraicNumber<edu.jas.root.RealAlgebraicNumber<C>> rrc = (edu.jas.root.RealAlgebraicNumber<edu.jas.root.RealAlgebraicNumber<C>>) (Object) c; // force resurrect recursion
1723        return new edu.jas.application.RealAlgebraicNumber<C>(rfac, rrc);
1724    }
1725}
1726
1727
1728/**
1729 * Coefficient to complex real algebriac functor.
1730 */
1731class CoeffToComplexReal<C extends GcdRingElem<C> & Rational>
1732                implements UnaryFunctor<Complex<C>, Complex<edu.jas.application.RealAlgebraicNumber<C>>> {
1733
1734
1735    final protected ComplexRing<edu.jas.application.RealAlgebraicNumber<C>> cfac;
1736
1737
1738    final edu.jas.application.RealAlgebraicRing<C> afac;
1739
1740
1741    final GenPolynomialRing<C> pfac;
1742
1743
1744    public CoeffToComplexReal(ComplexRing<edu.jas.application.RealAlgebraicNumber<C>> fac) {
1745        if (fac == null) {
1746            throw new IllegalArgumentException("fac must not be null");
1747        }
1748        cfac = fac;
1749        afac = (edu.jas.application.RealAlgebraicRing<C>) cfac.ring;
1750        pfac = afac.univs.ideal.getRing();
1751    }
1752
1753
1754    public Complex<edu.jas.application.RealAlgebraicNumber<C>> eval(Complex<C> c) {
1755        if (c == null) {
1756            return cfac.getZERO();
1757        }
1758        GenPolynomial<C> pr, pi;
1759        pr = new GenPolynomial<C>(pfac, c.getRe());
1760        pi = new GenPolynomial<C>(pfac, c.getIm());
1761        //System.out.println("pr = " + pr);
1762        //System.out.println("pi = " + pi);
1763        edu.jas.application.RealAlgebraicNumber<C> re, im;
1764        re = new edu.jas.application.RealAlgebraicNumber<C>(afac, pr);
1765        im = new edu.jas.application.RealAlgebraicNumber<C>(afac, pi);
1766        //System.out.println("re = " + re);
1767        //System.out.println("im = " + im);
1768        return new Complex<edu.jas.application.RealAlgebraicNumber<C>>(cfac, re, im);
1769    }
1770}
1771
1772
1773/**
1774 * Polynomial coefficient to complex real algebriac evaluation functor.
1775 */
1776class EvaluateToComplexReal<C extends GcdRingElem<C> & Rational> implements
1777                UnaryFunctor<GenPolynomial<Complex<C>>, Complex<edu.jas.application.RealAlgebraicNumber<C>>> {
1778
1779
1780    final protected GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<C>>> pfac;
1781
1782
1783    final protected ComplexRing<edu.jas.application.RealAlgebraicNumber<C>> cfac;
1784
1785
1786    final protected Complex<edu.jas.application.RealAlgebraicNumber<C>> root;
1787
1788
1789    public EvaluateToComplexReal(GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<C>>> fac,
1790                    Complex<edu.jas.application.RealAlgebraicNumber<C>> r) {
1791        if (fac == null) {
1792            throw new IllegalArgumentException("fac must not be null");
1793        }
1794        if (r == null) {
1795            throw new IllegalArgumentException("r must not be null");
1796        }
1797        pfac = fac;
1798        cfac = (ComplexRing<edu.jas.application.RealAlgebraicNumber<C>>) fac.coFac;
1799        root = r;
1800        //System.out.println("cfac  = " + cfac);
1801        //System.out.println("root  = " + root);
1802    }
1803
1804
1805    public Complex<edu.jas.application.RealAlgebraicNumber<C>> eval(GenPolynomial<Complex<C>> c) {
1806        if (c == null) {
1807            return cfac.getZERO();
1808        }
1809        //System.out.println("c  = " + c);
1810        GenPolynomial<Complex<edu.jas.application.RealAlgebraicNumber<C>>> cp;
1811        cp = PolyUtilApp.<C> convertToComplexRealCoefficients(pfac, c);
1812        Complex<edu.jas.application.RealAlgebraicNumber<C>> cr;
1813        cr = PolyUtil.<Complex<edu.jas.application.RealAlgebraicNumber<C>>> evaluateMain(cfac, cp, root);
1814        return cr;
1815    }
1816}