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