001/* 002 * $Id: ReductionSeq.java 5737 2017-02-18 20:36:07Z kredel $ 003 */ 004 005package edu.jas.gb; 006 007 008import java.util.List; 009import java.util.Map; 010 011import org.apache.log4j.Logger; 012 013import edu.jas.poly.ExpVector; 014import edu.jas.poly.GenPolynomial; 015import edu.jas.poly.Monomial; 016import edu.jas.structure.RingElem; 017 018 019/** 020 * Polynomial reduction sequential use algorithm. Implements normalform. 021 * @param <C> coefficient type 022 * @author Heinz Kredel 023 */ 024 025public class ReductionSeq<C extends RingElem<C>> // should be FieldElem<C>> 026 extends ReductionAbstract<C> { 027 028 029 private static final Logger logger = Logger.getLogger(ReductionSeq.class); 030 031 032 /** 033 * Constructor. 034 */ 035 public ReductionSeq() { 036 } 037 038 039 /** 040 * Normalform. 041 * @param Ap polynomial. 042 * @param Pp polynomial list. 043 * @return nf(Ap) with respect to Pp. 044 */ 045 @SuppressWarnings("unchecked") 046 public GenPolynomial<C> normalform(List<GenPolynomial<C>> Pp, GenPolynomial<C> Ap) { 047 if (Pp == null || Pp.isEmpty()) { 048 return Ap; 049 } 050 if (Ap == null || Ap.isZERO()) { 051 return Ap; 052 } 053 if (!Ap.ring.coFac.isField()) { 054 throw new IllegalArgumentException("coefficients not from a field"); 055 } 056 Map.Entry<ExpVector, C> m; 057 int l; 058 GenPolynomial<C>[] P; 059 synchronized (Pp) { 060 l = Pp.size(); 061 P = new GenPolynomial[l]; 062 //P = Pp.toArray(); 063 for (int i = 0; i < Pp.size(); i++) { 064 P[i] = Pp.get(i); 065 } 066 } 067 ExpVector[] htl = new ExpVector[l]; 068 Object[] lbc = new Object[l]; // want C[] 069 GenPolynomial<C>[] p = new GenPolynomial[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 ExpVector e; 084 C a; 085 boolean mt = false; 086 GenPolynomial<C> R = Ap.ring.getZERO().copy(); 087 088 //GenPolynomial<C> T = null; 089 //GenPolynomial<C> Q = null; 090 GenPolynomial<C> S = Ap.copy(); 091 while (S.length() > 0) { 092 m = S.leadingMonomial(); 093 e = m.getKey(); 094 a = m.getValue(); 095 for (i = 0; i < l; i++) { 096 mt = e.multipleOf(htl[i]); 097 if (mt) 098 break; 099 } 100 if (!mt) { 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(htl[i]); 109 a = a.divide((C) lbc[i]); 110 //logger.info("red div: e = " + e + ", a = " + a); 111 //Q = p[i].multiply( a, e ); 112 //S = S.subtract( Q ); 113 S = S.subtractMultiple(a, e, p[i]); 114 } 115 } 116 return R; 117 } 118 119 120 /** 121 * Normalform with respect to marked head terms. 122 * @param Mp leading monomial list. 123 * @param Pp polynomial list. 124 * @param Ap polynomial. 125 * @return nf(Ap) with respect to Mp+Pp. 126 */ 127 @Override 128 @SuppressWarnings("unchecked") 129 public GenPolynomial<C> normalformMarked(List<Monomial<C>> Mp, List<GenPolynomial<C>> Pp, 130 GenPolynomial<C> Ap) { 131 if (Pp == null || Pp.isEmpty()) { 132 return Ap; 133 } 134 if (Mp == null || Mp.isEmpty()) { 135 return Ap; 136 } 137 if (Ap == null || Ap.isZERO()) { 138 return Ap; 139 } 140 if (!Ap.ring.coFac.isField()) { 141 throw new IllegalArgumentException("coefficients not from a field"); 142 } 143 Map.Entry<ExpVector, C> m; 144 int l; 145 GenPolynomial<C>[] P; 146 Monomial<C>[] M; 147 synchronized (Pp) { 148 l = Pp.size(); 149 if (Mp.size() != l) { 150 throw new IllegalArgumentException("#Mp != #Pp: " + l + ", " + Mp.size()); 151 } 152 P = new GenPolynomial[l]; 153 M = new Monomial[l]; 154 //P = Pp.toArray(); 155 for (int i = 0; i < Pp.size(); i++) { 156 P[i] = Pp.get(i); 157 M[i] = Mp.get(i); 158 } 159 } 160 ExpVector[] htl = new ExpVector[l]; 161 RingElem[] lbc = new RingElem[l]; 162 GenPolynomial<C>[] p = new GenPolynomial[l]; 163 int i; 164 int j = 0; 165 for (i = 0; i < l; i++) { 166 p[i] = P[i]; 167 if (M[i] != null) { 168 p[j] = p[i]; 169 htl[j] = M[i].exponent(); 170 lbc[j] = M[i].coefficient(); 171 j++; 172 } 173 } 174 l = j; 175 ExpVector e, f; 176 C a, b; 177 boolean mt = false; 178 GenPolynomial<C> R = Ap.ring.getZERO().copy(); 179 GenPolynomial<C> S = Ap.copy(); 180 while (S.length() > 0) { 181 m = S.leadingMonomial(); 182 e = m.getKey(); 183 a = m.getValue(); 184 //System.out.println("NF a = " + a + ", e = " + e); 185 for (i = 0; i < l; i++) { 186 mt = e.multipleOf(htl[i]); 187 if (mt) 188 break; 189 } 190 if (!mt) { 191 logger.debug("irred"); 192 R.doAddTo(a, e); // needed, or sum 193 //R.doPutToMap(e, a); // not here 194 //S = S.subtract( a, e ); 195 S.doRemoveFromMap(e, a); 196 // System.out.println(" S = " + S); 197 } else { 198 //System.out.println("i = "+i+", htl[i] = " + Ap.ring.toScript(htl[i]) + ", lbc[i] = " + lbc[i] + ", p[i] = " + p[i].ring.toScript(p[i].leadingExpVector())); 199 f = e.subtract(htl[i]); 200 b = a.divide((C) lbc[i]); 201 //logger.info("red div: e = " + e + ", a = " + a + ", f = " + f + ", b = " + b); 202 //Q = p[i].multiply( a, e ); 203 //S = S.subtract( Q ); 204 S.doRemoveFromMap(e, a); 205 //S.doAddTo(a.negate(), e); 206 S = S.subtractMultiple(b, f, p[i]); 207 if (e.equals(S.leadingExpVector())) { 208 throw new RuntimeException( 209 "something is wrong: ht not descending e = " + e + ", S = " + S); 210 } 211 //System.out.println("NF R = " + R.leadingExpVector() + ", S = " + S.leadingExpVector() + ", e = " + e + ", f = " + f + ", #S = " + S.length()); 212 } 213 //System.out.println("NF R = " + R + ", S = " + S); 214 } 215 //System.out.println("NF Ap = " + Ap + " ==> " + R); 216 return R; 217 } 218 219 220 /** 221 * Normalform with recording. 222 * @param row recording matrix, is modified. 223 * @param Pp a polynomial list for reduction. 224 * @param Ap a polynomial. 225 * @return nf(Pp,Ap), the normal form of Ap wrt. Pp. 226 */ 227 @SuppressWarnings("unchecked") 228 public GenPolynomial<C> normalform(List<GenPolynomial<C>> row, List<GenPolynomial<C>> Pp, 229 GenPolynomial<C> Ap) { 230 if (Pp == null || Pp.isEmpty()) { 231 return Ap; 232 } 233 if (Ap == null || Ap.isZERO()) { 234 return Ap; 235 } 236 if (!Ap.ring.coFac.isField()) { 237 throw new IllegalArgumentException("coefficients not from a field"); 238 } 239 int l = Pp.size(); 240 GenPolynomial<C>[] P = new GenPolynomial[l]; 241 synchronized (Pp) { 242 //P = Pp.toArray(); 243 for (int i = 0; i < Pp.size(); i++) { 244 P[i] = Pp.get(i); 245 } 246 } 247 ExpVector[] htl = new ExpVector[l]; 248 Object[] lbc = new Object[l]; // want C[] 249 GenPolynomial<C>[] p = new GenPolynomial[l]; 250 Map.Entry<ExpVector, C> m; 251 int j = 0; 252 int i; 253 for (i = 0; i < l; i++) { 254 p[i] = P[i]; 255 m = p[i].leadingMonomial(); 256 if (m != null) { 257 p[j] = p[i]; 258 htl[j] = m.getKey(); 259 lbc[j] = m.getValue(); 260 j++; 261 } 262 } 263 l = j; 264 ExpVector e; 265 C a; 266 boolean mt = false; 267 GenPolynomial<C> zero = Ap.ring.getZERO(); 268 GenPolynomial<C> R = Ap.ring.getZERO().copy(); 269 270 GenPolynomial<C> fac = null; 271 // GenPolynomial<C> T = null; 272 //GenPolynomial<C> Q = null; 273 GenPolynomial<C> S = Ap.copy(); 274 while (S.length() > 0) { 275 m = S.leadingMonomial(); 276 e = m.getKey(); 277 a = m.getValue(); 278 for (i = 0; i < l; i++) { 279 mt = e.multipleOf(htl[i]); 280 if (mt) 281 break; 282 } 283 if (!mt) { 284 //logger.debug("irred"); 285 //R = R.sum( a, e ); 286 //S = S.subtract( a, e ); 287 R.doPutToMap(e, a); 288 S.doRemoveFromMap(e, a); 289 // System.out.println(" S = " + S); 290 } else { 291 e = e.subtract(htl[i]); 292 //logger.info("red div = " + e); 293 C c = (C) lbc[i]; 294 a = a.divide(c); 295 //Q = p[i].multiply( a, e ); 296 //S = S.subtract( Q ); 297 S = S.subtractMultiple(a, e, p[i]); 298 fac = row.get(i); 299 if (fac == null) { 300 fac = zero.sum(a, e); 301 } else { 302 fac = fac.sum(a, e); 303 } 304 row.set(i, fac); 305 } 306 } 307 return R; 308 } 309 310}