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 representation 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 representation 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 representation 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 representation 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 Representation 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 Representation 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 representation 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 coefficients.
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 Representation 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 Representation 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 representation 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 representation 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 complex roots for ideal(L).
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            //System.out.println("pip = " + pip);
707            logger.info("pi  = {}, pip = {}", pi, pip);
708            int[] depi = pip.degreeVector().dependencyOnVariables();
709            //System.out.println("depi = " + Arrays.toString(depi));
710            if (depi.length < 1 || depi.length > 2) {
711                throw new RuntimeException("wrong number of variables " + Arrays.toString(depi));
712            }
713            rra = RootFactory.<D> realAlgebraicNumbersIrred(pi);
714            //System.out.println("rra = " + rra);
715            if (logger.isInfoEnabled()) {
716                List<Interval<D>> il = new ArrayList<Interval<D>>();
717                for (RealAlgebraicNumber<D> rr : rra) {
718                    il.add(rr.ring.getRoot());
719                }
720                logger.info("roots(pi) = {}", il);
721            }
722            if (depi.length == 1) {
723                // all combinations are roots of the ideal I
724                for (RealAlgebraicNumber<D> rr : rra) {
725                    //System.out.println("rr.ring = " + rr.ring);
726                    for (List<RealAlgebraicNumber<D>> rx : ran) {
727                        //System.out.println("rx = " + rx);
728                        List<RealAlgebraicNumber<D>> ry = new ArrayList<RealAlgebraicNumber<D>>();
729                        ry.addAll(rx);
730                        ry.add(rr);
731                        rn.add(ry);
732                    }
733                }
734            } else { // depi.length == 2
735                // select roots of the ideal I
736                GenPolynomial<D> pip2 = PolyUtil.<D> removeUnusedUpperVariables(pip);
737                //System.out.println("pip2 = " + pip2.ring);
738                GenPolynomialRing<D> ufac = pip2.ring.contract(1);
739                TermOrder to = new TermOrder(TermOrder.INVLEX);
740                GenPolynomialRing<GenPolynomial<D>> rfac = new GenPolynomialRing<GenPolynomial<D>>(ufac, 1,
741                                                                                                   to); // new vars
742                GenPolynomial<GenPolynomial<D>> pip2r = PolyUtil.<D> recursive(rfac, pip2);
743                int ix = fac.nvar - 1 - depi[depi.length - 1];
744                //System.out.println("ix = " + ix);
745                for (RealAlgebraicNumber<D> rr : rra) {
746                    //System.out.println("rr.ring = " + rr.ring);
747                    Interval<D> rroot = rr.ring.getRoot();
748                    GenPolynomial<D> pip2el = PolyUtil.<D> evaluateMainRecursive(ufac, pip2r, rroot.left);
749                    GenPolynomial<D> pip2er = PolyUtil.<D> evaluateMainRecursive(ufac, pip2r, rroot.right);
750                    GenPolynomialRing<D> upfac = I.upolys.get(ix).ring;
751                    GenPolynomial<D> pip2elc = convert(upfac, pip2el);
752                    GenPolynomial<D> pip2erc = convert(upfac, pip2er);
753                    //System.out.println("pip2elc = " + pip2elc);
754                    //System.out.println("pip2erc = " + pip2erc);
755                    for (List<RealAlgebraicNumber<D>> rx : ran) {
756                        //System.out.println("rx = " + rx);
757                        RealAlgebraicRing<D> rar = rx.get(ix).ring;
758                        //System.out.println("rar = " + rar.toScript());
759                        RealAlgebraicNumber<D> rel = new RealAlgebraicNumber<D>(rar, pip2elc);
760                        RealAlgebraicNumber<D> rer = new RealAlgebraicNumber<D>(rar, pip2erc);
761                        int sl = rel.signum();
762                        int sr = rer.signum();
763                        //System.out.println("sl = " + sl + ", sr = " + sr + ", sl*sr = " + (sl*sr));
764                        if (sl * sr <= 0) {
765                            //System.out.println("sl * sr <= 0: rar = " + rar.toScript());
766                            List<RealAlgebraicNumber<D>> ry = new ArrayList<RealAlgebraicNumber<D>>();
767                            ry.addAll(rx);
768                            ry.add(rr);
769                            rn.add(ry);
770                        }
771                    }
772                }
773            }
774            ran = rn;
775        }
776        //System.out.println("ran = " + ran);
777        if (logger.isInfoEnabled()) {
778            for (List<RealAlgebraicNumber<D>> rz : ran) {
779                List<Interval<D>> il = new ArrayList<Interval<D>>();
780                for (RealAlgebraicNumber<D> rr : rz) {
781                    il.add(rr.ring.getRoot());
782                }
783                logger.info("root-tuple = {}", il);
784            }
785        }
786        IdealWithRealAlgebraicRoots<D> Ir = new IdealWithRealAlgebraicRoots<D>(I, ran);
787        return Ir;
788    }
789
790
791    /**
792     * Construct real roots for zero dimensional ideal(G).
793     * @param I list of zero dimensional ideal with univariate irreducible
794     *            polynomials and bi-variate polynomials.
795     * @return list of real algebraic roots for all ideal(I_i)
796     */
797    public static <D extends GcdRingElem<D> & Rational> List<IdealWithRealAlgebraicRoots<D>> realAlgebraicRoots(
798                    List<IdealWithUniv<D>> I) {
799        List<IdealWithRealAlgebraicRoots<D>> lir = new ArrayList<IdealWithRealAlgebraicRoots<D>>(I.size());
800        for (IdealWithUniv<D> iu : I) {
801            IdealWithRealAlgebraicRoots<D> iur = PolyUtilApp.<D> realAlgebraicRoots(iu);
802            //System.out.println("iur = " + iur);
803            lir.add(iur);
804        }
805        return lir;
806    }
807
808
809    /**
810     * Construct complex roots for zero dimensional ideal(G).
811     * @param I zero dimensional ideal with univariate irreducible polynomials
812     *            and bi-variate polynomials.
813     * @return complex algebraic roots for ideal(G) <b>Note:</b> not jet
814     *         completed in all cases.
815     */
816    public static <D extends GcdRingElem<D> & Rational> IdealWithComplexAlgebraicRoots<D> complexAlgebraicRoots(
817                    IdealWithUniv<D> I) {
818        List<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>> can;
819        can = new ArrayList<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>>();
820        if (I == null) {
821            throw new IllegalArgumentException("null ideal not permitted");
822        }
823        if (I.ideal == null || I.upolys == null) {
824            throw new IllegalArgumentException("null ideal components not permitted " + I);
825        }
826        if (I.ideal.isZERO() || I.upolys.size() == 0) {
827            return new IdealWithComplexAlgebraicRoots<D>(I, can);
828        }
829        GenPolynomialRing<D> fac = I.ideal.list.ring;
830        if (fac.nvar == 0) {
831            return new IdealWithComplexAlgebraicRoots<D>(I, can);
832        }
833        if (fac.nvar != I.upolys.size()) {
834            throw new IllegalArgumentException("ideal not zero dimnsional: " + I);
835        }
836        // case i == 0:
837        GenPolynomial<D> p0 = I.upolys.get(0);
838        GenPolynomial<D> p0p = PolyUtil.<D> selectWithVariable(I.ideal.list.list, fac.nvar - 1);
839        if (p0p == null) {
840            throw new RuntimeException("no polynomial found in " + (fac.nvar - 1) + " of  " + I.ideal);
841        }
842        logger.info("p0  = {}, p0p = {}", p0, p0p);
843        int[] dep0 = p0p.degreeVector().dependencyOnVariables();
844        //System.out.println("dep0 = " + Arrays.toString(dep0));
845        if (dep0.length != 1) {
846            throw new RuntimeException("wrong number of variables " + Arrays.toString(dep0));
847        }
848        RingFactory<D> cfac = p0.ring.coFac;
849        ComplexRing<D> ccfac = new ComplexRing<D>(cfac);
850        GenPolynomialRing<Complex<D>> facc = new GenPolynomialRing<Complex<D>>(ccfac, p0.ring);
851        GenPolynomial<Complex<D>> p0c = PolyUtil.<D> complexFromAny(facc, p0);
852        List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cra;
853        cra = edu.jas.application.RootFactoryApp.<D> complexAlgebraicNumbersSquarefree(p0c);
854        logger.info("#roots(p0c) = {}", cra.size());
855        for (Complex<edu.jas.application.RealAlgebraicNumber<D>> cr : cra) {
856            List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cl;
857            cl = new ArrayList<Complex<edu.jas.application.RealAlgebraicNumber<D>>>();
858            cl.add(cr);
859            can.add(cl);
860        }
861        if (fac.nvar == 1) {
862            return new IdealWithComplexAlgebraicRoots<D>(I, can);
863        }
864        // case i > 0:
865        for (int i = 1; i < I.upolys.size(); i++) {
866            List<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>> cn;
867            cn = new ArrayList<List<Complex<edu.jas.application.RealAlgebraicNumber<D>>>>();
868            GenPolynomial<D> pi = I.upolys.get(i);
869            GenPolynomial<D> pip = PolyUtil.selectWithVariable(I.ideal.list.list, fac.nvar - 1 - i);
870            if (pip == null) {
871                throw new RuntimeException(
872                                "no polynomial found in " + (fac.nvar - 1 - i) + " of  " + I.ideal);
873            }
874            if (logger.isInfoEnabled()) {
875                logger.info("pi({}) = {}", i, pi);
876                logger.info("pip  = {}", pip);
877            }
878            facc = new GenPolynomialRing<Complex<D>>(ccfac, pi.ring);
879            GenPolynomial<Complex<D>> pic = PolyUtil.<D> complexFromAny(facc, pi);
880            int[] depi = pip.degreeVector().dependencyOnVariables();
881            //System.out.println("depi = " + Arrays.toString(depi));
882            if (depi.length < 1 || depi.length > 2) {
883                throw new RuntimeException(
884                                "wrong number of variables " + Arrays.toString(depi) + " for " + pip);
885            }
886            cra = edu.jas.application.RootFactoryApp.<D> complexAlgebraicNumbersSquarefree(pic);
887            logger.info("#roots(pic) = {}", cra.size());
888            if (depi.length == 1) {
889                // all combinations are roots of the ideal I
890                for (Complex<edu.jas.application.RealAlgebraicNumber<D>> cr : cra) {
891                    //System.out.println("cr.ring = " + cr.ring);
892                    for (List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cx : can) {
893                        //System.out.println("cx = " + cx);
894                        List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cy;
895                        cy = new ArrayList<Complex<edu.jas.application.RealAlgebraicNumber<D>>>();
896                        cy.addAll(cx);
897                        cy.add(cr);
898                        cn.add(cy);
899                    }
900                }
901            } else { // depi.length == 2
902                // select roots of the ideal I
903                GenPolynomial<D> pip2 = PolyUtil.<D> removeUnusedUpperVariables(pip);
904                pip2 = PolyUtil.<D> removeUnusedLowerVariables(pip2);
905                pip2 = PolyUtil.<D> removeUnusedMiddleVariables(pip2);
906                GenPolynomialRing<GenPolynomial<D>> rfac = pip2.ring.recursive(1);
907                GenPolynomialRing<D> ufac = pip2.ring.contract(1);
908                GenPolynomialRing<Complex<D>> ucfac = new GenPolynomialRing<Complex<D>>(ccfac, ufac);
909                GenPolynomialRing<Complex<D>> c2fac = new GenPolynomialRing<Complex<D>>(ccfac, pip2.ring);
910                GenPolynomial<Complex<D>> pip2c = PolyUtil.<D> complexFromAny(c2fac, pip2);
911                GenPolynomialRing<GenPolynomial<Complex<D>>> rcfac;
912                rcfac = new GenPolynomialRing<GenPolynomial<Complex<D>>>(ucfac, rfac);
913                GenPolynomial<GenPolynomial<Complex<D>>> pip2cr = PolyUtil.<Complex<D>> recursive(rcfac,
914                                pip2c);
915                //System.out.println("pip2cr = " + pip2cr);
916                int ix = fac.nvar - 1 - depi[depi.length - 1];
917                //System.out.println("ix = " + ix);
918                for (Complex<edu.jas.application.RealAlgebraicNumber<D>> cr : cra) {
919                    //System.out.println("cr = " + toString(cr)); 
920                    edu.jas.application.RealAlgebraicRing<D> cring = (edu.jas.application.RealAlgebraicRing<D>) cr.ring.ring;
921                    RealRootTuple<D> rroot = cring.getRoot();
922                    List<RealAlgebraicNumber<D>> rlist = rroot.tuple;
923                    //System.out.println("rlist = " + rlist);
924                    Interval<D> vr = rlist.get(0).ring.getRoot();
925                    Interval<D> vi = rlist.get(1).ring.getRoot();
926                    //logger.info("vr = {}, vi = {}", vr, vi);
927                    edu.jas.application.RealAlgebraicNumber<D> vrl, vil, vrr, vir;
928                    vrl = new edu.jas.application.RealAlgebraicNumber<D>(cring, vr.left);
929                    vil = new edu.jas.application.RealAlgebraicNumber<D>(cring, vi.left);
930                    vrr = new edu.jas.application.RealAlgebraicNumber<D>(cring, vr.right);
931                    vir = new edu.jas.application.RealAlgebraicNumber<D>(cring, vi.right);
932                    ComplexRing<edu.jas.application.RealAlgebraicNumber<D>> crr;
933                    crr = new ComplexRing<edu.jas.application.RealAlgebraicNumber<D>>(cring);
934                    Complex<edu.jas.application.RealAlgebraicNumber<D>> csw, cne;
935                    csw = new Complex<edu.jas.application.RealAlgebraicNumber<D>>(crr, vrl, vil);
936                    cne = new Complex<edu.jas.application.RealAlgebraicNumber<D>>(crr, vrr, vir);
937                    //logger.info("csw  = {}, cne  = {}", toString(csw), toString(cne));
938                    Rectangle<edu.jas.application.RealAlgebraicNumber<D>> rec;
939                    rec = new Rectangle<edu.jas.application.RealAlgebraicNumber<D>>(csw, cne);
940                    //System.out.println("rec = " + rec);
941                    for (List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cx : can) {
942                        Complex<edu.jas.application.RealAlgebraicNumber<D>> cax = cx.get(ix);
943                        //System.out.println("cax = " + toString(cax));
944                        ComplexRing<edu.jas.application.RealAlgebraicNumber<D>> car = cax.ring;
945                        //System.out.println("car = " + car);
946                        GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<D>>> pcrfac;
947                        pcrfac = new GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<D>>>(
948                                        car, rcfac);
949                        GenPolynomial<Complex<edu.jas.application.RealAlgebraicNumber<D>>> pcr;
950                        pcr = evaluateToComplexRealCoefficients(pcrfac, pip2cr, cax);
951                        //System.out.println("pcr = " + pcr);
952                        ComplexRoots<edu.jas.application.RealAlgebraicNumber<D>> rengine;
953                        rengine = new ComplexRootsSturm<edu.jas.application.RealAlgebraicNumber<D>>(car);
954                        long nr = 0;
955                        try {
956                            nr = rengine.complexRootCount(rec, pcr);
957                            //logger.info("rootCount = {}", nr);
958                        } catch (InvalidBoundaryException e) {
959                            e.printStackTrace();
960                        }
961                        if (nr == 1) { // one root
962                            logger.info("   hit, cxi = {}, cr = {}", toString(cx.get(ix)), toString(cr));
963                            List<Complex<edu.jas.application.RealAlgebraicNumber<D>>> cy;
964                            cy = new ArrayList<Complex<edu.jas.application.RealAlgebraicNumber<D>>>();
965                            cy.addAll(cx);
966                            cy.add(cr);
967                            cn.add(cy);
968                        } else if (nr > 1) {
969                            logger.error("to many roots, cxi = {}, cr = {}", toString(cx.get(ix)), toString(cr));
970                        } else { // no root
971                            logger.info("no hit, cxi = {}, cr = {}", toString(cx.get(ix)), toString(cr));
972                        }
973                    }
974                }
975            }
976            can = cn;
977        }
978        IdealWithComplexAlgebraicRoots<D> Ic = new IdealWithComplexAlgebraicRoots<D>(I, can);
979        return Ic;
980    }
981
982
983    /**
984     * String representation of a deximal approximation of a complex number.
985     * @param c compelx number.
986     * @return String representation of c
987     */
988    public static <D extends GcdRingElem<D> & Rational> String toString(
989                    Complex<edu.jas.application.RealAlgebraicNumber<D>> c) {
990        edu.jas.application.RealAlgebraicNumber<D> re = c.getRe();
991        edu.jas.application.RealAlgebraicNumber<D> im = c.getIm();
992        String s = re.decimalMagnitude().toString();
993        if (!im.isZERO()) {
994            s = s + "i" + im.decimalMagnitude();
995        }
996        return s;
997    }
998
999
1000    /**
1001     * String representation of a deximal approximation of a complex number.
1002     * @param c compelx number.
1003     * @return String representation of c
1004     */
1005    public static <D extends GcdRingElem<D> & Rational> String toString1(Complex<D> c) {
1006        D re = c.getRe();
1007        D im = c.getIm();
1008        String s = new BigDecimal(re.getRational()).toString();
1009        if (!im.isZERO()) {
1010            s = s + "i" + new BigDecimal(im.getRational());
1011        }
1012        return s;
1013    }
1014
1015
1016    /**
1017     * Construct complex roots for zero dimensional ideal(G).
1018     * @param I list of zero dimensional ideal with univariate irreducible
1019     *            polynomials and bi-variate polynomials.
1020     * @return list of complex algebraic roots for ideal(G)
1021     */
1022    public static <D extends GcdRingElem<D> & Rational> List<IdealWithComplexAlgebraicRoots<D>> complexAlgebraicRoots(
1023                    List<IdealWithUniv<D>> I) {
1024        List<IdealWithComplexAlgebraicRoots<D>> lic = new ArrayList<IdealWithComplexAlgebraicRoots<D>>();
1025        for (IdealWithUniv<D> iu : I) {
1026            IdealWithComplexAlgebraicRoots<D> iuc = PolyUtilApp.<D> complexAlgebraicRoots(iu);
1027            //System.out.println("iuc = " + iuc);
1028            lic.add(iuc);
1029        }
1030        return lic;
1031    }
1032
1033
1034    /**
1035     * Construct exact set of complex roots for zero dimensional ideal(G).
1036     * @param I zero dimensional ideal.
1037     * @return list of coordinates of complex roots for ideal(G)
1038     */
1039    public static <D extends GcdRingElem<D> & Rational> List<IdealWithComplexAlgebraicRoots<D>> complexAlgebraicRoots(
1040                    Ideal<D> I) {
1041        List<IdealWithUniv<D>> Ir = I.zeroDimRootDecomposition();
1042        //System.out.println("Ir = " + Ir);
1043        List<IdealWithComplexAlgebraicRoots<D>> roots = PolyUtilApp.<D> complexAlgebraicRoots(Ir);
1044        return roots;
1045    }
1046
1047
1048    /*
1049     * Convert to a polynomial in given ring.
1050     * @param fac result polynomial ring.
1051     * @param p polynomial.
1052     * @return polynomial in ring fac <b>Note: </b> if p can not be represented
1053     *         in fac then the results are unpredictable.
1054     */
1055    static <C extends RingElem<C>> GenPolynomial<C> convert(GenPolynomialRing<C> fac, GenPolynomial<C> p) {
1056        if (fac.equals(p.factory())) {
1057            return p;
1058        }
1059        GenPolynomial<C> q = fac.parse(p.toString());
1060        if (!q.toString().equals(p.toString())) {
1061            throw new RuntimeException("convert(" + p + ") = " + q);
1062        }
1063        return q;
1064    }
1065
1066
1067    /*
1068     * Convert to a polynomial in given ring.
1069     * @param fac result polynomial ring.
1070     * @param p polynomial.
1071     * @return polynomial in ring fac <b>Note: </b> if p can not be represented
1072     *         in fac then the results are unpredictable.
1073     */
1074    static <C extends RingElem<C>> GenPolynomial<Complex<C>> convertComplex(GenPolynomialRing<Complex<C>> fac,
1075                    GenPolynomial<C> p) {
1076        GenPolynomial<Complex<C>> q = fac.parse(p.toString());
1077        if (!q.toString().equals(p.toString())) {
1078            throw new RuntimeException("convert(" + p + ") = " + q);
1079        }
1080        return q;
1081    }
1082
1083
1084    /*
1085     * Convert to a polynomial in given ring.
1086     * @param fac result polynomial ring.
1087     * @param p complex polynomial.
1088     * @return polynomial in ring fac <b>Note: </b> if p can not be represented
1089     *         in fac then the results are unpredictable.
1090     */
1091    static <C extends RingElem<C>> GenPolynomial<Complex<C>> convertComplexComplex(
1092                    GenPolynomialRing<Complex<C>> fac, GenPolynomial<Complex<C>> p) {
1093        if (fac.equals(p.factory())) {
1094            return p;
1095        }
1096        GenPolynomial<Complex<C>> q = fac.parse(p.toString());
1097        if (!q.toString().equals(p.toString())) {
1098            throw new RuntimeException("convert(" + p + ") = " + q);
1099        }
1100        return q;
1101    }
1102
1103
1104    /**
1105     * Construct exact set of real roots for zero dimensional ideal(G).
1106     * @param I zero dimensional ideal.
1107     * @return list of coordinates of real roots for ideal(G)
1108     */
1109    public static <D extends GcdRingElem<D> & Rational> List<IdealWithRealAlgebraicRoots<D>> realAlgebraicRoots(
1110                    Ideal<D> I) {
1111        List<IdealWithUniv<D>> Ir = I.zeroDimRootDecomposition();
1112        //System.out.println("Ir = " + Ir);
1113        List<IdealWithRealAlgebraicRoots<D>> roots = PolyUtilApp.<D> realAlgebraicRoots(Ir);
1114        return roots;
1115    }
1116
1117
1118    /**
1119     * Construct primitive element for double field extension.
1120     * @param a algebraic number ring with squarefree monic minimal polynomial
1121     * @param b algebraic number ring with squarefree monic minimal polynomial
1122     * @return primitive element container with algebraic number ring c, with
1123     *         Q(c) = Q(a,b)
1124     */
1125    public static <C extends GcdRingElem<C>> PrimitiveElement<C> primitiveElement(AlgebraicNumberRing<C> a,
1126                    AlgebraicNumberRing<C> b) {
1127        GenPolynomial<C> ap = a.modul;
1128        GenPolynomial<C> bp = b.modul;
1129
1130        // setup bivariate polynomial ring
1131        String[] cv = new String[2];
1132        cv[0] = ap.ring.getVars()[0];
1133        cv[1] = bp.ring.getVars()[0];
1134        TermOrder to = new TermOrder(TermOrder.INVLEX);
1135        GenPolynomialRing<C> cfac = new GenPolynomialRing<C>(ap.ring.coFac, 2, to, cv);
1136        GenPolynomial<C> as = ap.extendUnivariate(cfac, 0);
1137        GenPolynomial<C> bs = bp.extendUnivariate(cfac, 1);
1138        List<GenPolynomial<C>> L = new ArrayList<GenPolynomial<C>>(2);
1139        L.add(as);
1140        L.add(bs);
1141        List<GenPolynomial<C>> Op = new ArrayList<GenPolynomial<C>>();
1142
1143        Ideal<C> id = new Ideal<C>(cfac, L);
1144        //System.out.println("id = " + id);
1145        IdealWithUniv<C> iu = id.normalPositionFor(0, 1, Op);
1146        //System.out.println("iu = " + iu);
1147
1148        // extract result polynomials
1149        List<GenPolynomial<C>> Np = iu.ideal.getList();
1150        //System.out.println("Np = " + Np);
1151        as = PolyUtil.<C> selectWithVariable(Np, 1);
1152        bs = PolyUtil.<C> selectWithVariable(Np, 0);
1153        GenPolynomial<C> cs = PolyUtil.<C> selectWithVariable(Np, 2);
1154        //System.out.println("as = " + as);
1155        //System.out.println("bs = " + bs);
1156        //System.out.println("cs = " + cs);
1157        String[] ev = new String[] { cs.ring.getVars()[0] };
1158        GenPolynomialRing<C> efac = new GenPolynomialRing<C>(ap.ring.coFac, 1, to, ev);
1159        //System.out.println("efac = " + efac);
1160        cs = cs.contractCoeff(efac);
1161        //System.out.println("cs = " + cs);
1162        as = as.reductum().contractCoeff(efac);
1163        as = as.negate();
1164        //System.out.println("as = " + as);
1165        bs = bs.reductum().contractCoeff(efac);
1166        bs = bs.negate();
1167        //System.out.println("bs = " + bs);
1168        AlgebraicNumberRing<C> c = new AlgebraicNumberRing<C>(cs);
1169        AlgebraicNumber<C> ab = new AlgebraicNumber<C>(c, as);
1170        AlgebraicNumber<C> bb = new AlgebraicNumber<C>(c, bs);
1171        PrimitiveElement<C> pe = new PrimitiveElement<C>(c, ab, bb, a, b);
1172        logger.info("primitive element = {}", c);
1173        return pe;
1174    }
1175
1176
1177    /**
1178     * Convert to primitive element ring.
1179     * @param cfac primitive element ring.
1180     * @param A algebraic number representing the generating element of a in the
1181     *            new ring.
1182     * @param a algebraic number to convert.
1183     * @return a converted to the primitive element ring
1184     */
1185    public static <C extends GcdRingElem<C>> AlgebraicNumber<C> convertToPrimitiveElem(
1186                    AlgebraicNumberRing<C> cfac, AlgebraicNumber<C> A, AlgebraicNumber<C> a) {
1187        GenPolynomialRing<C> aufac = a.ring.ring;
1188        GenPolynomialRing<AlgebraicNumber<C>> ar = new GenPolynomialRing<AlgebraicNumber<C>>(cfac, aufac);
1189        GenPolynomial<AlgebraicNumber<C>> aps = PolyUtil.<C> convertToAlgebraicCoefficients(ar, a.val);
1190        AlgebraicNumber<C> ac = PolyUtil.<AlgebraicNumber<C>> evaluateMain(cfac, aps, A);
1191        return ac;
1192    }
1193
1194
1195    /**
1196     * Convert coefficients to primitive element ring.
1197     * @param cfac primitive element ring.
1198     * @param A algebraic number representing the generating element of a in the
1199     *            new ring.
1200     * @param a polynomial with coefficients algebraic number to convert.
1201     * @return a with coefficients converted to the primitive element ring
1202     */
1203    public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> convertToPrimitiveElem(
1204                    AlgebraicNumberRing<C> cfac, AlgebraicNumber<C> A, GenPolynomial<AlgebraicNumber<C>> a) {
1205        GenPolynomialRing<AlgebraicNumber<C>> cr = new GenPolynomialRing<AlgebraicNumber<C>>(cfac, a.ring);
1206        return PolyUtil.<AlgebraicNumber<C>, AlgebraicNumber<C>> map(cr, a, new CoeffConvertAlg<C>(cfac, A));
1207    }
1208
1209
1210    /**
1211     * Convert to primitive element ring.
1212     * @param cfac primitive element ring.
1213     * @param A algebraic number representing the generating element of a in the
1214     *            new ring.
1215     * @param a recursive algebraic number to convert.
1216     * @return a converted to the primitive element ring
1217     */
1218    public static <C extends GcdRingElem<C>> AlgebraicNumber<C> convertToPrimitiveElem(
1219                    AlgebraicNumberRing<C> cfac, AlgebraicNumber<C> A, AlgebraicNumber<C> B,
1220                    AlgebraicNumber<AlgebraicNumber<C>> a) {
1221        GenPolynomial<AlgebraicNumber<C>> aps = PolyUtilApp.<C> convertToPrimitiveElem(cfac, A, a.val);
1222        AlgebraicNumber<C> ac = PolyUtil.<AlgebraicNumber<C>> evaluateMain(cfac, aps, B);
1223        return ac;
1224    }
1225
1226
1227    /**
1228     * Construct primitive element for double field extension.
1229     * @param b algebraic number ring with squarefree monic minimal polynomial
1230     *            over Q(a)
1231     * @return primitive element container with algebraic number ring c, with
1232     *         Q(c) = Q(a)(b)
1233     */
1234    public static <C extends GcdRingElem<C>> PrimitiveElement<C> primitiveElement(
1235                    AlgebraicNumberRing<AlgebraicNumber<C>> b) {
1236        GenPolynomial<AlgebraicNumber<C>> bp = b.modul;
1237        AlgebraicNumberRing<C> a = (AlgebraicNumberRing<C>) b.ring.coFac;
1238        GenPolynomial<C> ap = a.modul;
1239
1240        // setup bivariate polynomial ring
1241        String[] cv = new String[2];
1242        cv[0] = ap.ring.getVars()[0];
1243        cv[1] = bp.ring.getVars()[0];
1244        TermOrder to = new TermOrder(TermOrder.INVLEX);
1245        GenPolynomialRing<C> cfac = new GenPolynomialRing<C>(ap.ring.coFac, 2, to, cv);
1246        GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(a.ring, 1,
1247                        bp.ring.getVars());
1248        GenPolynomial<C> as = ap.extendUnivariate(cfac, 0);
1249        GenPolynomial<GenPolynomial<C>> bss = PolyUtil.<C> fromAlgebraicCoefficients(rfac, bp);
1250        GenPolynomial<C> bs = PolyUtil.<C> distribute(cfac, bss);
1251        List<GenPolynomial<C>> L = new ArrayList<GenPolynomial<C>>(2);
1252        L.add(as);
1253        L.add(bs);
1254        List<GenPolynomial<C>> Op = new ArrayList<GenPolynomial<C>>();
1255
1256        Ideal<C> id = new Ideal<C>(cfac, L);
1257        //System.out.println("id = " + id);
1258        IdealWithUniv<C> iu = id.normalPositionFor(0, 1, Op);
1259        //System.out.println("iu = " + iu);
1260
1261        // extract result polynomials
1262        List<GenPolynomial<C>> Np = iu.ideal.getList();
1263        as = PolyUtil.<C> selectWithVariable(Np, 1);
1264        bs = PolyUtil.<C> selectWithVariable(Np, 0);
1265        GenPolynomial<C> cs = PolyUtil.<C> selectWithVariable(Np, 2);
1266        //System.out.println("as = " + as);
1267        //System.out.println("bs = " + bs);
1268        //System.out.println("cs = " + cs);
1269        String[] ev = new String[] { cs.ring.getVars()[0] };
1270        GenPolynomialRing<C> efac = new GenPolynomialRing<C>(ap.ring.coFac, 1, to, ev);
1271        // System.out.println("efac = " + efac);
1272        cs = cs.contractCoeff(efac);
1273        // System.out.println("cs = " + cs);
1274        as = as.reductum().contractCoeff(efac);
1275        as = as.negate();
1276        // System.out.println("as = " + as);
1277        bs = bs.reductum().contractCoeff(efac);
1278        bs = bs.negate();
1279        //System.out.println("bs = " + bs);
1280        AlgebraicNumberRing<C> c = new AlgebraicNumberRing<C>(cs);
1281        AlgebraicNumber<C> ab = new AlgebraicNumber<C>(c, as);
1282        AlgebraicNumber<C> bb = new AlgebraicNumber<C>(c, bs);
1283        PrimitiveElement<C> pe = new PrimitiveElement<C>(c, ab, bb); // missing ,a,b);
1284        logger.info("primitive element = {}", pe);
1285        return pe;
1286    }
1287
1288
1289    /**
1290     * Convert to primitive element ring.
1291     * @param cfac primitive element ring.
1292     * @param A algebraic number representing the generating element of a in the
1293     *            new ring.
1294     * @param a polynomial with recursive algebraic number coefficients to
1295     *            convert.
1296     * @return a converted to the primitive element ring
1297     */
1298    public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> convertToPrimitiveElem(
1299                    AlgebraicNumberRing<C> cfac, AlgebraicNumber<C> A, AlgebraicNumber<C> B,
1300                    GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>> a) {
1301        GenPolynomialRing<AlgebraicNumber<C>> cr = new GenPolynomialRing<AlgebraicNumber<C>>(cfac, a.ring);
1302        return PolyUtil.<AlgebraicNumber<AlgebraicNumber<C>>, AlgebraicNumber<C>> map(cr, a,
1303                        new CoeffRecConvertAlg<C>(cfac, A, B));
1304    }
1305
1306
1307    /**
1308     * Convert to RealAlgebraicNumber coefficients. Represent as polynomial with
1309     * RealAlgebraicNumber<C> coefficients from package
1310     * <code>edu.jas.root.</code>
1311     * @param afac result polynomial factory.
1312     * @param A polynomial with RealAlgebraicNumber&lt;C&gt; coefficients to be
1313     *            converted.
1314     * @return polynomial with RealAlgebraicNumber&lt;C&gt; coefficients.
1315     */
1316    public static <C extends GcdRingElem<C> & Rational> GenPolynomial<edu.jas.root.RealAlgebraicNumber<C>> realAlgFromRealCoefficients(
1317                    GenPolynomialRing<edu.jas.root.RealAlgebraicNumber<C>> afac,
1318                    GenPolynomial<edu.jas.application.RealAlgebraicNumber<C>> A) {
1319        edu.jas.root.RealAlgebraicRing<C> cfac = (edu.jas.root.RealAlgebraicRing<C>) afac.coFac;
1320        return PolyUtil.<edu.jas.application.RealAlgebraicNumber<C>, edu.jas.root.RealAlgebraicNumber<C>> map(
1321                        afac, A, new ReAlgFromRealCoeff<C>(cfac));
1322    }
1323
1324
1325    /**
1326     * Convert to RealAlgebraicNumber coefficients. Represent as polynomial with
1327     * RealAlgebraicNumber<C> coefficients from package
1328     * 
1329     * <pre>
1330     * edu.jas.application
1331     * </pre>
1332     * 
1333     * .
1334     * @param rfac result polynomial factory.
1335     * @param A polynomial with RealAlgebraicNumber&lt;C&gt; coefficients to be
1336     *            converted.
1337     * @return polynomial with RealAlgebraicNumber&lt;C&gt; coefficients.
1338     */
1339    public static <C extends GcdRingElem<C> & Rational> GenPolynomial<edu.jas.application.RealAlgebraicNumber<C>> realFromRealAlgCoefficients(
1340                    GenPolynomialRing<edu.jas.application.RealAlgebraicNumber<C>> rfac,
1341                    GenPolynomial<edu.jas.root.RealAlgebraicNumber<C>> A) {
1342        edu.jas.application.RealAlgebraicRing<C> cfac = (edu.jas.application.RealAlgebraicRing<C>) rfac.coFac;
1343        return PolyUtil.<edu.jas.root.RealAlgebraicNumber<C>, edu.jas.application.RealAlgebraicNumber<C>> map(
1344                        rfac, A, new RealFromReAlgCoeff<C>(cfac));
1345    }
1346
1347
1348    /**
1349     * Convert to Complex&lt;RealAlgebraicNumber&gt; coefficients. Represent as
1350     * polynomial with Complex&lt;RealAlgebraicNumber&gt; coefficients, C is
1351     * e.g. BigRational.
1352     * @param pfac result polynomial factory.
1353     * @param A polynomial with Complex coefficients to be converted.
1354     * @return polynomial with Complex&lt;RealAlgebraicNumber&gt; coefficients.
1355     */
1356    public static <C extends GcdRingElem<C> & Rational> GenPolynomial<Complex<edu.jas.application.RealAlgebraicNumber<C>>> convertToComplexRealCoefficients(
1357                    GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<C>>> pfac,
1358                    GenPolynomial<Complex<C>> A) {
1359        ComplexRing<edu.jas.application.RealAlgebraicNumber<C>> afac;
1360        afac = (ComplexRing<edu.jas.application.RealAlgebraicNumber<C>>) pfac.coFac;
1361        return PolyUtil.<Complex<C>, Complex<edu.jas.application.RealAlgebraicNumber<C>>> map(pfac, A,
1362                        new CoeffToComplexReal<C>(afac));
1363    }
1364
1365
1366    /**
1367     * Evaluate to Complex&lt;RealAlgebraicNumber&gt; coefficients. Represent as
1368     * polynomial with Complex&lt;RealAlgebraicNumber&gt; coefficients, C is
1369     * e.g. BigRational.
1370     * @param pfac result polynomial factory.
1371     * @param A = A(x,Y) a recursive polynomial with
1372     *            GenPolynomial&lt;Complex&gt; coefficients to be converted.
1373     * @param r Complex&lt;RealAlgebraicNumber&gt; to be evaluated at.
1374     * @return A(r,Y), a polynomial with Complex&lt;RealAlgebraicNumber&gt;
1375     *         coefficients.
1376     */
1377    public static <C extends GcdRingElem<C> & Rational> GenPolynomial<Complex<edu.jas.application.RealAlgebraicNumber<C>>> evaluateToComplexRealCoefficients(
1378                    GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<C>>> pfac,
1379                    GenPolynomial<GenPolynomial<Complex<C>>> A,
1380                    Complex<edu.jas.application.RealAlgebraicNumber<C>> r) {
1381        return PolyUtil.<GenPolynomial<Complex<C>>, Complex<edu.jas.application.RealAlgebraicNumber<C>>> map(
1382                        pfac, A, new EvaluateToComplexReal<C>(pfac, r));
1383    }
1384
1385
1386}
1387
1388
1389/**
1390 * Coefficient to convert algebriac functor.
1391 */
1392class CoeffConvertAlg<C extends GcdRingElem<C>>
1393                implements UnaryFunctor<AlgebraicNumber<C>, AlgebraicNumber<C>> {
1394
1395
1396    final protected AlgebraicNumberRing<C> afac;
1397
1398
1399    final protected AlgebraicNumber<C> A;
1400
1401
1402    public CoeffConvertAlg(AlgebraicNumberRing<C> fac, AlgebraicNumber<C> a) {
1403        if (fac == null || a == null) {
1404            throw new IllegalArgumentException("fac and a must not be null");
1405        }
1406        afac = fac;
1407        A = a;
1408    }
1409
1410
1411    public AlgebraicNumber<C> eval(AlgebraicNumber<C> c) {
1412        if (c == null) {
1413            return afac.getZERO();
1414        }
1415        return PolyUtilApp.<C> convertToPrimitiveElem(afac, A, c);
1416    }
1417}
1418
1419
1420/**
1421 * Coefficient recursive to convert algebriac functor.
1422 */
1423class CoeffRecConvertAlg<C extends GcdRingElem<C>>
1424                implements UnaryFunctor<AlgebraicNumber<AlgebraicNumber<C>>, AlgebraicNumber<C>> {
1425
1426
1427    final protected AlgebraicNumberRing<C> afac;
1428
1429
1430    final protected AlgebraicNumber<C> A;
1431
1432
1433    final protected AlgebraicNumber<C> B;
1434
1435
1436    public CoeffRecConvertAlg(AlgebraicNumberRing<C> fac, AlgebraicNumber<C> a, AlgebraicNumber<C> b) {
1437        if (fac == null || a == null || b == null) {
1438            throw new IllegalArgumentException("fac, a and b must not be null");
1439        }
1440        afac = fac;
1441        A = a;
1442        B = b;
1443    }
1444
1445
1446    public AlgebraicNumber<C> eval(AlgebraicNumber<AlgebraicNumber<C>> c) {
1447        if (c == null) {
1448            return afac.getZERO();
1449        }
1450        return PolyUtilApp.<C> convertToPrimitiveElem(afac, A, B, c);
1451    }
1452}
1453
1454
1455/**
1456 * Coefficient to real algebriac from real algebraic functor.
1457 */
1458class ReAlgFromRealCoeff<C extends GcdRingElem<C> & Rational> implements
1459                UnaryFunctor<edu.jas.application.RealAlgebraicNumber<C>, edu.jas.root.RealAlgebraicNumber<C>> {
1460
1461
1462    final protected edu.jas.root.RealAlgebraicRing<C> afac;
1463
1464
1465    public ReAlgFromRealCoeff(edu.jas.root.RealAlgebraicRing<C> fac) {
1466        if (fac == null) {
1467            throw new IllegalArgumentException("fac must not be null");
1468        }
1469        afac = fac;
1470    }
1471
1472
1473    @SuppressWarnings("unchecked")
1474    public edu.jas.root.RealAlgebraicNumber<C> eval(edu.jas.application.RealAlgebraicNumber<C> c) {
1475        if (c == null) {
1476            return afac.getZERO();
1477        }
1478        return (edu.jas.root.RealAlgebraicNumber<C>) (Object) c.number; // force ignore recursion
1479    }
1480}
1481
1482
1483/**
1484 * Coefficient to real algebriac from algebraic functor.
1485 */
1486class RealFromReAlgCoeff<C extends GcdRingElem<C> & Rational> implements
1487                UnaryFunctor<edu.jas.root.RealAlgebraicNumber<C>, edu.jas.application.RealAlgebraicNumber<C>> {
1488
1489
1490    final protected edu.jas.application.RealAlgebraicRing<C> rfac;
1491
1492
1493    public RealFromReAlgCoeff(edu.jas.application.RealAlgebraicRing<C> fac) {
1494        if (fac == null) {
1495            throw new IllegalArgumentException("fac must not be null");
1496        }
1497        rfac = fac;
1498    }
1499
1500
1501    @SuppressWarnings("unchecked")
1502    public edu.jas.application.RealAlgebraicNumber<C> eval(edu.jas.root.RealAlgebraicNumber<C> c) {
1503        if (c == null) {
1504            return rfac.getZERO();
1505        }
1506        edu.jas.root.RealAlgebraicNumber<edu.jas.root.RealAlgebraicNumber<C>> rrc = (edu.jas.root.RealAlgebraicNumber<edu.jas.root.RealAlgebraicNumber<C>>) (Object) c; // force resurrect recursion
1507        return new edu.jas.application.RealAlgebraicNumber<C>(rfac, rrc);
1508    }
1509}
1510
1511
1512/**
1513 * Coefficient to complex real algebriac functor.
1514 */
1515class CoeffToComplexReal<C extends GcdRingElem<C> & Rational>
1516                implements UnaryFunctor<Complex<C>, Complex<edu.jas.application.RealAlgebraicNumber<C>>> {
1517
1518
1519    final protected ComplexRing<edu.jas.application.RealAlgebraicNumber<C>> cfac;
1520
1521
1522    final edu.jas.application.RealAlgebraicRing<C> afac;
1523
1524
1525    final GenPolynomialRing<C> pfac;
1526
1527
1528    public CoeffToComplexReal(ComplexRing<edu.jas.application.RealAlgebraicNumber<C>> fac) {
1529        if (fac == null) {
1530            throw new IllegalArgumentException("fac must not be null");
1531        }
1532        cfac = fac;
1533        afac = (edu.jas.application.RealAlgebraicRing<C>) cfac.ring;
1534        pfac = afac.univs.ideal.getRing();
1535    }
1536
1537
1538    public Complex<edu.jas.application.RealAlgebraicNumber<C>> eval(Complex<C> c) {
1539        if (c == null) {
1540            return cfac.getZERO();
1541        }
1542        GenPolynomial<C> pr, pi;
1543        pr = new GenPolynomial<C>(pfac, c.getRe());
1544        pi = new GenPolynomial<C>(pfac, c.getIm());
1545        //System.out.println("pr = " + pr);
1546        //System.out.println("pi = " + pi);
1547        edu.jas.application.RealAlgebraicNumber<C> re, im;
1548        re = new edu.jas.application.RealAlgebraicNumber<C>(afac, pr);
1549        im = new edu.jas.application.RealAlgebraicNumber<C>(afac, pi);
1550        //System.out.println("re = " + re);
1551        //System.out.println("im = " + im);
1552        return new Complex<edu.jas.application.RealAlgebraicNumber<C>>(cfac, re, im);
1553    }
1554}
1555
1556
1557/**
1558 * Polynomial coefficient to complex real algebriac evaluation functor.
1559 */
1560class EvaluateToComplexReal<C extends GcdRingElem<C> & Rational> implements
1561                UnaryFunctor<GenPolynomial<Complex<C>>, Complex<edu.jas.application.RealAlgebraicNumber<C>>> {
1562
1563
1564    final protected GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<C>>> pfac;
1565
1566
1567    final protected ComplexRing<edu.jas.application.RealAlgebraicNumber<C>> cfac;
1568
1569
1570    final protected Complex<edu.jas.application.RealAlgebraicNumber<C>> root;
1571
1572
1573    public EvaluateToComplexReal(GenPolynomialRing<Complex<edu.jas.application.RealAlgebraicNumber<C>>> fac,
1574                    Complex<edu.jas.application.RealAlgebraicNumber<C>> r) {
1575        if (fac == null) {
1576            throw new IllegalArgumentException("fac must not be null");
1577        }
1578        if (r == null) {
1579            throw new IllegalArgumentException("r must not be null");
1580        }
1581        pfac = fac;
1582        cfac = (ComplexRing<edu.jas.application.RealAlgebraicNumber<C>>) fac.coFac;
1583        root = r;
1584        //System.out.println("cfac  = " + cfac);
1585        //System.out.println("root  = " + root);
1586    }
1587
1588
1589    public Complex<edu.jas.application.RealAlgebraicNumber<C>> eval(GenPolynomial<Complex<C>> c) {
1590        if (c == null) {
1591            return cfac.getZERO();
1592        }
1593        //System.out.println("c  = " + c);
1594        GenPolynomial<Complex<edu.jas.application.RealAlgebraicNumber<C>>> cp;
1595        cp = PolyUtilApp.<C> convertToComplexRealCoefficients(pfac, c);
1596        Complex<edu.jas.application.RealAlgebraicNumber<C>> cr;
1597        cr = PolyUtil.<Complex<edu.jas.application.RealAlgebraicNumber<C>>> evaluateMain(cfac, cp, root);
1598        return cr;
1599    }
1600}