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 > 257 * sign(this.polyB-facs.polyB) lexicographic > 258 * sign(this.coA-facs.coA) lexicographic > 259 * sign(this.coB-facs.coB) lexicographic > 260 * sign(this.left-facs.left) lexicographic > 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}