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