001/* 002 * $Id: PolyUfdUtil.java 5280 2015-07-30 16:18:15Z kredel $ 003 */ 004 005package edu.jas.ufd; 006 007 008import java.util.ArrayList; 009import java.util.Collection; 010import java.util.List; 011import java.util.Map; 012 013import org.apache.log4j.Logger; 014 015import edu.jas.arith.BigInteger; 016import edu.jas.arith.BigRational; 017import edu.jas.poly.AlgebraicNumber; 018import edu.jas.poly.AlgebraicNumberRing; 019import edu.jas.poly.ExpVector; 020import edu.jas.poly.GenPolynomial; 021import edu.jas.poly.GenPolynomialRing; 022import edu.jas.poly.PolyUtil; 023import edu.jas.structure.GcdRingElem; 024import edu.jas.structure.RingElem; 025import edu.jas.structure.RingFactory; 026import edu.jas.structure.UnaryFunctor; 027import edu.jas.util.ListUtil; 028 029 030/** 031 * Polynomial ufd utilities, like conversion between different representations 032 * and Hensel lifting. 033 * @author Heinz Kredel 034 */ 035 036public class PolyUfdUtil { 037 038 039 private static final Logger logger = Logger.getLogger(PolyUfdUtil.class); 040 041 042 private static boolean debug = logger.isDebugEnabled(); 043 044 045 /** 046 * Integral polynomial from rational function coefficients. Represent as 047 * polynomial with integral polynomial coefficients by multiplication with 048 * the lcm of the numerators of the rational function coefficients. 049 * @param fac result polynomial factory. 050 * @param A polynomial with rational function coefficients to be converted. 051 * @return polynomial with integral polynomial coefficients. 052 */ 053 public static <C extends GcdRingElem<C>> GenPolynomial<GenPolynomial<C>> integralFromQuotientCoefficients( 054 GenPolynomialRing<GenPolynomial<C>> fac, GenPolynomial<Quotient<C>> A) { 055 GenPolynomial<GenPolynomial<C>> B = fac.getZERO().copy(); 056 if (A == null || A.isZERO()) { 057 return B; 058 } 059 GenPolynomial<C> c = null; 060 GenPolynomial<C> d; 061 GenPolynomial<C> x; 062 GreatestCommonDivisor<C> ufd = new GreatestCommonDivisorSubres<C>(); 063 int s = 0; 064 // lcm of denominators 065 for (Quotient<C> y : A.getMap().values()) { 066 x = y.den; 067 // c = lcm(c,x) 068 if (c == null) { 069 c = x; 070 s = x.signum(); 071 } else { 072 d = ufd.gcd(c, x); 073 c = c.multiply(x.divide(d)); 074 } 075 } 076 if (s < 0) { 077 c = c.negate(); 078 } 079 for (Map.Entry<ExpVector, Quotient<C>> y : A.getMap().entrySet()) { 080 ExpVector e = y.getKey(); 081 Quotient<C> a = y.getValue(); 082 // p = n*(c/d) 083 GenPolynomial<C> b = c.divide(a.den); 084 GenPolynomial<C> p = a.num.multiply(b); 085 //B = B.sum( p, e ); // inefficient 086 B.doPutToMap(e, p); 087 } 088 return B; 089 } 090 091 092 /** 093 * Integral polynomial from rational function coefficients. Represent as 094 * polynomial with integral polynomial coefficients by multiplication with 095 * the lcm of the numerators of the rational function coefficients. 096 * @param fac result polynomial factory. 097 * @param L list of polynomial with rational function coefficients to be 098 * converted. 099 * @return list of polynomials with integral polynomial coefficients. 100 */ 101 public static <C extends GcdRingElem<C>> List<GenPolynomial<GenPolynomial<C>>> integralFromQuotientCoefficients( 102 GenPolynomialRing<GenPolynomial<C>> fac, Collection<GenPolynomial<Quotient<C>>> L) { 103 if (L == null) { 104 return null; 105 } 106 List<GenPolynomial<GenPolynomial<C>>> list = new ArrayList<GenPolynomial<GenPolynomial<C>>>(L.size()); 107 for (GenPolynomial<Quotient<C>> p : L) { 108 list.add(integralFromQuotientCoefficients(fac, p)); 109 } 110 return list; 111 } 112 113 114 /** 115 * Rational function from integral polynomial coefficients. Represent as 116 * polynomial with type Quotient<C> coefficients. 117 * @param fac result polynomial factory. 118 * @param A polynomial with integral polynomial coefficients to be 119 * converted. 120 * @return polynomial with type Quotient<C> coefficients. 121 */ 122 public static <C extends GcdRingElem<C>> GenPolynomial<Quotient<C>> quotientFromIntegralCoefficients( 123 GenPolynomialRing<Quotient<C>> fac, GenPolynomial<GenPolynomial<C>> A) { 124 GenPolynomial<Quotient<C>> B = fac.getZERO().copy(); 125 if (A == null || A.isZERO()) { 126 return B; 127 } 128 RingFactory<Quotient<C>> cfac = fac.coFac; 129 QuotientRing<C> qfac = (QuotientRing<C>) cfac; 130 for (Map.Entry<ExpVector, GenPolynomial<C>> y : A.getMap().entrySet()) { 131 ExpVector e = y.getKey(); 132 GenPolynomial<C> a = y.getValue(); 133 Quotient<C> p = new Quotient<C>(qfac, a); // can not be zero 134 if (!p.isZERO()) { 135 //B = B.sum( p, e ); // inefficient 136 B.doPutToMap(e, p); 137 } 138 } 139 return B; 140 } 141 142 143 /** 144 * Rational function from integral polynomial coefficients. Represent as 145 * polynomial with type Quotient<C> coefficients. 146 * @param fac result polynomial factory. 147 * @param L list of polynomials with integral polynomial coefficients to be 148 * converted. 149 * @return list of polynomials with type Quotient<C> coefficients. 150 */ 151 public static <C extends GcdRingElem<C>> List<GenPolynomial<Quotient<C>>> quotientFromIntegralCoefficients( 152 GenPolynomialRing<Quotient<C>> fac, Collection<GenPolynomial<GenPolynomial<C>>> L) { 153 if (L == null) { 154 return null; 155 } 156 List<GenPolynomial<Quotient<C>>> list = new ArrayList<GenPolynomial<Quotient<C>>>(L.size()); 157 for (GenPolynomial<GenPolynomial<C>> p : L) { 158 list.add(quotientFromIntegralCoefficients(fac, p)); 159 } 160 return list; 161 } 162 163 164 /** 165 * From BigInteger coefficients. Represent as polynomial with type 166 * GenPolynomial<C> coefficients, e.g. ModInteger or BigRational. 167 * @param fac result polynomial factory. 168 * @param A polynomial with GenPolynomial<BigInteger> coefficients to 169 * be converted. 170 * @return polynomial with type GenPolynomial<C> coefficients. 171 */ 172 public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> fromIntegerCoefficients( 173 GenPolynomialRing<GenPolynomial<C>> fac, GenPolynomial<GenPolynomial<BigInteger>> A) { 174 GenPolynomial<GenPolynomial<C>> B = fac.getZERO().copy(); 175 if (A == null || A.isZERO()) { 176 return B; 177 } 178 RingFactory<GenPolynomial<C>> cfac = fac.coFac; 179 GenPolynomialRing<C> rfac = (GenPolynomialRing<C>) cfac; 180 for (Map.Entry<ExpVector, GenPolynomial<BigInteger>> y : A.getMap().entrySet()) { 181 ExpVector e = y.getKey(); 182 GenPolynomial<BigInteger> a = y.getValue(); 183 GenPolynomial<C> p = PolyUtil.<C> fromIntegerCoefficients(rfac, a); 184 if (!p.isZERO()) { 185 //B = B.sum( p, e ); // inefficient 186 B.doPutToMap(e, p); 187 } 188 } 189 return B; 190 } 191 192 193 /** 194 * From BigInteger coefficients. Represent as polynomial with type 195 * GenPolynomial<C> coefficients, e.g. ModInteger or BigRational. 196 * @param fac result polynomial factory. 197 * @param L polynomial list with GenPolynomial<BigInteger> 198 * coefficients to be converted. 199 * @return polynomial list with polynomials with type GenPolynomial<C> 200 * coefficients. 201 */ 202 public static <C extends RingElem<C>> List<GenPolynomial<GenPolynomial<C>>> fromIntegerCoefficients( 203 GenPolynomialRing<GenPolynomial<C>> fac, List<GenPolynomial<GenPolynomial<BigInteger>>> L) { 204 List<GenPolynomial<GenPolynomial<C>>> K = null; 205 if (L == null) { 206 return K; 207 } 208 K = new ArrayList<GenPolynomial<GenPolynomial<C>>>(L.size()); 209 if (L.size() == 0) { 210 return K; 211 } 212 for (GenPolynomial<GenPolynomial<BigInteger>> a : L) { 213 GenPolynomial<GenPolynomial<C>> b = fromIntegerCoefficients(fac, a); 214 K.add(b); 215 } 216 return K; 217 } 218 219 //------------------------------ 220 221 /** 222 * BigInteger from BigRational coefficients. Represent as polynomial with type 223 * GenPolynomial<BigInteger> coefficients. 224 * @param fac result polynomial factory. 225 * @param A polynomial with GenPolynomial<BigRational> coefficients to 226 * be converted. 227 * @return polynomial with type GenPolynomial<BigInteger> coefficients. 228 */ 229 public static GenPolynomial<GenPolynomial<BigInteger>> integerFromRationalCoefficients( 230 GenPolynomialRing<GenPolynomial<BigInteger>> fac, GenPolynomial<GenPolynomial<BigRational>> A) { 231 GenPolynomial<GenPolynomial<BigInteger>> B = fac.getZERO().copy(); 232 if (A == null || A.isZERO()) { 233 return B; 234 } 235 RingFactory<GenPolynomial<BigInteger>> cfac = fac.coFac; 236 GenPolynomialRing<BigInteger> rfac = (GenPolynomialRing<BigInteger>) cfac; 237 for (Map.Entry<ExpVector, GenPolynomial<BigRational>> y : A.getMap().entrySet()) { 238 ExpVector e = y.getKey(); 239 GenPolynomial<BigRational> a = y.getValue(); 240 // TODO: check/fix common denominator 241 GenPolynomial<BigInteger> p = PolyUtil.integerFromRationalCoefficients(rfac, a); 242 if (!p.isZERO()) { 243 //B = B.sum( p, e ); // inefficient 244 B.doPutToMap(e, p); 245 } 246 } 247 return B; 248 } 249 250 251 /** 252 * BigInteger from BigRational coefficients. Represent as polynomial with type 253 * GenPolynomial<BigInteger> coefficients. 254 * @param fac result polynomial factory. 255 * @param L polynomial list with GenPolynomial<BigRational> 256 * coefficients to be converted. 257 * @return polynomial list with polynomials with type GenPolynomial<BigInteger> 258 * coefficients. 259 */ 260 public static List<GenPolynomial<GenPolynomial<BigInteger>>> integerFromRationalCoefficients( 261 GenPolynomialRing<GenPolynomial<BigInteger>> fac, List<GenPolynomial<GenPolynomial<BigRational>>> L) { 262 List<GenPolynomial<GenPolynomial<BigInteger>>> K = null; 263 if (L == null) { 264 return K; 265 } 266 K = new ArrayList<GenPolynomial<GenPolynomial<BigInteger>>>(L.size()); 267 if (L.isEmpty()) { 268 return K; 269 } 270 for (GenPolynomial<GenPolynomial<BigRational>> a : L) { 271 GenPolynomial<GenPolynomial<BigInteger>> b = integerFromRationalCoefficients(fac, a); 272 K.add(b); 273 } 274 return K; 275 } 276 277 278 /** 279 * Introduce lower variable. Represent as polynomial with type 280 * GenPolynomial<C> coefficients. 281 * @param rfac result polynomial factory. 282 * @param A polynomial to be extended. 283 * @return polynomial with type GenPolynomial<C> coefficients. 284 */ 285 public static <C extends GcdRingElem<C>> GenPolynomial<GenPolynomial<C>> introduceLowerVariable( 286 GenPolynomialRing<GenPolynomial<C>> rfac, GenPolynomial<C> A) { 287 if (A == null || rfac == null) { 288 return null; 289 } 290 GenPolynomial<GenPolynomial<C>> Pc = rfac.getONE().multiply(A); 291 if (Pc.isZERO()) { 292 return Pc; 293 } 294 Pc = PolyUtil.<C> switchVariables(Pc); 295 return Pc; 296 } 297 298 299 /** 300 * From AlgebraicNumber coefficients. Represent as polynomial with type 301 * GenPolynomial<C> coefficients, e.g. ModInteger or BigRational. 302 * @param rfac result polynomial factory. 303 * @param A polynomial with AlgebraicNumber coefficients to be converted. 304 * @param k for (y-k x) substitution. 305 * @return polynomial with type GenPolynomial<C> coefficients. 306 */ 307 public static <C extends GcdRingElem<C>> GenPolynomial<GenPolynomial<C>> substituteFromAlgebraicCoefficients( 308 GenPolynomialRing<GenPolynomial<C>> rfac, GenPolynomial<AlgebraicNumber<C>> A, long k) { 309 if (A == null || rfac == null) { 310 return null; 311 } 312 if (A.isZERO()) { 313 return rfac.getZERO(); 314 } 315 // setup x - k alpha 316 GenPolynomialRing<AlgebraicNumber<C>> apfac = A.ring; 317 GenPolynomial<AlgebraicNumber<C>> x = apfac.univariate(0); 318 AlgebraicNumberRing<C> afac = (AlgebraicNumberRing<C>) A.ring.coFac; 319 AlgebraicNumber<C> alpha = afac.getGenerator(); 320 AlgebraicNumber<C> ka = afac.fromInteger(k); 321 GenPolynomial<AlgebraicNumber<C>> s = x.subtract(ka.multiply(alpha)); // x - k alpha 322 if (debug) { 323 logger.info("x - k alpha: " + s); 324 } 325 // substitute, convert and switch 326 GenPolynomial<AlgebraicNumber<C>> B = PolyUtil.<AlgebraicNumber<C>> substituteMain(A, s); 327 GenPolynomial<GenPolynomial<C>> Pc = PolyUtil.<C> fromAlgebraicCoefficients(rfac, B); // Q[alpha][x] 328 Pc = PolyUtil.<C> switchVariables(Pc); // Q[x][alpha] 329 return Pc; 330 } 331 332 333 /** 334 * Convert to AlgebraicNumber coefficients. Represent as polynomial with 335 * AlgebraicNumber<C> coefficients, C is e.g. ModInteger or BigRational. 336 * @param pfac result polynomial factory. 337 * @param A polynomial with GenPolynomial<BigInteger> coefficients to 338 * be converted. 339 * @param k for (y-k x) substitution. 340 * @return polynomial with AlgebraicNumber<C> coefficients. 341 */ 342 public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> substituteConvertToAlgebraicCoefficients( 343 GenPolynomialRing<AlgebraicNumber<C>> pfac, GenPolynomial<C> A, long k) { 344 if (A == null || pfac == null) { 345 return null; 346 } 347 if (A.isZERO()) { 348 return pfac.getZERO(); 349 } 350 // convert to Q(alpha)[x] 351 GenPolynomial<AlgebraicNumber<C>> B = PolyUtil.<C> convertToAlgebraicCoefficients(pfac, A); 352 // setup x .+. k alpha for back substitution 353 GenPolynomial<AlgebraicNumber<C>> x = pfac.univariate(0); 354 AlgebraicNumberRing<C> afac = (AlgebraicNumberRing<C>) pfac.coFac; 355 AlgebraicNumber<C> alpha = afac.getGenerator(); 356 AlgebraicNumber<C> ka = afac.fromInteger(k); 357 GenPolynomial<AlgebraicNumber<C>> s = x.sum(ka.multiply(alpha)); // x + k alpha 358 // substitute 359 GenPolynomial<AlgebraicNumber<C>> N = PolyUtil.<AlgebraicNumber<C>> substituteMain(B, s); 360 return N; 361 } 362 363 364 /** 365 * Norm of a polynomial with AlgebraicNumber coefficients. 366 * @param A polynomial from GenPolynomial<AlgebraicNumber<C>>. 367 * @param k for (y - k x) substitution. 368 * @return norm(A) = res_x(A(x,y),m(x)) in GenPolynomialRing<C>. 369 */ 370 public static <C extends GcdRingElem<C>> GenPolynomial<C> norm(GenPolynomial<AlgebraicNumber<C>> A, long k) { 371 if (A == null) { 372 return null; 373 } 374 GenPolynomialRing<AlgebraicNumber<C>> pfac = A.ring; // Q(alpha)[x] 375 if (pfac.nvar > 1) { 376 throw new IllegalArgumentException("only for univariate polynomials"); 377 } 378 AlgebraicNumberRing<C> afac = (AlgebraicNumberRing<C>) pfac.coFac; 379 GenPolynomial<C> agen = afac.modul; 380 GenPolynomialRing<C> cfac = afac.ring; 381 if (A.isZERO()) { 382 return cfac.getZERO(); 383 } 384 AlgebraicNumber<C> ldcf = A.leadingBaseCoefficient(); 385 if (!ldcf.isONE()) { 386 A = A.monic(); 387 } 388 GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(cfac, pfac); 389 390 // transform minimal polynomial to bi-variate polynomial 391 GenPolynomial<GenPolynomial<C>> Ac = PolyUfdUtil.<C> introduceLowerVariable(rfac, agen); 392 //System.out.println("Ac = " + Ac.toScript()); 393 394 // transform to bi-variate polynomial, 395 // switching varaible sequence from Q[alpha][x] to Q[X][alpha] 396 GenPolynomial<GenPolynomial<C>> Pc = PolyUfdUtil.<C> substituteFromAlgebraicCoefficients(rfac, A, k); 397 Pc = PolyUtil.<C> monic(Pc); 398 //System.out.println("Pc = " + Pc.toScript()); 399 400 GreatestCommonDivisorSubres<C> engine = new GreatestCommonDivisorSubres<C>( /*cfac.coFac*/); 401 // = (GreatestCommonDivisorAbstract<C>)GCDFactory.<C>getImplementation( cfac.coFac ); 402 403 GenPolynomial<GenPolynomial<C>> Rc = engine.recursiveUnivariateResultant(Pc, Ac); 404 //System.out.println("Rc = " + Rc.toScript()); 405 GenPolynomial<C> res = Rc.leadingBaseCoefficient(); 406 res = res.monic(); 407 return res; 408 } 409 410 411 /** 412 * Norm of a polynomial with AlgebraicNumber coefficients. 413 * @param A polynomial from GenPolynomial<AlgebraicNumber<C>>. 414 * @return norm(A) = resultant_x( A(x,y), m(x) ) in K[y]. 415 */ 416 public static <C extends GcdRingElem<C>> GenPolynomial<C> norm(GenPolynomial<AlgebraicNumber<C>> A) { 417 return norm(A, 0L); 418 } 419 420 421 /** 422 * Ensure that the field property is determined. Checks if modul is 423 * irreducible and modifies the algebraic number ring. 424 * @param afac algebraic number ring. 425 */ 426 public static <C extends GcdRingElem<C>> void ensureFieldProperty(AlgebraicNumberRing<C> afac) { 427 if (afac.getField() != -1) { 428 return; 429 } 430 if (!afac.ring.coFac.isField()) { 431 afac.setField(false); 432 return; 433 } 434 Factorization<C> mf = FactorFactory.<C> getImplementation(afac.ring); 435 if (mf.isIrreducible(afac.modul)) { 436 afac.setField(true); 437 } else { 438 afac.setField(false); 439 } 440 } 441 442 443 /** 444 * Kronecker substitution. Substitute x_i by x**d**(i-1) to construct a 445 * univariate polynomial. 446 * @param A polynomial to be converted. 447 * @return a univariate polynomial. 448 */ 449 public static <C extends GcdRingElem<C>> GenPolynomial<C> substituteKronecker(GenPolynomial<C> A) { 450 if (A == null) { 451 return A; 452 } 453 long d = A.degree() + 1L; 454 return substituteKronecker(A, d); 455 } 456 457 458 /** 459 * Kronecker substitution. Substitute x_i by x**d**(i-1) to construct a 460 * univariate polynomial. 461 * @param A polynomial to be converted. 462 * @return a univariate polynomial. 463 */ 464 public static <C extends GcdRingElem<C>> GenPolynomial<C> substituteKronecker(GenPolynomial<C> A, long d) { 465 if (A == null) { 466 return A; 467 } 468 RingFactory<C> cfac = A.ring.coFac; 469 GenPolynomialRing<C> ufac = new GenPolynomialRing<C>(cfac, 1); 470 GenPolynomial<C> B = ufac.getZERO().copy(); 471 if (A.isZERO()) { 472 return B; 473 } 474 for (Map.Entry<ExpVector, C> y : A.getMap().entrySet()) { 475 ExpVector e = y.getKey(); 476 C a = y.getValue(); 477 long f = 0L; 478 long h = 1L; 479 for (int i = 0; i < e.length(); i++) { 480 long j = e.getVal(i) * h; 481 f += j; 482 h *= d; 483 } 484 ExpVector g = ExpVector.create(1, 0, f); 485 B.doPutToMap(g, a); 486 } 487 return B; 488 } 489 490 491 /** 492 * Kronecker substitution. Substitute x_i by x**d**(i-1) to construct a 493 * univariate polynomials. 494 * @param A list of polynomials to be converted. 495 * @return a list of univariate polynomials. 496 */ 497 public static <C extends GcdRingElem<C>> List<GenPolynomial<C>> substituteKronecker( 498 List<GenPolynomial<C>> A, int d) { 499 if (A == null || A.get(0) == null) { 500 return null; 501 } 502 return ListUtil.<GenPolynomial<C>, GenPolynomial<C>> map(A, new SubstKronecker<C>(d)); 503 } 504 505 506 /** 507 * Kronecker back substitution. Substitute x**d**(i-1) to x_i to construct a 508 * multivariate polynomial. 509 * @param A polynomial to be converted. 510 * @param fac result polynomial factory. 511 * @return a multivariate polynomial. 512 */ 513 public static <C extends GcdRingElem<C>> GenPolynomial<C> backSubstituteKronecker( 514 GenPolynomialRing<C> fac, GenPolynomial<C> A, long d) { 515 if (A == null) { 516 return A; 517 } 518 if (fac == null) { 519 throw new IllegalArgumentException("null factory not allowed "); 520 } 521 int n = fac.nvar; 522 GenPolynomial<C> B = fac.getZERO().copy(); 523 if (A.isZERO()) { 524 return B; 525 } 526 for (Map.Entry<ExpVector, C> y : A.getMap().entrySet()) { 527 ExpVector e = y.getKey(); 528 C a = y.getValue(); 529 long f = e.getVal(0); 530 ExpVector g = ExpVector.create(n); 531 for (int i = 0; i < n; i++) { 532 long j = f % d; 533 f /= d; 534 g = g.subst(i, j); 535 } 536 B.doPutToMap(g, a); 537 } 538 return B; 539 } 540 541 542 /** 543 * Kronecker back substitution. Substitute x**d**(i-1) to x_i to construct a 544 * multivariate polynomials. 545 * @param A list of polynomials to be converted. 546 * @param fac result polynomial factory. 547 * @return a list of multivariate polynomials. 548 */ 549 public static <C extends GcdRingElem<C>> List<GenPolynomial<C>> backSubstituteKronecker( 550 GenPolynomialRing<C> fac, List<GenPolynomial<C>> A, long d) { 551 return ListUtil.<GenPolynomial<C>, GenPolynomial<C>> map(A, new BackSubstKronecker<C>(fac, d)); 552 } 553 554} 555 556 557/** 558 * Kronecker substitutuion functor. 559 */ 560class SubstKronecker<C extends GcdRingElem<C>> implements UnaryFunctor<GenPolynomial<C>, GenPolynomial<C>> { 561 562 563 final long d; 564 565 566 public SubstKronecker(long d) { 567 this.d = d; 568 } 569 570 571 public GenPolynomial<C> eval(GenPolynomial<C> c) { 572 if (c == null) { 573 return null; 574 } 575 return PolyUfdUtil.<C> substituteKronecker(c, d); 576 } 577} 578 579 580/** 581 * Kronecker back substitutuion functor. 582 */ 583class BackSubstKronecker<C extends GcdRingElem<C>> implements 584 UnaryFunctor<GenPolynomial<C>, GenPolynomial<C>> { 585 586 587 final long d; 588 589 590 final GenPolynomialRing<C> fac; 591 592 593 public BackSubstKronecker(GenPolynomialRing<C> fac, long d) { 594 this.d = d; 595 this.fac = fac; 596 } 597 598 599 public GenPolynomial<C> eval(GenPolynomial<C> c) { 600 if (c == null) { 601 return null; 602 } 603 return PolyUfdUtil.<C> backSubstituteKronecker(fac, c, d); 604 } 605}