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