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