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