001/* 002 * $Id$ 003 */ 004 005package edu.jas.gb; 006 007 008import java.util.List; 009import java.util.Map; 010 011import org.apache.logging.log4j.LogManager; 012import org.apache.logging.log4j.Logger; 013 014import edu.jas.poly.ExpVector; 015import edu.jas.poly.GenSolvablePolynomial; 016import edu.jas.structure.RingElem; 017 018 019/** 020 * Solvable polynomial Reduction algorithm. Implements left, right normalform. 021 * @param <C> coefficient type 022 * @author Heinz Kredel 023 */ 024 025public class SolvableReductionSeq<C extends RingElem<C>> extends SolvableReductionAbstract<C> { 026 027 028 private static final Logger logger = LogManager.getLogger(SolvableReductionSeq.class); 029 030 031 /** 032 * Constructor. 033 */ 034 public SolvableReductionSeq() { 035 } 036 037 038 /** 039 * Left Normalform. 040 * @param Ap solvable polynomial. 041 * @param Pp solvable polynomial list. 042 * @return left-nf(Ap) with respect to Pp. 043 */ 044 @SuppressWarnings("unchecked") 045 public GenSolvablePolynomial<C> leftNormalform(List<GenSolvablePolynomial<C>> Pp, 046 GenSolvablePolynomial<C> Ap) { 047 if (Pp == null || Pp.isEmpty()) { 048 return Ap; 049 } 050 if (Ap == null || Ap.isZERO()) { 051 return Ap; 052 } 053 Map.Entry<ExpVector, C> m; 054 GenSolvablePolynomial<C>[] P = new GenSolvablePolynomial[0]; 055 synchronized (Pp) { 056 P = Pp.toArray(P); 057 } 058 int l = P.length; 059 int i; 060 ExpVector[] htl = new ExpVector[l]; 061 //C[] lbc = (C[]) new RingElem[l]; 062 GenSolvablePolynomial<C>[] p = new GenSolvablePolynomial[l]; 063 int j = 0; 064 for (i = 0; i < l; i++) { 065 if (P[i] == null) { 066 continue; 067 } 068 p[i] = P[i]; 069 m = p[i].leadingMonomial(); 070 if (m != null) { 071 p[j] = p[i]; 072 htl[j] = m.getKey(); 073 //lbc[j] = m.getValue(); 074 j++; 075 } 076 } 077 l = j; 078 ExpVector e; //, f; 079 C a, b; 080 boolean mt = false; 081 GenSolvablePolynomial<C> R = Ap.ring.getZERO().copy(); 082 GenSolvablePolynomial<C> Q = null; 083 GenSolvablePolynomial<C> S = Ap.copy(); 084 GenSolvablePolynomial<C> Sp; 085 while (S.length() > 0) { 086 m = S.leadingMonomial(); 087 e = m.getKey(); 088 logger.debug("red, e = {}", e); 089 a = m.getValue(); 090 for (i = 0; i < l; i++) { 091 mt = e.multipleOf(htl[i]); 092 if (mt) 093 break; 094 } 095 if (!mt) { 096 //logger.debug("irred"); 097 //R = (GenSolvablePolynomial<C>) R.sum(a, e); 098 //S = (GenSolvablePolynomial<C>) S.subtract(a, e); 099 R.doPutToMap(e, a); 100 S.doRemoveFromMap(e, a); 101 // System.out.println(" S = " + S); 102 } else { 103 //f = e; 104 e = e.subtract(htl[i]); 105 //logger.debug("red div = {}", e); 106 Q = p[i].multiplyLeft(e); 107 b = a; 108 a = a.divide(Q.leadingBaseCoefficient()); 109 //Q = Q.multiplyLeft(a); 110 //S = (GenSolvablePolynomial<C>) S.subtract(Q); 111 ExpVector g1 = S.leadingExpVector(); 112 Sp = S; 113 S = S.subtractMultiple(a, Q); 114 //S = S.subtractMultiple(a, e, p[i]); 115 ExpVector g2 = S.leadingExpVector(); 116 if (g1.equals(g2)) { 117 logger.info("g1.equals(g2): Pp = {}", Pp); 118 logger.info("g1.equals(g2): Ap = {}", Ap); 119 logger.info("g1.equals(g2): p[i] = {}", p[i]); 120 logger.info("g1.equals(g2): Q = {}", Q); 121 logger.info("g1.equals(g2): R = {}", R); 122 logger.info("g1.equals(g2): Sp = {}", Sp); 123 logger.info("g1.equals(g2): S = {}", S); 124 throw new RuntimeException("g1.equals(g2): " + g1 + ", a = " + a + ", b = " + b); 125 } 126 } 127 } 128 return R; 129 } 130 131 132 /** 133 * LeftNormalform with recording. 134 * @param row recording matrix, is modified. 135 * @param Pp a polynomial list for reduction. 136 * @param Ap a polynomial. 137 * @return nf(Pp,Ap), the left normal form of Ap wrt. Pp. 138 */ 139 @SuppressWarnings({ "cast", "unchecked" }) 140 public GenSolvablePolynomial<C> leftNormalform(List<GenSolvablePolynomial<C>> row, 141 List<GenSolvablePolynomial<C>> Pp, GenSolvablePolynomial<C> Ap) { 142 if (Pp == null || Pp.isEmpty()) { 143 return Ap; 144 } 145 if (Ap == null || Ap.isZERO()) { 146 return Ap; 147 } 148 GenSolvablePolynomial<C>[] P = new GenSolvablePolynomial[0]; 149 synchronized (Pp) { 150 P = Pp.toArray(P); 151 } 152 int l = P.length; 153 ExpVector[] htl = new ExpVector[l]; 154 //C[] lbc = (C[]) new RingElem[l]; 155 GenSolvablePolynomial<C>[] p = (GenSolvablePolynomial<C>[]) new GenSolvablePolynomial[l]; 156 Map.Entry<ExpVector, C> m; 157 int j = 0; 158 int i; 159 for (i = 0; i < l; i++) { 160 p[i] = P[i]; 161 m = p[i].leadingMonomial(); 162 if (m != null) { 163 p[j] = p[i]; 164 htl[j] = m.getKey(); 165 //lbc[j] = m.getValue(); 166 j++; 167 } 168 } 169 l = j; 170 ExpVector e; 171 C a; 172 boolean mt = false; 173 //GenSolvablePolynomial<C> zero = Ap.ring.getZERO(); 174 GenSolvablePolynomial<C> R = Ap.ring.getZERO().copy(); 175 176 GenSolvablePolynomial<C> fac = null; 177 GenSolvablePolynomial<C> Q = null; 178 GenSolvablePolynomial<C> S = Ap.copy(); 179 while (S.length() > 0) { 180 m = S.leadingMonomial(); 181 e = m.getKey(); 182 a = m.getValue(); 183 for (i = 0; i < l; i++) { 184 mt = e.multipleOf(htl[i]); 185 if (mt) 186 break; 187 } 188 if (!mt) { 189 //logger.debug("irred"); 190 //R = (GenSolvablePolynomial<C>) R.sum(a, e); 191 //S = (GenSolvablePolynomial<C>) S.subtract(a, e); 192 R.doPutToMap(e, a); 193 S.doRemoveFromMap(e, a); 194 // System.out.println(" S = " + S); 195 } else { 196 e = e.subtract(htl[i]); 197 //logger.info("red div = {}", e); 198 //a = a.divide( (C)lbc[i] ); 199 //Q = p[i].multiplyLeft( a, e ); 200 Q = p[i].multiplyLeft(e); 201 a = a.divide(Q.leadingBaseCoefficient()); 202 //Q = Q.multiplyLeft(a); 203 //S = (GenSolvablePolynomial<C>) S.subtract(Q); 204 ExpVector g1 = S.leadingExpVector(); 205 S = S.subtractMultiple(a, Q); 206 ExpVector g2 = S.leadingExpVector(); 207 if (g1.equals(g2)) { 208 throw new RuntimeException("g1.equals(g2): " + g1 + ", a = " + a + ", lc(S) = " 209 + S.leadingBaseCoefficient()); 210 } 211 fac = row.get(i); 212 if (fac == null) { 213 //fac = (GenSolvablePolynomial<C>) zero.sum(a, e); 214 fac = Ap.ring.valueOf(a, e); 215 } else { 216 //fac = (GenSolvablePolynomial<C>) fac.sum(a, e); 217 fac.doAddTo(a, e); 218 } 219 row.set(i, fac); 220 } 221 } 222 return R; 223 } 224 225 226 /** 227 * Right Normalform. 228 * @param Ap solvable polynomial. 229 * @param Pp solvable polynomial list. 230 * @return right-nf(Ap) with respect to Pp. 231 */ 232 @SuppressWarnings({ "cast", "unchecked" }) 233 public GenSolvablePolynomial<C> rightNormalform(List<GenSolvablePolynomial<C>> Pp, 234 GenSolvablePolynomial<C> Ap) { 235 if (Pp == null || Pp.isEmpty()) { 236 return Ap; 237 } 238 if (Ap == null || Ap.isZERO()) { 239 return Ap; 240 } 241 int l; 242 Map.Entry<ExpVector, C> m; 243 GenSolvablePolynomial<C>[] P; 244 synchronized (Pp) { 245 l = Pp.size(); 246 P = (GenSolvablePolynomial<C>[]) new GenSolvablePolynomial[l]; 247 //P = Pp.toArray(); 248 for (int j = 0; j < Pp.size(); j++) { 249 P[j] = Pp.get(j); 250 } 251 } 252 int i; 253 ExpVector[] htl = new ExpVector[l]; 254 //C[] lbc = (C[]) new RingElem[l]; 255 GenSolvablePolynomial<C>[] p = (GenSolvablePolynomial<C>[]) new GenSolvablePolynomial[l]; 256 int j = 0; 257 for (i = 0; i < l; i++) { 258 p[i] = P[i]; 259 m = p[i].leadingMonomial(); 260 if (m != null) { 261 p[j] = p[i]; 262 htl[j] = m.getKey(); 263 //lbc[j] = m.getValue(); 264 j++; 265 } 266 } 267 l = j; 268 ExpVector e; 269 C a; 270 boolean mt = false; 271 GenSolvablePolynomial<C> R = Ap.ring.getZERO().copy(); 272 273 //GenSolvablePolynomial<C> T = null; 274 GenSolvablePolynomial<C> Q = null; 275 GenSolvablePolynomial<C> S = Ap.copy(); 276 while (S.length() > 0) { 277 m = S.leadingMonomial(); 278 e = m.getKey(); 279 //logger.info("red = {}", e); 280 a = m.getValue(); 281 for (i = 0; i < l; i++) { 282 mt = e.multipleOf(htl[i]); 283 if (mt) 284 break; 285 } 286 if (!mt) { 287 //logger.debug("irred"); 288 //R = (GenSolvablePolynomial<C>) R.sum(a, e); 289 //S = (GenSolvablePolynomial<C>) S.subtract(a, e); 290 R.doPutToMap(e, a); 291 S.doRemoveFromMap(e, a); 292 // System.out.println(" S = " + S); 293 } else { 294 //logger.debug("red"); 295 e = e.subtract(htl[i]); 296 //a = a.divide( (C)lbc[i] ); 297 Q = p[i].multiply(e); // p_i * (a e) TODO 298 a = a.divide(Q.leadingBaseCoefficient()); 299 Q = Q.multiply(a); // p_i * (e a) !! 300 ExpVector g1 = S.leadingExpVector(); 301 S = (GenSolvablePolynomial<C>) S.subtract(Q); 302 //S = S.subtractMultiple(Q, a); 303 ExpVector g2 = S.leadingExpVector(); 304 if (g1.equals(g2)) { 305 throw new RuntimeException("g1.equals(g2): " + g1 + ", a = " + a + ", lc(S) = " 306 + S.leadingBaseCoefficient()); 307 } 308 } 309 } 310 return R; 311 } 312 313 314 /** 315 * RightNormalform with recording. 316 * @param row recording matrix, is modified. 317 * @param Pp a polynomial list for reduction. 318 * @param Ap a polynomial. 319 * @return nf(Pp,Ap), the right normal form of Ap wrt. Pp. 320 */ 321 @SuppressWarnings({ "cast", "unchecked" }) 322 public GenSolvablePolynomial<C> rightNormalform(List<GenSolvablePolynomial<C>> row, 323 List<GenSolvablePolynomial<C>> Pp, GenSolvablePolynomial<C> Ap) { 324 if (Pp == null || Pp.isEmpty()) { 325 return Ap; 326 } 327 if (Ap == null || Ap.isZERO()) { 328 return Ap; 329 } 330 int l = Pp.size(); 331 GenSolvablePolynomial<C>[] P = (GenSolvablePolynomial<C>[]) new GenSolvablePolynomial[l]; 332 synchronized (Pp) { 333 //P = Pp.toArray(); 334 for (int i = 0; i < Pp.size(); i++) { 335 P[i] = Pp.get(i); 336 } 337 } 338 ExpVector[] htl = new ExpVector[l]; 339 //C[] lbc = (C[]) new RingElem[l]; 340 GenSolvablePolynomial<C>[] p = (GenSolvablePolynomial<C>[]) new GenSolvablePolynomial[l]; 341 Map.Entry<ExpVector, C> m; 342 int j = 0; 343 int i; 344 for (i = 0; i < l; i++) { 345 p[i] = P[i]; 346 m = p[i].leadingMonomial(); 347 if (m != null) { 348 p[j] = p[i]; 349 htl[j] = m.getKey(); 350 //lbc[j] = m.getValue(); 351 j++; 352 } 353 } 354 l = j; 355 ExpVector e; 356 C a; 357 boolean mt = false; 358 GenSolvablePolynomial<C> zero = Ap.ring.getZERO(); 359 GenSolvablePolynomial<C> R = Ap.ring.getZERO().copy(); 360 361 GenSolvablePolynomial<C> fac = null; 362 // GenSolvablePolynomial<C> T = null; 363 GenSolvablePolynomial<C> Q = null; 364 GenSolvablePolynomial<C> S = Ap.copy(); 365 while (S.length() > 0) { 366 m = S.leadingMonomial(); 367 e = m.getKey(); 368 a = m.getValue(); 369 for (i = 0; i < l; i++) { 370 mt = e.multipleOf(htl[i]); 371 if (mt) 372 break; 373 } 374 if (!mt) { 375 //logger.debug("irred"); 376 //R = (GenSolvablePolynomial<C>) R.sum(a, e); 377 //S = (GenSolvablePolynomial<C>) S.subtract(a, e); 378 R.doPutToMap(e, a); 379 S.doRemoveFromMap(e, a); 380 } else { 381 e = e.subtract(htl[i]); 382 //logger.info("red div = {}", e); 383 //a = a.divide( (C)lbc[i] ); 384 //Q = p[i].multiply( a, e ); 385 Q = p[i].multiply(e); // p_i * (a e) TODO 386 a = a.divide(Q.leadingBaseCoefficient()); 387 Q = Q.multiply(a); // p_i * (e a) 388 ExpVector g1 = S.leadingExpVector(); 389 S = (GenSolvablePolynomial<C>) S.subtract(Q); 390 //S = S.subtractMultiple(Q, a); 391 ExpVector g2 = S.leadingExpVector(); 392 if (g1.equals(g2)) { 393 throw new RuntimeException("g1.equals(g2): " + g1 + ", a = " + a + ", lc(S) = " 394 + S.leadingBaseCoefficient()); 395 } 396 fac = row.get(i); 397 if (fac == null) { 398 //fac = (GenSolvablePolynomial<C>) zero.sum(a, e); 399 fac = Ap.ring.valueOf(a, e); 400 } else { 401 //fac = (GenSolvablePolynomial<C>) fac.sum(a, e); 402 fac.doAddTo(a, e); 403 } 404 row.set(i, fac); 405 } 406 } 407 return R; 408 } 409 410}