/** * The constructor creates a Quotient object from a ring factory and a numerator and denominator * element. * * @param r ring factory. * @param n numerator. * @param d denominator. * @param isred true if gcd(n,d) == 1, else false. */ @SuppressWarnings("unchecked") protected Quotient(QuotientRing<C> r, C n, C d, boolean isred) { if (d == null || d.isZERO()) { throw new IllegalArgumentException("denominator may not be zero"); } ring = r; if (d.signum() < 0) { n = n.negate(); d = d.negate(); } if (isred) { num = n; den = d; return; } // must reduce to lowest terms if (n instanceof GcdRingElem && d instanceof GcdRingElem) { GcdRingElem ng = (GcdRingElem) n; GcdRingElem dg = (GcdRingElem) d; C gcd = (C) ng.gcd(dg); if (debug) { logger.info("gcd = " + gcd); } // RingElem<C> gcd = ring.ring.getONE(); if (gcd.isONE()) { num = n; den = d; } else { num = n.divide(gcd); den = d.divide(gcd); } // } else { // univariate polynomial? } else { logger.warn("gcd = ????"); num = n; den = d; } }
/** * GenPolynomial recursive univariate polynomial squarefree factorization. * * @param P recursive univariate GenPolynomial. * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} p_i^{e_i} and p_i * squarefree. */ @Override public SortedMap<GenPolynomial<GenPolynomial<C>>, Long> recursiveUnivariateSquarefreeFactors( GenPolynomial<GenPolynomial<C>> P) { SortedMap<GenPolynomial<GenPolynomial<C>>, Long> sfactors = new TreeMap<GenPolynomial<GenPolynomial<C>>, Long>(); if (P == null || P.isZERO()) { return sfactors; } GenPolynomialRing<GenPolynomial<C>> pfac = P.ring; if (pfac.nvar > 1) { // recursiveContent not possible by return type throw new IllegalArgumentException( this.getClass().getName() + " only for univariate polynomials"); } // if base coefficient ring is a field, make monic GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) pfac.coFac; C ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient(); if (!ldbcf.isONE()) { GenPolynomial<C> lc = cfac.getONE().multiply(ldbcf); GenPolynomial<GenPolynomial<C>> pl = pfac.getONE().multiply(lc); sfactors.put(pl, 1L); C li = ldbcf.inverse(); // System.out.println("li = " + li); P = P.multiply(cfac.getONE().multiply(li)); // System.out.println("P,monic = " + P); ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient(); if (debug) { logger.debug("new ldbcf: " + ldbcf); } } // factors of content GenPolynomial<C> Pc = engine.recursiveContent(P); if (logger.isInfoEnabled()) { logger.info("Pc = " + Pc); } Pc = Pc.monic(); if (!Pc.isONE()) { P = PolyUtil.<C>coefficientPseudoDivide(P, Pc); } SortedMap<GenPolynomial<C>, Long> rsf = squarefreeFactors(Pc); if (logger.isInfoEnabled()) { logger.info("rsf = " + rsf); } // add factors of content for (Map.Entry<GenPolynomial<C>, Long> me : rsf.entrySet()) { GenPolynomial<C> c = me.getKey(); if (!c.isONE()) { GenPolynomial<GenPolynomial<C>> cr = pfac.getONE().multiply(c); Long rk = me.getValue(); // rsf.get(c); sfactors.put(cr, rk); } } // factors of recursive polynomial GenPolynomial<GenPolynomial<C>> T0 = P; long e = 1L; GenPolynomial<GenPolynomial<C>> Tp; GenPolynomial<GenPolynomial<C>> T = null; GenPolynomial<GenPolynomial<C>> V = null; long k = 0L; long mp = 0L; boolean init = true; while (true) { if (init) { if (T0.isConstant() || T0.isZERO()) { break; } Tp = PolyUtil.<C>recursiveDeriviative(T0); T = engine.recursiveUnivariateGcd(T0, Tp); T = PolyUtil.<C>monic(T); V = PolyUtil.<C>recursivePseudoDivide(T0, T); // System.out.println("iT0 = " + T0); // System.out.println("iTp = " + Tp); // System.out.println("iT = " + T); // System.out.println("iV = " + V); k = 0L; mp = 0L; init = false; } if (V.isConstant()) { mp = pfac.characteristic().longValue(); // assert != 0 // T0 = PolyUtil.<C> recursiveModRoot(T,mp); T0 = recursiveUnivariateRootCharacteristic(T); logger.info("char root: T0r = " + T0 + ", Tr = " + T); if (T0 == null) { // break; T0 = pfac.getZERO(); } e = e * mp; init = true; // continue; } k++; if (mp != 0L && k % mp == 0L) { T = PolyUtil.<C>recursivePseudoDivide(T, V); System.out.println("k = " + k); // System.out.println("T = " + T); k++; } GenPolynomial<GenPolynomial<C>> W = engine.recursiveUnivariateGcd(T, V); W = PolyUtil.<C>monic(W); GenPolynomial<GenPolynomial<C>> z = PolyUtil.<C>recursivePseudoDivide(V, W); // System.out.println("W = " + W); // System.out.println("z = " + z); V = W; T = PolyUtil.<C>recursivePseudoDivide(T, V); // System.out.println("V = " + V); // System.out.println("T = " + T); // was: if ( z.degree(0) > 0 ) { if (!z.isONE() && !z.isZERO()) { z = PolyUtil.<C>monic(z); logger.info("z,put = " + z); sfactors.put(z, (e * k)); } } logger.info("exit char root: T0 = " + T0 + ", T = " + T); if (sfactors.size() == 0) { sfactors.put(pfac.getONE(), 1L); } return sfactors; }
/** * GenPolynomial polynomial squarefree factorization. * * @param A GenPolynomial. * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} p_i^{e_i} and p_i * squarefree. */ @Override public SortedMap<GenPolynomial<C>, Long> baseSquarefreeFactors(GenPolynomial<C> A) { SortedMap<GenPolynomial<C>, Long> sfactors = new TreeMap<GenPolynomial<C>, Long>(); if (A == null || A.isZERO()) { return sfactors; } GenPolynomialRing<C> pfac = A.ring; if (A.isConstant()) { C coeff = A.leadingBaseCoefficient(); // System.out.println("coeff = " + coeff + " @ " + coeff.factory()); SortedMap<C, Long> rfactors = squarefreeFactors(coeff); // System.out.println("rfactors,const = " + rfactors); if (rfactors != null && rfactors.size() > 0) { for (Map.Entry<C, Long> me : rfactors.entrySet()) { C c = me.getKey(); if (!c.isONE()) { GenPolynomial<C> cr = pfac.getONE().multiply(c); Long rk = me.getValue(); // rfactors.get(c); sfactors.put(cr, rk); } } } else { sfactors.put(A, 1L); } return sfactors; } if (pfac.nvar > 1) { throw new IllegalArgumentException( this.getClass().getName() + " only for univariate polynomials"); } C ldbcf = A.leadingBaseCoefficient(); if (!ldbcf.isONE()) { A = A.divide(ldbcf); SortedMap<C, Long> rfactors = squarefreeFactors(ldbcf); // System.out.println("rfactors,ldbcf = " + rfactors); if (rfactors != null && rfactors.size() > 0) { for (Map.Entry<C, Long> me : rfactors.entrySet()) { C c = me.getKey(); if (!c.isONE()) { GenPolynomial<C> cr = pfac.getONE().multiply(c); Long rk = me.getValue(); // rfactors.get(c); sfactors.put(cr, rk); } } } else { GenPolynomial<C> f1 = pfac.getONE().multiply(ldbcf); // System.out.println("gcda sqf f1 = " + f1); sfactors.put(f1, 1L); } ldbcf = pfac.coFac.getONE(); } GenPolynomial<C> T0 = A; long e = 1L; GenPolynomial<C> Tp; GenPolynomial<C> T = null; GenPolynomial<C> V = null; long k = 0L; long mp = 0L; boolean init = true; while (true) { // System.out.println("T0 = " + T0); if (init) { if (T0.isConstant() || T0.isZERO()) { break; } Tp = PolyUtil.<C>baseDeriviative(T0); T = engine.baseGcd(T0, Tp); T = T.monic(); V = PolyUtil.<C>basePseudoDivide(T0, T); // System.out.println("iT0 = " + T0); // System.out.println("iTp = " + Tp); // System.out.println("iT = " + T); // System.out.println("iV = " + V); // System.out.println("const(iV) = " + V.isConstant()); k = 0L; mp = 0L; init = false; } if (V.isConstant()) { mp = pfac.characteristic().longValue(); // assert != 0 // T0 = PolyUtil.<C> baseModRoot(T,mp); T0 = baseRootCharacteristic(T); logger.info("char root: T0 = " + T0 + ", T = " + T); if (T0 == null) { // break; T0 = pfac.getZERO(); } e = e * mp; init = true; continue; } k++; if (mp != 0L && k % mp == 0L) { T = PolyUtil.<C>basePseudoDivide(T, V); System.out.println("k = " + k); // System.out.println("T = " + T); k++; } GenPolynomial<C> W = engine.baseGcd(T, V); W = W.monic(); GenPolynomial<C> z = PolyUtil.<C>basePseudoDivide(V, W); // System.out.println("W = " + W); // System.out.println("z = " + z); V = W; T = PolyUtil.<C>basePseudoDivide(T, V); // System.out.println("V = " + V); // System.out.println("T = " + T); if (z.degree(0) > 0) { if (ldbcf.isONE() && !z.leadingBaseCoefficient().isONE()) { z = z.monic(); logger.info("z,monic = " + z); } sfactors.put(z, (e * k)); } } // look, a stupid error: // if ( !ldbcf.isONE() ) { // GenPolynomial<C> f1 = sfactors.firstKey(); // long e1 = sfactors.remove(f1); // System.out.println("gcda sqf c = " + c); // f1 = f1.multiply(c); // //System.out.println("gcda sqf f1e = " + f1); // sfactors.put(f1,e1); // } logger.info("exit char root: T0 = " + T0 + ", T = " + T); return sfactors; }