001/* 002 * $Id: WordPseudoReductionSeq.java 5303 2015-08-16 17:11:07Z kredel $ 003 */ 004 005package edu.jas.gbufd; 006 007 008import java.util.List; 009import java.util.Map; 010 011import org.apache.log4j.Logger; 012 013import edu.jas.gb.WordReductionAbstract; 014import edu.jas.poly.GenPolynomial; 015import edu.jas.poly.GenWordPolynomial; 016import edu.jas.poly.PolyUtil; 017import edu.jas.poly.Word; 018import edu.jas.structure.RingElem; 019 020 021/** 022 * Polynomial word reduction sequential use algorithm. Implements normalform. 023 * @param <C> coefficient type 024 * @author Heinz Kredel 025 */ 026 027public class WordPseudoReductionSeq<C extends RingElem<C>> extends WordReductionAbstract<C> implements 028 WordPseudoReduction<C> { 029 030 031 private static final Logger logger = Logger.getLogger(WordPseudoReductionSeq.class); 032 033 034 private static boolean debug = logger.isDebugEnabled(); 035 036 037 /** 038 * Constructor. 039 */ 040 public WordPseudoReductionSeq() { 041 } 042 043 044 /** 045 * Normalform. 046 * @param Ap polynomial. 047 * @param Pp polynomial list. 048 * @return nf(Ap) with respect to Pp. 049 */ 050 //@SuppressWarnings("unchecked") 051 public GenWordPolynomial<C> normalform(List<GenWordPolynomial<C>> Pp, GenWordPolynomial<C> Ap) { 052 if (Pp == null || Pp.isEmpty()) { 053 return Ap; 054 } 055 if (Ap == null || Ap.isZERO()) { 056 return Ap; 057 } 058 if (!Ap.ring.coFac.isCommutative()) { 059 throw new IllegalArgumentException("coefficient ring not commutative"); 060 } 061 Map.Entry<Word, C> m; 062 GenWordPolynomial<C>[] P = new GenWordPolynomial[0]; 063 synchronized (Pp) { 064 P = Pp.toArray(P); 065 } 066 int l = P.length; 067 Word[] htl = new Word[l]; 068 C[] lbc = (C[]) new RingElem[l]; 069 GenWordPolynomial<C>[] p = new GenWordPolynomial[l]; 070 int i; 071 int j = 0; 072 for (i = 0; i < l; i++) { 073 p[i] = P[i]; 074 m = p[i].leadingMonomial(); 075 if (m != null) { 076 p[j] = p[i]; 077 htl[j] = m.getKey(); 078 lbc[j] = m.getValue(); 079 j++; 080 } 081 } 082 l = j; 083 Word e; 084 C a; 085 boolean mt = false; 086 GenWordPolynomial<C> R = Ap.ring.getZERO().copy(); 087 C cone = Ap.ring.coFac.getONE(); 088 GenWordPolynomial<C> Q = null; 089 GenWordPolynomial<C> S = Ap.copy(); 090 while (S.length() > 0) { 091 m = S.leadingMonomial(); 092 e = m.getKey(); 093 a = m.getValue(); 094 for (i = 0; i < l; i++) { 095 mt = e.multipleOf(htl[i]); 096 if (mt) 097 break; 098 } 099 if (!mt) { 100 //logger.debug("irred"); 101 //R = R.sum(a, e); 102 //S = S.subtract(a, e); 103 R.doPutToMap(e, a); 104 S.doRemoveFromMap(e, a); 105 // System.out.println(" S = " + S); 106 } else { 107 Word[] elr = e.divideWord(htl[i]); 108 e = elr[0]; 109 Word f = elr[1]; 110 if (debug) { 111 logger.info("red divideWord: e = " + e + ", f = " + f); 112 } 113 C c = lbc[i]; 114 if (a.remainder(c).isZERO()) { 115 a = a.divide(c); 116 Q = p[i].multiply(a, e, cone, f); 117 } else { 118 R = R.multiply(c); 119 S = S.multiply(c); 120 Q = p[i].multiply(a, e, cone, f); 121 } 122 S = S.subtract(Q); 123 } 124 } 125 return R; 126 } 127 128 129 /** 130 * Normalform with left and right recording. 131 * @param lrow left recording matrix, is modified. 132 * @param rrow right recording matrix, is modified. 133 * @param Pp a polynomial list for reduction. 134 * @param Ap a polynomial. 135 * @return nf(Pp,Ap), the normal form of Ap wrt. Pp. 136 */ 137 //@SuppressWarnings("unchecked") 138 public GenWordPolynomial<C> normalform(List<GenWordPolynomial<C>> lrow, List<GenWordPolynomial<C>> rrow, 139 List<GenWordPolynomial<C>> Pp, GenWordPolynomial<C> Ap) { 140 if (Pp == null || Pp.isEmpty()) { 141 return Ap; 142 } 143 if (Ap == null || Ap.isZERO()) { 144 return Ap; 145 } 146 if (!Ap.ring.coFac.isCommutative()) { 147 throw new IllegalArgumentException("coefficient ring not commutative"); 148 } 149 GenWordPolynomial<C>[] P = new GenWordPolynomial[0]; 150 synchronized (Pp) { 151 P = Pp.toArray(P); 152 } 153 int l = P.length; 154 Word[] htl = new Word[l]; 155 C[] lbc = (C[]) new RingElem[l]; 156 GenWordPolynomial<C>[] p = new GenWordPolynomial[l]; 157 Map.Entry<Word, C> m; 158 int j = 0; 159 int i; 160 for (i = 0; i < l; i++) { 161 p[i] = P[i]; 162 m = p[i].leadingMonomial(); 163 if (m != null) { 164 p[j] = p[i]; 165 htl[j] = m.getKey(); 166 lbc[j] = m.getValue(); 167 j++; 168 } 169 } 170 l = j; 171 Word e; 172 C a; 173 boolean mt = false; 174 GenWordPolynomial<C> zero = Ap.ring.getZERO().copy(); 175 GenWordPolynomial<C> R = Ap.ring.getZERO(); 176 C cone = Ap.ring.coFac.getONE(); 177 GenWordPolynomial<C> fac = null; 178 GenWordPolynomial<C> Q = null; 179 GenWordPolynomial<C> S = Ap.copy(); 180 while (S.length() > 0) { 181 m = S.leadingMonomial(); 182 e = m.getKey(); 183 a = m.getValue(); 184 for (i = 0; i < l; i++) { 185 mt = e.multipleOf(htl[i]); 186 if (mt) 187 break; 188 } 189 if (!mt) { 190 //logger.debug("irred"); 191 //R = R.sum(a, e); 192 //S = S.subtract(a, e); 193 R.doPutToMap(e, a); 194 S.doRemoveFromMap(e, a); 195 // System.out.println(" S = " + S); 196 } else { 197 Word[] elr = e.divideWord(htl[i]); 198 e = elr[0]; 199 Word f = elr[1]; 200 if (debug) { 201 logger.info("redRec divideWord: e = " + e + ", f = " + f); 202 } 203 C c = lbc[i]; 204 if (a.remainder(c).isZERO()) { 205 a = a.divide(c); 206 Q = p[i].multiply(a, e, cone, f); 207 } else { 208 R = R.multiply(c); 209 S = S.multiply(c); 210 Q = p[i].multiply(a, e, cone, f); 211 } 212 S = S.subtract(Q); 213 // left row 214 fac = lrow.get(i); 215 if (fac == null) { 216 fac = zero.sum(cone, e); 217 } else { 218 fac = fac.sum(cone, e); 219 } 220 lrow.set(i, fac); 221 // right row 222 fac = rrow.get(i); 223 if (fac == null) { 224 fac = zero.sum(a, f); 225 } else { 226 fac = fac.sum(a, f); 227 } 228 rrow.set(i, fac); 229 } 230 } 231 return R; 232 } 233 234 235 /** 236 * Normalform with multiplication factor. 237 * @param Pp polynomial list. 238 * @param Ap polynomial. 239 * @return ( nf(Ap), mf ) with respect to Pp and mf as multiplication factor 240 * for Ap. 241 */ 242 public WordPseudoReductionEntry<C> normalformFactor(List<GenWordPolynomial<C>> Pp, GenWordPolynomial<C> Ap) { 243 throw new UnsupportedOperationException("normalformFactor not imlemented"); 244 } 245 246 247 /** 248 * Normalform with polynomial coefficients. 249 * @param Ap polynomial. 250 * @param Pp polynomial list. 251 * @return nf(Ap) with respect to Pp. 252 */ 253 //@SuppressWarnings("unchecked") 254 public GenWordPolynomial<GenPolynomial<C>> normalformRecursive( 255 List<GenWordPolynomial<GenPolynomial<C>>> Pp, GenWordPolynomial<GenPolynomial<C>> Ap) { 256 if (Pp == null || Pp.isEmpty()) { 257 return Ap; 258 } 259 if (Ap == null || Ap.isZERO()) { 260 return Ap; 261 } 262 if (!Ap.ring.coFac.isCommutative()) { 263 throw new IllegalArgumentException("coefficient ring not commutative"); 264 } 265 Map.Entry<Word, GenPolynomial<C>> m; 266 GenWordPolynomial<GenPolynomial<C>>[] P = new GenWordPolynomial[0]; 267 synchronized (Pp) { 268 P = Pp.toArray(P); 269 } 270 int l = P.length; 271 Word[] htl = new Word[l]; 272 GenPolynomial<C>[] lbc = new GenPolynomial[l]; //(GenPolynomial<C>[]) 273 GenWordPolynomial<GenPolynomial<C>>[] p = new GenWordPolynomial[l]; 274 int i; 275 int j = 0; 276 for (i = 0; i < l; i++) { 277 p[i] = P[i]; 278 m = p[i].leadingMonomial(); 279 if (m != null) { 280 p[j] = p[i]; 281 htl[j] = m.getKey(); 282 lbc[j] = m.getValue(); 283 j++; 284 } 285 } 286 l = j; 287 Word e, fr, fl; 288 GenPolynomial<C> a, b = null; 289 boolean mt = false; 290 GenWordPolynomial<GenPolynomial<C>> R = Ap.ring.getZERO().copy(); 291 GenPolynomial<C> cone = Ap.ring.coFac.getONE(); 292 GenWordPolynomial<GenPolynomial<C>> Q = null; 293 GenWordPolynomial<GenPolynomial<C>> S = Ap.copy(); 294 GenWordPolynomial<GenPolynomial<C>> Sp; 295 while (S.length() > 0) { 296 m = S.leadingMonomial(); 297 e = m.getKey(); 298 a = m.getValue(); 299 for (i = 0; i < l; i++) { 300 mt = e.multipleOf(htl[i]); 301 if (mt) 302 break; 303 } 304 if (!mt) { 305 //logger.debug("irred"); 306 //R = R.sum(a, e); 307 //S = S.subtract(a, e); 308 R.doPutToMap(e, a); 309 S.doRemoveFromMap(e, a); 310 // System.out.println(" S = " + S); 311 } else { 312 Word[] elr = e.divideWord(htl[i]); 313 fl = elr[0]; 314 fr = elr[1]; 315 if (debug) { 316 logger.info("redRec divideWord: e = " + e + ", fl = " + fl + ", fr = " + fr); 317 } 318 GenPolynomial<C> c = lbc[i]; 319 if (PolyUtil.<C> baseSparsePseudoRemainder(a, c).isZERO()) { 320 b = PolyUtil.<C> basePseudoDivide(a, c); 321 Q = p[i].multiply(b, fl, cone, fr); 322 } else { 323 R = R.multiply(c); 324 S = S.multiply(c); 325 Q = p[i].multiply(a, fl, cone, fr); 326 } 327 Sp = S.subtract(Q); 328 if (e.equals(Sp.leadingWord())) { // TODO: avoid not possible in general 329 //logger.info("redRec: e = " + e + ", hti = " + htl[i] + ", fl = " + fl + ", fr = " + fr); 330 //logger.info("redRec: S = " + S + ", Sp = " + Sp + ", a = " + a + ", b = " + b + ", c = " + c); 331 //throw new RuntimeException("degree not descending"); 332 R = R.multiply(c); 333 S = S.multiply(c); 334 Q = p[i].multiply(a, fl, cone, fr); 335 Sp = S.subtract(Q); 336 } 337 S = Sp; 338 } 339 } 340 return R; 341 } 342 343 344 @Override 345 public GenWordPolynomial<C> leftNormalform(List<GenWordPolynomial<C>> Pp, GenWordPolynomial<C> Ap) { 346 throw new UnsupportedOperationException("leftNormalform not imlemented"); 347 } 348 349 350 @Override 351 public GenWordPolynomial<C> leftNormalform(List<GenWordPolynomial<C>> lrow, 352 List<GenWordPolynomial<C>> Pp, GenWordPolynomial<C> Ap) { 353 throw new UnsupportedOperationException("leftNormalform not imlemented"); 354 } 355 356 357 @Override 358 public GenWordPolynomial<C> rightNormalform(List<GenWordPolynomial<C>> Pp, GenWordPolynomial<C> Ap) { 359 throw new UnsupportedOperationException("rightNormalform not imlemented"); 360 } 361 362 363 @Override 364 public GenWordPolynomial<C> rightNormalform(List<GenWordPolynomial<C>> rrow, 365 List<GenWordPolynomial<C>> Pp, GenWordPolynomial<C> Ap) { 366 throw new UnsupportedOperationException("rightNormalform not imlemented"); 367 } 368 369}