001/* 002 * $Id: WordReductionAbstract.java 4946 2014-10-05 22:03:04Z axelclk $ 003 */ 004 005package edu.jas.gb; 006 007 008import java.util.ArrayList; 009import java.util.LinkedList; 010import java.util.List; 011import java.util.Map; 012 013import org.apache.log4j.Logger; 014 015import edu.jas.poly.GenWordPolynomial; 016import edu.jas.poly.Overlap; 017import edu.jas.poly.OverlapList; 018import edu.jas.poly.Word; 019import edu.jas.structure.RingElem; 020 021 022/** 023 * Polynomial word reduction abstract class. Implements common S-Polynomial, 024 * normalform, module criterion and irreducible set. 025 * @param <C> coefficient type 026 * @author Heinz Kredel 027 */ 028 029public abstract class WordReductionAbstract<C extends RingElem<C>> implements WordReduction<C> { 030 031 032 private static final Logger logger = Logger.getLogger(WordReductionAbstract.class); 033 034 035 //private final boolean debug = logger.isDebugEnabled(); 036 037 038 /** 039 * Constructor. 040 */ 041 public WordReductionAbstract() { 042 } 043 044 045 /** 046 * S-Polynomials of non-commutative polynomials. 047 * @param Ap word polynomial. 048 * @param Bp word polynomial. 049 * @return list of all spol(Ap,Bp) the S-polynomials of Ap and Bp. 050 */ 051 public List<GenWordPolynomial<C>> SPolynomials(GenWordPolynomial<C> Ap, GenWordPolynomial<C> Bp) { 052 List<GenWordPolynomial<C>> sp = new ArrayList<GenWordPolynomial<C>>(); 053 if (Bp == null || Bp.isZERO()) { 054 if (Ap == null) { 055 sp.add(Bp); 056 return sp; 057 } 058 sp.add(Ap.ring.getZERO()); 059 return sp; 060 } 061 if (Ap == null || Ap.isZERO()) { 062 sp.add(Bp.ring.getZERO()); 063 return sp; 064 } 065 Map.Entry<Word, C> ma = Ap.leadingMonomial(); 066 Map.Entry<Word, C> mb = Bp.leadingMonomial(); 067 Word e = ma.getKey(); 068 Word f = mb.getKey(); 069 C a = ma.getValue(); 070 C b = mb.getValue(); 071 OverlapList oll = e.overlap(f); 072 if (oll.ols.isEmpty()) { 073 return sp; 074 } 075 for (Overlap ol : oll.ols) { 076 GenWordPolynomial<C> s = SPolynomial(ol, b, Ap, a, Bp); 077 sp.add(s); 078 } 079 return sp; 080 } 081 082 083 /** 084 * S-Polynomials of non-commutative polynomials. 085 * @param a leading base coefficient of B. 086 * @param l1 word. 087 * @param A word polynomial. 088 * @param r1 word. 089 * @param b leading base coefficient of A. 090 * @param l2 word. 091 * @param B word polynomial. 092 * @param r2 word. 093 * @return list of all spol(Ap,Bp) the S-polynomials of Ap and Bp. 094 */ 095 public GenWordPolynomial<C> SPolynomial(C a, Word l1, GenWordPolynomial<C> A, Word r1, C b, Word l2, 096 GenWordPolynomial<C> B, Word r2) { 097 C one = A.ring.coFac.getONE(); 098 GenWordPolynomial<C> s1 = A.multiply(a, l1, one, r1); 099 GenWordPolynomial<C> s2 = B.multiply(b, l2, one, r2); 100 GenWordPolynomial<C> s = s1.subtract(s2); 101 return s; 102 } 103 104 105 /** 106 * S-Polynomials of non-commutative polynomials. 107 * @param ol Overlap tuple. 108 * @param a leading base coefficient of B. 109 * @param A word polynomial. 110 * @param b leading base coefficient of A. 111 * @param B word polynomial. 112 * @return list of all spol(Ap,Bp) the S-polynomials of Ap and Bp. 113 */ 114 public GenWordPolynomial<C> SPolynomial(Overlap ol, C a, GenWordPolynomial<C> A, C b, 115 GenWordPolynomial<C> B) { 116 C one = A.ring.coFac.getONE(); 117 GenWordPolynomial<C> s1 = A.multiply(a, ol.l1, one, ol.r1); 118 GenWordPolynomial<C> s2 = B.multiply(b, ol.l2, one, ol.r2); 119 GenWordPolynomial<C> s = s1.subtract(s2); 120 return s; 121 } 122 123 124 /** 125 * Normalform Set. 126 * @param Ap polynomial list. 127 * @param Pp polynomial list. 128 * @return list of nf(a) with respect to Pp for all a in Ap. 129 */ 130 public List<GenWordPolynomial<C>> normalform(List<GenWordPolynomial<C>> Pp, List<GenWordPolynomial<C>> Ap) { 131 if (Pp == null || Pp.isEmpty()) { 132 return Ap; 133 } 134 if (Ap == null || Ap.isEmpty()) { 135 return Ap; 136 } 137 ArrayList<GenWordPolynomial<C>> red = new ArrayList<GenWordPolynomial<C>>(); 138 for (GenWordPolynomial<C> A : Ap) { 139 A = normalform(Pp, A); 140 red.add(A); 141 } 142 return red; 143 } 144 145 146 /** 147 * Is top reducible. 148 * @param A polynomial. 149 * @param P polynomial list. 150 * @return true if A is top reducible with respect to P. 151 */ 152 public boolean isTopReducible(List<GenWordPolynomial<C>> P, GenWordPolynomial<C> A) { 153 if (P == null || P.isEmpty()) { 154 return false; 155 } 156 if (A == null || A.isZERO()) { 157 return false; 158 } 159 boolean mt = false; 160 Word e = A.leadingWord(); 161 for (GenWordPolynomial<C> p : P) { 162 mt = e.multipleOf(p.leadingWord()); 163 if (mt) { 164 return true; 165 } 166 } 167 return false; 168 } 169 170 171 /** 172 * Is reducible. 173 * @param Ap polynomial. 174 * @param Pp polynomial list. 175 * @return true if Ap is reducible with respect to Pp. 176 */ 177 public boolean isReducible(List<GenWordPolynomial<C>> Pp, GenWordPolynomial<C> Ap) { 178 return !isNormalform(Pp, Ap); 179 } 180 181 182 /** 183 * Is in Normalform. 184 * @param Ap polynomial. 185 * @param Pp polynomial list. 186 * @return true if Ap is in normalform with respect to Pp. 187 */ 188 @SuppressWarnings("unchecked") 189 public boolean isNormalform(List<GenWordPolynomial<C>> Pp, GenWordPolynomial<C> Ap) { 190 if (Pp == null || Pp.isEmpty()) { 191 return true; 192 } 193 if (Ap == null || Ap.isZERO()) { 194 return true; 195 } 196 int l; 197 GenWordPolynomial<C>[] P; 198 synchronized (Pp) { 199 l = Pp.size(); 200 P = new GenWordPolynomial[l]; 201 //P = Pp.toArray(); 202 for (int i = 0; i < Pp.size(); i++) { 203 P[i] = Pp.get(i); 204 } 205 } 206 Word[] htl = new Word[l]; 207 GenWordPolynomial<C>[] p = new GenWordPolynomial[l]; 208 Map.Entry<Word, C> m; 209 int i; 210 int j = 0; 211 for (i = 0; i < l; i++) { 212 p[i] = P[i]; 213 m = p[i].leadingMonomial(); 214 if (m != null) { 215 p[j] = p[i]; 216 htl[j] = m.getKey(); 217 j++; 218 } 219 } 220 l = j; 221 boolean mt = false; 222 for (Word e : Ap.getMap().keySet()) { 223 for (i = 0; i < l; i++) { 224 mt = e.multipleOf(htl[i]); 225 if (mt) { 226 return false; 227 } 228 } 229 } 230 return true; 231 } 232 233 234 /** 235 * Is in Normalform. 236 * @param Pp polynomial list. 237 * @return true if each Ap in Pp is in normalform with respect to Pp\{Ap}. 238 */ 239 public boolean isNormalform(List<GenWordPolynomial<C>> Pp) { 240 if (Pp == null || Pp.isEmpty()) { 241 return true; 242 } 243 GenWordPolynomial<C> Ap; 244 List<GenWordPolynomial<C>> P = new LinkedList<GenWordPolynomial<C>>(Pp); 245 int s = P.size(); 246 for (int i = 0; i < s; i++) { 247 Ap = P.remove(i); 248 if (!isNormalform(P, Ap)) { 249 return false; 250 } 251 P.add(Ap); 252 } 253 return true; 254 } 255 256 257 /** 258 * Irreducible set. 259 * @param Pp polynomial list. 260 * @return a list P of monic polynomials which are in normalform wrt. P and 261 * with ideal(Pp) = ideal(P). 262 */ 263 public List<GenWordPolynomial<C>> irreducibleSet(List<GenWordPolynomial<C>> Pp) { 264 ArrayList<GenWordPolynomial<C>> P = new ArrayList<GenWordPolynomial<C>>(); 265 for (GenWordPolynomial<C> a : Pp) { 266 if (a.length() != 0) { 267 a = a.monic(); 268 if (a.isONE()) { 269 P.clear(); 270 P.add(a); 271 return P; 272 } 273 P.add(a); 274 } 275 } 276 int l = P.size(); 277 if (l <= 1) 278 return P; 279 280 int irr = 0; 281 Word e; 282 Word f; 283 GenWordPolynomial<C> a; 284 logger.debug("irr = "); 285 while (irr != l) { 286 //it = P.listIterator(); 287 //a = P.get(0); //it.next(); 288 a = P.remove(0); 289 e = a.leadingWord(); 290 a = normalform(P, a); 291 logger.debug(String.valueOf(irr)); 292 if (a.length() == 0) { 293 l--; 294 if (l <= 1) { 295 return P; 296 } 297 } else { 298 f = a.leadingWord(); 299 if (f.signum() == 0) { 300 P = new ArrayList<GenWordPolynomial<C>>(); 301 P.add(a.monic()); 302 return P; 303 } 304 if (e.equals(f)) { 305 irr++; 306 } else { 307 irr = 0; 308 a = a.monic(); 309 } 310 P.add(a); 311 } 312 } 313 //System.out.println(); 314 return P; 315 } 316 317 318 /** 319 * Is reduction of normal form. 320 * @param lrow left recording matrix. 321 * @param rrow right recording matrix. 322 * @param Pp a polynomial list for reduction. 323 * @param Ap a polynomial. 324 * @param Np nf(Pp,Ap), a normal form of Ap wrt. Pp. 325 * @return true, if Np + sum( row[i]*Pp[i] ) == Ap, else false. 326 */ 327 public boolean isReductionNF(List<GenWordPolynomial<C>> lrow, List<GenWordPolynomial<C>> rrow, 328 List<GenWordPolynomial<C>> Pp, GenWordPolynomial<C> Ap, GenWordPolynomial<C> Np) { 329 if (lrow == null && rrow == null && Pp == null) { 330 if (Ap == null) { 331 return (Np == null); 332 } 333 return Ap.equals(Np); 334 } 335 if (lrow == null || rrow == null || Pp == null) { 336 return false; 337 } 338 if (lrow.size() != Pp.size() || rrow.size() != Pp.size()) { 339 return false; 340 } 341 GenWordPolynomial<C> t = Np; 342 //System.out.println("t0 = " + t ); 343 GenWordPolynomial<C> r, rl, rr; 344 GenWordPolynomial<C> p; 345 for (int m = 0; m < Pp.size(); m++) { 346 rl = lrow.get(m); 347 rr = rrow.get(m); 348 p = Pp.get(m); 349 if (rl != null && rr != null && p != null) { 350 if (t == null) { 351 t = p.multiply(rl, rr); 352 } else { 353 t = t.sum(p.multiply(rl, rr)); 354 } 355 } 356 //System.out.println("r = " + r ); 357 //System.out.println("p = " + p ); 358 } 359 //System.out.println("t+ = " + t ); 360 if (t == null) { 361 if (Ap == null) { 362 return true; 363 } 364 return Ap.isZERO(); 365 } 366 r = t.subtract(Ap); 367 boolean z = r.isZERO(); 368 if (!z) { 369 logger.info("t = " + t); 370 logger.info("a = " + Ap); 371 logger.info("t-a = " + r); 372 } 373 return z; 374 } 375}