001/* 002 * $Id: Factors.java 5477 2016-03-25 18:55:43Z kredel $ 003 */ 004 005package edu.jas.ufd; 006 007 008import java.io.Serializable; 009import java.util.ArrayList; 010import java.util.List; 011 012import edu.jas.poly.AlgebraicNumber; 013import edu.jas.poly.AlgebraicNumberRing; 014import edu.jas.poly.GenPolynomial; 015import edu.jas.poly.GenPolynomialRing; 016import edu.jas.poly.PolynomialList; 017import edu.jas.structure.GcdRingElem; 018 019 020/** 021 * Container for the factors of absolute factorization. 022 * @author Heinz Kredel 023 * @param <C> coefficient type 024 */ 025 026public class Factors<C extends GcdRingElem<C>> implements Comparable<Factors<C>>, Serializable { 027 028 029 /** 030 * Original (irreducible) polynomial to be factored with coefficients from 031 * C. 032 */ 033 public final GenPolynomial<C> poly; 034 035 036 /** 037 * Algebraic field extension over C. Should be null, if p is absolutely 038 * irreducible. 039 */ 040 public final AlgebraicNumberRing<C> afac; 041 042 043 /** 044 * Original polynomial to be factored with coefficients from 045 * AlgebraicNumberRing<C>. Should be null, if p is absolutely 046 * irreducible. 047 */ 048 public final GenPolynomial<AlgebraicNumber<C>> apoly; 049 050 051 /** 052 * List of factors with coefficients from AlgebraicNumberRing<C>. 053 * Should be null, if p is absolutely irreducible. 054 */ 055 public final List<GenPolynomial<AlgebraicNumber<C>>> afactors; 056 057 058 /** 059 * List of factors with coefficients from 060 * AlgebraicNumberRing<AlgebraicNumber<C>>. Should be null, if p 061 * is absolutely irreducible. 062 */ 063 public final List<Factors<AlgebraicNumber<C>>> arfactors; 064 065 066 /** 067 * Constructor. 068 * @param p absolute irreducible GenPolynomial. 069 */ 070 public Factors(GenPolynomial<C> p) { 071 this(p, null, null, null, null); 072 } 073 074 075 /** 076 * Constructor. 077 * @param p irreducible GenPolynomial over C. 078 * @param af algebraic extension field of C where p has factors from afact. 079 * @param ap GenPolynomial p represented with coefficients from af. 080 * @param afact absolute irreducible factors of p with coefficients from af. 081 */ 082 public Factors(GenPolynomial<C> p, AlgebraicNumberRing<C> af, GenPolynomial<AlgebraicNumber<C>> ap, 083 List<GenPolynomial<AlgebraicNumber<C>>> afact) { 084 this(p, af, ap, afact, null); 085 } 086 087 088 /** 089 * Constructor. 090 * @param p irreducible GenPolynomial over C. 091 * @param af algebraic extension field of C where p has factors from afact. 092 * @param ap GenPolynomial p represented with coefficients from af. 093 * @param afact absolute irreducible factors of p with coefficients from af. 094 * @param arfact further absolute irreducible factors of p with coefficients 095 * from extensions of af. 096 */ 097 public Factors(GenPolynomial<C> p, AlgebraicNumberRing<C> af, GenPolynomial<AlgebraicNumber<C>> ap, 098 List<GenPolynomial<AlgebraicNumber<C>>> afact, List<Factors<AlgebraicNumber<C>>> arfact) { 099 poly = p; 100 afac = af; 101 apoly = ap; 102 afactors = afact; 103 arfactors = arfact; 104 } 105 106 107 /** 108 * Get the String representation. 109 * @see java.lang.Object#toString() 110 */ 111 @Override 112 public String toString() { 113 StringBuffer sb = new StringBuffer(); 114 sb.append(poly.toString()); 115 if (afac == null) { 116 return sb.toString(); 117 } 118 sb.append(" = "); 119 boolean first = true; 120 for (GenPolynomial<AlgebraicNumber<C>> ap : afactors) { 121 if (first) { 122 first = false; 123 } else { 124 sb.append(", "); 125 } 126 sb.append(ap.toString()); 127 } 128 sb.append("\n ## over " + afac.toString() + "\n"); 129 if (arfactors == null) { 130 return sb.toString(); 131 } 132 first = true; 133 for (Factors<AlgebraicNumber<C>> arp : arfactors) { 134 if (first) { 135 first = false; 136 } else { 137 sb.append(",\n"); 138 } 139 sb.append(arp.toString()); 140 } 141 return sb.toString(); 142 } 143 144 145 /** 146 * Get a scripting compatible string representation. 147 * @return script compatible representation for this container. 148 * @see edu.jas.structure.ElemFactory#toScript() 149 */ 150 public String toScript() { 151 // Python case 152 StringBuffer sb = new StringBuffer(); 153 //sb.append(poly.toScript()); 154 if (afac == null) { 155 return sb.toString(); 156 } 157 //sb.append(" =\n"); 158 boolean first = true; 159 for (GenPolynomial<AlgebraicNumber<C>> ap : afactors) { 160 if (first) { 161 first = false; 162 } else { 163 sb.append("\n * "); 164 } 165 //sb.append("( " + ap.toScript() + " )"); 166 sb.append(ap.toScript()); 167 } 168 sb.append(" #:: " + afac.toScript() + ""); 169 if (arfactors == null) { 170 return sb.toString(); 171 } 172 for (Factors<AlgebraicNumber<C>> arp : arfactors) { 173 if (first) { 174 first = false; 175 } else { 176 sb.append("\n * "); 177 } 178 sb.append(arp.toScript()); 179 } 180 return sb.toString(); 181 } 182 183 184 /** 185 * Length. Number of factors. 186 * @return number of factors. 187 */ 188 public int length() { 189 int i = 0; 190 if (afac == null) { 191 return i; 192 } 193 i += afactors.size(); 194 if (arfactors == null) { 195 return i; 196 } 197 for (Factors<AlgebraicNumber<C>> f : arfactors) { 198 i += f.length(); 199 } 200 return i; 201 } 202 203 204 /** 205 * Hash code for this Factors. 206 * @see java.lang.Object#hashCode() 207 */ 208 @Override 209 public int hashCode() { 210 int h; 211 h = poly.hashCode(); 212 if (afac == null) { 213 return h; 214 } 215 h = (h << 27); 216 h += afac.hashCode(); 217 if (afactors != null) { 218 h = (h << 27); 219 h += afactors.hashCode(); 220 } 221 if (arfactors != null) { 222 h = (h << 27); 223 h += arfactors.hashCode(); 224 } 225 return h; 226 } 227 228 229 /** 230 * Comparison with any other object. 231 * @see java.lang.Object#equals(java.lang.Object) 232 */ 233 @Override 234 @SuppressWarnings("unchecked") 235 public boolean equals(Object B) { 236 if (B == null) { 237 return false; 238 } 239 if (!(B instanceof Factors)) { 240 return false; 241 } 242 Factors<C> a = (Factors<C>) B; 243 return this.compareTo(a) == 0; 244 } 245 246 247 /** 248 * Comparison. 249 * @param facs factors container. 250 * @return sign(this.poly-facs.poly) lexicographic > 251 * sign(afac.modul-facs.afac.modul) lexicographic > 252 * afactors.compareTo(facs.afactors) lexicographic > 253 * arfactors[i].compareTo(facs.arfactors[i]) 254 */ 255 public int compareTo(Factors<C> facs) { 256 int s = poly.compareTo(facs.poly); 257 //System.out.println("s1 = " + s); 258 if (s != 0) { 259 return s; 260 } 261 if (afac == null) { 262 return -1; 263 } 264 if (facs.afac == null) { 265 return +1; 266 } 267 s = afac.modul.compareTo(facs.afac.modul); 268 //System.out.println("s2 = " + s); 269 if (s != 0) { 270 return s; 271 } 272 GenPolynomialRing<AlgebraicNumber<C>> ar = afactors.get(0).ring; 273 GenPolynomialRing<AlgebraicNumber<C>> br = facs.afactors.get(0).ring; 274 PolynomialList<AlgebraicNumber<C>> ap = new PolynomialList<AlgebraicNumber<C>>(ar, afactors); 275 PolynomialList<AlgebraicNumber<C>> bp = new PolynomialList<AlgebraicNumber<C>>(br, facs.afactors); 276 s = ap.compareTo(bp); 277 //System.out.println("s3 = " + s); 278 if (s != 0) { 279 return s; 280 } 281 if (arfactors == null && facs.arfactors == null) { 282 return 0; 283 } 284 if (arfactors == null) { 285 return -1; 286 } 287 if (facs.arfactors == null) { 288 return +1; 289 } 290 // lexicographic (?) 291 int i = 0; 292 for (Factors<AlgebraicNumber<C>> arp : arfactors) { 293 if (i >= facs.arfactors.size()) { 294 return +1; 295 } 296 Factors<AlgebraicNumber<C>> brp = facs.arfactors.get(i); 297 //System.out.println("arp = " + arp); 298 //System.out.println("brp = " + brp); 299 s = arp.compareTo(brp); 300 //System.out.println("s4 = " + s); 301 if (s != 0) { 302 return s; 303 } 304 i++; 305 } 306 if (i < facs.arfactors.size()) { 307 return -1; 308 } 309 return 0; 310 } 311 312 313 /** 314 * Find largest extension field. 315 * @return largest extension field or null if no extension field 316 */ 317 @SuppressWarnings("unchecked") 318 public AlgebraicNumberRing<C> findExtensionField() { 319 if (afac == null) { 320 return null; 321 } 322 if (arfactors == null) { 323 return afac; 324 } 325 AlgebraicNumberRing<C> arr = afac; 326 int depth = 1; 327 for (Factors<AlgebraicNumber<C>> af : arfactors) { 328 AlgebraicNumberRing<AlgebraicNumber<C>> aring = af.findExtensionField(); 329 if (aring == null) { 330 continue; 331 } 332 int d = aring.depth(); 333 if (d > depth) { 334 depth = d; 335 arr = (AlgebraicNumberRing<C>) (Object) aring; 336 } 337 } 338 return arr; 339 } 340 341 342 /** 343 * Get the list of factors at one level. 344 * @return list of algebraic factors 345 */ 346 public List<GenPolynomial<AlgebraicNumber<C>>> getFactors() { 347 List<GenPolynomial<AlgebraicNumber<C>>> af = new ArrayList<GenPolynomial<AlgebraicNumber<C>>>(); 348 if (afac == null) { 349 return af; 350 } 351 af.addAll(afactors); 352 if (arfactors == null) { 353 return af; 354 } 355 for (Factors<AlgebraicNumber<C>> arp : arfactors) { 356 af.add(arp.poly); 357 } 358 return af; 359 } 360 361 362 /** 363 * Get the factor for polynomial. 364 * @return algebraic factor 365 */ 366 public Factors<AlgebraicNumber<C>> getFactor(GenPolynomial<AlgebraicNumber<C>> p) { 367 if (afac == null) { 368 return null; 369 } 370 for (Factors<AlgebraicNumber<C>> arp : arfactors) { 371 if (p.equals(arp.poly)) { 372 return arp; 373 } 374 } 375 return null; 376 } 377 378}