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