001/* 002 * $Id: GroebnerBaseQuotient.java 4806 2014-04-13 12:17:31Z kredel $ 003 */ 004 005package edu.jas.gbufd; 006 007 008import java.util.ArrayList; 009import java.util.List; 010 011import org.apache.log4j.Logger; 012 013import edu.jas.gb.GroebnerBaseAbstract; 014import edu.jas.gb.PairList; 015import edu.jas.poly.GenPolynomial; 016import edu.jas.poly.GenPolynomialRing; 017import edu.jas.poly.PolyUtil; 018import edu.jas.structure.GcdRingElem; 019import edu.jas.ufd.PolyUfdUtil; 020import edu.jas.ufd.Quotient; 021import edu.jas.ufd.QuotientRing; 022 023 024/** 025 * Groebner Base sequential algorithm for rational function coefficients, 026 * fraction free computation. Implements Groebner bases. 027 * @param <C> Quotient coefficient type 028 * @author Heinz Kredel 029 */ 030 031public class GroebnerBaseQuotient<C extends GcdRingElem<C>> extends GroebnerBaseAbstract<Quotient<C>> { 032 033 034 private static final Logger logger = Logger.getLogger(GroebnerBaseQuotient.class); 035 036 037 private final boolean debug = logger.isDebugEnabled(); 038 039 040 public final GroebnerBaseAbstract<GenPolynomial<C>> bba; 041 042 043 /** 044 * Constructor. 045 * @param rf quotient coefficient ring factory. 046 */ 047 public GroebnerBaseQuotient(QuotientRing<C> rf) { 048 this(new GroebnerBasePseudoRecSeq<C>(rf.ring)); 049 } 050 051 052 /** 053 * Constructor. 054 * @param threads the number of parallel threads. 055 * @param rf quotient coefficient ring factory. 056 */ 057 public GroebnerBaseQuotient(int threads, QuotientRing<C> rf) { 058 this(new GroebnerBasePseudoRecParallel<C>(threads, rf.ring)); 059 } 060 061 062 /** 063 * Constructor. 064 * @param rf quotient coefficient ring factory. 065 * @param pl pair selection strategy (for fraction parts). 066 */ 067 public GroebnerBaseQuotient(QuotientRing<C> rf, PairList<GenPolynomial<C>> pl) { 068 this(new GroebnerBasePseudoRecSeq<C>(rf.ring, pl)); 069 } 070 071 072 /** 073 * Constructor. 074 * @param threads the number of parallel threads. 075 * @param rf quotient coefficient ring factory. 076 * @param pl pair selection strategy (for fraction parts). 077 */ 078 public GroebnerBaseQuotient(int threads, QuotientRing<C> rf, PairList<GenPolynomial<C>> pl) { 079 this(new GroebnerBasePseudoRecParallel<C>(threads, rf.ring, pl)); 080 } 081 082 083 /** 084 * Constructor. 085 * @param bba Groebner base algorithm for GenPolynomial coefficients. 086 */ 087 public GroebnerBaseQuotient(GroebnerBaseAbstract<GenPolynomial<C>> bba) { 088 super(); 089 this.bba = bba; 090 } 091 092 093 /** 094 * Get the String representation with GB engines. 095 * @see java.lang.Object#toString() 096 */ 097 @Override 098 public String toString() { 099 return this.getClass().getSimpleName() + "(" + bba.toString() + ")"; 100 } 101 102 103 /** 104 * Groebner base using fraction free computation. 105 * @param modv module variable number. 106 * @param F polynomial list. 107 * @return GB(F) a Groebner base of F. 108 */ 109 @Override 110 public List<GenPolynomial<Quotient<C>>> GB(int modv, List<GenPolynomial<Quotient<C>>> F) { 111 List<GenPolynomial<Quotient<C>>> G = F; 112 if (F == null || F.isEmpty()) { 113 return G; 114 } 115 GenPolynomialRing<Quotient<C>> rring = F.get(0).ring; 116 QuotientRing<C> cf = (QuotientRing<C>) rring.coFac; 117 GenPolynomialRing<GenPolynomial<C>> iring = new GenPolynomialRing<GenPolynomial<C>>(cf.ring, rring); 118 List<GenPolynomial<GenPolynomial<C>>> Fi = PolyUfdUtil.<C> integralFromQuotientCoefficients(iring, F); 119 //System.out.println("Fi = " + Fi); 120 logger.info("#Fi = " + Fi.size()); 121 122 List<GenPolynomial<GenPolynomial<C>>> Gi = bba.GB(modv, Fi); 123 //System.out.println("Gi = " + Gi); 124 logger.info("#Gi = " + Gi.size()); 125 126 G = PolyUfdUtil.<C> quotientFromIntegralCoefficients(rring, Gi); 127 G = PolyUtil.<Quotient<C>> monic(G); 128 return G; 129 } 130 131 132 /** 133 * Minimal ordered Groebner basis. 134 * @param Gp a Groebner base. 135 * @return a reduced Groebner base of Gp. 136 */ 137 @Override 138 public List<GenPolynomial<Quotient<C>>> minimalGB(List<GenPolynomial<Quotient<C>>> Gp) { 139 if (Gp == null || Gp.size() <= 1) { 140 return Gp; 141 } 142 // remove zero polynomials 143 List<GenPolynomial<Quotient<C>>> G = new ArrayList<GenPolynomial<Quotient<C>>>(Gp.size()); 144 for (GenPolynomial<Quotient<C>> a : Gp) { 145 if (a != null && !a.isZERO()) { // always true in GB() 146 // already positive a = a.abs(); 147 G.add(a); 148 } 149 } 150 if (G.size() <= 1) { 151 return G; 152 } 153 // remove top reducible polynomials 154 GenPolynomial<Quotient<C>> a; 155 List<GenPolynomial<Quotient<C>>> F; 156 F = new ArrayList<GenPolynomial<Quotient<C>>>(G.size()); 157 while (G.size() > 0) { 158 a = G.remove(0); 159 if (red.isTopReducible(G, a) || red.isTopReducible(F, a)) { 160 // drop polynomial 161 if (debug) { 162 System.out.println("dropped " + a); 163 List<GenPolynomial<Quotient<C>>> ff; 164 ff = new ArrayList<GenPolynomial<Quotient<C>>>(G); 165 ff.addAll(F); 166 a = red.normalform(ff, a); 167 if (!a.isZERO()) { 168 System.out.println("error, nf(a) " + a); 169 } 170 } 171 } else { 172 F.add(a); 173 } 174 } 175 G = F; 176 if (G.size() <= 1) { 177 return G; 178 } 179 180 // reduce remaining polynomials 181 GenPolynomialRing<Quotient<C>> rring = G.get(0).ring; 182 QuotientRing<C> cf = (QuotientRing<C>) rring.coFac; 183 GenPolynomialRing<GenPolynomial<C>> iring = new GenPolynomialRing<GenPolynomial<C>>(cf.ring, rring); 184 List<GenPolynomial<GenPolynomial<C>>> Fi = PolyUfdUtil.integralFromQuotientCoefficients(iring, F); 185 logger.info("#Fi = " + Fi.size()); 186 187 List<GenPolynomial<GenPolynomial<C>>> Gi = bba.minimalGB(Fi); 188 logger.info("#Gi = " + Gi.size()); 189 190 G = PolyUfdUtil.<C> quotientFromIntegralCoefficients(rring, Gi); 191 G = PolyUtil.<Quotient<C>> monic(G); 192 return G; 193 } 194 195 196 /** 197 * Cleanup and terminate ThreadPool. 198 */ 199 @Override 200 public void terminate() { 201 bba.terminate(); 202 } 203 204 205 /** 206 * Cancel ThreadPool. 207 */ 208 @Override 209 public int cancel() { 210 return bba.cancel(); 211 } 212 213}