001/*
002 * $Id: GreatestCommonDivisorSyzygy.java 5773 2017-11-05 15:10:09Z kredel $
003 */
004
005package edu.jas.fd;
006
007
008import java.util.ArrayList;
009import java.util.List;
010
011import org.apache.log4j.Logger;
012
013import edu.jas.gb.SolvableGroebnerBaseAbstract;
014import edu.jas.gb.SolvableGroebnerBaseSeq;
015import edu.jas.poly.GenPolynomial;
016import edu.jas.poly.GenSolvablePolynomial;
017import edu.jas.structure.GcdRingElem;
018import edu.jas.structure.RingFactory;
019
020
021/**
022 * (Non-unique) factorization domain greatest common divisor common algorithms
023 * with syzygy computation. The implementation uses solvable syzygy gcd
024 * computation.
025 * @param <C> coefficient type
026 * @author Heinz Kredel
027 */
028
029public class GreatestCommonDivisorSyzygy<C extends GcdRingElem<C>> extends GreatestCommonDivisorAbstract<C> {
030
031
032    private static final Logger logger = Logger.getLogger(GreatestCommonDivisorSyzygy.class);
033
034
035    private static final boolean debug = true; //logger.isDebugEnabled();
036
037
038    /**
039     * Constructor.
040     * @param cf coefficient ring.
041     */
042    public GreatestCommonDivisorSyzygy(RingFactory<C> cf) {
043        super(cf);
044    }
045
046
047    /**
048     * Left univariate GenSolvablePolynomial greatest common divisor.
049     * @param P univariate GenSolvablePolynomial.
050     * @param S univariate GenSolvablePolynomial.
051     * @return gcd(P,S) with P = P'*gcd(P,S) and S = S'*gcd(P,S).
052     */
053    @Override
054    public GenSolvablePolynomial<C> leftBaseGcd(GenSolvablePolynomial<C> P, GenSolvablePolynomial<C> S) {
055        return leftGcd(P, S);
056    }
057
058
059    /**
060     * Right univariate GenSolvablePolynomial greatest common divisor.
061     * @param P univariate GenSolvablePolynomial.
062     * @param S univariate GenSolvablePolynomial.
063     * @return gcd(P,S) with P = P'*gcd(P,S) and S = S'*gcd(P,S).
064     */
065    @Override
066    public GenSolvablePolynomial<C> rightBaseGcd(GenSolvablePolynomial<C> P, GenSolvablePolynomial<C> S) {
067        return rightGcd(P, S);
068    }
069
070
071    /**
072     * Left GenSolvablePolynomial greatest common divisor.
073     * @param P GenSolvablePolynomial.
074     * @param S GenSolvablePolynomial.
075     * @return gcd(P,S) with P = P'*gcd(P,S) and S = S'*gcd(P,S).
076     */
077    @Override
078    public GenSolvablePolynomial<C> leftGcd(GenSolvablePolynomial<C> P, GenSolvablePolynomial<C> S) {
079        if (S == null || S.isZERO()) {
080            return P;
081        }
082        if (P == null || P.isZERO()) {
083            return S;
084        }
085        if (P.isConstant()) {
086            return P.ring.getONE();
087        }
088        if (S.isConstant()) {
089            return P.ring.getONE();
090        }
091        List<GenSolvablePolynomial<C>> A = new ArrayList<GenSolvablePolynomial<C>>(2);
092        A.add(P);
093        A.add(S);
094        SolvableGroebnerBaseAbstract<C> sbb = new SolvableGroebnerBaseSeq<C>();
095        logger.info("left syzGcd computing GB: " + A);
096        List<GenSolvablePolynomial<C>> G = sbb.rightGB(A); //not: leftGB, not: sbb.twosidedGB(A);
097        if (debug) {
098            logger.info("G = " + G);
099        }
100        if (G.size() == 1) {
101            return G.get(0);
102        }
103        logger.info("gcd not determined, set to 1: " + G); // + ", A = " + A);
104        return P.ring.getONE();
105    }
106
107
108    /**
109     * Right GenSolvablePolynomial right greatest common divisor.
110     * @param P GenSolvablePolynomial.
111     * @param S GenSolvablePolynomial.
112     * @return gcd(P,S) with P = gcd(P,S)*P' and S = gcd(P,S)*S'.
113     */
114    @Override
115    public GenSolvablePolynomial<C> rightGcd(GenSolvablePolynomial<C> P, GenSolvablePolynomial<C> S) {
116        if (S == null || S.isZERO()) {
117            return P;
118        }
119        if (P == null || P.isZERO()) {
120            return S;
121        }
122        if (P.isConstant()) {
123            return P.ring.getONE();
124        }
125        if (S.isConstant()) {
126            return P.ring.getONE();
127        }
128        List<GenSolvablePolynomial<C>> A = new ArrayList<GenSolvablePolynomial<C>>(2);
129        A.add(P);
130        A.add(S);
131        SolvableGroebnerBaseAbstract<C> sbb = new SolvableGroebnerBaseSeq<C>();
132        logger.info("left syzGcd computing GB: " + A);
133        List<GenSolvablePolynomial<C>> G = sbb.leftGB(A); //not: sbb.twosidedGB(A);
134        if (debug) {
135            logger.info("G = " + G);
136        }
137        if (G.size() == 1) {
138            return G.get(0);
139        }
140        logger.info("gcd not determined, set to 1: " + G); // + ", A = " + A);
141        return P.ring.getONE();
142    }
143
144
145    /**
146     * Univariate GenSolvablePolynomial left recursive greatest common divisor.
147     * @param P univariate recursive GenSolvablePolynomial.
148     * @param S univariate recursive GenSolvablePolynomial.
149     * @return gcd(P,S) with P = P'*gcd(P,S)*p and S = S'*gcd(P,S)*s, where
150     *         deg_main(p) = deg_main(s) == 0.
151     */
152    @Override
153    public GenSolvablePolynomial<GenPolynomial<C>> leftRecursiveUnivariateGcd(
154                    GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<GenPolynomial<C>> S) {
155        if (S == null || S.isZERO()) {
156            return P;
157        }
158        if (P == null || P.isZERO()) {
159            return S;
160        }
161        if (P.ring.nvar > 1) {
162            throw new IllegalArgumentException("no univariate polynomial");
163        }
164        if (P.isConstant()) {
165            return P.ring.getONE();
166        }
167        if (S.isConstant()) {
168            return P.ring.getONE();
169        }
170        List<GenSolvablePolynomial<GenPolynomial<C>>> A = new ArrayList<GenSolvablePolynomial<GenPolynomial<C>>>(
171                        2);
172        A.add(P);
173        A.add(S);
174        SolvableGroebnerBaseAbstract<GenPolynomial<C>> sbb = new SolvableGroebnerBaseSeq<GenPolynomial<C>>();
175        logger.info("left syzGcd computing GB: " + A);
176        // will not work, not field
177        List<GenSolvablePolynomial<GenPolynomial<C>>> G = sbb.rightGB(A); //not: leftGB, not: sbb.twosidedGB(A);
178        if (debug) {
179            logger.info("G = " + G);
180        }
181        if (G.size() == 1) {
182            return G.get(0);
183        }
184        logger.info("gcd not determined, set to 1: " + G); // + ", A = " + A);
185        return P.ring.getONE();
186    }
187
188
189    /**
190     * Univariate GenSolvablePolynomial right recursive greatest common divisor.
191     * @param P univariate recursive GenSolvablePolynomial.
192     * @param S univariate recursive GenSolvablePolynomial.
193     * @return gcd(P,S) with P = p*gcd(P,S)*P' and S = s*gcd(P,S)*S', where
194     *         deg_main(p) = deg_main(s) == 0.
195     */
196    @Override
197    public GenSolvablePolynomial<GenPolynomial<C>> rightRecursiveUnivariateGcd(
198                    GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<GenPolynomial<C>> S) {
199        if (S == null || S.isZERO()) {
200            return P;
201        }
202        if (P == null || P.isZERO()) {
203            return S;
204        }
205        if (P.ring.nvar > 1) {
206            throw new IllegalArgumentException("no univariate polynomial");
207        }
208        if (P.isConstant()) {
209            return P.ring.getONE();
210        }
211        if (S.isConstant()) {
212            return P.ring.getONE();
213        }
214        List<GenSolvablePolynomial<GenPolynomial<C>>> A = new ArrayList<GenSolvablePolynomial<GenPolynomial<C>>>(
215                        2);
216        A.add(P);
217        A.add(S);
218        SolvableGroebnerBaseAbstract<GenPolynomial<C>> sbb = new SolvableGroebnerBaseSeq<GenPolynomial<C>>();
219        logger.info("right syzGcd computing GB: " + A);
220        // will not work, not field
221        List<GenSolvablePolynomial<GenPolynomial<C>>> G = sbb.leftGB(A); //not: sbb.twosidedGB(A);
222        if (debug) {
223            logger.info("G = " + G);
224        }
225        if (G.size() == 1) {
226            return G.get(0);
227        }
228        logger.info("gcd not determined, set to 1: " + G); // + ", A = " + A);
229        return P.ring.getONE();
230    }
231
232}