001/* 002 * $Id: SolvableReductionAbstract.java 5914 2018-08-29 19:44:48Z kredel $ 003 */ 004 005package edu.jas.gb; 006 007 008import java.util.ArrayList; 009import java.util.Iterator; 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.ModuleList; 017import edu.jas.poly.PolynomialList; 018import edu.jas.poly.ExpVector; 019import edu.jas.poly.GenSolvablePolynomial; 020import edu.jas.poly.GenSolvablePolynomialRing; 021import edu.jas.structure.RingElem; 022 023 024/** 025 * Solvable polynomial Reduction abstract class. Implements common left, right 026 * S-Polynomial, left normalform and left irreducible set. 027 * @param <C> coefficient type 028 * @author Heinz Kredel 029 */ 030 031public abstract class SolvableReductionAbstract<C extends RingElem<C>> implements SolvableReduction<C> { 032 033 034 private static final Logger logger = LogManager.getLogger(SolvableReductionAbstract.class); 035 036 037 private static final boolean debug = logger.isDebugEnabled(); 038 039 040 /** 041 * Constructor. 042 */ 043 public SolvableReductionAbstract() { 044 } 045 046 047 /** 048 * Left S-Polynomial. 049 * @param Ap solvable polynomial. 050 * @param Bp solvable polynomial. 051 * @return left-spol(Ap,Bp) the left S-polynomial of Ap and Bp. 052 */ 053 public GenSolvablePolynomial<C> leftSPolynomial(GenSolvablePolynomial<C> Ap, GenSolvablePolynomial<C> Bp) { 054 if (logger.isInfoEnabled()) { 055 if (Bp == null || Bp.isZERO()) { 056 if (Ap != null) { 057 return Ap.ring.getZERO(); 058 } 059 return null; 060 } 061 if (Ap == null || Ap.isZERO()) { 062 return Bp.ring.getZERO(); 063 } 064 if (!Ap.ring.equals(Bp.ring)) { 065 logger.error("rings not equal"); 066 } 067 } 068 Map.Entry<ExpVector, C> ma = Ap.leadingMonomial(); 069 Map.Entry<ExpVector, C> mb = Bp.leadingMonomial(); 070 071 ExpVector e = ma.getKey(); 072 ExpVector f = mb.getKey(); 073 074 ExpVector g = e.lcm(f); 075 ExpVector e1 = g.subtract(e); 076 ExpVector f1 = g.subtract(f); 077 078 C a = ma.getValue(); 079 C b = mb.getValue(); 080 081 GenSolvablePolynomial<C> App = Ap.multiplyLeft(b, e1); 082 GenSolvablePolynomial<C> Bpp = Bp.multiplyLeft(a, f1); 083 GenSolvablePolynomial<C> Cp = (GenSolvablePolynomial<C>) App.subtract(Bpp); 084 return Cp; 085 } 086 087 088 /** 089 * S-Polynomial with recording. 090 * @param S recording matrix, is modified. 091 * @param i index of Ap in basis list. 092 * @param Ap a polynomial. 093 * @param j index of Bp in basis list. 094 * @param Bp a polynomial. 095 * @return leftSpol(Ap, Bp), the left S-Polynomial for Ap and Bp. 096 */ 097 public GenSolvablePolynomial<C> leftSPolynomial(List<GenSolvablePolynomial<C>> S, int i, 098 GenSolvablePolynomial<C> Ap, int j, GenSolvablePolynomial<C> Bp) { 099 if (debug /*logger.isInfoEnabled()*/) { 100 if (Bp == null || Bp.isZERO()) { 101 throw new ArithmeticException("Spol B is zero"); 102 } 103 if (Ap == null || Ap.isZERO()) { 104 throw new ArithmeticException("Spol A is zero"); 105 } 106 if (!Ap.ring.equals(Bp.ring)) { 107 logger.error("rings not equal"); 108 } 109 } 110 Map.Entry<ExpVector, C> ma = Ap.leadingMonomial(); 111 Map.Entry<ExpVector, C> mb = Bp.leadingMonomial(); 112 113 ExpVector e = ma.getKey(); 114 ExpVector f = mb.getKey(); 115 116 ExpVector g = e.lcm(f); 117 ExpVector e1 = g.subtract(e); 118 ExpVector f1 = g.subtract(f); 119 120 C a = ma.getValue(); 121 C b = mb.getValue(); 122 123 GenSolvablePolynomial<C> App = Ap.multiplyLeft(b, e1); 124 GenSolvablePolynomial<C> Bpp = Bp.multiplyLeft(a, f1); 125 GenSolvablePolynomial<C> Cp = (GenSolvablePolynomial<C>) App.subtract(Bpp); 126 127 GenSolvablePolynomial<C> zero = Ap.ring.getZERO(); 128 GenSolvablePolynomial<C> As = (GenSolvablePolynomial<C>) zero.sum(b.negate(), e1); 129 GenSolvablePolynomial<C> Bs = (GenSolvablePolynomial<C>) zero.sum(a, f1); 130 S.set(i, As); 131 S.set(j, Bs); 132 return Cp; 133 } 134 135 136 /** 137 * Left Normalform Set. 138 * @param Ap solvable polynomial list. 139 * @param Pp solvable polynomial list. 140 * @return list of left-nf(a) with respect to Pp for all a in Ap. 141 */ 142 public List<GenSolvablePolynomial<C>> leftNormalform(List<GenSolvablePolynomial<C>> Pp, 143 List<GenSolvablePolynomial<C>> Ap) { 144 if (Pp == null || Pp.isEmpty()) { 145 return Ap; 146 } 147 if (Ap == null || Ap.isEmpty()) { 148 return Ap; 149 } 150 ArrayList<GenSolvablePolynomial<C>> red = new ArrayList<GenSolvablePolynomial<C>>(); 151 for (GenSolvablePolynomial<C> A : Ap) { 152 A = leftNormalform(Pp, A); 153 red.add(A); 154 } 155 return red; 156 } 157 158 159 /** 160 * Module left normalform set. 161 * @param Ap module list. 162 * @param Pp module list. 163 * @return list of left-nf(a) with respect to Pp for all a in Ap. 164 */ 165 public ModuleList<C> leftNormalform(ModuleList<C> Pp, ModuleList<C> Ap) { 166 return leftNormalform(Pp, Ap, false); 167 } 168 169 170 /** 171 * Module left normalform set. 172 * @param Ap module list. 173 * @param Pp module list. 174 * @param top true for TOP term order, false for POT term order. 175 * @return list of left-nf(a) with respect to Pp for all a in Ap. 176 */ 177 public ModuleList<C> leftNormalform(ModuleList<C> Pp, ModuleList<C> Ap, boolean top) { 178 if (Pp == null || Pp.isEmpty()) { 179 return Ap; 180 } 181 if (Ap == null || Ap.isEmpty()) { 182 return Ap; 183 } 184 GenSolvablePolynomialRing<C> sring = (GenSolvablePolynomialRing<C>) Pp.ring; 185 int modv = Pp.cols; 186 GenSolvablePolynomialRing<C> pfac = sring.extend(modv, top); 187 logger.debug("extended ring = " + pfac.toScript()); 188 //System.out.println("extended ring = " + pfac.toScript()); 189 PolynomialList<C> P = Pp.getPolynomialList(pfac); 190 PolynomialList<C> A = Ap.getPolynomialList(pfac); 191 //System.out.println("P = " + P.toScript()); 192 193 List<GenSolvablePolynomial<C>> red = leftNormalform(P.castToSolvableList(), A.castToSolvableList()); 194 PolynomialList<C> Fr = new PolynomialList<C>(pfac, red); 195 ModuleList<C> Nr = Fr.getModuleList(modv); 196 return Nr; 197 } 198 199 200 /** 201 * Left irreducible set. 202 * @param Pp solvable polynomial list. 203 * @return a list P of solvable polynomials which are in normalform wrt. P. 204 */ 205 public List<GenSolvablePolynomial<C>> leftIrreducibleSet(List<GenSolvablePolynomial<C>> Pp) { 206 ArrayList<GenSolvablePolynomial<C>> P = new ArrayList<GenSolvablePolynomial<C>>(); 207 for (GenSolvablePolynomial<C> a : Pp) { 208 if (a.length() != 0) { 209 a = a.monic(); 210 P.add(a); 211 } 212 } 213 int l = P.size(); 214 if (l <= 1) 215 return P; 216 217 int irr = 0; 218 ExpVector e; 219 ExpVector f; 220 GenSolvablePolynomial<C> a; 221 Iterator<GenSolvablePolynomial<C>> it; 222 logger.debug("irr = "); 223 while (irr != l) { 224 it = P.listIterator(); 225 a = it.next(); 226 P.remove(0); 227 e = a.leadingExpVector(); 228 a = leftNormalform(P, a); 229 logger.debug(String.valueOf(irr)); 230 if (a.length() == 0) { 231 l--; 232 if (l <= 1) { 233 return P; 234 } 235 } else { 236 f = a.leadingExpVector(); 237 if (f.signum() == 0) { 238 P = new ArrayList<GenSolvablePolynomial<C>>(); 239 P.add(a.monic()); 240 return P; 241 } 242 if (e.equals(f)) { 243 irr++; 244 } else { 245 irr = 0; 246 a = a.monic(); 247 } 248 P.add(a); 249 } 250 } 251 //System.out.println(); 252 return P; 253 } 254 255 256 /** 257 * Is reduction of normal form. 258 * @param row recording matrix. 259 * @param Pp a solvable polynomial list for reduction. 260 * @param Ap a solvable polynomial. 261 * @param Np nf(Pp,Ap), a left normal form of Ap wrt. Pp. 262 * @return true, if Np + sum( row[i]*Pp[i] ) == Ap, else false. 263 */ 264 @SuppressWarnings("unchecked") 265 public boolean isLeftReductionNF(List<GenSolvablePolynomial<C>> row, List<GenSolvablePolynomial<C>> Pp, 266 GenSolvablePolynomial<C> Ap, GenSolvablePolynomial<C> Np) { 267 if (row == null && Pp == null) { 268 if (Ap == null) { 269 return Np == null; 270 } 271 return Ap.equals(Np); 272 } 273 if (row == null || Pp == null) { 274 return false; 275 } 276 if (row.size() != Pp.size()) { 277 return false; 278 } 279 GenSolvablePolynomial<C> t = Np; 280 GenSolvablePolynomial<C> r; 281 GenSolvablePolynomial<C> p; 282 for (int m = 0; m < Pp.size(); m++) { 283 r = row.get(m); 284 p = Pp.get(m); 285 if (r != null && p != null) { 286 if (t == null) { 287 t = r.multiply(p); 288 } else { 289 t = (GenSolvablePolynomial<C>) t.sum(r.multiply(p)); 290 } 291 } 292 //System.out.println("r = " + r ); 293 //System.out.println("p = " + p ); 294 } 295 if (debug) { 296 logger.info("t = " + t); 297 logger.info("a = " + Ap); 298 } 299 if (t == null) { 300 if (Ap == null) { 301 return true; 302 } 303 return Ap.isZERO(); 304 } 305 t = (GenSolvablePolynomial<C>) t.subtract(Ap); 306 return t.isZERO(); 307 } 308 309 310 /** 311 * Right S-Polynomial. 312 * @param Ap solvable polynomial. 313 * @param Bp solvable polynomial. 314 * @return right-spol(Ap,Bp) the right S-polynomial of Ap and Bp. 315 */ 316 @SuppressWarnings("unchecked") 317 public GenSolvablePolynomial<C> rightSPolynomial(GenSolvablePolynomial<C> Ap, GenSolvablePolynomial<C> Bp) { 318 if (logger.isInfoEnabled()) { 319 if (Bp == null || Bp.isZERO()) { 320 if (Ap != null) { 321 return Ap.ring.getZERO(); 322 } 323 return null; 324 } 325 if (Ap == null || Ap.isZERO()) { 326 return Bp.ring.getZERO(); 327 } 328 if (!Ap.ring.equals(Bp.ring)) { 329 logger.error("rings not equal"); 330 } 331 } 332 ExpVector e = Ap.leadingExpVector(); 333 ExpVector f = Bp.leadingExpVector(); 334 335 ExpVector g = e.lcm(f); 336 ExpVector e1 = g.subtract(e); 337 ExpVector f1 = g.subtract(f); 338 339 GenSolvablePolynomial<C> App = Ap.multiply(e1); 340 GenSolvablePolynomial<C> Bpp = Bp.multiply(f1); 341 342 C a = App.leadingBaseCoefficient(); 343 C b = Bpp.leadingBaseCoefficient(); 344 App = App.multiply(b); 345 Bpp = Bpp.multiply(a); 346 347 GenSolvablePolynomial<C> Cp = (GenSolvablePolynomial<C>) App.subtract(Bpp); 348 return Cp; 349 } 350 351 352 /** 353 * Is top reducible. Is left right symmetric. 354 * @param A solvable polynomial. 355 * @param P solvable polynomial list. 356 * @return true if A is top reducible with respect to P. 357 */ 358 public boolean isTopReducible(List<GenSolvablePolynomial<C>> P, GenSolvablePolynomial<C> A) { 359 if (P == null || P.isEmpty()) { 360 return false; 361 } 362 if (A == null || A.isZERO()) { 363 return false; 364 } 365 boolean mt = false; 366 ExpVector e = A.leadingExpVector(); 367 for (GenSolvablePolynomial<C> p : P) { 368 mt = e.multipleOf(p.leadingExpVector()); 369 if (mt) { 370 return true; 371 } 372 } 373 return false; 374 } 375 376 377 /** 378 * Is reducible. Is left right symmetric. 379 * @param Ap solvable polynomial. 380 * @param Pp solvable polynomial list. 381 * @return true if Ap is reducible with respect to Pp. 382 */ 383 public boolean isReducible(List<GenSolvablePolynomial<C>> Pp, GenSolvablePolynomial<C> Ap) { 384 return !isNormalform(Pp, Ap); 385 } 386 387 388 /** 389 * Is in Normalform. Is left right symmetric. 390 * @param Ap polynomial. 391 * @param Pp polynomial list. 392 * @return true if Ap is in normalform with respect to Pp. 393 */ 394 @SuppressWarnings("unchecked") 395 public boolean isNormalform(List<GenSolvablePolynomial<C>> Pp, GenSolvablePolynomial<C> Ap) { 396 if (Pp == null || Pp.isEmpty()) { 397 return true; 398 } 399 if (Ap == null || Ap.isZERO()) { 400 return true; 401 } 402 GenSolvablePolynomial<C>[] P = new GenSolvablePolynomial[0]; 403 synchronized (Pp) { 404 P = Pp.toArray(P); 405 } 406 int l = P.length; 407 ExpVector[] htl = new ExpVector[l]; 408 GenSolvablePolynomial<C>[] p = new GenSolvablePolynomial[l]; 409 ExpVector f; 410 int i; 411 int j = 0; 412 for (i = 0; i < l; i++) { 413 p[i] = P[i]; 414 f = p[i].leadingExpVector(); 415 if (f != null) { 416 p[j] = p[i]; 417 htl[j] = f; 418 j++; 419 } 420 } 421 l = j; 422 boolean mt = false; 423 for (ExpVector e : Ap.getMap().keySet()) { 424 for (i = 0; i < l; i++) { 425 mt = e.multipleOf(htl[i]); 426 if (mt) { 427 return false; 428 } 429 } 430 } 431 return true; 432 } 433 434 435 /** 436 * Two-sided Normalform. 437 * @param Ap solvable polynomial. 438 * @param Pp solvable polynomial list. 439 * @return two-sided-nf(Ap) with respect to Pp. 440 */ 441 public GenSolvablePolynomial<C> normalform(List<GenSolvablePolynomial<C>> Pp, 442 GenSolvablePolynomial<C> Ap) { 443 throw new UnsupportedOperationException("two-sided normalform not implemented"); 444 } 445 446}