001/* 002 * $Id: PseudoReductionPar.java 5870 2018-07-20 15:56:23Z kredel $ 003 */ 004 005package edu.jas.gbufd; 006 007 008import java.util.ArrayList; 009import java.util.List; 010import java.util.Map; 011 012import org.apache.logging.log4j.Logger; 013import org.apache.logging.log4j.LogManager; 014 015import edu.jas.gb.ReductionAbstract; 016import edu.jas.poly.PolyUtil; 017import edu.jas.poly.ExpVector; 018import edu.jas.poly.GenPolynomial; 019import edu.jas.structure.RingElem; 020 021 022/** 023 * Polynomial pseudo reduction sequential use algorithm. Coefficients of 024 * polynomials must not be from a field, i.e. the fraction free reduction is 025 * implemented. Implements normalform. 026 * @param <C> coefficient type 027 * @author Heinz Kredel 028 */ 029 030public class PseudoReductionPar<C extends RingElem<C>> extends ReductionAbstract<C> implements 031 PseudoReduction<C> { 032 033 034 private static final Logger logger = LogManager.getLogger(PseudoReductionPar.class); 035 036 037 private static final boolean debug = logger.isDebugEnabled(); 038 039 040 /** 041 * Constructor. 042 */ 043 public PseudoReductionPar() { 044 } 045 046 047 /** 048 * Normalform. 049 * @param Ap polynomial. 050 * @param Pp polynomial list. 051 * @return nf(Ap) with respect to Pp. 052 */ 053 @SuppressWarnings("unchecked") 054 public GenPolynomial<C> normalform(List<GenPolynomial<C>> Pp, GenPolynomial<C> Ap) { 055 if (Pp == null || Pp.isEmpty()) { 056 return Ap; 057 } 058 if (Ap == null || Ap.isZERO()) { 059 return Ap; 060 } 061 GenPolynomial<C>[] P = new GenPolynomial[0]; 062 List<GenPolynomial<C>> Ppp; 063 synchronized (Pp) { 064 Ppp = new ArrayList<GenPolynomial<C>>(Pp); // sic 065 } 066 P = Ppp.toArray(P); 067 int ll = Ppp.size(); 068 GenPolynomial<C> Rz = Ap.ring.getZERO(); 069 GenPolynomial<C> R = Rz.copy(); 070 071 GenPolynomial<C> S = Ap.copy(); 072 while (S.length() > 0) { 073 if (Pp.size() != ll) { 074 //System.out.println("Pp.size() = " + Pp.size() + ", ll = " + ll); 075 //long t = System.currentTimeMillis(); 076 synchronized (Pp) { 077 Ppp = new ArrayList<GenPolynomial<C>>(Pp); // sic 078 } 079 P = Ppp.toArray(P); 080 ll = Ppp.size(); 081 //ll = P.length; // wrong 082 //t = System.currentTimeMillis()-t; 083 //logger.info("Pp.toArray(): size() = " + l + ", ll = " + ll); 084 S = Ap.copy(); // S.add(R)? // restart reduction ? 085 R = Rz.copy(); 086 } 087 boolean mt = false; 088 Map.Entry<ExpVector, C> m = S.leadingMonomial(); 089 ExpVector e = m.getKey(); 090 C a = m.getValue(); 091 ExpVector f = null; 092 int i; 093 for (i = 0; i < ll; i++) { 094 f = P[i].leadingExpVector(); 095 mt = e.multipleOf(f); 096 if (mt) 097 break; 098 } 099 if (!mt) { 100 //System.out.println("m = " + m); 101 //logger.debug("irred"); 102 //R = R.sum(a, e); 103 //S = S.subtract(a, e); 104 R.doPutToMap(e, a); 105 S.doRemoveFromMap(e, a); 106 //System.out.println(" S = " + S); 107 } else { 108 e = e.subtract(f); 109 //logger.info("red div = " + e); 110 C c = P[i].leadingBaseCoefficient(); 111 if (a.remainder(c).isZERO()) { //c.isUnit() ) { 112 a = a.divide(c); 113 S = S.subtractMultiple(a, e, P[i]); 114 } else { 115 R = R.multiply(c); 116 //S = S.multiply(c); 117 S = S.scaleSubtractMultiple(c, a, e, P[i]); 118 } 119 //Q = p[i].multiply(a, e); 120 //S = S.subtract(Q); 121 } 122 } 123 return R; 124 } 125 126 127 /** 128 * Normalform. 129 * @param Pp polynomial list. 130 * @param Ap polynomial. 131 * @return ( nf(Ap), mf ) with respect to Pp and mf as multiplication factor 132 * for Ap. 133 */ 134 @SuppressWarnings("unchecked") 135 public PseudoReductionEntry<C> normalformFactor(List<GenPolynomial<C>> Pp, GenPolynomial<C> Ap) { 136 if (Ap == null) { 137 return null; 138 } 139 C mfac = Ap.ring.getONECoefficient(); 140 PseudoReductionEntry<C> pf = new PseudoReductionEntry<C>(Ap, mfac); 141 if (Pp == null || Pp.isEmpty()) { 142 return pf; 143 } 144 if (Ap.isZERO()) { 145 return pf; 146 } 147 GenPolynomial<C>[] P = new GenPolynomial[0]; 148 List<GenPolynomial<C>> Ppp; 149 synchronized (Pp) { 150 Ppp = new ArrayList<GenPolynomial<C>>(Pp); // sic 151 } 152 P = Ppp.toArray(P); 153 int l = Ppp.size(); 154 boolean mt = false; 155 GenPolynomial<C> Rz = Ap.ring.getZERO(); 156 GenPolynomial<C> R = Rz.copy(); 157 //GenPolynomial<C> T = null; 158 //GenPolynomial<C> Q = null; 159 GenPolynomial<C> S = Ap.copy(); 160 while (S.length() > 0) { 161 if (Pp.size() != l) { 162 //long t = System.currentTimeMillis(); 163 synchronized (Pp) { 164 Ppp = new ArrayList<GenPolynomial<C>>(Pp); 165 } 166 P = Ppp.toArray(P); 167 l = Ppp.size(); 168 //t = System.currentTimeMillis()-t; 169 //logger.info("Pp.toArray() = " + t + " ms, size() = " + l); 170 S = Ap.copy(); // S.add(R)? // restart reduction ? 171 R = Rz.copy(); 172 } 173 Map.Entry<ExpVector, C> m = S.leadingMonomial(); 174 ExpVector e = m.getKey(); 175 C a = m.getValue(); 176 ExpVector f = null; 177 int i; 178 for (i = 0; i < l; i++) { 179 f = P[i].leadingExpVector(); 180 mt = e.multipleOf(f); 181 if (mt) 182 break; 183 } 184 if (!mt) { 185 //logger.debug("irred"); 186 //R = R.sum(a, e); 187 //S = S.subtract(a, e); 188 R.doPutToMap(e, a); 189 S.doRemoveFromMap(e, a); 190 //System.out.println(" S = " + S); 191 } else { 192 e = e.subtract(f); 193 //logger.info("red div = " + e); 194 C c = P[i].leadingBaseCoefficient(); 195 if (a.remainder(c).isZERO()) { //c.isUnit() ) { 196 a = a.divide(c); 197 S = S.subtractMultiple(a, e, P[i]); 198 } else { 199 mfac = mfac.multiply(c); 200 R = R.multiply(c); 201 //S = S.multiply(c); 202 S = S.scaleSubtractMultiple(c, a, e, P[i]); 203 } 204 //Q = p[i].multiply(a, e); 205 //S = S.subtract(Q); 206 } 207 } 208 if (logger.isInfoEnabled()) { 209 logger.info("multiplicative factor = " + mfac); 210 } 211 pf = new PseudoReductionEntry<C>(R, mfac); 212 return pf; 213 } 214 215 216 /** 217 * Normalform with recording. <b>Note:</b> Only meaningful if all divisions 218 * are exact. Compute first the multiplication factor <code>m</code> with 219 * <code>normalform(Pp,Ap,m)</code>, then call this method with 220 * <code>normalform(row,Pp,m*Ap)</code>. 221 * @param row recording matrix, is modified. 222 * @param Pp a polynomial list for reduction. 223 * @param Ap a polynomial. 224 * @return nf(Pp,Ap), the normal form of Ap wrt. Pp. 225 */ 226 @SuppressWarnings("unchecked") 227 public GenPolynomial<C> normalform(List<GenPolynomial<C>> row, List<GenPolynomial<C>> Pp, 228 GenPolynomial<C> Ap) { 229 throw new RuntimeException("normalform with recording not implemented"); 230 } 231 232 233 /** 234 * Normalform recursive. 235 * @param Ap recursive polynomial. 236 * @param Pp recursive polynomial list. 237 * @return nf(Ap) with respect to Pp. 238 */ 239 @SuppressWarnings("unchecked") 240 public GenPolynomial<GenPolynomial<C>> normalformRecursive(List<GenPolynomial<GenPolynomial<C>>> Pp, GenPolynomial<GenPolynomial<C>> Ap) { 241 if (Pp == null || Pp.isEmpty()) { 242 return Ap; 243 } 244 if (Ap == null || Ap.isZERO()) { 245 return Ap; 246 } 247 GenPolynomial<GenPolynomial<C>>[] P = new GenPolynomial[0]; 248 List<GenPolynomial<GenPolynomial<C>>> Ppp; 249 synchronized (Pp) { 250 Ppp = new ArrayList<GenPolynomial<GenPolynomial<C>>>(Pp); // sic 251 } 252 P = Ppp.toArray(P); 253 int ll = Ppp.size(); 254 GenPolynomial<GenPolynomial<C>> Rz = Ap.ring.getZERO(); 255 GenPolynomial<GenPolynomial<C>> R = Rz.copy(); 256 257 GenPolynomial<GenPolynomial<C>> S = Ap.copy(); 258 while (S.length() > 0) { 259 if (Pp.size() != ll) { 260 //System.out.println("Pp.size() = " + Pp.size() + ", ll = " + ll); 261 //long t = System.currentTimeMillis(); 262 synchronized (Pp) { 263 Ppp = new ArrayList<GenPolynomial<GenPolynomial<C>>>(Pp); // sic 264 } 265 P = Ppp.toArray(P); 266 ll = Ppp.size(); 267 //ll = P.length; // wrong 268 //t = System.currentTimeMillis()-t; 269 //logger.info("Pp.toArray(): size() = " + l + ", ll = " + ll); 270 S = Ap.copy(); // S.add(R)? // restart reduction ? 271 R = Rz.copy(); 272 } 273 boolean mt = false; 274 Map.Entry<ExpVector, GenPolynomial<C>> m = S.leadingMonomial(); 275 ExpVector e = m.getKey(); 276 GenPolynomial<C> a = m.getValue(); 277 ExpVector f = null; 278 int i; 279 for (i = 0; i < ll; i++) { 280 f = P[i].leadingExpVector(); 281 mt = e.multipleOf(f); 282 if (mt) 283 break; 284 } 285 if (!mt) { 286 //System.out.println("m = " + m); 287 //logger.debug("irred"); 288 //R = R.sum(a, e); 289 //S = S.subtract(a, e); 290 R.doPutToMap(e, a); 291 S.doRemoveFromMap(e, a); 292 //System.out.println(" S = " + S); 293 } else { 294 f = e.subtract(f); 295 if (debug) { 296 logger.info("red div = " + e); 297 } 298 GenPolynomial<C> c = P[i].leadingBaseCoefficient(); 299 //if (a.remainder(c).isZERO()) { //c.isUnit() ) { 300 if (PolyUtil.<C> baseSparsePseudoRemainder(a,c).isZERO()) { 301 if (debug) { 302 logger.info("red c = " + c); 303 } 304 //a = a.divide(c); 305 GenPolynomial<C> b = PolyUtil.<C> basePseudoDivide(a,c); 306 GenPolynomial<GenPolynomial<C>> Sp = S.subtractMultiple(b, f, P[i]); 307 if (e.equals(Sp.leadingExpVector())) { // TODO: avoid if possible 308 //throw new RuntimeException("degree not descending"); 309 logger.info("degree not descending: S = " + S + ", Sp = " + Sp); 310 R = R.multiply(c); 311 //S = S.multiply(c); 312 Sp = S.scaleSubtractMultiple(c, a, f, P[i]); 313 } 314 S = Sp; 315 } else { 316 R = R.multiply(c); 317 //S = S.multiply(c); 318 S = S.scaleSubtractMultiple(c, a, f, P[i]); 319 } 320 //Q = p[i].multiply(a, f); 321 //S = S.subtract(Q); 322 } 323 } 324 return R; 325 } 326 327}