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<C> coefficients to be 1550 * converted. 1551 * @return polynomial with RealAlgebraicNumber<C> 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<C> coefficients to be 1573 * converted. 1574 * @return polynomial with RealAlgebraicNumber<C> 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<RealAlgebraicNumber> coefficients. Represent as 1587 * polynomial with Complex<RealAlgebraicNumber> 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<RealAlgebraicNumber> 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<RealAlgebraicNumber> coefficients. Represent as 1605 * polynomial with Complex<RealAlgebraicNumber> 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<Complex> coefficients to be converted. 1610 * @param r Complex<RealAlgebraicNumber> to be evaluated at. 1611 * @return A(r,Y), a polynomial with Complex<RealAlgebraicNumber> 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}