001 /* 002 * $Id: GreatestCommonDivisorSimple.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 monic polynomial remainder sequence. 017 * If C is a field, then the monic PRS (on coefficients) is computed otherwise 018 * no simplifications in the reduction are made. 019 * @author Heinz Kredel 020 */ 021 022 public class GreatestCommonDivisorSimple<C extends GcdRingElem<C>> extends GreatestCommonDivisorAbstract<C> { 023 024 025 private static final Logger logger = Logger.getLogger(GreatestCommonDivisorSimple.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 boolean field = P.ring.coFac.isField(); 050 long e = P.degree(0); 051 long f = S.degree(0); 052 GenPolynomial<C> q; 053 GenPolynomial<C> r; 054 if (f > e) { 055 r = P; 056 q = S; 057 long g = f; 058 f = e; 059 e = g; 060 } else { 061 q = P; 062 r = S; 063 } 064 C c; 065 if (field) { 066 r = r.monic(); 067 q = q.monic(); 068 c = P.ring.getONECoefficient(); 069 } else { 070 r = r.abs(); 071 q = q.abs(); 072 C a = baseContent(r); 073 C b = baseContent(q); 074 c = gcd(a, b); // indirection 075 r = divide(r, a); // indirection 076 q = divide(q, b); // indirection 077 } 078 if (r.isONE()) { 079 return r.multiply(c); 080 } 081 if (q.isONE()) { 082 return q.multiply(c); 083 } 084 GenPolynomial<C> x; 085 //System.out.println("q = " + q); 086 //System.out.println("r = " + r); 087 while (!r.isZERO()) { 088 x = PolyUtil.<C> basePseudoRemainder(q, r); 089 q = r; 090 if (field) { 091 r = x.monic(); 092 } else { 093 r = x; 094 } 095 //System.out.println("q = " + q); 096 //System.out.println("r = " + r); 097 } 098 q = basePrimitivePart(q); 099 return (q.multiply(c)).abs(); 100 } 101 102 103 /** 104 * Univariate GenPolynomial recursive greatest comon divisor. Uses 105 * pseudoRemainder for remainder. 106 * @param P univariate recursive GenPolynomial. 107 * @param S univariate recursive GenPolynomial. 108 * @return gcd(P,S). 109 */ 110 @Override 111 public GenPolynomial<GenPolynomial<C>> recursiveUnivariateGcd(GenPolynomial<GenPolynomial<C>> P, 112 GenPolynomial<GenPolynomial<C>> S) { 113 if (S == null || S.isZERO()) { 114 return P; 115 } 116 if (P == null || P.isZERO()) { 117 return S; 118 } 119 if (P.ring.nvar > 1) { 120 throw new IllegalArgumentException(this.getClass().getName() + " no univariate polynomial"); 121 } 122 boolean field = P.leadingBaseCoefficient().ring.coFac.isField(); 123 long e = P.degree(0); 124 long f = S.degree(0); 125 GenPolynomial<GenPolynomial<C>> q; 126 GenPolynomial<GenPolynomial<C>> r; 127 if (f > e) { 128 r = P; 129 q = S; 130 long g = f; 131 f = e; 132 e = g; 133 } else { 134 q = P; 135 r = S; 136 } 137 if (field) { 138 r = PolyUtil.<C> monic(r); 139 q = PolyUtil.<C> monic(q); 140 } else { 141 r = r.abs(); 142 q = q.abs(); 143 } 144 GenPolynomial<C> a = recursiveContent(r); 145 GenPolynomial<C> b = recursiveContent(q); 146 147 GenPolynomial<C> c = gcd(a, b); // go to recursion 148 //System.out.println("rgcd c = " + c); 149 r = PolyUtil.<C> recursiveDivide(r, a); 150 q = PolyUtil.<C> recursiveDivide(q, b); 151 if (r.isONE()) { 152 return r.multiply(c); 153 } 154 if (q.isONE()) { 155 return q.multiply(c); 156 } 157 GenPolynomial<GenPolynomial<C>> x; 158 while (!r.isZERO()) { 159 x = PolyUtil.<C> recursivePseudoRemainder(q, r); 160 q = r; 161 if (field) { 162 r = PolyUtil.<C> monic(x); 163 } else { 164 r = x; 165 } 166 } 167 q = recursivePrimitivePart(q); 168 q = q.abs().multiply(c); 169 return q; 170 } 171 172 }