001/* 002 * $Id: DGroebnerBaseSeq.java 4948 2014-10-09 22:10:04Z axelclk $ 003 */ 004 005package edu.jas.gb; 006 007 008import java.util.ArrayList; 009import java.util.List; 010import java.util.ListIterator; 011 012import org.apache.log4j.Logger; 013 014import edu.jas.poly.GenPolynomial; 015import edu.jas.poly.GenPolynomialRing; 016import edu.jas.structure.RingElem; 017 018 019/** 020 * D-Groebner Base sequential algorithm. Implements D-Groebner bases and GB 021 * test. <b>Note:</b> Minimal reduced GBs are not unique. see BWK, section 10.1. 022 * @param <C> coefficient type 023 * @author Heinz Kredel 024 */ 025 026public class DGroebnerBaseSeq<C extends RingElem<C>> extends GroebnerBaseAbstract<C> { 027 028 029 private static final Logger logger = Logger.getLogger(DGroebnerBaseSeq.class); 030 031 032 private final boolean debug = logger.isDebugEnabled(); 033 034 035 /** 036 * Reduction engine. 037 */ 038 protected DReduction<C> dred; // shadow super.red ?? 039 040 041 /** 042 * Constructor. 043 */ 044 public DGroebnerBaseSeq() { 045 this(new DReductionSeq<C>()); 046 } 047 048 049 /** 050 * Constructor. 051 * @param dred D-Reduction engine 052 */ 053 public DGroebnerBaseSeq(DReduction<C> dred) { 054 super(dred); 055 this.dred = dred; 056 assert this.dred == super.red; 057 } 058 059 060 /** 061 * D-Groebner base test. 062 * @param modv module variable number. 063 * @param F polynomial list. 064 * @return true, if F is a D-Groebner base, else false. 065 */ 066 @Override 067 public boolean isGB(int modv, List<GenPolynomial<C>> F) { 068 GenPolynomial<C> pi, pj, s, d; 069 for (int i = 0; i < F.size(); i++) { 070 pi = F.get(i); 071 for (int j = i + 1; j < F.size(); j++) { 072 pj = F.get(j); 073 if (!red.moduleCriterion(modv, pi, pj)) { 074 continue; 075 } 076 d = dred.GPolynomial(pi, pj); 077 if (!d.isZERO()) { 078 // better check for top reduction only 079 d = red.normalform(F, d); 080 } 081 if (!d.isZERO()) { 082 System.out.println("d-pol(" + i + "," + j + ") != 0: " + d); 083 return false; 084 } 085 // works ok 086 if (!red.criterion4(pi, pj)) { 087 continue; 088 } 089 s = red.SPolynomial(pi, pj); 090 if (!s.isZERO()) { 091 s = red.normalform(F, s); 092 } 093 if (!s.isZERO()) { 094 System.out.println("s-pol(" + i + "," + j + ") != 0: " + s); 095 return false; 096 } 097 } 098 } 099 return true; 100 } 101 102 103 /** 104 * D-Groebner base using pairlist class. 105 * @param modv module variable number. 106 * @param F polynomial list. 107 * @return GB(F) a D-Groebner base of F. 108 */ 109 public List<GenPolynomial<C>> GB(int modv, List<GenPolynomial<C>> F) { 110 List<GenPolynomial<C>> G = normalizeZerosOnes(F); 111 if ( G.size() <= 1 ) { 112 return G; 113 } 114 GenPolynomialRing<C> ring = G.get(0).ring; 115 OrderedDPairlist<C> pairlist = new OrderedDPairlist<C>(modv, ring); 116 pairlist.put(G); 117 /* 118 int l = G.size(); 119 GenPolynomial<C> p; 120 //new ArrayList<GenPolynomial<C>>(); 121 ListIterator<GenPolynomial<C>> it = F.listIterator(); 122 while (it.hasNext()) { 123 p = it.next(); 124 if (!p.isZERO()) { 125 p = p.abs(); // not monic 126 if (p.isONE()) { 127 G.clear(); 128 G.add(p); 129 return G; // since no threads are activated 130 } 131 G.add(p); //G.add( 0, p ); //reverse list 132 if (pairlist == null) { 133 pairlist = new OrderedDPairlist<C>(modv, p.ring); 134 } 135 // putOne not required 136 pairlist.put(p); 137 } else { 138 l--; 139 } 140 } 141 if (l <= 1) { 142 return G; // since no threads are activated 143 } 144 */ 145 146 Pair<C> pair; 147 GenPolynomial<C> pi, pj, S, D, H; 148 while (pairlist.hasNext()) { 149 pair = pairlist.removeNext(); 150 //System.out.println("pair = " + pair); 151 if (pair == null) 152 continue; 153 154 pi = pair.pi; 155 pj = pair.pj; 156 if (debug) { 157 logger.debug("pi = " + pi); 158 logger.debug("pj = " + pj); 159 } 160 161 // D-polynomial case ---------------------- 162 D = dred.GPolynomial(pi, pj); 163 //System.out.println("D_d = " + D); 164 if (!D.isZERO() && !red.isTopReducible(G, D)) { 165 H = red.normalform(G, D); 166 if (H.isONE()) { 167 G.clear(); 168 G.add(H); 169 return G; // since no threads are activated 170 } 171 if (!H.isZERO()) { 172 logger.info("Dred = " + H); 173 //l++; 174 G.add(H); 175 pairlist.put(H); 176 } 177 } 178 179 // S-polynomial case ----------------------- 180 if (pair.getUseCriterion3() && pair.getUseCriterion4()) { 181 S = red.SPolynomial(pi, pj); 182 //System.out.println("S_d = " + S); 183 if (S.isZERO()) { 184 pair.setZero(); 185 continue; 186 } 187 if (logger.isDebugEnabled()) { 188 logger.debug("ht(S) = " + S.leadingExpVector()); 189 } 190 191 H = red.normalform(G, S); 192 if (H.isZERO()) { 193 pair.setZero(); 194 continue; 195 } 196 if (logger.isDebugEnabled()) { 197 logger.debug("ht(H) = " + H.leadingExpVector()); 198 } 199 200 if (H.isONE()) { 201 G.clear(); 202 G.add(H); 203 return G; // since no threads are activated 204 } 205 if (logger.isDebugEnabled()) { 206 logger.debug("H = " + H); 207 } 208 if (!H.isZERO()) { 209 logger.info("Sred = " + H); 210 //len = G.size(); 211 //l++; 212 G.add(H); 213 pairlist.put(H); 214 } 215 } 216 } 217 logger.debug("#sequential list = " + G.size()); 218 G = minimalGB(G); 219 logger.info("" + pairlist); 220 return G; 221 } 222 223}