/** * Univariate GenPolynomial algebraic partial fraction decomposition, via absolute factorization * to linear factors. * * @param A univariate GenPolynomial, deg(A) < deg(P). * @param P univariate squarefree GenPolynomial, gcd(A,P) == 1. * @return partial fraction container. */ public PartialFraction<C> baseAlgebraicPartialFractionIrreducibleAbsolute( GenPolynomial<C> A, GenPolynomial<C> P) { if (P == null || P.isZERO()) { throw new RuntimeException(" P == null or P == 0"); } // System.out.println("\nP_base_algeb_part = " + P); GenPolynomialRing<C> pfac = P.ring; // K[x] if (pfac.nvar > 1) { // System.out.println("facs_base_irred: univ"); throw new RuntimeException("only for univariate polynomials"); } if (!pfac.coFac.isField()) { // System.out.println("facs_base_irred: field"); throw new RuntimeException("only for field coefficients"); } List<C> cfactors = new ArrayList<C>(); List<GenPolynomial<C>> cdenom = new ArrayList<GenPolynomial<C>>(); List<AlgebraicNumber<C>> afactors = new ArrayList<AlgebraicNumber<C>>(); List<GenPolynomial<AlgebraicNumber<C>>> adenom = new ArrayList<GenPolynomial<AlgebraicNumber<C>>>(); // P linear if (P.degree(0) <= 1) { cfactors.add(A.leadingBaseCoefficient()); cdenom.add(P); return new PartialFraction<C>(A, P, cfactors, cdenom, afactors, adenom); } // non linear case Factors<C> afacs = factorsAbsoluteIrreducible(P); // System.out.println("linear algebraic factors = " + afacs); // System.out.println("afactors = " + afacs.afactors); // System.out.println("arfactors = " + afacs.arfactors); // System.out.println("arfactors pol = " + afacs.arfactors.get(0).poly); // System.out.println("arfactors2 = " + afacs.arfactors.get(0).afactors); List<GenPolynomial<AlgebraicNumber<C>>> fact = afacs.getFactors(); // System.out.println("factors = " + fact); GenPolynomial<AlgebraicNumber<C>> Pa = afacs.apoly; GenPolynomial<AlgebraicNumber<C>> Aa = PolyUtil.<C>convertToRecAlgebraicCoefficients(1, Pa.ring, A); GreatestCommonDivisorAbstract<AlgebraicNumber<C>> aengine = GCDFactory.getProxy(afacs.afac); // System.out.println("denom = " + Pa); // System.out.println("numer = " + Aa); List<GenPolynomial<AlgebraicNumber<C>>> numers = aengine.basePartialFraction(Aa, fact); // System.out.println("part frac = " + numers); GenPolynomial<AlgebraicNumber<C>> A0 = numers.remove(0); if (!A0.isZERO()) { throw new RuntimeException(" A0 != 0: deg(A)>= deg(P)"); } int i = 0; for (GenPolynomial<AlgebraicNumber<C>> fa : fact) { GenPolynomial<AlgebraicNumber<C>> an = numers.get(i++); if (fa.degree(0) <= 1) { afactors.add(an.leadingBaseCoefficient()); adenom.add(fa); continue; } System.out.println("fa = " + fa); Factors<AlgebraicNumber<C>> faf = afacs.getFactor(fa); System.out.println("faf = " + faf); List<GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>>> fafact = faf.getFactors(); GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>> Aaa = PolyUtil.<AlgebraicNumber<C>>convertToRecAlgebraicCoefficients(1, faf.apoly.ring, an); GreatestCommonDivisorAbstract<AlgebraicNumber<AlgebraicNumber<C>>> aaengine = GCDFactory.getImplementation(faf.afac); List<GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>>> anumers = aaengine.basePartialFraction(Aaa, fafact); System.out.println("algeb part frac = " + anumers); GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>> A0a = anumers.remove(0); if (!A0a.isZERO()) { throw new RuntimeException(" A0 != 0: deg(A)>= deg(P)"); } int k = 0; for (GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>> faa : fafact) { GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>> ana = anumers.get(k++); System.out.println("faa = " + faa); System.out.println("ana = " + ana); if (faa.degree(0) > 1) { throw new RuntimeException(" faa not linear"); } GenPolynomial<AlgebraicNumber<C>> ana1 = (GenPolynomial<AlgebraicNumber<C>>) (GenPolynomial) ana; GenPolynomial<AlgebraicNumber<C>> faa1 = (GenPolynomial<AlgebraicNumber<C>>) (GenPolynomial) faa; afactors.add(ana1.leadingBaseCoefficient()); adenom.add(faa1); } } return new PartialFraction<C>(A, P, cfactors, cdenom, afactors, adenom); }
/** * Univariate GenPolynomial algebraic partial fraction decomposition, Rothstein-Trager algorithm. * * @param A univariate GenPolynomial, deg(A) < deg(P). * @param P univariate squarefree GenPolynomial, gcd(A,P) == 1. * @return partial fraction container. */ @Deprecated public PartialFraction<C> baseAlgebraicPartialFractionIrreducible( GenPolynomial<C> A, GenPolynomial<C> P) { if (P == null || P.isZERO()) { throw new RuntimeException(" P == null or P == 0"); } // System.out.println("\nP_base_algeb_part = " + P); GenPolynomialRing<C> pfac = P.ring; // K[x] if (pfac.nvar > 1) { // System.out.println("facs_base_irred: univ"); throw new RuntimeException("only for univariate polynomials"); } if (!pfac.coFac.isField()) { // System.out.println("facs_base_irred: field"); throw new RuntimeException("only for field coefficients"); } List<C> cfactors = new ArrayList<C>(); List<GenPolynomial<C>> cdenom = new ArrayList<GenPolynomial<C>>(); List<AlgebraicNumber<C>> afactors = new ArrayList<AlgebraicNumber<C>>(); List<GenPolynomial<AlgebraicNumber<C>>> adenom = new ArrayList<GenPolynomial<AlgebraicNumber<C>>>(); // P linear if (P.degree(0) <= 1) { cfactors.add(A.leadingBaseCoefficient()); cdenom.add(P); return new PartialFraction<C>(A, P, cfactors, cdenom, afactors, adenom); } // deriviative GenPolynomial<C> Pp = PolyUtil.<C>baseDeriviative(P); // no: Pp = Pp.monic(); // System.out.println("\nP = " + P); // System.out.println("Pp = " + Pp); // Q[t] String[] vars = new String[] {"t"}; GenPolynomialRing<C> cfac = new GenPolynomialRing<C>(pfac.coFac, 1, pfac.tord, vars); GenPolynomial<C> t = cfac.univariate(0); // System.out.println("t = " + t); // Q[x][t] GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(pfac, cfac); // sic // System.out.println("rfac = " + rfac.toScript()); // transform polynomials to bi-variate polynomial GenPolynomial<GenPolynomial<C>> Ac = PolyUfdUtil.<C>introduceLowerVariable(rfac, A); // System.out.println("Ac = " + Ac); GenPolynomial<GenPolynomial<C>> Pc = PolyUfdUtil.<C>introduceLowerVariable(rfac, P); // System.out.println("Pc = " + Pc); GenPolynomial<GenPolynomial<C>> Pcp = PolyUfdUtil.<C>introduceLowerVariable(rfac, Pp); // System.out.println("Pcp = " + Pcp); // Q[t][x] GenPolynomialRing<GenPolynomial<C>> rfac1 = Pc.ring; // System.out.println("rfac1 = " + rfac1.toScript()); // A - t P' GenPolynomial<GenPolynomial<C>> tc = rfac1.getONE().multiply(t); // System.out.println("tc = " + tc); GenPolynomial<GenPolynomial<C>> At = Ac.subtract(tc.multiply(Pcp)); // System.out.println("At = " + At); GreatestCommonDivisorSubres<C> engine = new GreatestCommonDivisorSubres<C>(); // = GCDFactory.<C>getImplementation( cfac.coFac ); GreatestCommonDivisorAbstract<AlgebraicNumber<C>> aengine = null; GenPolynomial<GenPolynomial<C>> Rc = engine.recursiveResultant(Pc, At); // System.out.println("Rc = " + Rc); GenPolynomial<C> res = Rc.leadingBaseCoefficient(); // no: res = res.monic(); // System.out.println("\nres = " + res); SortedMap<GenPolynomial<C>, Long> resfac = baseFactors(res); // System.out.println("resfac = " + resfac + "\n"); for (GenPolynomial<C> r : resfac.keySet()) { // System.out.println("\nr(t) = " + r); if (r.isConstant()) { continue; } // if ( r.degree(0) <= 1L ) { // System.out.println("warning linear factor in resultant ignored"); // continue; // //throw new RuntimeException("input not irreducible"); // } // vars = new String[] { "z_" + Math.abs(r.hashCode() % 1000) }; vars = pfac.newVars("z_"); pfac = pfac.clone(); vars = pfac.setVars(vars); r = pfac.copy(r); // hack to exchange the variables // System.out.println("r(z_) = " + r); AlgebraicNumberRing<C> afac = new AlgebraicNumberRing<C>(r, true); // since irreducible logger.debug("afac = " + afac.toScript()); AlgebraicNumber<C> a = afac.getGenerator(); // no: a = a.negate(); // System.out.println("a = " + a); // K(alpha)[x] GenPolynomialRing<AlgebraicNumber<C>> pafac = new GenPolynomialRing<AlgebraicNumber<C>>(afac, Pc.ring); // System.out.println("pafac = " + pafac.toScript()); // convert to K(alpha)[x] GenPolynomial<AlgebraicNumber<C>> Pa = PolyUtil.<C>convertToAlgebraicCoefficients(pafac, P); // System.out.println("Pa = " + Pa); GenPolynomial<AlgebraicNumber<C>> Pap = PolyUtil.<C>convertToAlgebraicCoefficients(pafac, Pp); // System.out.println("Pap = " + Pap); GenPolynomial<AlgebraicNumber<C>> Aa = PolyUtil.<C>convertToAlgebraicCoefficients(pafac, A); // System.out.println("Aa = " + Aa); // A - a P' GenPolynomial<AlgebraicNumber<C>> Ap = Aa.subtract(Pap.multiply(a)); // System.out.println("Ap = " + Ap); if (aengine == null) { aengine = GCDFactory.<AlgebraicNumber<C>>getImplementation(afac); // System.out.println("aengine = " + aengine); } GenPolynomial<AlgebraicNumber<C>> Ga = aengine.baseGcd(Pa, Ap); // System.out.println("Ga = " + Ga); if (Ga.isConstant()) { // System.out.println("warning constant gcd ignored"); continue; } afactors.add(a); adenom.add(Ga); // quadratic case if (P.degree(0) == 2 && Ga.degree(0) == 1) { GenPolynomial<AlgebraicNumber<C>>[] qra = PolyUtil.<AlgebraicNumber<C>>basePseudoQuotientRemainder(Pa, Ga); GenPolynomial<AlgebraicNumber<C>> Qa = qra[0]; if (!qra[1].isZERO()) { throw new RuntimeException("remainder not zero"); } // System.out.println("Qa = " + Qa); afactors.add(a.negate()); adenom.add(Qa); } if (false && P.degree(0) == 3 && Ga.degree(0) == 1) { GenPolynomial<AlgebraicNumber<C>>[] qra = PolyUtil.<AlgebraicNumber<C>>basePseudoQuotientRemainder(Pa, Ga); GenPolynomial<AlgebraicNumber<C>> Qa = qra[0]; if (!qra[1].isZERO()) { throw new RuntimeException("remainder not zero"); } System.out.println("Qa3 = " + Qa); // afactors.add( a.negate() ); // adenom.add( Qa ); } } return new PartialFraction<C>(A, P, cfactors, cdenom, afactors, adenom); }