001/*
002 * $Id: GCDcoFactors.java 5731 2017-02-11 11:38:15Z kredel $
003 */
004
005package edu.jas.fd;
006
007
008import java.io.Serializable;
009
010import edu.jas.poly.GenSolvablePolynomial;
011import edu.jas.structure.GcdRingElem;
012
013
014/**
015 * Container for the co-factors of left-right GCD computation. Invariant is left
016 * * coA * right = polyA and left * coB * right = polyB.
017 * @param <C> coefficient type
018 * @author Heinz Kredel
019 */
020
021public class GCDcoFactors<C extends GcdRingElem<C>> implements Serializable {
022
023
024    /**
025     * GCD algorithm to use for verification.
026     */
027    public final GreatestCommonDivisorAbstract<C> fd;
028
029
030    /**
031     * Original polynomial A of the GCD computation.
032     */
033    public final GenSolvablePolynomial<C> polyA;
034
035
036    /**
037     * Original polynomial B of the GCD computation.
038     */
039    public final GenSolvablePolynomial<C> polyB;
040
041
042    /**
043     * Co-factor of A.
044     */
045    public final GenSolvablePolynomial<C> coA;
046
047
048    /**
049     * Co-factor of B.
050     */
051    public final GenSolvablePolynomial<C> coB;
052
053
054    /**
055     * Left GCD of A and B.
056     */
057    public final GenSolvablePolynomial<C> left;
058
059
060    /**
061     * Right GCD of A and B.
062     */
063    public final GenSolvablePolynomial<C> right;
064
065
066    /**
067     * Constructor.
068     * @param g GCD algorithm to use for verification.
069     * @param a polynomial A.
070     * @param b polynomial B.
071     * @param ca polynomial coA.
072     * @param cb polynomial coB.
073     * @param l polynomial left GCD.
074     * @param r polynomial right GCD.
075     */
076    public GCDcoFactors(GreatestCommonDivisorAbstract<C> g, GenSolvablePolynomial<C> a,
077                    GenSolvablePolynomial<C> b, GenSolvablePolynomial<C> ca, GenSolvablePolynomial<C> cb,
078                    GenSolvablePolynomial<C> l, GenSolvablePolynomial<C> r) {
079        fd = g;
080        polyA = a;
081        polyB = b;
082        coA = ca;
083        coB = cb;
084        left = l;
085        right = r;
086    }
087
088
089    /**
090     * Test if the invariants of this are fulfilled.
091     * @return true if x * (left * coA * right) = y * (polyA), for x, y with x *
092     *         lc(left * coA * right) == y * lc(polyA) and x * (left * coB *
093     *         right) == y * (polyB), for x, y with x * lc(left * coB * right)
094     *         == y * lc(polyB).
095     */
096    public boolean isGCD() {
097        GenSolvablePolynomial<C> a, ap, bp;
098        //C l = left.leadingBaseCoefficient();
099        //C c1 = fd.leftBaseContent((GenSolvablePolynomial<C>)a.abs());
100        //C c2 = fd.leftBaseContent((GenSolvablePolynomial<C>)polyA.abs());
101        //System.out.println("c1 = " + c1 + ", c2 = " + c2 + ", c1/l = " + c1.leftDivide(l) + ", c2/l = " + c2.leftDivide(l));
102        //System.out.println("c1 = " + c1 + ", c2 = " + c2 + ", l\\c1 = " + c1.rightDivide(l) + ", l\\c2 = " + c2.rightDivide(l));
103        //System.out.println("c1%l = " + c1.leftRemainder(l) + ", c2%l = " + c2.leftRemainder(l));
104        //GenSolvablePolynomial<C> a = left.multiply(right).multiply(coA); // left right coA
105        //a = (GenSolvablePolynomial<C>)fd.leftBasePrimitivePart(a).abs();
106        //System.out.println("a = " + a);
107        //if (! a.equals(fd.leftBasePrimitivePart(polyA).abs())) {
108        //    System.out.println("a = " + a + ",\nA != " + polyA);
109        //    return false;
110        //}
111        //C d1 = fd.leftBaseContent((GenSolvablePolynomial<C>)b.abs());
112        //C d2 = fd.leftBaseContent((GenSolvablePolynomial<C>)polyB.abs());
113        //System.out.println("d1 = " + d1 + ", d2 = " + d2 + ", d1/l = " + d1.leftDivide(l) + ", d2/l = " + d2.leftDivide(l));
114        //System.out.println("d1 = " + d1 + ", d2 = " + d2 + ", l\\d1 = " + d1.rightDivide(l) + ", l\\d2 = " + d2.rightDivide(l));
115        //System.out.println("d1%l = " + d1.leftRemainder(l) + ", d2%l = " + d2.leftRemainder(l));
116        //GenSolvablePolynomial<C> b = left.multiply(right).multiply(coB);
117        //b = (GenSolvablePolynomial<C>)fd.leftBasePrimitivePart(b).abs();
118        //System.out.println("b = " + b);
119        //if (! b.abs().equals(fd.leftBasePrimitivePart(polyB).abs())) {
120        //    System.out.println("b = " + b + ",\nB != " + polyB);
121        //    return false;
122        //}
123        // check via Ore condition
124        a = left.multiply(coA).multiply(right);
125        C c1 = a.leadingBaseCoefficient();
126        C c2 = polyA.leadingBaseCoefficient();
127        C[] oc = fd.leftOreCond(c1, c2);
128        ap = a.multiplyLeft(oc[0]);
129        bp = polyA.multiplyLeft(oc[1]);
130        if (!ap.equals(bp)) {
131            //System.out.println("a: ap_l = " + ap + ", bp = " + bp);
132            oc = fd.rightOreCond(c1, c2);
133            ap = a.multiply(oc[0]);
134            bp = polyA.multiply(oc[1]);
135            if (!ap.equals(bp)) {
136                System.out.println("a: ap_r = " + ap + ", bp = " + bp);
137                return false;
138            }
139        }
140        a = left.multiply(coB).multiply(right);
141        c1 = a.leadingBaseCoefficient();
142        c2 = polyB.leadingBaseCoefficient();
143        oc = fd.leftOreCond(c1, c2);
144        ap = a.multiplyLeft(oc[0]);
145        bp = polyB.multiplyLeft(oc[1]);
146        if (!ap.equals(bp)) {
147            //System.out.println("b: ap_l = " + ap + ", bp = " + bp);
148            oc = fd.rightOreCond(c1, c2);
149            ap = a.multiply(oc[0]);
150            bp = polyB.multiply(oc[1]);
151            if (!ap.equals(bp)) {
152                System.out.println("b: ap_r = " + ap + ", bp = " + bp);
153                return false;
154            }
155        }
156        return true;
157    }
158
159
160    /**
161     * Get the String representation.
162     * @see java.lang.Object#toString()
163     */
164    @Override
165    public String toString() {
166        StringBuffer sb = new StringBuffer();
167        sb.append(left.toString());
168        sb.append(" * ");
169        sb.append(coA.toString());
170        sb.append(" * ");
171        sb.append(right.toString());
172        sb.append(" == ");
173        sb.append(polyA.toString());
174        sb.append(",\n ");
175        sb.append(left.toString());
176        sb.append(" * ");
177        sb.append(coB.toString());
178        sb.append(" * ");
179        sb.append(right.toString());
180        sb.append(" == ");
181        sb.append(polyB.toString());
182        return sb.toString();
183    }
184
185
186    /**
187     * Get a scripting compatible string representation.
188     * @return script compatible representation for this container.
189     * @see edu.jas.structure.ElemFactory#toScript()
190     */
191    public String toScript() {
192        // Python case
193        StringBuffer sb = new StringBuffer();
194        sb.append(left.toScript());
195        sb.append(" * ");
196        sb.append(coA.toScript());
197        sb.append(" * ");
198        sb.append(right.toScript());
199        sb.append(" == ");
200        sb.append(polyA.toString());
201        sb.append(" && ");
202        sb.append(left.toScript());
203        sb.append(" * ");
204        sb.append(coB.toScript());
205        sb.append(" * ");
206        sb.append(right.toScript());
207        sb.append(" == ");
208        sb.append(polyB.toString());
209        sb.append(" ");
210        return sb.toString();
211    }
212
213
214    /**
215     * Hash code for this GCDcoFactors.
216     * @see java.lang.Object#hashCode()
217     */
218    @Override
219    public int hashCode() {
220        int h = polyA.hashCode();
221        h = (h << 7);
222        h += polyB.hashCode();
223        h = (h << 7);
224        h += coA.hashCode();
225        h = (h << 7);
226        h += coB.hashCode();
227        h = (h << 7);
228        h += left.hashCode();
229        h = (h << 7);
230        h += right.hashCode();
231        return h;
232    }
233
234
235    /**
236     * Comparison with any other object.
237     * @see java.lang.Object#equals(java.lang.Object)
238     */
239    @Override
240    @SuppressWarnings("unchecked")
241    public boolean equals(Object B) {
242        if (B == null) {
243            return false;
244        }
245        if (!(B instanceof GCDcoFactors)) {
246            return false;
247        }
248        GCDcoFactors<C> a = (GCDcoFactors<C>) B;
249        return this.compareTo(a) == 0;
250    }
251
252
253    /**
254     * Comparison.
255     * @param facs gcd co-factors container.
256     * @return sign(this.polyA-facs.polyA) lexicographic &gt;
257     *         sign(this.polyB-facs.polyB) lexicographic &gt;
258     *         sign(this.coA-facs.coA) lexicographic &gt;
259     *         sign(this.coB-facs.coB) lexicographic &gt;
260     *         sign(this.left-facs.left) lexicographic &gt;
261     *         sign(this.right-facs.right).
262     */
263    public int compareTo(GCDcoFactors<C> facs) {
264        int s = polyA.compareTo(facs.polyA);
265        if (s != 0) {
266            return s;
267        }
268        s = polyB.compareTo(facs.polyB);
269        if (s != 0) {
270            return s;
271        }
272        s = coA.compareTo(facs.coA);
273        if (s != 0) {
274            return s;
275        }
276        s = coB.compareTo(facs.coB);
277        if (s != 0) {
278            return s;
279        }
280        s = left.compareTo(facs.left);
281        if (s != 0) {
282            return s;
283        }
284        s = right.compareTo(facs.right);
285        if (s != 0) {
286            return s;
287        }
288        return 0;
289    }
290
291}