001 /* 002 * $Id: GreatestCommonDivisorPrimitive.java 3290 2010-08-26 09:18:48Z kredel $ 003 */ 004 005 package edu.jas.ufd; 006 007 008 import org.apache.log4j.Logger; 009 010 import edu.jas.poly.GenPolynomial; 011 import edu.jas.poly.PolyUtil; 012 import edu.jas.structure.GcdRingElem; 013 014 015 /** 016 * Greatest common divisor algorithms with primitive polynomial remainder 017 * sequence. 018 * @author Heinz Kredel 019 */ 020 021 public class GreatestCommonDivisorPrimitive<C extends GcdRingElem<C>> extends 022 GreatestCommonDivisorAbstract<C> { 023 024 025 private static final Logger logger = Logger.getLogger(GreatestCommonDivisorPrimitive.class); 026 027 028 private final boolean debug = logger.isDebugEnabled(); 029 030 031 /** 032 * Univariate GenPolynomial greatest comon divisor. Uses pseudoRemainder for 033 * remainder. 034 * @param P univariate GenPolynomial. 035 * @param S univariate GenPolynomial. 036 * @return gcd(P,S). 037 */ 038 @Override 039 public GenPolynomial<C> baseGcd(GenPolynomial<C> P, GenPolynomial<C> S) { 040 if (S == null || S.isZERO()) { 041 return P; 042 } 043 if (P == null || P.isZERO()) { 044 return S; 045 } 046 if (P.ring.nvar > 1) { 047 throw new IllegalArgumentException(this.getClass().getName() + " no univariate polynomial"); 048 } 049 long e = P.degree(0); 050 long f = S.degree(0); 051 GenPolynomial<C> q; 052 GenPolynomial<C> r; 053 if (f > e) { 054 r = P; 055 q = S; 056 long g = f; 057 f = e; 058 e = g; 059 } else { 060 q = P; 061 r = S; 062 } 063 r = r.abs(); 064 q = q.abs(); 065 C a = baseContent(r); 066 C b = baseContent(q); 067 C c = gcd(a, b); // indirection 068 r = divide(r, a); // indirection 069 q = divide(q, b); // indirection 070 if (r.isONE()) { 071 return r.multiply(c); 072 } 073 if (q.isONE()) { 074 return q.multiply(c); 075 } 076 GenPolynomial<C> x; 077 while (!r.isZERO()) { 078 x = PolyUtil.<C> basePseudoRemainder(q, r); 079 q = r; 080 r = basePrimitivePart(x); 081 } 082 return (q.multiply(c)).abs(); 083 } 084 085 086 /** 087 * Univariate GenPolynomial recursive greatest comon divisor. Uses 088 * pseudoRemainder for remainder. 089 * @param P univariate recursive GenPolynomial. 090 * @param S univariate recursive GenPolynomial. 091 * @return gcd(P,S). 092 */ 093 @Override 094 public GenPolynomial<GenPolynomial<C>> recursiveUnivariateGcd(GenPolynomial<GenPolynomial<C>> P, 095 GenPolynomial<GenPolynomial<C>> S) { 096 if (S == null || S.isZERO()) { 097 return P; 098 } 099 if (P == null || P.isZERO()) { 100 return S; 101 } 102 if (P.ring.nvar > 1) { 103 throw new IllegalArgumentException(this.getClass().getName() + " no univariate polynomial"); 104 } 105 long e = P.degree(0); 106 long f = S.degree(0); 107 GenPolynomial<GenPolynomial<C>> q; 108 GenPolynomial<GenPolynomial<C>> r; 109 if (f > e) { 110 r = P; 111 q = S; 112 long g = f; 113 f = e; 114 e = g; 115 } else { 116 q = P; 117 r = S; 118 } 119 r = r.abs(); 120 q = q.abs(); 121 GenPolynomial<C> a = recursiveContent(r); 122 GenPolynomial<C> b = recursiveContent(q); 123 124 GenPolynomial<C> c = gcd(a, b); // go to recursion 125 //System.out.println("rgcd c = " + c); 126 r = PolyUtil.<C> recursiveDivide(r, a); 127 q = PolyUtil.<C> recursiveDivide(q, b); 128 if (r.isONE()) { 129 return r.multiply(c); 130 } 131 if (q.isONE()) { 132 return q.multiply(c); 133 } 134 GenPolynomial<GenPolynomial<C>> x; 135 while (!r.isZERO()) { 136 x = PolyUtil.<C> recursivePseudoRemainder(q, r); 137 //System.out.println("rgcd x = " + x); 138 q = r; 139 r = recursivePrimitivePart(x); 140 } 141 return q.abs().multiply(c); //.abs(); 142 } 143 144 }