001/* 002 * $Id: PolyUtilRoot.java 4063 2012-07-27 13:05:07Z kredel $ 003 */ 004 005package edu.jas.root; 006 007 008import java.util.ArrayList; 009import java.util.List; 010 011import org.apache.log4j.Logger; 012 013import edu.jas.arith.Rational; 014import edu.jas.poly.AlgebraicNumber; 015import edu.jas.poly.AlgebraicNumberRing; 016import edu.jas.poly.Complex; 017import edu.jas.poly.ComplexRing; 018import edu.jas.poly.GenPolynomial; 019import edu.jas.poly.GenPolynomialRing; 020import edu.jas.poly.PolyUtil; 021import edu.jas.structure.GcdRingElem; 022import edu.jas.structure.RingFactory; 023import edu.jas.structure.UnaryFunctor; 024 025 026/** 027 * Polynomial utilities related to real and complex roots. 028 * @author Heinz Kredel 029 */ 030 031public class PolyUtilRoot { 032 033 034 private static final Logger logger = Logger.getLogger(PolyUtilRoot.class); 035 036 037 private static boolean debug = logger.isDebugEnabled(); 038 039 040 /** 041 * Convert to RealAlgebraicNumber coefficients. Represent as polynomial with 042 * RealAlgebraicNumber<C> coefficients, C is e.g. ModInteger or BigRational. 043 * @param pfac result polynomial factory. 044 * @param A polynomial with C coefficients to be converted. 045 * @return polynomial with RealAlgebraicNumber<C> coefficients. 046 */ 047 public static <C extends GcdRingElem<C> & Rational> GenPolynomial<RealAlgebraicNumber<C>> convertToAlgebraicCoefficients( 048 GenPolynomialRing<RealAlgebraicNumber<C>> pfac, GenPolynomial<C> A) { 049 RealAlgebraicRing<C> afac = (RealAlgebraicRing<C>) pfac.coFac; 050 if (debug) { 051 logger.info("afac = " + afac); 052 } 053 return PolyUtil.<C, RealAlgebraicNumber<C>> map(pfac, A, new CoeffToReAlg<C>(afac)); 054 } 055 056 057 /** 058 * Convert to recursive RealAlgebraicNumber coefficients. Represent as 059 * polynomial with recursive RealAlgebraicNumber<C> coefficients, C is e.g. 060 * ModInteger or BigRational. 061 * @param depth recursion depth of RealAlgebraicNumber coefficients. 062 * @param pfac result polynomial factory. 063 * @param A polynomial with C coefficients to be converted. 064 * @return polynomial with RealAlgebraicNumber<C> coefficients. 065 */ 066 public static <C extends GcdRingElem<C> & Rational> GenPolynomial<RealAlgebraicNumber<C>> convertToRecAlgebraicCoefficients( 067 int depth, GenPolynomialRing<RealAlgebraicNumber<C>> pfac, GenPolynomial<C> A) { 068 RealAlgebraicRing<C> afac = (RealAlgebraicRing<C>) pfac.coFac; 069 return PolyUtil.<C, RealAlgebraicNumber<C>> map(pfac, A, new CoeffToRecReAlg<C>(depth, afac)); 070 } 071 072 073 /** 074 * Convert to RealAlgebraicNumber coefficients. Represent as polynomial with 075 * RealAlgebraicNumber<C> coefficients, C is e.g. ModInteger or BigRational. 076 * @param pfac result polynomial factory. 077 * @param A recursive polynomial with GenPolynomial<BigInteger> 078 * coefficients to be converted. 079 * @return polynomial with RealAlgebraicNumber<C> coefficients. 080 */ 081 public static <C extends GcdRingElem<C> & Rational> GenPolynomial<RealAlgebraicNumber<C>> convertRecursiveToAlgebraicCoefficients( 082 GenPolynomialRing<RealAlgebraicNumber<C>> pfac, GenPolynomial<GenPolynomial<C>> A) { 083 RealAlgebraicRing<C> afac = (RealAlgebraicRing<C>) pfac.coFac; 084 return PolyUtil.<GenPolynomial<C>, RealAlgebraicNumber<C>> map(pfac, A, new PolyToReAlg<C>(afac)); 085 } 086 087 088 /** 089 * Convert to AlgebraicNumber coefficients. Represent as polynomial with 090 * AlgebraicNumber<C> coefficients. 091 * @param afac result polynomial factory. 092 * @param A polynomial with RealAlgebraicNumber<C> coefficients to be 093 * converted. 094 * @return polynomial with AlgebraicNumber<C> coefficients. 095 */ 096 public static <C extends GcdRingElem<C> & Rational> GenPolynomial<AlgebraicNumber<C>> algebraicFromRealCoefficients( 097 GenPolynomialRing<AlgebraicNumber<C>> afac, GenPolynomial<RealAlgebraicNumber<C>> A) { 098 AlgebraicNumberRing<C> cfac = (AlgebraicNumberRing<C>) afac.coFac; 099 return PolyUtil.<RealAlgebraicNumber<C>, AlgebraicNumber<C>> map(afac, A, new AlgFromRealCoeff<C>( 100 cfac)); 101 } 102 103 104 /** 105 * Convert to RealAlgebraicNumber coefficients. Represent as polynomial with 106 * RealAlgebraicNumber<C> coefficients. 107 * @param rfac result polynomial factory. 108 * @param A polynomial with AlgebraicNumber<C> coefficients to be 109 * converted. 110 * @return polynomial with RealAlgebraicNumber<C> coefficients. 111 */ 112 public static <C extends GcdRingElem<C> & Rational> GenPolynomial<RealAlgebraicNumber<C>> realFromAlgebraicCoefficients( 113 GenPolynomialRing<RealAlgebraicNumber<C>> rfac, GenPolynomial<AlgebraicNumber<C>> A) { 114 RealAlgebraicRing<C> cfac = (RealAlgebraicRing<C>) rfac.coFac; 115 return PolyUtil.<AlgebraicNumber<C>, RealAlgebraicNumber<C>> map(rfac, A, new RealFromAlgCoeff<C>( 116 cfac)); 117 } 118 119 120 /** 121 * Convert to RealAlgebraicNumber coefficients. Represent as polynomial with 122 * RealAlgebraicNumber<C> coefficients, C is e.g. BigRational. 123 * @param pfac result polynomial factory. 124 * @param A polynomial with C coefficients to be converted. 125 * @return polynomial with RealAlgebraicNumber<C> coefficients. 126 */ 127 public static <C extends GcdRingElem<C> & Rational> GenPolynomial<RealAlgebraicNumber<C>> convertToRealCoefficients( 128 GenPolynomialRing<RealAlgebraicNumber<C>> pfac, GenPolynomial<C> A) { 129 RealAlgebraicRing<C> afac = (RealAlgebraicRing<C>) pfac.coFac; 130 return PolyUtil.<C, RealAlgebraicNumber<C>> map(pfac, A, new CoeffToReal<C>(afac)); 131 } 132 133 134 /** 135 * Convert to ComplexAlgebraicNumber coefficients. Represent as polynomial 136 * with ComplexAlgebraicNumber<C> coefficients, C is e.g. BigRational. 137 * @param pfac result polynomial factory. 138 * @param A polynomial with C coefficients to be converted. 139 * @return polynomial with ComplexAlgebraicNumber<C> coefficients. 140 */ 141 public static <C extends GcdRingElem<C> & Rational> GenPolynomial<ComplexAlgebraicNumber<C>> convertToComplexCoefficients( 142 GenPolynomialRing<ComplexAlgebraicNumber<C>> pfac, GenPolynomial<C> A) { 143 ComplexAlgebraicRing<C> afac = (ComplexAlgebraicRing<C>) pfac.coFac; 144 return PolyUtil.<C, ComplexAlgebraicNumber<C>> map(pfac, A, new CoeffToComplex<C>(afac)); 145 } 146 147 148 /** 149 * Convert to ComplexAlgebraicNumber coefficients. Represent as polynomial 150 * with ComplexAlgebraicNumber<C> coefficients, C is e.g. BigRational. 151 * @param pfac result polynomial factory. 152 * @param A polynomial with C coefficients to be converted. 153 * @return polynomial with ComplexAlgebraicNumber<C> coefficients. 154 */ 155 public static <C extends GcdRingElem<C> & Rational> GenPolynomial<ComplexAlgebraicNumber<C>> convertToComplexCoefficientsFromComplex( 156 GenPolynomialRing<ComplexAlgebraicNumber<C>> pfac, GenPolynomial<Complex<C>> A) { 157 ComplexAlgebraicRing<C> afac = (ComplexAlgebraicRing<C>) pfac.coFac; 158 return PolyUtil.<Complex<C>, ComplexAlgebraicNumber<C>> map(pfac, A, 159 new CoeffToComplexFromComplex<C>(afac)); 160 } 161 162} 163 164 165/** 166 * Polynomial to algebraic functor. 167 */ 168class PolyToReAlg<C extends GcdRingElem<C> & Rational> implements 169 UnaryFunctor<GenPolynomial<C>, RealAlgebraicNumber<C>> { 170 171 172 final protected RealAlgebraicRing<C> afac; 173 174 175 public PolyToReAlg(RealAlgebraicRing<C> fac) { 176 if (fac == null) { 177 throw new IllegalArgumentException("fac must not be null"); 178 } 179 afac = fac; 180 } 181 182 183 public RealAlgebraicNumber<C> eval(GenPolynomial<C> c) { 184 if (c == null) { 185 return afac.getZERO(); 186 } 187 return new RealAlgebraicNumber<C>(afac, c); 188 } 189} 190 191 192/** 193 * Coefficient to algebraic functor. 194 */ 195class CoeffToReAlg<C extends GcdRingElem<C> & Rational> implements UnaryFunctor<C, RealAlgebraicNumber<C>> { 196 197 198 final protected RealAlgebraicRing<C> afac; 199 200 201 final protected GenPolynomial<C> zero; 202 203 204 public CoeffToReAlg(RealAlgebraicRing<C> fac) { 205 if (fac == null) { 206 throw new IllegalArgumentException("fac must not be null"); 207 } 208 afac = fac; 209 GenPolynomialRing<C> pfac = afac.algebraic.ring; 210 zero = pfac.getZERO(); 211 } 212 213 214 public RealAlgebraicNumber<C> eval(C c) { 215 if (c == null) { 216 return afac.getZERO(); 217 } 218 return new RealAlgebraicNumber<C>(afac, zero.sum(c)); 219 } 220} 221 222 223/** 224 * Coefficient to recursive algebraic functor. 225 */ 226class CoeffToRecReAlg<C extends GcdRingElem<C> & Rational> implements UnaryFunctor<C, RealAlgebraicNumber<C>> { 227 228 229 final protected List<RealAlgebraicRing<C>> lfac; 230 231 232 final int depth; 233 234 235 @SuppressWarnings("unchecked") 236 public CoeffToRecReAlg(int depth, RealAlgebraicRing<C> fac) { 237 if (fac == null) { 238 throw new IllegalArgumentException("fac must not be null"); 239 } 240 RealAlgebraicRing<C> afac = fac; 241 this.depth = depth; 242 lfac = new ArrayList<RealAlgebraicRing<C>>(this.depth); 243 lfac.add(fac); 244 for (int i = 1; i < this.depth; i++) { 245 RingFactory<C> rf = afac.algebraic.ring.coFac; 246 if (!(rf instanceof RealAlgebraicRing)) { 247 throw new IllegalArgumentException("fac depth to low"); 248 } 249 afac = (RealAlgebraicRing<C>) (Object) rf; 250 lfac.add(afac); 251 } 252 } 253 254 255 @SuppressWarnings("unchecked") 256 public RealAlgebraicNumber<C> eval(C c) { 257 if (c == null) { 258 return lfac.get(0).getZERO(); 259 } 260 C ac = c; 261 RealAlgebraicRing<C> af = lfac.get(lfac.size() - 1); 262 GenPolynomial<C> zero = af.algebraic.ring.getZERO(); 263 RealAlgebraicNumber<C> an = new RealAlgebraicNumber<C>(af, zero.sum(ac)); 264 for (int i = lfac.size() - 2; i >= 0; i--) { 265 af = lfac.get(i); 266 zero = af.algebraic.ring.getZERO(); 267 ac = (C) (Object) an; 268 an = new RealAlgebraicNumber<C>(af, zero.sum(ac)); 269 } 270 return an; 271 } 272} 273 274 275/** 276 * Coefficient to algebraic from real algebraic functor. 277 */ 278class AlgFromRealCoeff<C extends GcdRingElem<C> & Rational> implements 279 UnaryFunctor<RealAlgebraicNumber<C>, AlgebraicNumber<C>> { 280 281 282 final protected AlgebraicNumberRing<C> afac; 283 284 285 public AlgFromRealCoeff(AlgebraicNumberRing<C> fac) { 286 if (fac == null) { 287 throw new IllegalArgumentException("fac must not be null"); 288 } 289 afac = fac; 290 } 291 292 293 public AlgebraicNumber<C> eval(RealAlgebraicNumber<C> c) { 294 if (c == null) { 295 return afac.getZERO(); 296 } 297 return c.number; 298 } 299} 300 301 302/** 303 * Coefficient to real algebriac from algebraic functor. 304 */ 305class RealFromAlgCoeff<C extends GcdRingElem<C> & Rational> implements 306 UnaryFunctor<AlgebraicNumber<C>, RealAlgebraicNumber<C>> { 307 308 309 final protected RealAlgebraicRing<C> rfac; 310 311 312 public RealFromAlgCoeff(RealAlgebraicRing<C> fac) { 313 if (fac == null) { 314 throw new IllegalArgumentException("fac must not be null"); 315 } 316 rfac = fac; 317 } 318 319 320 public RealAlgebraicNumber<C> eval(AlgebraicNumber<C> c) { 321 if (c == null) { 322 return rfac.getZERO(); 323 } 324 return new RealAlgebraicNumber<C>(rfac, c); 325 } 326} 327 328 329/** 330 * Coefficient to real algebraic functor. 331 */ 332class CoeffToReal<C extends GcdRingElem<C> & Rational> implements UnaryFunctor<C, RealAlgebraicNumber<C>> { 333 334 335 final protected RealAlgebraicRing<C> rfac; 336 337 338 final protected AlgebraicNumber<C> zero; 339 340 341 public CoeffToReal(RealAlgebraicRing<C> fac) { 342 if (fac == null) { 343 throw new IllegalArgumentException("fac must not be null"); 344 } 345 rfac = fac; 346 AlgebraicNumberRing<C> afac = rfac.algebraic; 347 zero = afac.getZERO(); 348 } 349 350 351 public RealAlgebraicNumber<C> eval(C c) { 352 if (c == null) { 353 return rfac.getZERO(); 354 } 355 return new RealAlgebraicNumber<C>(rfac, zero.sum(c)); 356 } 357} 358 359 360/** 361 * Coefficient to complex algebraic functor. 362 */ 363class CoeffToComplex<C extends GcdRingElem<C> & Rational> implements 364 UnaryFunctor<C, ComplexAlgebraicNumber<C>> { 365 366 367 final protected ComplexAlgebraicRing<C> cfac; 368 369 370 final protected AlgebraicNumber<Complex<C>> zero; 371 372 373 final protected ComplexRing<C> cr; 374 375 376 public CoeffToComplex(ComplexAlgebraicRing<C> fac) { 377 if (fac == null) { 378 throw new IllegalArgumentException("fac must not be null"); 379 } 380 cfac = fac; 381 AlgebraicNumberRing<Complex<C>> afac = cfac.algebraic; 382 zero = afac.getZERO(); 383 cr = (ComplexRing<C>) afac.ring.coFac; 384 } 385 386 387 public ComplexAlgebraicNumber<C> eval(C c) { 388 if (c == null) { 389 return cfac.getZERO(); 390 } 391 return new ComplexAlgebraicNumber<C>(cfac, zero.sum(new Complex<C>(cr, c))); 392 } 393} 394 395 396/** 397 * Coefficient to complex algebraic from complex functor. 398 */ 399class CoeffToComplexFromComplex<C extends GcdRingElem<C> & Rational> implements 400 UnaryFunctor<Complex<C>, ComplexAlgebraicNumber<C>> { 401 402 403 final protected ComplexAlgebraicRing<C> cfac; 404 405 406 final protected AlgebraicNumber<Complex<C>> zero; 407 408 409 //final protected ComplexRing<C> cr; 410 411 412 public CoeffToComplexFromComplex(ComplexAlgebraicRing<C> fac) { 413 if (fac == null) { 414 throw new IllegalArgumentException("fac must not be null"); 415 } 416 cfac = fac; 417 AlgebraicNumberRing<Complex<C>> afac = cfac.algebraic; 418 zero = afac.getZERO(); 419 //cr = (ComplexRing<C>) afac.ring.coFac; 420 } 421 422 423 public ComplexAlgebraicNumber<C> eval(Complex<C> c) { 424 if (c == null) { 425 return cfac.getZERO(); 426 } 427 return new ComplexAlgebraicNumber<C>(cfac, zero.sum(c)); 428 } 429}