001/* 002 * $Id: FDUtil.java 5733 2017-02-12 12:52:17Z kredel $ 003 */ 004 005package edu.jas.fd; 006 007 008import java.util.ArrayList; 009import java.util.Collection; 010import java.util.List; 011import java.util.Map; 012 013import org.apache.log4j.Logger; 014 015import edu.jas.poly.ExpVector; 016import edu.jas.poly.GenPolynomial; 017import edu.jas.poly.GenPolynomialRing; 018import edu.jas.poly.GenSolvablePolynomial; 019import edu.jas.poly.GenSolvablePolynomialRing; 020import edu.jas.poly.RecSolvablePolynomial; 021import edu.jas.poly.RecSolvablePolynomialRing; 022import edu.jas.structure.GcdRingElem; 023import edu.jas.structure.RingFactory; 024 025 026/** 027 * Solvable polynomials factorization domain utilities, for example recursive 028 * pseudo remainder. 029 * @author Heinz Kredel 030 */ 031 032public class FDUtil { 033 034 035 private static final Logger logger = Logger.getLogger(FDUtil.class); 036 037 038 private static final boolean debug = true; //logger.isDebugEnabled(); 039 040 041 private static final boolean info = logger.isInfoEnabled(); 042 043 044 /** 045 * GenSolvablePolynomial sparse pseudo remainder for univariate polynomials. 046 * @param <C> coefficient type. 047 * @param P GenSolvablePolynomial. 048 * @param S nonzero GenSolvablePolynomial. 049 * @return remainder with ore(ldcf(S)<sup>m'</sup>) P = quotient * S + 050 * remainder. m' ≤ deg(P)-deg(S) 051 * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). 052 */ 053 @SuppressWarnings("unchecked") 054 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<C> leftBaseSparsePseudoRemainder( 055 GenSolvablePolynomial<C> P, GenSolvablePolynomial<C> S) { 056 return leftBasePseudoQuotientRemainder(P, S)[1]; 057 } 058 059 060 /** 061 * GenSolvablePolynomial sparse right pseudo remainder for univariate 062 * polynomials. 063 * @param <C> coefficient type. 064 * @param P GenSolvablePolynomial. 065 * @param S nonzero GenSolvablePolynomial. 066 * @return remainder with P ore(ldcf(S)<sup>m'</sup>) = S * quotient + 067 * remainder. m' ≤ deg(P)-deg(S) 068 * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). 069 */ 070 @SuppressWarnings("unchecked") 071 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<C> rightBaseSparsePseudoRemainder( 072 GenSolvablePolynomial<C> P, GenSolvablePolynomial<C> S) { 073 return rightBasePseudoQuotientRemainder(P, S)[1]; 074 } 075 076 077 /** 078 * GenSolvablePolynomial sparse pseudo quotient for univariate polynomials 079 * or exact division. 080 * @param <C> coefficient type. 081 * @param P GenSolvablePolynomial. 082 * @param S nonzero GenSolvablePolynomial. 083 * @return quotient with ore(ldcf(S)<sup>m'</sup>) P = quotient * S + 084 * remainder. m' ≤ deg(P)-deg(S) 085 * @see edu.jas.poly.GenPolynomial#divide(edu.jas.poly.GenPolynomial). 086 */ 087 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<C> leftBasePseudoQuotient( 088 GenSolvablePolynomial<C> P, GenSolvablePolynomial<C> S) { 089 return leftBasePseudoQuotientRemainder(P, S)[0]; 090 } 091 092 093 /** 094 * GenSolvablePolynomial right sparse pseudo quotient for univariate 095 * polynomials or exact division. 096 * @param <C> coefficient type. 097 * @param P GenSolvablePolynomial. 098 * @param S nonzero GenSolvablePolynomial. 099 * @return quotient with P ore(ldcf(S)<sup>m'</sup>) = S * quotient + 100 * remainder. m' ≤ deg(P)-deg(S) 101 * @see edu.jas.poly.GenPolynomial#divide(edu.jas.poly.GenPolynomial). 102 */ 103 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<C> rightBasePseudoQuotient( 104 GenSolvablePolynomial<C> P, GenSolvablePolynomial<C> S) { 105 return rightBasePseudoQuotientRemainder(P, S)[0]; 106 } 107 108 109 /** 110 * GenSolvablePolynomial sparse pseudo quotient and remainder for univariate 111 * polynomials or exact division. 112 * @param <C> coefficient type. 113 * @param P GenSolvablePolynomial. 114 * @param S nonzero GenSolvablePolynomial. 115 * @return [ quotient, remainder ] with ore(ldcf(S)<sup>m'</sup>) P = 116 * quotient * S + remainder. m' ≤ deg(P)-deg(S) 117 * @see edu.jas.poly.GenPolynomial#divide(edu.jas.poly.GenPolynomial). 118 */ 119 @SuppressWarnings("unchecked") 120 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<C>[] leftBasePseudoQuotientRemainder( 121 GenSolvablePolynomial<C> P, GenSolvablePolynomial<C> S) { 122 if (S == null || S.isZERO()) { 123 throw new ArithmeticException(P.toString() + " division by zero " + S); 124 } 125 //if (S.ring.nvar != 1) { // ok if exact division 126 // throw new RuntimeException("univariate polynomials only"); 127 //} 128 GenSolvablePolynomial<C>[] ret = new GenSolvablePolynomial[2]; 129 ret[0] = null; 130 ret[1] = null; 131 if (P.isZERO() || S.isONE()) { 132 ret[0] = P; 133 ret[1] = S.ring.getZERO(); 134 return ret; 135 } 136 if (P instanceof RecSolvablePolynomial) { 137 RecSolvablePolynomial<C> Pr = (RecSolvablePolynomial) P; 138 if (!Pr.ring.coeffTable.isEmpty()) { 139 throw new UnsupportedOperationException( 140 "RecSolvablePolynomial with twisted coeffs not supported"); 141 } 142 } 143 GreatestCommonDivisorAbstract<C> fd = new GreatestCommonDivisorFake<C>(P.ring.coFac); 144 ExpVector e = S.leadingExpVector(); 145 GenSolvablePolynomial<C> h; 146 GenSolvablePolynomial<C> r = P; 147 GenSolvablePolynomial<C> q = S.ring.getZERO().copy(); 148 while (!r.isZERO()) { 149 ExpVector f = r.leadingExpVector(); 150 if (f.multipleOf(e)) { 151 C a = r.leadingBaseCoefficient(); 152 f = f.subtract(e); 153 h = S.multiplyLeft(f); // coeff a 154 C c = h.leadingBaseCoefficient(); 155 // need ga, gc: ga a = gc c 156 C[] oc = fd.leftOreCond(a, c); 157 C ga = oc[0]; 158 C gc = oc[1]; 159 r = r.multiplyLeft(ga); // coeff ga a, exp f 160 h = h.multiplyLeft(gc); // coeff gc c, exp f 161 q = q.multiplyLeft(ga); // c 162 q = (GenSolvablePolynomial<C>) q.sum(gc, f); // a 163 //System.out.println("q = " + q); 164 r = (GenSolvablePolynomial<C>) r.subtract(h); 165 } else { 166 break; 167 } 168 } 169 int sp = P.signum(); 170 int ss = S.signum(); 171 int sq = q.signum(); 172 // sp = ss * sq 173 if (sp != ss * sq) { 174 q = (GenSolvablePolynomial<C>) q.negate(); 175 r = (GenSolvablePolynomial<C>) r.negate(); 176 } 177 ret[0] = q; 178 ret[1] = r; 179 return ret; 180 } 181 182 183 /** 184 * GenSolvablePolynomial sparse pseudo quotient and remainder for univariate 185 * polynomials or exact division. 186 * @param <C> coefficient type. 187 * @param P GenSolvablePolynomial. 188 * @param S nonzero GenSolvablePolynomial. 189 * @return [ quotient, remainder ] with P ore(ldcf(S)<sup>m'</sup>) = S * 190 * quotient + remainder. m' ≤ deg(P)-deg(S) 191 * @see edu.jas.poly.GenPolynomial#divide(edu.jas.poly.GenPolynomial). 192 */ 193 @SuppressWarnings("unchecked") 194 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<C>[] rightBasePseudoQuotientRemainder( 195 GenSolvablePolynomial<C> P, GenSolvablePolynomial<C> S) { 196 if (S == null || S.isZERO()) { 197 throw new ArithmeticException(P.toString() + " division by zero " + S); 198 } 199 //if (S.ring.nvar != 1) { // ok if exact division 200 // throw new RuntimeException("univariate polynomials only"); 201 //} 202 GenSolvablePolynomial<C>[] ret = new GenSolvablePolynomial[2]; 203 ret[0] = null; 204 ret[1] = null; 205 if (P.isZERO() || S.isONE()) { 206 ret[0] = P; 207 ret[1] = S.ring.getZERO(); 208 return ret; 209 } 210 if (P instanceof RecSolvablePolynomial) { 211 RecSolvablePolynomial<C> Pr = (RecSolvablePolynomial) P; 212 if (!Pr.ring.coeffTable.isEmpty()) { 213 throw new UnsupportedOperationException( 214 "RecSolvablePolynomial with twisted coeffs not supported"); 215 } 216 } 217 GreatestCommonDivisorAbstract<C> fd = new GreatestCommonDivisorFake<C>(P.ring.coFac); 218 ExpVector e = S.leadingExpVector(); 219 GenSolvablePolynomial<C> h; 220 GenSolvablePolynomial<C> r = P; 221 GenSolvablePolynomial<C> q = S.ring.getZERO().copy(); 222 while (!r.isZERO()) { 223 ExpVector f = r.leadingExpVector(); 224 if (f.multipleOf(e)) { 225 C a = r.leadingBaseCoefficient(); 226 f = f.subtract(e); 227 h = S.multiply(f); // coeff a 228 C c = h.leadingBaseCoefficient(); 229 // need ga, gc: a ga = c gc 230 C[] oc = fd.rightOreCond(a, c); 231 C ga = oc[0]; 232 C gc = oc[1]; 233 r = r.multiply(ga); // coeff a ga, exp f 234 h = h.multiply(gc); // coeff c gc, exp f wanted but is exp f * coeff c gc, okay for base 235 q = q.multiply(ga); // c 236 q = (GenSolvablePolynomial<C>) q.sum(gc, f); // a 237 r = (GenSolvablePolynomial<C>) r.subtract(h); 238 } else { 239 break; 240 } 241 } 242 int sp = P.signum(); 243 int ss = S.signum(); 244 int sq = q.signum(); 245 // sp = ss * sq 246 if (sp != ss * sq) { 247 q = (GenSolvablePolynomial<C>) q.negate(); 248 r = (GenSolvablePolynomial<C>) r.negate(); 249 } 250 ret[0] = q; 251 ret[1] = r; 252 return ret; 253 } 254 255 256 /** 257 * Is recursive GenSolvablePolynomial pseudo quotient and remainder. For 258 * recursive polynomials. 259 * @param <C> coefficient type. 260 * @param P recursive GenSolvablePolynomial. 261 * @param S nonzero recursive GenSolvablePolynomial. 262 * @return true, if P ~= q * S + r, else false. 263 * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). 264 * <b>Note:</b> not always meaningful and working 265 */ 266 @SuppressWarnings("unchecked") 267 public static <C extends GcdRingElem<C>> boolean isRecursivePseudoQuotientRemainder( 268 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<GenPolynomial<C>> S, 269 GenSolvablePolynomial<GenPolynomial<C>> q, GenSolvablePolynomial<GenPolynomial<C>> r) { 270 GenSolvablePolynomial<GenPolynomial<C>> rhs, lhs; 271 rhs = (GenSolvablePolynomial<GenPolynomial<C>>) q.multiply(S).sum(r); 272 lhs = P; 273 GenPolynomial<C> ldcf = S.leadingBaseCoefficient(); 274 long d = P.degree(0) - S.degree(0) + 1; 275 d = (d > 0 ? d : -d + 2); 276 for (long i = 0; i <= d; i++) { 277 //System.out.println("lhs = " + lhs); 278 //System.out.println("rhs = " + rhs); 279 //System.out.println("lhs-rhs = " + lhs.subtract(rhs)); 280 if (lhs.equals(rhs)) { 281 return true; 282 } 283 lhs = lhs.multiply(ldcf); 284 } 285 GenSolvablePolynomial<GenPolynomial<C>> Pp = P; 286 rhs = q.multiply(S); 287 //System.out.println("rhs,2 = " + rhs); 288 for (long i = 0; i <= d; i++) { 289 lhs = (GenSolvablePolynomial<GenPolynomial<C>>) Pp.subtract(r); 290 //System.out.println("lhs = " + lhs); 291 //System.out.println("rhs = " + rhs); 292 //System.out.println("lhs-rhs = " + lhs.subtract(rhs)); 293 if (lhs.equals(rhs)) { 294 //System.out.println("lhs,2 = " + lhs); 295 return true; 296 } 297 Pp = Pp.multiply(ldcf); 298 } 299 GenPolynomialRing<C> cofac = (GenPolynomialRing) P.ring.coFac; 300 GreatestCommonDivisorAbstract<C> fd = new GreatestCommonDivisorSimple<C>(cofac.coFac); 301 GenSolvablePolynomial<C> a = (GenSolvablePolynomial<C>) P.leadingBaseCoefficient(); 302 rhs = (GenSolvablePolynomial<GenPolynomial<C>>) q.multiply(S).sum(r); 303 GenSolvablePolynomial<C> b = (GenSolvablePolynomial<C>) rhs.leadingBaseCoefficient(); 304 GenSolvablePolynomial<C>[] oc = fd.leftOreCond(a, b); 305 GenPolynomial<C> ga = oc[0]; 306 GenPolynomial<C> gb = oc[1]; 307 //System.out.println("FDQR: OreCond: a = " + a + ", b = " + b); 308 //System.out.println("FDQR: OreCond: ga = " + ga + ", gb = " + gb); 309 // ga a = gd d 310 GenSolvablePolynomial<GenPolynomial<C>> Pa = P.multiplyLeft(ga); // coeff ga a 311 GenSolvablePolynomial<GenPolynomial<C>> Rb = rhs.multiplyLeft(gb); // coeff gb b 312 GenSolvablePolynomial<GenPolynomial<C>> D = (GenSolvablePolynomial<GenPolynomial<C>>) Pa.subtract(Rb); 313 if (D.isZERO()) { 314 return true; 315 } 316 if (debug) { 317 logger.info("not QR: D = " + D); 318 } 319 //System.out.println("FDQR: Pa = " + Pa); 320 //System.out.println("FDQR: Rb = " + Rb); 321 //System.out.println("FDQR: Pa-Rb = " + D); 322 return false; 323 } 324 325 326 /** 327 * GenSolvablePolynomial sparse pseudo remainder for recursive solvable 328 * polynomials. 329 * @param <C> coefficient type. 330 * @param P recursive GenSolvablePolynomial. 331 * @param S nonzero recursive GenSolvablePolynomial. 332 * @return remainder with ore(ldcf(S)<sup>m'</sup>) P = quotient * S + 333 * remainder. 334 * @see edu.jas.poly.PolyUtil#recursiveSparsePseudoRemainder(edu.jas.poly.GenPolynomial,edu.jas.poly.GenPolynomial) 335 * . 336 */ 337 @SuppressWarnings("unchecked") 338 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> recursiveSparsePseudoRemainder( 339 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<GenPolynomial<C>> S) { 340 return recursivePseudoQuotientRemainder(P, S)[1]; 341 } 342 343 344 /** 345 * GenSolvablePolynomial recursive pseudo quotient for recursive 346 * polynomials. 347 * @param <C> coefficient type. 348 * @param P recursive GenSolvablePolynomial. 349 * @param S nonzero recursive GenSolvablePolynomial. 350 * @return quotient with ore(ldcf(S)<sup>m'</sup>) P = quotient * S + 351 * remainder. 352 * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). 353 */ 354 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> recursivePseudoQuotient( 355 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<GenPolynomial<C>> S) { 356 return recursivePseudoQuotientRemainder(P, S)[0]; 357 } 358 359 360 /** 361 * GenSolvablePolynomial recursive pseudo quotient and remainder for 362 * recursive polynomials. 363 * @param <C> coefficient type. 364 * @param P recursive GenSolvablePolynomial. 365 * @param S nonzero recursive GenSolvablePolynomial. 366 * @return [ quotient, remainder ] with ore(ldcf(S)<sup>m'</sup>) P = 367 * quotient * S + remainder. 368 * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). 369 */ 370 @SuppressWarnings("unchecked") 371 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>>[] recursivePseudoQuotientRemainder( 372 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<GenPolynomial<C>> S) { 373 if (S == null || S.isZERO()) { 374 throw new ArithmeticException(P + " division by zero " + S); 375 } 376 //if (S.ring.nvar != 1) { // ok if exact division 377 // throw new RuntimeException("univariate polynomials only"); 378 //} 379 GenSolvablePolynomial<GenPolynomial<C>>[] ret = new GenSolvablePolynomial[2]; 380 if (P == null || P.isZERO()) { 381 ret[0] = S.ring.getZERO(); 382 ret[1] = S.ring.getZERO(); 383 return ret; 384 } 385 if (S.isONE()) { 386 ret[0] = P; 387 ret[1] = S.ring.getZERO(); 388 return ret; 389 } 390 GenPolynomialRing<C> cofac = (GenPolynomialRing) P.ring.coFac; 391 GreatestCommonDivisorAbstract<C> fd = new GreatestCommonDivisorSimple<C>(cofac.coFac); 392 393 ExpVector e = S.leadingExpVector(); 394 GenSolvablePolynomial<GenPolynomial<C>> h; 395 GenSolvablePolynomial<GenPolynomial<C>> r = P; 396 GenSolvablePolynomial<GenPolynomial<C>> q = S.ring.getZERO().copy(); 397 while (!r.isZERO()) { 398 ExpVector g = r.leadingExpVector(); 399 ExpVector f = g; 400 if (f.multipleOf(e)) { 401 f = f.subtract(e); 402 h = S.multiplyLeft(f); // coeff c, exp (f/e) e 403 GenSolvablePolynomial<C> a = (GenSolvablePolynomial<C>) r.leadingBaseCoefficient(); 404 GenSolvablePolynomial<C> d = (GenSolvablePolynomial<C>) h.leadingBaseCoefficient(); 405 GenSolvablePolynomial<C>[] oc = fd.leftOreCond(a, d); 406 GenPolynomial<C> ga = oc[0]; // d 407 GenPolynomial<C> gd = oc[1]; // a 408 // ga a = gd d 409 r = r.multiplyLeft(ga); // coeff ga a, exp f 410 h = h.multiplyLeft(gd); // coeff gd d, exp f 411 q = q.multiplyLeft(ga); // d 412 q = (GenSolvablePolynomial<GenPolynomial<C>>) q.sum(gd, f); // a 413 r = (GenSolvablePolynomial<GenPolynomial<C>>) r.subtract(h); 414 if (!r.isZERO() && g.equals(r.leadingExpVector())) { 415 throw new RuntimeException("degree not descending: r = " + r); 416 } 417 } else { 418 break; 419 } 420 } 421 int sp = P.signum(); 422 int ss = S.signum(); 423 int sq = q.signum(); 424 // sp = ss * sq 425 if (sp != ss * sq) { 426 q = (GenSolvablePolynomial<GenPolynomial<C>>) q.negate(); 427 r = (GenSolvablePolynomial<GenPolynomial<C>>) r.negate(); 428 } 429 ret[0] = q; 430 ret[1] = r; 431 return ret; 432 } 433 434 435 /** 436 * Is recursive GenSolvablePolynomial right pseudo quotient and remainder. 437 * For recursive polynomials. 438 * @param <C> coefficient type. 439 * @param P recursive GenSolvablePolynomial. 440 * @param S nonzero recursive GenSolvablePolynomial. 441 * @return true, if P ~= S * q + r, else false. 442 * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). 443 * <b>Note:</b> not always meaningful and working 444 */ 445 @SuppressWarnings("unchecked") 446 public static <C extends GcdRingElem<C>> boolean isRecursiveRightPseudoQuotientRemainder( 447 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<GenPolynomial<C>> S, 448 GenSolvablePolynomial<GenPolynomial<C>> q, GenSolvablePolynomial<GenPolynomial<C>> r) { 449 GenSolvablePolynomial<GenPolynomial<C>> rhs, lhs; 450 rhs = (GenSolvablePolynomial<GenPolynomial<C>>) S.multiply(q).sum(r); 451 lhs = P; 452 GenPolynomial<C> ldcf = S.leadingBaseCoefficient(); 453 long d = P.degree(0) - S.degree(0) + 1; 454 d = (d > 0 ? d : -d + 2); 455 for (long i = 0; i <= d; i++) { 456 //System.out.println("lhs = " + lhs); 457 //System.out.println("rhs = " + rhs); 458 //System.out.println("lhs-rhs = " + lhs.subtract(rhs)); 459 if (lhs.equals(rhs)) { 460 return true; 461 } 462 lhs = lhs.multiplyLeft(ldcf); // side? 463 } 464 GenSolvablePolynomial<GenPolynomial<C>> Pp = P; 465 rhs = S.multiply(q); 466 //System.out.println("rhs,2 = " + rhs); 467 for (long i = 0; i <= d; i++) { 468 lhs = (GenSolvablePolynomial<GenPolynomial<C>>) Pp.subtract(r); 469 //System.out.println("lhs = " + lhs); 470 //System.out.println("rhs = " + rhs); 471 //System.out.println("lhs-rhs = " + lhs.subtract(rhs)); 472 if (lhs.equals(rhs)) { 473 //System.out.println("lhs,2 = " + lhs); 474 return true; 475 } 476 Pp = Pp.multiplyLeft(ldcf); // side? 477 } 478 GenPolynomialRing<C> cofac = (GenPolynomialRing) P.ring.coFac; 479 GreatestCommonDivisorAbstract<C> fd = new GreatestCommonDivisorSimple<C>(cofac.coFac); 480 481 //GenSolvablePolynomial<GenPolynomial<C>> pr = P.rightRecursivePolynomial(); 482 RecSolvablePolynomial<C> pr = (RecSolvablePolynomial<C>) P.rightRecursivePolynomial(); 483 GenSolvablePolynomial<C> a = (GenSolvablePolynomial<C>) pr.leadingBaseCoefficient(); 484 485 rhs = (GenSolvablePolynomial<GenPolynomial<C>>) S.multiply(q).sum(r); 486 //GenSolvablePolynomial<GenPolynomial<C>> rr = rhs.rightRecursivePolynomial(); 487 RecSolvablePolynomial<C> rr = (RecSolvablePolynomial<C>) rhs.rightRecursivePolynomial(); 488 GenSolvablePolynomial<C> b = (GenSolvablePolynomial<C>) rr.leadingBaseCoefficient(); 489 490 GenSolvablePolynomial<C>[] oc = fd.rightOreCond(a, b); 491 GenPolynomial<C> ga = oc[0]; 492 GenPolynomial<C> gb = oc[1]; 493 //System.out.println("FDQR: OreCond: a = " + a + ", b = " + b); 494 //System.out.println("FDQR: OreCond: ga = " + ga + ", gb = " + gb); 495 // a ga = d gd 496 GenSolvablePolynomial<GenPolynomial<C>> Pa = pr.multiplyRightComm(ga); // coeff a ga 497 GenSolvablePolynomial<GenPolynomial<C>> Rb = rr.multiplyRightComm(gb); // coeff b gb 498 //System.out.println("right(P) = " + pr + ", P = " + P); 499 //System.out.println("right(rhs)= " + rr + ", rhs = " + rhs); 500 //System.out.println("Pa = " + Pa + ", ga = " + ga); 501 //System.out.println("Rb = " + Rb + ", gb = " + gb); 502 GenSolvablePolynomial<GenPolynomial<C>> D = (GenSolvablePolynomial<GenPolynomial<C>>) Pa.subtract(Rb); 503 if (D.isZERO()) { 504 return true; 505 } 506 if (true) { 507 System.out.println("Pa = " + Pa); 508 System.out.println("Rb = " + Rb); 509 logger.info("not right QR: Pa-Rb = " + D); 510 } 511 return false; 512 } 513 514 515 /** 516 * GenSolvablePolynomial right sparse pseudo remainder for recursive 517 * solvable polynomials. <b>Note:</b> uses right multiplication of P by 518 * ldcf(S), not always applicable. 519 * @param <C> coefficient type. 520 * @param P recursive GenSolvablePolynomial. 521 * @param S nonzero recursive GenSolvablePolynomial. 522 * @return remainder with P ore(ldcf(S)<sup>m'</sup>) = quotient * S + 523 * remainder. 524 * @see edu.jas.poly.PolyUtil#recursiveSparsePseudoRemainder(edu.jas.poly.GenPolynomial,edu.jas.poly.GenPolynomial) 525 * . 526 */ 527 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> recursiveRightSparsePseudoRemainder( 528 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<GenPolynomial<C>> S) { 529 return recursiveRightPseudoQuotientRemainder(P, S)[1]; 530 } 531 532 533 /** 534 * GenSolvablePolynomial recursive right pseudo quotient for recursive 535 * polynomials. 536 * @param <C> coefficient type. 537 * @param P recursive GenSolvablePolynomial. 538 * @param S nonzero recursive GenSolvablePolynomial. 539 * @return quotient with P ore(ldcf(S)<sup>m'</sup>) = S * quotient + 540 * remainder. 541 * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). 542 */ 543 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> recursiveRightPseudoQuotient( 544 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<GenPolynomial<C>> S) { 545 return recursiveRightPseudoQuotientRemainder(P, S)[0]; 546 } 547 548 549 /** 550 * GenSolvablePolynomial right sparse pseudo quotient and remainder for 551 * recursive solvable polynomials. <b>Note:</b> uses right multiplication of 552 * P by ldcf(S), not always applicable. 553 * @param <C> coefficient type. 554 * @param P recursive GenSolvablePolynomial. 555 * @param S nonzero recursive GenSolvablePolynomial. 556 * @return remainder with P ore(ldcf(S)<sup>m'</sup>) = S * quotient + 557 * remainder. 558 * @see edu.jas.poly.PolyUtil#recursiveSparsePseudoRemainder(edu.jas.poly.GenPolynomial,edu.jas.poly.GenPolynomial) 559 * . 560 */ 561 @SuppressWarnings("unchecked") 562 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>>[] recursiveRightPseudoQuotientRemainder( 563 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<GenPolynomial<C>> S) { 564 if (S == null || S.isZERO()) { 565 throw new ArithmeticException(P + " division by zero " + S); 566 } 567 GenSolvablePolynomial<GenPolynomial<C>>[] ret = new GenSolvablePolynomial[2]; 568 if (P == null || P.isZERO()) { 569 ret[0] = S.ring.getZERO(); 570 ret[1] = S.ring.getZERO(); 571 return ret; 572 } 573 if (S.isONE()) { 574 ret[0] = P; 575 ret[1] = S.ring.getZERO(); 576 return ret; 577 } 578 //if (S.isConstant()) { 579 // ret[0] = P.ring.getZERO(); 580 // ret[1] = S.ring.getZERO(); 581 // return ret; 582 //} 583 GenPolynomialRing<C> cofac = (GenPolynomialRing) P.ring.coFac; 584 GreatestCommonDivisorAbstract<C> fd = new GreatestCommonDivisorSimple<C>(cofac.coFac); 585 586 ExpVector e = S.leadingExpVector(); 587 GenSolvablePolynomial<GenPolynomial<C>> h, q, r; 588 RecSolvablePolynomial<C> hr, rr, qr; 589 r = P; 590 qr = (RecSolvablePolynomial<C>) S.ring.getZERO().copy(); 591 while (!r.isZERO()) { 592 ExpVector g = r.leadingExpVector(); 593 ExpVector f = g; 594 if (f.multipleOf(e)) { 595 f = f.subtract(e); 596 //System.out.println("f = " + f); 597 h = S.multiply(f); // coeff c, exp e (f/e) 598 hr = (RecSolvablePolynomial<C>) h.rightRecursivePolynomial(); 599 rr = (RecSolvablePolynomial<C>) r.rightRecursivePolynomial(); 600 GenSolvablePolynomial<C> a = (GenSolvablePolynomial<C>) rr.leadingBaseCoefficient(); 601 GenSolvablePolynomial<C> d = (GenSolvablePolynomial<C>) hr.leadingBaseCoefficient(); 602 GenSolvablePolynomial<C>[] oc = fd.rightOreCond(a, d); 603 GenPolynomial<C> ga = oc[0]; // d 604 GenPolynomial<C> gd = oc[1]; // a 605 //System.out.println("OreCond: a = " + a + ", d = " + d); 606 //System.out.println("OreCond: ga = " + ga + ", gd = " + gd); 607 // a ga = d gd 608 //rr = rr.multiply(ga); // exp f, coeff a ga 609 //hr = hr.multiply(gd,f); // exp f, coeff d gd 610 rr = rr.multiplyRightComm(ga); // exp f, coeff a ga 611 hr = hr.multiplyRightComm(gd); // exp f, coeff d gd ///.shift(f) 612 h = hr.evalAsRightRecursivePolynomial(); 613 r = rr.evalAsRightRecursivePolynomial(); 614 r = (GenSolvablePolynomial<GenPolynomial<C>>) r.subtract(h); 615 qr = qr.multiplyRightComm(ga); // d 616 qr = (RecSolvablePolynomial<C>) qr.sum(gd, f); // a // same for right coefficients 617 //System.out.println("q = " + qr); //.leadingMonomial()); 618 if (!r.isZERO() && g.equals(r.leadingExpVector())) { 619 throw new RuntimeException("something is wrong: g == lc(r), terms not descending " + r); 620 } 621 //System.out.println("r = " + r + ", qr = " + qr); 622 } else { 623 break; 624 } 625 } 626 q = qr.evalAsRightRecursivePolynomial(); 627 int sp = P.signum(); 628 int ss = S.signum(); 629 int sq = q.signum(); 630 // sp = ss * sq 631 if (sp != ss * sq) { 632 q = (GenSolvablePolynomial<GenPolynomial<C>>) q.negate(); 633 r = (GenSolvablePolynomial<GenPolynomial<C>>) r.negate(); 634 } 635 ret[0] = q; 636 ret[1] = r; 637 return ret; 638 } 639 640 641 // ---------------------------------------------------------------------- 642 643 644 /** 645 * GenSolvablePolynomial recursive quotient for recursive polynomials and 646 * exact division by coefficient ring element. 647 * @param <C> coefficient type. 648 * @param P recursive GenSolvablePolynomial. 649 * @param s GenSolvablePolynomial. 650 * @return P/s. 651 */ 652 @SuppressWarnings("unchecked") 653 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> recursiveDivideRightEval( 654 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<C> s) { 655 if (s.isONE()) { 656 return P; 657 } 658 GenSolvablePolynomial<GenPolynomial<C>> Pr = P.rightRecursivePolynomial(); 659 GenSolvablePolynomial<GenPolynomial<C>> Qr = FDUtil.<C> recursiveLeftDivide(Pr, s); // Left/Right 660 GenSolvablePolynomial<GenPolynomial<C>> Q = Qr.evalAsRightRecursivePolynomial(); 661 if (debug) { 662 if (!Qr.multiplyLeft(s).equals(Pr)) { 663 System.out.println("rDivREval: Pr = " + Pr + ", P = " + P); 664 System.out.println("rDivREval: Qr = " + Qr + ", Q = " + Q); 665 System.out.println("rDivREval: s*Qr = " + Qr.multiplyLeft(s) + ", s = " + s); 666 System.out.println("rDivREval: Qr*s = " + Qr.multiply(s)); 667 //System.out.println("rDivREval: P.ring == Q.ring: " + P.ring.equals(Q.ring) ); 668 throw new RuntimeException("rDivREval: s*Qr != Pr"); 669 } 670 if (!Q.multiply(s).equals(P)) { 671 System.out.println("rDivREval: P = " + P + ", right(P) = " + Pr); 672 System.out.println("rDivREval: Q = " + Q + ", right(Q) = " + Qr); 673 System.out.println("rDivREval: Q*s = " + Q.multiply(s) + ", s = " + s); 674 System.out.println("rDivREval: s*Q = " + Q.multiplyLeft(s)); 675 //System.out.println("rDivREval: P.ring == Q.ring: " + P.ring.equals(Q.ring) ); 676 throw new RuntimeException("rDivREval: Q*s != P"); 677 } 678 } 679 return Q; 680 } 681 682 683 /** 684 * GenSolvablePolynomial left recursive quotient for recursive polynomials 685 * and exact division by coefficient ring element. 686 * @param <C> coefficient type. 687 * @param P recursive GenSolvablePolynomial. 688 * @param s GenSolvablePolynomial. 689 * @return this/s. 690 */ 691 @SuppressWarnings({ "unchecked", "cast" }) 692 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> recursiveDivide( 693 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<C> s) { 694 if (s == null || s.isZERO()) { 695 throw new ArithmeticException("division by zero " + P + ", " + s); 696 } 697 if (P.isZERO()) { 698 return P; 699 } 700 if (s.isONE()) { 701 return P; 702 } 703 GenSolvablePolynomialRing<GenPolynomial<C>> rfac = (GenSolvablePolynomialRing<GenPolynomial<C>>) P.ring; 704 GenSolvablePolynomial<GenPolynomial<C>> onep = rfac.getONE(); 705 //ExpVector zero = rfac.evzero; 706 GenSolvablePolynomial<GenPolynomial<C>> q = rfac.getZERO(); 707 GenSolvablePolynomial<GenPolynomial<C>> r; 708 GenSolvablePolynomial<GenPolynomial<C>> p = P; //.ring.getZERO().copy(); 709 while (!p.isZERO()) { 710 // for (Map.Entry<ExpVector, GenPolynomial<C>> m1 : P.getMap().entrySet()) { 711 Map.Entry<ExpVector, GenPolynomial<C>> m1 = p.leadingMonomial(); 712 GenSolvablePolynomial<C> c1 = (GenSolvablePolynomial<C>) m1.getValue(); 713 ExpVector e1 = m1.getKey(); 714 GenSolvablePolynomial<C> c = c1.divide(s); 715 if (c.isZERO()) { 716 throw new RuntimeException("something is wrong: c is zero, c1 = " + c1 + ", s = " + s); 717 } 718 r = onep.multiplyLeft(c.multiply(s), e1); // right: (c e1) * 1 * (s zero) 719 if (!c1.equals(r.leadingBaseCoefficient())) { 720 System.out.println("recRightDivide: lc(r) = " + r.leadingBaseCoefficient() + ", c1 = " + c1); 721 System.out.println("recRightDivide: lc(r) = " + c.multiply(s) + ", c = " + c + ", s = " + s); 722 throw new RuntimeException("something is wrong: lc(r) != c*s"); 723 } 724 p = (RecSolvablePolynomial<C>) p.subtract(r); 725 if (!p.isZERO() && e1.compareTo(p.leadingExpVector()) == 0) { 726 System.out.println("recRightDivide: c = " + c); 727 System.out.println("recRightDivide: lt(p) = " + p.leadingExpVector() + ", e1 = " + e1); 728 System.out.println("recRightDivide: c1/s = " + c1.divide(s)); 729 System.out.println("recRightDivide: s*c = " + s.multiply(c)); 730 System.out.println("recRightDivide: c*s = " + c.multiply(s)); 731 throw new RuntimeException("something is wrong: degree not descending"); 732 } 733 q = (RecSolvablePolynomial<C>) q.sum(c, e1); 734 } 735 return q; 736 } 737 738 739 /* 740 * GenSolvablePolynomial recursive right quotient for recursive polynomials 741 * and partial right exact division by coefficient ring element. 742 * @param <C> coefficient type. 743 * @param P recursive GenSolvablePolynomial. 744 * @param s GenSolvablePolynomial. 745 * @return this/s. 746 @SuppressWarnings("unchecked") 747 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> recursiveRightDivide( 748 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<C> s) { 749 if (s == null || s.isZERO()) { 750 throw new ArithmeticException("division by zero " + P + ", " + s); 751 } 752 if (P.isZERO()) { 753 return P; 754 } 755 if (s.isONE()) { 756 return P; 757 } 758 GenSolvablePolynomial<GenPolynomial<C>> p = P.ring.getZERO().copy(); 759 GenSolvablePolynomial<GenPolynomial<C>> Pr = P.rightRecursivePolynomial(); 760 logger.info("P = " + P + ", right(P) = " + Pr + ", left(s) = " + s); 761 for (Map.Entry<ExpVector, GenPolynomial<C>> m1 : Pr.getMap().entrySet()) { 762 GenSolvablePolynomial<C> c1 = (GenSolvablePolynomial<C>) m1.getValue(); 763 ExpVector e1 = m1.getKey(); 764 //GenSolvablePolynomial<C> c = FDUtil.<C> basePseudoQuotient(c1, s); 765 GenSolvablePolynomial<C> c = FDUtil.<C> divideRightPolynomial(c1, s); 766 //GenSolvablePolynomial<C>[] QR = FDUtil.<C> basePseudoQuotientRemainder(c1, s); 767 if (!c.isZERO()) { 768 //pv.put(e1, c); 769 p.doPutToMap(e1, c); 770 } 771 } 772 GenSolvablePolynomial<GenPolynomial<C>> pl = p.evalAsRightRecursivePolynomial(); 773 logger.info("pl = " + pl + ", p = " + p); 774 return pl; 775 } 776 */ 777 778 779 /* 780 * GenSolvablePolynomial right quotient for polynomials and partial right 781 * exact division by coefficient ring element. 782 * @param <C> coefficient type. 783 * @param P GenSolvablePolynomial. 784 * @param s GenSolvablePolynomial, constant wrt. the main variable. 785 * @return P/s. 786 @SuppressWarnings("unchecked") 787 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<C> divideRightPolynomial( 788 GenSolvablePolynomial<C> P, GenSolvablePolynomial<C> s) { 789 if (s == null || s.isZERO()) { 790 throw new ArithmeticException("division by zero " + P + ", " + s); 791 } 792 if (P.isZERO()) { 793 return P; 794 } 795 if (s.isONE()) { 796 return P; 797 } 798 GenSolvablePolynomialRing<C> pfac = P.ring; 799 GenSolvablePolynomial<C> q; 800 if (pfac.nvar <= 1) { 801 GenSolvablePolynomial<C>[] QR1; 802 QR1 = FDUtil.<C> leftBasePseudoQuotientRemainder(P, s); 803 q = QR1[0]; 804 if (debug) { 805 if (!QR1[1].isZERO()) { 806 System.out.println("rDivPol, P = " + P); 807 System.out.println("rDivPol, s = " + s); 808 throw new RuntimeException("non zero remainder, q = " + q + ", r = " + QR1[1]); 809 } 810 } 811 return q; 812 } 813 GenSolvablePolynomialRing<GenPolynomial<C>> rfac = pfac.recursive(1); 814 GenSolvablePolynomial<GenPolynomial<C>> pr, sr, qr, rr; 815 GenSolvablePolynomial<GenPolynomial<C>>[] QR; 816 pr = (GenSolvablePolynomial<GenPolynomial<C>>) PolyUtil.<C> recursive(rfac, P); 817 sr = (GenSolvablePolynomial<GenPolynomial<C>>) PolyUtil.<C> recursive(rfac, s); 818 //qr = FDUtil.<C> recursiveDivideRightPolynomial(pr,sc); 819 QR = FDUtil.<C> recursiveRightPseudoQuotientRemainder(pr, sr); 820 //QR = FDUtil.<C> recursivePseudoQuotientRemainder(pr,sr); 821 qr = QR[0]; 822 rr = QR[1]; 823 if (debug) { 824 if (!rr.isZERO()) { 825 System.out.println("rDivPol, pr = " + pr); 826 System.out.println("rDivPol, sr = " + sr); 827 throw new RuntimeException("non zero remainder, q = " + qr + ", r = " + rr); 828 } 829 } 830 q = (GenSolvablePolynomial<C>) PolyUtil.<C> distribute(pfac, qr); 831 return q; 832 } 833 */ 834 835 836 /** 837 * GenSolvablePolynomial recursive quotient for recursive polynomials and 838 * partial right exact division by coefficient ring element. 839 * @param <C> coefficient type. 840 * @param P recursive GenSolvablePolynomial. 841 * @param s GenSolvablePolynomial. 842 * @return P/s. 843 */ 844 @SuppressWarnings({ "unchecked", "cast" }) 845 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> recursiveRightDivide( 846 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<C> s) { 847 if (s == null || s.isZERO()) { 848 throw new ArithmeticException("division by zero " + P + ", " + s); 849 } 850 if (P.isZERO()) { 851 return P; 852 } 853 if (s.isONE()) { 854 return P; 855 } 856 if (!(P instanceof RecSolvablePolynomial)) { 857 //return FDUtil.<C> recursiveDivide(P,s); 858 } 859 RecSolvablePolynomialRing<C> rfac = (RecSolvablePolynomialRing<C>) P.ring; 860 if (rfac.coeffTable.isEmpty()) { 861 //return FDUtil.<C> recursiveDivide(P,s); 862 } 863 RecSolvablePolynomial<C> onep = rfac.getONE(); 864 //ExpVector zero = rfac.evzero; 865 RecSolvablePolynomial<C> q = rfac.getZERO(); 866 RecSolvablePolynomial<C> r; 867 RecSolvablePolynomial<C> p = (RecSolvablePolynomial<C>) P; 868 //System.out.println("recRightDivide: p = " + p + ", s = " + s); 869 while (!p.isZERO()) { 870 Map.Entry<ExpVector, GenPolynomial<C>> m1 = p.leadingMonomial(); 871 GenSolvablePolynomial<C> a = (GenSolvablePolynomial<C>) m1.getValue(); 872 ExpVector f = m1.getKey(); 873 GenSolvablePolynomial<C> c = (GenSolvablePolynomial<C>) a.rightDivide(s); 874 if (c.isZERO()) { 875 //logger.info("something is wrong: c is zero, a = " + a + ", s = " + s); 876 throw new RuntimeException("something is wrong: c is zero, a = " + a + ", s = " + s); 877 } 878 //r = onep.multiply(c, f, s, zero); // right: (c f) * 1 * (s zero) 879 ///r = onep.multiply(c.multiply(s), f); //, c, zero); // 880 r = onep.multiply(s.multiply(c), f); //, c, zero); // 881 if (!a.equals(r.leadingBaseCoefficient())) { 882 System.out.println("recRightDivide: a = " + a + ", lc(r) = " + r.leadingBaseCoefficient()); 883 System.out.println("recRightDivide: c*s = " + c.multiply(s) + ", s = " + s + ", c = " + c); 884 System.out.println( 885 "recRightDivide: s*c = " + s.multiply(c) + ", a%s = " + a.rightRemainder(s)); 886 throw new RuntimeException("something is wrong: c*s != a: " + rfac.toScript()); 887 } 888 p = (RecSolvablePolynomial<C>) p.subtract(r); 889 if (!p.isZERO() && f.compareTo(p.leadingExpVector()) == 0) { 890 System.out.println("recRightDivide: c = " + c); 891 System.out.println("recRightDivide: lt(p) = " + p.leadingExpVector() + ", f = " + f); 892 System.out.println("recRightDivide: a/s = " + a.divide(s)); 893 System.out.println("recRightDivide: s*c = " + s.multiply(c)); 894 System.out.println("recRightDivide: c*s = " + c.multiply(s)); 895 throw new RuntimeException("something is wrong: degree not descending"); 896 } 897 q = (RecSolvablePolynomial<C>) q.sum(c, f); 898 } 899 return q; 900 } 901 902 903 /** 904 * GenSolvablePolynomial recursive quotient for recursive polynomials and 905 * partial left exact division by coefficient ring element. 906 * @param <C> coefficient type. 907 * @param P recursive GenSolvablePolynomial. 908 * @param s GenSolvablePolynomial. 909 * @return P/s. 910 */ 911 @SuppressWarnings({ "unchecked", "cast" }) 912 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> recursiveLeftDivide( 913 GenSolvablePolynomial<GenPolynomial<C>> P, GenSolvablePolynomial<C> s) { 914 if (s == null || s.isZERO()) { 915 throw new ArithmeticException("division by zero " + P + ", " + s); 916 } 917 if (P.isZERO()) { 918 return P; 919 } 920 if (s.isONE()) { 921 return P; 922 } 923 if (!(P instanceof RecSolvablePolynomial)) { 924 //return FDUtil.<C> recursiveDivide(P,s); 925 } 926 RecSolvablePolynomialRing<C> rfac = (RecSolvablePolynomialRing<C>) P.ring; 927 if (rfac.coeffTable.isEmpty()) { 928 //return FDUtil.<C> recursiveDivide(P,s); 929 } 930 RecSolvablePolynomial<C> onep = rfac.getONE(); 931 //ExpVector zero = rfac.evzero; 932 RecSolvablePolynomial<C> q = rfac.getZERO(); 933 RecSolvablePolynomial<C> r, Pp; 934 //RecSolvablePolynomial<C> p = (RecSolvablePolynomial<C>) P; 935 RecSolvablePolynomial<C> p = (RecSolvablePolynomial<C>) P.rightRecursivePolynomial(); 936 Pp = p; 937 while (!p.isZERO()) { 938 ExpVector f = p.leadingExpVector(); 939 GenSolvablePolynomial<C> a = (GenSolvablePolynomial<C>) p.leadingBaseCoefficient(); 940 GenSolvablePolynomial<C> c = (GenSolvablePolynomial<C>) a.divide(s); 941 ///GenSolvablePolynomial<C> c = (GenSolvablePolynomial<C>) a.rightDivide(s); 942 if (c.isZERO()) { 943 throw new RuntimeException("something is wrong: c is zero, a = " + a + ", s = " + s); 944 } 945 //r = onep.multiply(c, f, s, zero); // right: (c f) * 1 * (s zero) 946 r = onep.multiplyLeft(c.multiply(s), f); // right: (c*s f) * one 947 ///r = onep.multiplyLeft(s.multiply(c), f); // left: (s*c f) * one 948 if (!a.equals(r.leadingBaseCoefficient())) { 949 System.out.println("recLeftDivide: a = " + a); 950 C ac = a.leadingBaseCoefficient(); 951 C rc = r.leadingBaseCoefficient().leadingBaseCoefficient(); 952 C cc = rc.inverse().multiply(ac); 953 System.out.println("recLeftDivide: cc = " + cc); 954 c = c.multiply(cc); 955 r = onep.multiplyLeft(c.multiply(s), f); // right: (c f) * 1 * (s zero) 956 ///r = onep.multiplyLeft(s.multiply(c), f); // left: (s*c f) * 1 957 System.out.println("recLeftDivide: lc(r) = " + r.leadingBaseCoefficient()); 958 throw new RuntimeException("something is wrong: c*s != a: " + rfac.toScript()); 959 } 960 p = (RecSolvablePolynomial<C>) p.subtract(r); 961 if (!p.isZERO() && f.compareTo(p.leadingExpVector()) == 0) { 962 System.out.println("recLeftDivide: P = " + P + ", s = " + s); 963 System.out.println("recLeftDivide: right(P) = " + Pp); 964 System.out.println("recLeftDivide: c = " + c); 965 System.out.println("recLeftDivide: lt(p) = " + p.leadingExpVector() + ", f = " + f); 966 System.out.println("recLeftDivide: a/s = " + a.divide(s)); 967 System.out.println("recLeftDivide: a\\s = " + a.rightDivide(s)); 968 System.out.println("recLeftDivide: s*c = " + s.multiply(c)); 969 System.out.println("recLeftDivide: c*s = " + c.multiply(s)); 970 throw new RuntimeException("something is wrong: degree not descending"); 971 } 972 q = (RecSolvablePolynomial<C>) q.sum(c, f); 973 } 974 q = (RecSolvablePolynomial<C>) q.evalAsRightRecursivePolynomial(); 975 return q; 976 } 977 978 979 /** 980 * Integral solvable polynomial from solvable rational function 981 * coefficients. Represent as polynomial with integral solvable polynomial 982 * coefficients by multiplication with the lcm(??) of the numerators of the 983 * rational function coefficients. 984 * @param fac result polynomial factory. 985 * @param A polynomial with solvable rational function coefficients to be 986 * converted. 987 * @return polynomial with integral solvable polynomial coefficients. 988 */ 989 @SuppressWarnings({ "unchecked", "cast" }) 990 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> integralFromQuotientCoefficients( 991 GenSolvablePolynomialRing<GenPolynomial<C>> fac, 992 GenSolvablePolynomial<SolvableQuotient<C>> A) { 993 GenSolvablePolynomial<GenPolynomial<C>> B = fac.getZERO().copy(); 994 if (A == null || A.isZERO()) { 995 return B; 996 } 997 GenSolvablePolynomial<C> c = null; 998 GenSolvablePolynomial<C> d; 999 GenSolvablePolynomial<C> x; 1000 GenSolvablePolynomial<C> z; 1001 GenPolynomialRing<C> cofac = (GenPolynomialRing) fac.coFac; 1002 GreatestCommonDivisorAbstract<C> fd = new GreatestCommonDivisorPrimitive<C>(cofac.coFac); 1003 int s = 0; 1004 // lcm/ore of denominators ?? 1005 Map<ExpVector, SolvableQuotient<C>> Am = A.getMap(); 1006 for (SolvableQuotient<C> y : Am.values()) { 1007 x = y.den; 1008 // c = lcm(c,x) 1009 if (c == null) { 1010 c = x; 1011 s = x.signum(); 1012 } else { 1013 d = fd.leftGcd(c, x); 1014 z = (GenSolvablePolynomial<C>) x.divide(d); // ?? 1015 c = z.multiply(c); // ?? multiplyLeft 1016 } 1017 } 1018 if (s < 0) { 1019 c = (GenSolvablePolynomial<C>) c.negate(); 1020 } 1021 for (Map.Entry<ExpVector, SolvableQuotient<C>> y : Am.entrySet()) { 1022 ExpVector e = y.getKey(); 1023 SolvableQuotient<C> a = y.getValue(); 1024 // p = n*(c/d) 1025 GenPolynomial<C> b = c.divide(a.den); 1026 GenPolynomial<C> p = a.num.multiply(b); 1027 //B = B.sum( p, e ); // inefficient 1028 B.doPutToMap(e, p); 1029 } 1030 return B; 1031 } 1032 1033 1034 /** 1035 * Integral solvable polynomial from solvable rational function 1036 * coefficients. Represent as polynomial with integral solvable polynomial 1037 * coefficients by multiplication with the lcm(??) of the numerators of the 1038 * solvable rational function coefficients. 1039 * @param fac result polynomial factory. 1040 * @param L list of polynomials with solvable rational function coefficients 1041 * to be converted. 1042 * @return list of polynomials with integral solvable polynomial 1043 * coefficients. 1044 */ 1045 @SuppressWarnings("unchecked") 1046 public static <C extends GcdRingElem<C>> List<GenSolvablePolynomial<GenPolynomial<C>>> integralFromQuotientCoefficients( 1047 GenSolvablePolynomialRing<GenPolynomial<C>> fac, 1048 Collection<GenSolvablePolynomial<SolvableQuotient<C>>> L) { 1049 if (L == null) { 1050 return null; 1051 } 1052 List<GenSolvablePolynomial<GenPolynomial<C>>> list = new ArrayList<GenSolvablePolynomial<GenPolynomial<C>>>( 1053 L.size()); 1054 for (GenSolvablePolynomial<SolvableQuotient<C>> p : L) { 1055 list.add(integralFromQuotientCoefficients(fac, p)); 1056 } 1057 return list; 1058 } 1059 1060 1061 /** 1062 * Solvable rational function from integral solvable polynomial 1063 * coefficients. Represent as polynomial with type SolvableQuotient 1064 * <C> coefficients. 1065 * @param fac result polynomial factory. 1066 * @param A polynomial with integral solvable polynomial coefficients to be 1067 * converted. 1068 * @return polynomial with type SolvableQuotient<C> coefficients. 1069 */ 1070 @SuppressWarnings("unchecked") 1071 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<SolvableQuotient<C>> quotientFromIntegralCoefficients( 1072 GenSolvablePolynomialRing<SolvableQuotient<C>> fac, 1073 GenSolvablePolynomial<GenPolynomial<C>> A) { 1074 GenSolvablePolynomial<SolvableQuotient<C>> B = fac.getZERO().copy(); 1075 if (A == null || A.isZERO()) { 1076 return B; 1077 } 1078 RingFactory<SolvableQuotient<C>> cfac = fac.coFac; 1079 SolvableQuotientRing<C> qfac = (SolvableQuotientRing<C>) cfac; 1080 for (Map.Entry<ExpVector, GenPolynomial<C>> y : A.getMap().entrySet()) { 1081 ExpVector e = y.getKey(); 1082 GenSolvablePolynomial<C> a = (GenSolvablePolynomial<C>) y.getValue(); 1083 SolvableQuotient<C> p = new SolvableQuotient<C>(qfac, a); // can not be zero 1084 if (!p.isZERO()) { 1085 //B = B.sum( p, e ); // inefficient 1086 B.doPutToMap(e, p); 1087 } 1088 } 1089 return B; 1090 } 1091 1092 1093 /** 1094 * Solvable rational function from integral solvable polynomial 1095 * coefficients. Represent as polynomial with type SolvableQuotient 1096 * <C> coefficients. 1097 * @param fac result polynomial factory. 1098 * @param L list of polynomials with integral solvable polynomial 1099 * coefficients to be converted. 1100 * @return list of polynomials with type SolvableQuotient<C> coefficients. 1101 */ 1102 public static <C extends GcdRingElem<C>> List<GenSolvablePolynomial<SolvableQuotient<C>>> quotientFromIntegralCoefficients( 1103 GenSolvablePolynomialRing<SolvableQuotient<C>> fac, 1104 Collection<GenSolvablePolynomial<GenPolynomial<C>>> L) { 1105 if (L == null) { 1106 return null; 1107 } 1108 List<GenSolvablePolynomial<SolvableQuotient<C>>> list = new ArrayList<GenSolvablePolynomial<SolvableQuotient<C>>>( 1109 L.size()); 1110 for (GenSolvablePolynomial<GenPolynomial<C>> p : L) { 1111 list.add(quotientFromIntegralCoefficients(fac, p)); 1112 } 1113 return list; 1114 } 1115 1116 1117 /** 1118 * Left greatest common divisor and cofactors. 1119 * @param r solvable polynomial ring. 1120 * @param n first solvable polynomial. 1121 * @param d second solvable polynomial. 1122 * @return [ g=leftGcd(n,d), n/g, d/g ] 1123 */ 1124 @SuppressWarnings({ "cast", "unchecked" }) 1125 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<C>[] leftGcdCofactors( 1126 GenSolvablePolynomialRing<C> r, GenSolvablePolynomial<C> n, GenSolvablePolynomial<C> d) { 1127 //GreatestCommonDivisorAbstract<C> e1 = new GreatestCommonDivisorSimple<C>(r.coFac); 1128 GreatestCommonDivisorAbstract<C> e1 = new GreatestCommonDivisorPrimitive<C>(r.coFac); 1129 //GreatestCommonDivisorAbstract<C> engine = new GreatestCommonDivisorFake<C>(r.coFac); 1130 GreatestCommonDivisorAbstract<C> e2 = new GreatestCommonDivisorSyzygy<C>(r.coFac); 1131 GreatestCommonDivisorAbstract<C> engine = new SGCDParallelProxy<C>(r.coFac, e1, e2); 1132 if (info) { 1133 logger.info("leftGCD_in: " + n + ", " + d); 1134 } 1135 GenSolvablePolynomial<C>[] res = (GenSolvablePolynomial<C>[]) new GenSolvablePolynomial[3]; 1136 res[0] = engine.leftGcd(n, d); 1137 //res[0] = PolyModUtil.<C> syzLeftGcd(r, n, d); 1138 res[1] = n; 1139 res[2] = d; 1140 if (res[0].isONE()) { 1141 return res; 1142 } 1143 if (info) { 1144 logger.info("leftGCD_out: " + res[0]); 1145 } 1146 GenSolvablePolynomial<C>[] nqr; 1147 nqr = FDUtil.<C> rightBasePseudoQuotientRemainder(n, res[0]); 1148 if (!nqr[1].isZERO()) { 1149 res[0] = r.getONE(); 1150 return res; 1151 } 1152 GenSolvablePolynomial<C>[] dqr; 1153 dqr = FDUtil.<C> rightBasePseudoQuotientRemainder(d, res[0]); 1154 if (!dqr[1].isZERO()) { 1155 res[0] = r.getONE(); 1156 return res; 1157 } 1158 res[1] = nqr[0]; 1159 res[2] = dqr[0]; 1160 return res; 1161 } 1162 1163 1164 /** 1165 * Right greatest common divisor and cofactors. 1166 * @param r solvable polynomial ring. 1167 * @param n first solvable polynomial. 1168 * @param d second solvable polynomial. 1169 * @return [ g=rightGcd(n,d), n/g, d/g ] 1170 */ 1171 @SuppressWarnings({ "cast", "unchecked" }) 1172 public static <C extends GcdRingElem<C>> GenSolvablePolynomial<C>[] rightGcdCofactors( 1173 GenSolvablePolynomialRing<C> r, GenSolvablePolynomial<C> n, GenSolvablePolynomial<C> d) { 1174 //GreatestCommonDivisorAbstract<C> e1 = new GreatestCommonDivisorSimple<C>(r.coFac); 1175 //GreatestCommonDivisorAbstract<C> e1 = new GreatestCommonDivisorPrimitive<C>(r.coFac); 1176 GreatestCommonDivisorAbstract<C> engine = new GreatestCommonDivisorFake<C>(r.coFac); 1177 //GreatestCommonDivisorAbstract<C> e2 = new GreatestCommonDivisorSyzygy<C>(r.coFac); 1178 //GreatestCommonDivisorAbstract<C> engine = new SGCDParallelProxy<C>(r.coFac, e1, e2); 1179 if (info) { 1180 logger.info("rightGCD_in: " + n + ", " + d); 1181 } 1182 GenSolvablePolynomial<C>[] res = (GenSolvablePolynomial<C>[]) new GenSolvablePolynomial[3]; 1183 res[0] = engine.rightGcd(n, d); 1184 //res[0] = PolyModUtil.<C> syzRightGcd(r, n, d); 1185 res[1] = n; 1186 res[2] = d; 1187 if (res[0].isONE()) { 1188 return res; 1189 } 1190 if (info) { 1191 logger.info("rightGCD_out: " + res[0]); 1192 } 1193 GenSolvablePolynomial<C>[] nqr; 1194 nqr = FDUtil.<C> leftBasePseudoQuotientRemainder(n, res[0]); 1195 if (!nqr[1].isZERO()) { 1196 res[0] = r.getONE(); 1197 return res; 1198 } 1199 GenSolvablePolynomial<C>[] dqr; 1200 dqr = FDUtil.<C> leftBasePseudoQuotientRemainder(d, res[0]); 1201 if (!dqr[1].isZERO()) { 1202 res[0] = r.getONE(); 1203 return res; 1204 } 1205 res[1] = nqr[0]; 1206 res[2] = dqr[0]; 1207 return res; 1208 } 1209 1210}