001/* 002 * $Id: TermOrder.java 5990 2020-02-05 22:50:21Z kredel $ 003 */ 004 005package edu.jas.poly; 006 007 008import java.io.Serializable; 009import java.util.Arrays; 010import java.util.Comparator; 011import java.util.List; 012 013import org.apache.logging.log4j.Logger; 014import org.apache.logging.log4j.LogManager; 015 016import edu.jas.kern.Scripting; 017 018 019/** 020 * Term order class for ordered polynomials. Implements the most used term 021 * orders: graded, lexicographical, weight aray and block orders. For the 022 * definitions see for example the articles <a 023 * href="http://doi.acm.org/10.1145/43882.43887">Kredel 024 * "Admissible term orderings used in computer algebra systems"</a> and <a 025 * href="http://doi.acm.org/10.1145/70936.70941">Sit, 026 * "Some comments on term-ordering in Gröbner basis computations"</a>. 027 * <b>Note: </b> the naming is not quite easy to understand: in case of doubt 028 * use the term orders with "I" in the name, like IGRLEX (the default) or 029 * INVLEX. Not all algorithms may work with all term orders since not all are 030 * well-founded, so watch your step. This class does not implement orders by 031 * linear forms over Q[t]. Objects of this class are immutable. 032 * 033 * @author Heinz Kredel 034 */ 035 036public final class TermOrder implements Serializable { 037 038 039 private static final Logger logger = LogManager.getLogger(TermOrder.class); 040 041 042 private static final boolean debug = logger.isDebugEnabled(); 043 044 045 // TermOrder index values 046 047 public static final int LEX = 1; 048 049 050 public final static int MIN_EVORD = LEX; 051 052 053 public static final int INVLEX = 2; 054 055 056 public static final int GRLEX = 3; 057 058 059 public static final int IGRLEX = 4; 060 061 062 public static final int REVLEX = 5; 063 064 065 public static final int REVILEX = 6; 066 067 068 public static final int REVTDEG = 7; 069 070 071 public static final int REVITDG = 8; 072 073 074 public static final int ITDEGLEX = 9; 075 076 077 public static final int REVITDEG = 10; 078 079 080 public final static int MAX_EVORD = REVITDEG; 081 082 083 public final static int DEFAULT_EVORD = IGRLEX; 084 085 086 //public final static int DEFAULT_EVORD = INVLEX; 087 088 089 // instance variables 090 091 private final int evord; 092 093 094 // for split termorders 095 private final int evord2; 096 097 098 private final int evbeg1; 099 100 101 private final int evend1; 102 103 104 private final int evbeg2; 105 106 107 private final int evend2; 108 109 110 /** 111 * Defined array of weight vectors. 112 */ 113 private final long[][] weight; 114 115 116 /** 117 * Defined descending order comparator. Sorts the highest terms first. 118 */ 119 private final EVComparator horder; 120 121 122 /** 123 * Defined ascending order comparator. Sorts the lowest terms first. 124 */ 125 private final EVComparator lorder; 126 127 128 /** 129 * Defined sugar order comparator. Sorts the graded lowest terms first. 130 */ 131 private final EVComparator sugar; 132 133 134 /** 135 * Termorders for modules: TOP or POT. 136 * POT: position over term (default) 137 * TOP: term over position (new) 138 */ 139 public final boolean TOP; 140 141 142 /** 143 * Comparator for ExpVectors. 144 */ 145 public static abstract class EVComparator implements Comparator<ExpVector>, Serializable { 146 147 148 public abstract int compare(ExpVector e1, ExpVector e2); 149 } 150 151 152 /** 153 * Constructor for default term order. 154 */ 155 public TermOrder() { 156 this(DEFAULT_EVORD); 157 } 158 159 160 /** 161 * Constructor for given term order. 162 * @param evord requested term order indicator / enumerator. 163 */ 164 public TermOrder(int evord) { 165 if (evord < MIN_EVORD || MAX_EVORD < evord) { 166 throw new IllegalArgumentException("invalid term order: " + evord); 167 } 168 this.evord = evord; 169 this.evord2 = 0; 170 weight = null; 171 evbeg1 = 0; 172 evend1 = Integer.MAX_VALUE; 173 evbeg2 = evend1; 174 evend2 = evend1; 175 TOP = false; 176 switch (evord) { // horder = new EVhorder(); 177 case TermOrder.LEX: { 178 horder = new EVComparator() { 179 180 181 @Override 182 public int compare(ExpVector e1, ExpVector e2) { 183 return e1.invLexCompareTo(e2); 184 } 185 }; 186 break; 187 } 188 case TermOrder.INVLEX: { 189 horder = new EVComparator() { 190 191 192 @Override 193 public int compare(ExpVector e1, ExpVector e2) { 194 return -e1.invLexCompareTo(e2); 195 } 196 }; 197 break; 198 } 199 case TermOrder.GRLEX: { 200 horder = new EVComparator() { 201 202 203 @Override 204 public int compare(ExpVector e1, ExpVector e2) { 205 return e1.invGradCompareTo(e2); 206 } 207 }; 208 break; 209 } 210 case TermOrder.IGRLEX: { 211 horder = new EVComparator() { 212 213 214 @Override 215 public int compare(ExpVector e1, ExpVector e2) { 216 return -e1.invGradCompareTo(e2); 217 } 218 }; 219 break; 220 } 221 case TermOrder.REVLEX: { 222 horder = new EVComparator() { 223 224 225 @Override 226 public int compare(ExpVector e1, ExpVector e2) { 227 return e1.revInvLexCompareTo(e2); 228 } 229 }; 230 break; 231 } 232 case TermOrder.REVILEX: { 233 horder = new EVComparator() { 234 235 236 @Override 237 public int compare(ExpVector e1, ExpVector e2) { 238 return -e1.revInvLexCompareTo(e2); 239 } 240 }; 241 break; 242 } 243 case TermOrder.REVTDEG: { 244 horder = new EVComparator() { 245 246 247 @Override 248 public int compare(ExpVector e1, ExpVector e2) { 249 return e1.revInvGradCompareTo(e2); 250 } 251 }; 252 break; 253 } 254 case TermOrder.REVITDG: { 255 horder = new EVComparator() { 256 257 258 @Override 259 public int compare(ExpVector e1, ExpVector e2) { 260 return -e1.revInvGradCompareTo(e2); 261 } 262 }; 263 break; 264 } 265 case TermOrder.ITDEGLEX: { 266 horder = new EVComparator() { 267 268 269 @Override 270 public int compare(ExpVector e1, ExpVector e2) { 271 return -e1.invTdegCompareTo(e2); // okay +/- 272 } 273 }; 274 break; 275 } 276 case TermOrder.REVITDEG: { 277 horder = new EVComparator() { 278 279 280 @Override 281 public int compare(ExpVector e1, ExpVector e2) { 282 return e1.revLexInvTdegCompareTo(e2); // okay +/- 283 } 284 }; 285 break; 286 } 287 default: { 288 horder = null; 289 } 290 } 291 if (horder == null) { 292 throw new IllegalArgumentException("invalid term order: " + evord); 293 } 294 295 // lorder = new EVlorder(); 296 lorder = new EVComparator() { 297 298 299 @Override 300 public int compare(ExpVector e1, ExpVector e2) { 301 return -horder.compare(e1, e2); 302 } 303 }; 304 305 // sugar = new EVsugar(); 306 sugar = new EVComparator() { 307 308 309 @Override 310 public int compare(ExpVector e1, ExpVector e2) { 311 return e1.invGradCompareTo(e2); 312 } 313 }; 314 } 315 316 317 /** 318 * Constructor for given exponent weights. 319 * @param w weight vector of longs. 320 */ 321 public TermOrder(long[] w) { 322 this(new long[][] { w }); 323 } 324 325 326 /** 327 * Constructor for given exponent weights. 328 * @param w weight array of longs. 329 */ 330 public TermOrder(long[][] w) { 331 if (w == null || w.length == 0) { 332 throw new IllegalArgumentException("invalid term order weight"); 333 } 334 weight = Arrays.copyOf(w, w.length); // > Java-5 335 this.evord = 0; 336 this.evord2 = 0; 337 evbeg1 = 0; 338 evend1 = weight[0].length; 339 evbeg2 = evend1; 340 evend2 = evend1; 341 TOP = false; 342 343 horder = new EVComparator() { 344 345 346 @Override 347 public int compare(ExpVector e1, ExpVector e2) { 348 return -e1.invWeightCompareTo(weight, e2); 349 } 350 }; 351 352 // lorder = new EVlorder(); 353 lorder = new EVComparator() { 354 355 356 @Override 357 public int compare(ExpVector e1, ExpVector e2) { 358 return +e1.invWeightCompareTo(weight, e2); 359 // return - horder.compare( e1, e2 ); 360 } 361 }; 362 363 // sugar = new EVsugar(); 364 sugar = horder; 365 } 366 367 368 /** 369 * Test if this term order is a split order. 370 * @return true if this is a split term order, else false. 371 */ 372 public boolean isSplit() { 373 //System.out.println("isSplit: " + evend2 + " == " + evbeg2); 374 if (evend2 == evbeg2 || evend1 == Integer.MAX_VALUE) { 375 return false; 376 } 377 return true; 378 } 379 380 381 /** 382 * Constructor for given split order. 383 * @param ev1 requested term order indicator for first block. 384 * @param ev2 requested term order indicator for second block. 385 * @param r max number of exponents to compare. 386 * @param split index. 387 */ 388 public TermOrder(int ev1, int ev2, int r, int split) { 389 this(ev1, ev2, r, split, false); 390 } 391 392 393 /** 394 * Constructor for given split order. 395 * @param ev1 requested term order indicator for first block. 396 * @param ev2 requested term order indicator for second block. 397 * @param r max number of exponents to compare. 398 * @param split index. 399 * @param top module termorder, if true, default false. 400 */ 401 public TermOrder(int ev1, int ev2, int r, int split, boolean top) { 402 if (ev1 < MIN_EVORD || MAX_EVORD - 2 < ev1) { 403 throw new IllegalArgumentException("invalid split term order 1: " + ev1); 404 } 405 if (ev2 < MIN_EVORD || MAX_EVORD - 2 < ev2) { 406 throw new IllegalArgumentException("invalid split term order 2: " + ev2); 407 } 408 this.evord = ev1; 409 this.evord2 = ev2; 410 weight = null; 411 evbeg1 = 0; 412 evend1 = split; // excluded 413 evbeg2 = split; 414 evend2 = r; 415 if (evbeg2 < 0 || evbeg2 > evend2) { 416 throw new IllegalArgumentException("invalid term order split, r = " + r + ", split = " + split); 417 } 418 //System.out.println("evbeg2 " + evbeg2 + ", evend2 " + evend2); 419 TOP = top; 420 if (debug) { 421 logger.info("module TermOrder is " + (TOP ? "TOP" : "POT") + ", split = " + split 422 + ", evord = " + toScriptOrder(evord) + ", evord2 = " + toScriptOrder(evord2)); 423 } 424 switch (evord) { // horder = new EVhorder(); 425 case TermOrder.LEX: { 426 switch (evord2) { 427 case TermOrder.LEX: { 428 horder = new EVComparator() { 429 430 431 @Override 432 public int compare(ExpVector e1, ExpVector e2) { 433 int t = e1.invLexCompareTo(e2, evbeg1, evend1); 434 if (t != 0) { 435 return t; 436 } 437 return e1.invLexCompareTo(e2, evbeg2, evend2); 438 } 439 }; 440 break; 441 } 442 case TermOrder.INVLEX: { 443 horder = new EVComparator() { 444 445 446 @Override 447 public int compare(ExpVector e1, ExpVector e2) { 448 int t = e1.invLexCompareTo(e2, evbeg1, evend1); 449 if (t != 0) { 450 return t; 451 } 452 return -e1.invLexCompareTo(e2, evbeg2, evend2); 453 } 454 }; 455 break; 456 } 457 case TermOrder.GRLEX: { 458 horder = new EVComparator() { 459 460 461 @Override 462 public int compare(ExpVector e1, ExpVector e2) { 463 int t = e1.invLexCompareTo(e2, evbeg1, evend1); 464 if (t != 0) { 465 return t; 466 } 467 return e1.invGradCompareTo(e2, evbeg2, evend2); 468 } 469 }; 470 break; 471 } 472 case TermOrder.IGRLEX: { 473 horder = new EVComparator() { 474 475 476 @Override 477 public int compare(ExpVector e1, ExpVector e2) { 478 int t = e1.invLexCompareTo(e2, evbeg1, evend1); 479 if (t != 0) { 480 return t; 481 } 482 return -e1.invGradCompareTo(e2, evbeg2, evend2); 483 } 484 }; 485 break; 486 } 487 default: { 488 horder = null; 489 } 490 } 491 break; 492 } 493 case TermOrder.INVLEX: { 494 switch (evord2) { 495 case TermOrder.LEX: { 496 horder = new EVComparator() { 497 498 499 @Override 500 public int compare(ExpVector e1, ExpVector e2) { 501 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 502 if (t != 0) { 503 return t; 504 } 505 return e1.invLexCompareTo(e2, evbeg2, evend2); 506 } 507 }; 508 break; 509 } 510 case TermOrder.INVLEX: { 511 if (!TOP) { 512 horder = new EVComparator() { // POT 513 514 @Override 515 public int compare(ExpVector e1, ExpVector e2) { 516 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 517 if (t != 0) { 518 return t; 519 } 520 return -e1.invLexCompareTo(e2, evbeg2, evend2); 521 } 522 }; 523 break; 524 } 525 horder = new EVComparator() { // TOP 526 527 @Override 528 public int compare(ExpVector e1, ExpVector e2) { 529 int t = -e1.invLexCompareTo(e2, evbeg2, evend2); 530 if (t != 0) { 531 return t; 532 } 533 return -e1.invLexCompareTo(e2, evbeg1, evend1); 534 } 535 }; 536 break; 537 } 538 case TermOrder.GRLEX: { 539 horder = new EVComparator() { 540 541 542 @Override 543 public int compare(ExpVector e1, ExpVector e2) { 544 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 545 if (t != 0) { 546 return t; 547 } 548 return e1.invGradCompareTo(e2, evbeg2, evend2); 549 } 550 }; 551 break; 552 } 553 case TermOrder.IGRLEX: { 554 if (!TOP) { 555 horder = new EVComparator() { // POT 556 557 @Override 558 public int compare(ExpVector e1, ExpVector e2) { 559 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 560 if (t != 0) { 561 return t; 562 } 563 return -e1.invGradCompareTo(e2, evbeg2, evend2); 564 } 565 }; 566 break; 567 } 568 horder = new EVComparator() { // TOP 569 570 @Override 571 public int compare(ExpVector e1, ExpVector e2) { 572 int t = -e1.invGradCompareTo(e2, evbeg2, evend2); 573 if (t != 0) { 574 return t; 575 } 576 return -e1.invLexCompareTo(e2, evbeg1, evend1); 577 } 578 }; 579 break; 580 } 581 case TermOrder.REVLEX: { 582 horder = new EVComparator() { 583 584 585 @Override 586 public int compare(ExpVector e1, ExpVector e2) { 587 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 588 if (t != 0) { 589 return t; 590 } 591 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 592 } 593 }; 594 break; 595 } 596 case TermOrder.REVILEX: { 597 horder = new EVComparator() { 598 599 600 @Override 601 public int compare(ExpVector e1, ExpVector e2) { 602 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 603 if (t != 0) { 604 return t; 605 } 606 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 607 } 608 }; 609 break; 610 } 611 case TermOrder.REVTDEG: { 612 horder = new EVComparator() { 613 614 615 @Override 616 public int compare(ExpVector e1, ExpVector e2) { 617 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 618 if (t != 0) { 619 return t; 620 } 621 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 622 } 623 }; 624 break; 625 } 626 case TermOrder.REVITDG: { 627 horder = new EVComparator() { 628 629 630 @Override 631 public int compare(ExpVector e1, ExpVector e2) { 632 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 633 if (t != 0) { 634 return t; 635 } 636 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 637 } 638 }; 639 break; 640 } 641 default: { 642 horder = null; 643 } 644 } 645 break; 646 } 647 case TermOrder.GRLEX: { 648 switch (evord2) { 649 case TermOrder.LEX: { 650 horder = new EVComparator() { 651 652 653 @Override 654 public int compare(ExpVector e1, ExpVector e2) { 655 int t = e1.invGradCompareTo(e2, evbeg1, evend1); 656 if (t != 0) { 657 return t; 658 } 659 return e1.invLexCompareTo(e2, evbeg2, evend2); 660 } 661 }; 662 break; 663 } 664 case TermOrder.INVLEX: { 665 horder = new EVComparator() { 666 667 668 @Override 669 public int compare(ExpVector e1, ExpVector e2) { 670 int t = e1.invGradCompareTo(e2, evbeg1, evend1); 671 if (t != 0) { 672 return t; 673 } 674 return -e1.invLexCompareTo(e2, evbeg2, evend2); 675 } 676 }; 677 break; 678 } 679 case TermOrder.GRLEX: { 680 horder = new EVComparator() { 681 682 683 @Override 684 public int compare(ExpVector e1, ExpVector e2) { 685 int t = e1.invGradCompareTo(e2, evbeg1, evend1); 686 if (t != 0) { 687 return t; 688 } 689 return e1.invGradCompareTo(e2, evbeg2, evend2); 690 } 691 }; 692 break; 693 } 694 case TermOrder.IGRLEX: { 695 horder = new EVComparator() { 696 697 698 @Override 699 public int compare(ExpVector e1, ExpVector e2) { 700 int t = e1.invGradCompareTo(e2, evbeg1, evend1); 701 if (t != 0) { 702 return t; 703 } 704 return -e1.invGradCompareTo(e2, evbeg2, evend2); 705 } 706 }; 707 break; 708 } 709 default: { 710 horder = null; 711 } 712 } 713 break; 714 } 715 case TermOrder.IGRLEX: { 716 switch (evord2) { 717 case TermOrder.LEX: { 718 horder = new EVComparator() { 719 720 721 @Override 722 public int compare(ExpVector e1, ExpVector e2) { 723 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 724 if (t != 0) { 725 return t; 726 } 727 return e1.invLexCompareTo(e2, evbeg2, evend2); 728 } 729 }; 730 break; 731 } 732 case TermOrder.INVLEX: { 733 if (!TOP) { 734 horder = new EVComparator() { // POT 735 736 @Override 737 public int compare(ExpVector e1, ExpVector e2) { 738 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 739 if (t != 0) { 740 return t; 741 } 742 return -e1.invLexCompareTo(e2, evbeg2, evend2); 743 } 744 }; 745 break; 746 } 747 horder = new EVComparator() { // TOP 748 749 @Override 750 public int compare(ExpVector e1, ExpVector e2) { 751 int t = -e1.invLexCompareTo(e2, evbeg2, evend2); 752 if (t != 0) { 753 return t; 754 } 755 return -e1.invGradCompareTo(e2, evbeg1, evend1); 756 } 757 }; 758 break; 759 } 760 case TermOrder.GRLEX: { 761 horder = new EVComparator() { 762 763 764 @Override 765 public int compare(ExpVector e1, ExpVector e2) { 766 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 767 if (t != 0) { 768 return t; 769 } 770 return e1.invGradCompareTo(e2, evbeg2, evend2); 771 } 772 }; 773 break; 774 } 775 case TermOrder.IGRLEX: { 776 if (!TOP) { 777 horder = new EVComparator() { // POT 778 779 @Override 780 public int compare(ExpVector e1, ExpVector e2) { 781 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 782 if (t != 0) { 783 return t; 784 } 785 return -e1.invGradCompareTo(e2, evbeg2, evend2); 786 } 787 }; 788 break; 789 } 790 horder = new EVComparator() { // TOP 791 792 @Override 793 public int compare(ExpVector e1, ExpVector e2) { 794 int t = -e1.invGradCompareTo(e2, evbeg2, evend2); 795 if (t != 0) { 796 return t; 797 } 798 return -e1.invGradCompareTo(e2, evbeg1, evend1); 799 } 800 }; 801 break; 802 } 803 case TermOrder.REVLEX: { 804 horder = new EVComparator() { 805 806 807 @Override 808 public int compare(ExpVector e1, ExpVector e2) { 809 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 810 if (t != 0) { 811 return t; 812 } 813 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 814 } 815 }; 816 break; 817 } 818 case TermOrder.REVILEX: { 819 horder = new EVComparator() { 820 821 822 @Override 823 public int compare(ExpVector e1, ExpVector e2) { 824 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 825 if (t != 0) { 826 return t; 827 } 828 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 829 } 830 }; 831 break; 832 } 833 case TermOrder.REVTDEG: { 834 horder = new EVComparator() { 835 836 837 @Override 838 public int compare(ExpVector e1, ExpVector e2) { 839 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 840 if (t != 0) { 841 return t; 842 } 843 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 844 } 845 }; 846 break; 847 } 848 case TermOrder.REVITDG: { 849 horder = new EVComparator() { 850 851 852 @Override 853 public int compare(ExpVector e1, ExpVector e2) { 854 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 855 if (t != 0) { 856 return t; 857 } 858 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 859 } 860 }; 861 break; 862 } 863 default: { 864 horder = null; 865 } 866 } 867 break; 868 } 869 //----- begin reversed ----------- 870 case TermOrder.REVLEX: { 871 switch (evord2) { 872 case TermOrder.LEX: { 873 horder = new EVComparator() { 874 875 876 @Override 877 public int compare(ExpVector e1, ExpVector e2) { 878 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 879 if (t != 0) { 880 return t; 881 } 882 return e1.invLexCompareTo(e2, evbeg2, evend2); 883 } 884 }; 885 break; 886 } 887 case TermOrder.INVLEX: { 888 horder = new EVComparator() { 889 890 891 @Override 892 public int compare(ExpVector e1, ExpVector e2) { 893 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 894 if (t != 0) { 895 return t; 896 } 897 return -e1.invLexCompareTo(e2, evbeg2, evend2); 898 } 899 }; 900 break; 901 } 902 case TermOrder.GRLEX: { 903 horder = new EVComparator() { 904 905 906 @Override 907 public int compare(ExpVector e1, ExpVector e2) { 908 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 909 if (t != 0) { 910 return t; 911 } 912 return e1.invGradCompareTo(e2, evbeg2, evend2); 913 } 914 }; 915 break; 916 } 917 case TermOrder.IGRLEX: { 918 horder = new EVComparator() { 919 920 921 @Override 922 public int compare(ExpVector e1, ExpVector e2) { 923 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 924 if (t != 0) { 925 return t; 926 } 927 return -e1.invGradCompareTo(e2, evbeg2, evend2); 928 } 929 }; 930 break; 931 } 932 case TermOrder.REVLEX: { 933 horder = new EVComparator() { 934 935 936 @Override 937 public int compare(ExpVector e1, ExpVector e2) { 938 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 939 if (t != 0) { 940 return t; 941 } 942 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 943 } 944 }; 945 break; 946 } 947 case TermOrder.REVILEX: { 948 horder = new EVComparator() { 949 950 951 @Override 952 public int compare(ExpVector e1, ExpVector e2) { 953 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 954 if (t != 0) { 955 return t; 956 } 957 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 958 } 959 }; 960 break; 961 } 962 case TermOrder.REVTDEG: { 963 horder = new EVComparator() { 964 965 966 @Override 967 public int compare(ExpVector e1, ExpVector e2) { 968 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 969 if (t != 0) { 970 return t; 971 } 972 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 973 } 974 }; 975 break; 976 } 977 case TermOrder.REVITDG: { 978 horder = new EVComparator() { 979 980 981 @Override 982 public int compare(ExpVector e1, ExpVector e2) { 983 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 984 if (t != 0) { 985 return t; 986 } 987 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 988 } 989 }; 990 break; 991 } 992 default: { 993 horder = null; 994 } 995 } 996 break; 997 } 998 case TermOrder.REVILEX: { 999 switch (evord2) { 1000 case TermOrder.LEX: { 1001 horder = new EVComparator() { 1002 1003 1004 @Override 1005 public int compare(ExpVector e1, ExpVector e2) { 1006 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1007 if (t != 0) { 1008 return t; 1009 } 1010 return e1.invLexCompareTo(e2, evbeg2, evend2); 1011 } 1012 }; 1013 break; 1014 } 1015 case TermOrder.INVLEX: { 1016 horder = new EVComparator() { 1017 1018 1019 @Override 1020 public int compare(ExpVector e1, ExpVector e2) { 1021 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1022 if (t != 0) { 1023 return t; 1024 } 1025 return -e1.invLexCompareTo(e2, evbeg2, evend2); 1026 } 1027 }; 1028 break; 1029 } 1030 case TermOrder.GRLEX: { 1031 horder = new EVComparator() { 1032 1033 1034 @Override 1035 public int compare(ExpVector e1, ExpVector e2) { 1036 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1037 if (t != 0) { 1038 return t; 1039 } 1040 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 1041 } 1042 }; 1043 break; 1044 } 1045 case TermOrder.IGRLEX: { 1046 horder = new EVComparator() { 1047 1048 1049 @Override 1050 public int compare(ExpVector e1, ExpVector e2) { 1051 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1052 if (t != 0) { 1053 return t; 1054 } 1055 return -e1.invGradCompareTo(e2, evbeg2, evend2); 1056 } 1057 }; 1058 break; 1059 } 1060 case TermOrder.REVLEX: { 1061 horder = new EVComparator() { 1062 1063 1064 @Override 1065 public int compare(ExpVector e1, ExpVector e2) { 1066 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1067 if (t != 0) { 1068 return t; 1069 } 1070 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 1071 } 1072 }; 1073 break; 1074 } 1075 case TermOrder.REVILEX: { 1076 horder = new EVComparator() { 1077 1078 1079 @Override 1080 public int compare(ExpVector e1, ExpVector e2) { 1081 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1082 if (t != 0) { 1083 return t; 1084 } 1085 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 1086 } 1087 }; 1088 break; 1089 } 1090 case TermOrder.REVTDEG: { 1091 horder = new EVComparator() { 1092 1093 1094 @Override 1095 public int compare(ExpVector e1, ExpVector e2) { 1096 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1097 if (t != 0) { 1098 return t; 1099 } 1100 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 1101 } 1102 }; 1103 break; 1104 } 1105 case TermOrder.REVITDG: { 1106 horder = new EVComparator() { 1107 1108 1109 @Override 1110 public int compare(ExpVector e1, ExpVector e2) { 1111 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1112 if (t != 0) { 1113 return t; 1114 } 1115 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 1116 } 1117 }; 1118 break; 1119 } 1120 default: { 1121 horder = null; 1122 } 1123 } 1124 break; 1125 } 1126 case TermOrder.REVTDEG: { 1127 switch (evord2) { 1128 case TermOrder.LEX: { 1129 horder = new EVComparator() { 1130 1131 1132 @Override 1133 public int compare(ExpVector e1, ExpVector e2) { 1134 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1135 if (t != 0) { 1136 return t; 1137 } 1138 return e1.invLexCompareTo(e2, evbeg2, evend2); 1139 } 1140 }; 1141 break; 1142 } 1143 case TermOrder.INVLEX: { 1144 horder = new EVComparator() { 1145 1146 1147 @Override 1148 public int compare(ExpVector e1, ExpVector e2) { 1149 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1150 if (t != 0) { 1151 return t; 1152 } 1153 return -e1.invLexCompareTo(e2, evbeg2, evend2); 1154 } 1155 }; 1156 break; 1157 } 1158 case TermOrder.GRLEX: { 1159 horder = new EVComparator() { 1160 1161 1162 @Override 1163 public int compare(ExpVector e1, ExpVector e2) { 1164 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1165 if (t != 0) { 1166 return t; 1167 } 1168 return e1.invGradCompareTo(e2, evbeg2, evend2); 1169 } 1170 }; 1171 break; 1172 } 1173 case TermOrder.IGRLEX: { 1174 horder = new EVComparator() { 1175 1176 1177 @Override 1178 public int compare(ExpVector e1, ExpVector e2) { 1179 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1180 if (t != 0) { 1181 return t; 1182 } 1183 return -e1.invGradCompareTo(e2, evbeg2, evend2); 1184 } 1185 }; 1186 break; 1187 } 1188 case TermOrder.REVLEX: { 1189 horder = new EVComparator() { 1190 1191 1192 @Override 1193 public int compare(ExpVector e1, ExpVector e2) { 1194 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1195 if (t != 0) { 1196 return t; 1197 } 1198 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 1199 } 1200 }; 1201 break; 1202 } 1203 case TermOrder.REVILEX: { 1204 horder = new EVComparator() { 1205 1206 1207 @Override 1208 public int compare(ExpVector e1, ExpVector e2) { 1209 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1210 if (t != 0) { 1211 return t; 1212 } 1213 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 1214 } 1215 }; 1216 break; 1217 } 1218 case TermOrder.REVTDEG: { 1219 horder = new EVComparator() { 1220 1221 1222 @Override 1223 public int compare(ExpVector e1, ExpVector e2) { 1224 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1225 if (t != 0) { 1226 return t; 1227 } 1228 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 1229 } 1230 }; 1231 break; 1232 } 1233 case TermOrder.REVITDG: { 1234 horder = new EVComparator() { 1235 1236 1237 @Override 1238 public int compare(ExpVector e1, ExpVector e2) { 1239 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1240 if (t != 0) { 1241 return t; 1242 } 1243 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 1244 } 1245 }; 1246 break; 1247 } 1248 default: { 1249 horder = null; 1250 } 1251 } 1252 break; 1253 } 1254 case TermOrder.REVITDG: { 1255 switch (evord2) { 1256 case TermOrder.LEX: { 1257 horder = new EVComparator() { 1258 1259 1260 @Override 1261 public int compare(ExpVector e1, ExpVector e2) { 1262 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1263 if (t != 0) { 1264 return t; 1265 } 1266 return e1.invLexCompareTo(e2, evbeg2, evend2); 1267 } 1268 }; 1269 break; 1270 } 1271 case TermOrder.INVLEX: { 1272 horder = new EVComparator() { 1273 1274 1275 @Override 1276 public int compare(ExpVector e1, ExpVector e2) { 1277 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1278 if (t != 0) { 1279 return t; 1280 } 1281 return -e1.invLexCompareTo(e2, evbeg2, evend2); 1282 } 1283 }; 1284 break; 1285 } 1286 case TermOrder.GRLEX: { 1287 horder = new EVComparator() { 1288 1289 1290 @Override 1291 public int compare(ExpVector e1, ExpVector e2) { 1292 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1293 if (t != 0) { 1294 return t; 1295 } 1296 return e1.invGradCompareTo(e2, evbeg2, evend2); 1297 } 1298 }; 1299 break; 1300 } 1301 case TermOrder.IGRLEX: { 1302 horder = new EVComparator() { 1303 1304 1305 @Override 1306 public int compare(ExpVector e1, ExpVector e2) { 1307 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1308 if (t != 0) { 1309 return t; 1310 } 1311 return -e1.invGradCompareTo(e2, evbeg2, evend2); 1312 } 1313 }; 1314 break; 1315 } 1316 case TermOrder.REVLEX: { 1317 horder = new EVComparator() { 1318 1319 1320 @Override 1321 public int compare(ExpVector e1, ExpVector e2) { 1322 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1323 if (t != 0) { 1324 return t; 1325 } 1326 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 1327 } 1328 }; 1329 break; 1330 } 1331 case TermOrder.REVILEX: { 1332 horder = new EVComparator() { 1333 1334 1335 @Override 1336 public int compare(ExpVector e1, ExpVector e2) { 1337 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1338 if (t != 0) { 1339 return t; 1340 } 1341 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 1342 } 1343 }; 1344 break; 1345 } 1346 case TermOrder.REVTDEG: { 1347 horder = new EVComparator() { 1348 1349 1350 @Override 1351 public int compare(ExpVector e1, ExpVector e2) { 1352 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1353 if (t != 0) { 1354 return t; 1355 } 1356 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 1357 } 1358 }; 1359 break; 1360 } 1361 case TermOrder.REVITDG: { 1362 horder = new EVComparator() { 1363 1364 1365 @Override 1366 public int compare(ExpVector e1, ExpVector e2) { 1367 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1368 if (t != 0) { 1369 return t; 1370 } 1371 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 1372 } 1373 }; 1374 break; 1375 } 1376 default: { 1377 horder = null; 1378 } 1379 } 1380 break; 1381 } 1382 //----- end reversed----------- 1383 default: { 1384 horder = null; 1385 } 1386 } 1387 if (horder == null) { 1388 throw new IllegalArgumentException("invalid term order: " + evord + " 2 " + evord2); 1389 } 1390 1391 lorder = new EVComparator() { 1392 1393 1394 @Override 1395 public int compare(ExpVector e1, ExpVector e2) { 1396 return -horder.compare(e1, e2); 1397 } 1398 }; 1399 1400 // sugar = new EVsugar(); 1401 sugar = new EVComparator() { 1402 1403 1404 @Override 1405 public int compare(ExpVector e1, ExpVector e2) { 1406 return e1.invGradCompareTo(e2); 1407 } 1408 }; 1409 } 1410 1411 1412 /* 1413 * Constructor for default split order. 1414 * @param r max number of exponents to compare. 1415 * @param split index. 1416 public TermOrder(int r, int split) { 1417 this(DEFAULT_EVORD, DEFAULT_EVORD, r, split); 1418 } 1419 */ 1420 1421 1422 /** 1423 * Create block term order at split index. 1424 * @param s split index. 1425 * @return block TermOrder with split index. 1426 */ 1427 public TermOrder blockOrder(int s) { 1428 return blockOrder(s, Integer.MAX_VALUE); 1429 } 1430 1431 1432 /** 1433 * Create block term order at split index. 1434 * @param s split index. 1435 * @param len length of ExpVectors to compare 1436 * @return block TermOrder with split index. 1437 */ 1438 public TermOrder blockOrder(int s, int len) { 1439 return new TermOrder(evord, evord, len, s); 1440 } 1441 1442 1443 /** 1444 * Create block term order at split index. 1445 * @param s split index. 1446 * @param t second term order. 1447 * @return block TermOrder with split index. 1448 */ 1449 public TermOrder blockOrder(int s, TermOrder t) { 1450 return blockOrder(s, t, Integer.MAX_VALUE); 1451 } 1452 1453 1454 /** 1455 * Create block term order at split index. 1456 * @param s split index. 1457 * @param t second term order. 1458 * @param len length of ExpVectors to compare 1459 * @return block TermOrder with split index. 1460 */ 1461 public TermOrder blockOrder(int s, TermOrder t, int len) { 1462 return new TermOrder(evord, t.evord, len, s); 1463 } 1464 1465 1466 /** 1467 * Get the first defined order indicator. 1468 * @return evord. 1469 */ 1470 public int getEvord() { 1471 return evord; 1472 } 1473 1474 1475 /** 1476 * Get the second defined order indicator. 1477 * @return evord2. 1478 */ 1479 public int getEvord2() { 1480 return evord2; 1481 } 1482 1483 1484 /** 1485 * Get the split index. 1486 * @return split. 1487 */ 1488 public int getSplit() { 1489 return evend1; // = evbeg2 1490 } 1491 1492 1493 /** 1494 * Get the exponent vector size. 1495 * <b>Note:</b> can be INTEGER.MAX_VALUE. 1496 * @return size. 1497 */ 1498 public int getSize() { 1499 return evend2; // can be INTEGER.MAX_VALUE 1500 } 1501 1502 1503 /** 1504 * Get the weight array. 1505 * @return weight. 1506 */ 1507 public long[][] getWeight() { 1508 if (weight == null) { 1509 return null; 1510 } 1511 return Arrays.copyOf(weight, weight.length); // > Java-5 1512 } 1513 1514 1515 /** 1516 * Get the descending order comparator. Sorts the highest terms first. 1517 * @return horder. 1518 */ 1519 public EVComparator getDescendComparator() { 1520 return horder; 1521 } 1522 1523 1524 /** 1525 * Get the ascending order comparator. Sorts the lowest terms first. 1526 * @return lorder. 1527 */ 1528 public EVComparator getAscendComparator() { 1529 return lorder; 1530 } 1531 1532 1533 /** 1534 * Get the sugar order comparator. Sorts the graded lowest terms first. 1535 * @return sugar. 1536 */ 1537 public EVComparator getSugarComparator() { 1538 return sugar; 1539 } 1540 1541 1542 /** 1543 * Comparison with any other object. 1544 * @see java.lang.Object#equals(java.lang.Object) 1545 */ 1546 @Override 1547 public boolean equals(Object B) { 1548 if (!(B instanceof TermOrder)) { 1549 return false; 1550 } 1551 TermOrder b = (TermOrder) B; 1552 boolean t = evord == b.getEvord() && evord2 == b.evord2 && evbeg1 == b.evbeg1 && evend1 == b.evend1 1553 && evbeg2 == b.evbeg2 && evend2 == b.evend2; 1554 if (!t) { 1555 return t; 1556 } 1557 if (!Arrays.deepEquals(weight, b.weight)) { 1558 return false; 1559 } 1560 return true; 1561 } 1562 1563 1564 /** 1565 * Hash code. 1566 * @see java.lang.Object#hashCode() 1567 */ 1568 @Override 1569 public int hashCode() { 1570 int h = evord; 1571 h = (h << 3) + evord2; 1572 h = (h << 4) + evbeg1; 1573 h = (h << 4) + evend1; 1574 h = (h << 4) + evbeg2; 1575 h = (h << 4) + evend2; 1576 if (weight == null) { 1577 return h; 1578 } 1579 h = h * 7 + Arrays.deepHashCode(weight); 1580 return h; 1581 } 1582 1583 1584 /** 1585 * String representation of weight matrix. 1586 * @return string representation of weight matrix. 1587 */ 1588 public String weightToString() { 1589 StringBuffer erg = new StringBuffer(); 1590 if (weight != null) { 1591 erg.append("("); 1592 for (int j = 0; j < weight.length; j++) { 1593 if (j > 0) { 1594 erg.append(","); 1595 } 1596 long[] wj = weight[j]; 1597 erg.append("("); 1598 for (int i = 0; i < wj.length; i++) { 1599 if (i > 0) { 1600 erg.append(","); 1601 } 1602 erg.append(String.valueOf(wj[wj.length - 1 - i])); 1603 } 1604 erg.append(")"); 1605 } 1606 erg.append(")"); 1607 } 1608 return erg.toString(); 1609 } 1610 1611 1612 /** 1613 * Script representation of weight matrix. 1614 * @return script representation of weight matrix. 1615 */ 1616 public String weightToScript() { 1617 // cases Python and Ruby 1618 StringBuffer erg = new StringBuffer(); 1619 if (weight != null) { 1620 erg.append("["); 1621 for (int j = 0; j < weight.length; j++) { 1622 if (j > 0) { 1623 erg.append(","); 1624 } 1625 long[] wj = weight[j]; 1626 erg.append("["); 1627 for (int i = 0; i < wj.length; i++) { 1628 if (i > 0) { 1629 erg.append(","); 1630 } 1631 erg.append(String.valueOf(wj[wj.length - 1 - i])); 1632 } 1633 erg.append("]"); 1634 } 1635 erg.append("]"); 1636 } 1637 return erg.toString(); 1638 } 1639 1640 1641 /** 1642 * String representation of TermOrder. 1643 * @return script representation of TermOrder. 1644 */ 1645 public String toScript() { 1646 // cases Python and Ruby 1647 if (weight != null) { 1648 StringBuffer erg = new StringBuffer(); 1649 //erg.append("TermOrder( "); 1650 erg.append(weightToScript()); 1651 if (evend1 == evend2) { 1652 //erg.append(" )"); 1653 return erg.toString(); 1654 } 1655 erg.append("[" + evbeg1 + "," + evend1 + "]"); 1656 erg.append("[" + evbeg2 + "," + evend2 + "]"); 1657 //erg.append(" )"); 1658 return erg.toString(); 1659 } 1660 return toScriptPlain(); 1661 } 1662 1663 1664 /** 1665 * String representation of TermOrder. 1666 * @see java.lang.Object#toString() 1667 */ 1668 @Override 1669 public String toString() { 1670 if (weight != null) { 1671 StringBuffer erg = new StringBuffer(); 1672 erg.append("W( "); 1673 erg.append(weightToString()); 1674 if (evend1 == evend2) { 1675 erg.append(" )"); 1676 return erg.toString(); 1677 } 1678 erg.append("[" + evbeg1 + "," + evend1 + "]"); 1679 erg.append("[" + evbeg2 + "," + evend2 + "]"); 1680 erg.append(" )"); 1681 return erg.toString(); 1682 } 1683 return toStringPlain(); 1684 } 1685 1686 1687 /** 1688 * String representation of TermOrder without prefix and weight matrix. 1689 */ 1690 public String toStringPlain() { 1691 StringBuffer erg = new StringBuffer(); 1692 if (weight != null) { 1693 return erg.toString(); 1694 } 1695 erg.append(toScriptOrder(evord)); // JAS only 1696 if (evord2 <= 0) { 1697 return erg.toString(); 1698 } 1699 erg.append("[" + evbeg1 + "," + evend1 + "]"); 1700 erg.append(toScriptOrder(evord2)); // JAS only 1701 erg.append("[" + evbeg2 + "," + evend2 + "]"); 1702 return erg.toString(); 1703 } 1704 1705 1706 /** 1707 * Script representation of TermOrder without prefix and weight matrix. 1708 */ 1709 public String toScriptPlain() { 1710 StringBuffer erg = new StringBuffer(); 1711 if (weight != null) { 1712 return toScript(); 1713 } 1714 erg.append("Order"); 1715 switch (Scripting.getLang()) { 1716 case Ruby: 1717 erg.append("::"); 1718 break; 1719 case Python: 1720 default: 1721 erg.append("."); 1722 } 1723 erg.append(toScriptOrder(evord)); 1724 if (evord2 <= 0) { 1725 return erg.toString(); 1726 } 1727 if (evord == evord2) { 1728 erg.append(".blockOrder(" + evend1 + ")"); 1729 return erg.toString(); 1730 } 1731 erg.append(".blockOrder("); 1732 erg.append(evend1 + ","); 1733 erg.append("Order"); 1734 switch (Scripting.getLang()) { 1735 case Ruby: 1736 erg.append("::"); 1737 break; 1738 case Python: 1739 default: 1740 erg.append("."); 1741 } 1742 erg.append(toScriptOrder(evord2)); 1743 erg.append(")"); 1744 return erg.toString(); 1745 } 1746 1747 1748 /** 1749 * Script and String representation of TermOrder name. 1750 */ 1751 public String toScriptOrder(int ev) { 1752 switch (Scripting.getCAS()) { 1753 case Math: 1754 switch (ev) { 1755 case LEX: 1756 return "NegativeReverseLexicographic"; 1757 case INVLEX: 1758 return "ReverseLexicographic"; 1759 case GRLEX: 1760 return "NegativeDegreeReverseLexicographic"; 1761 case ITDEGLEX: //IGRLEX: 1762 return "DegreeReverseLexicographic"; 1763 case REVLEX: 1764 return "NegativeLexicographic"; 1765 case REVILEX: 1766 return "Lexicographic"; 1767 case REVITDEG: //REVTDEG: 1768 return "NegativeDegreeLexicographic"; 1769 case REVITDG: 1770 return "DegreeLexicographic"; 1771 default: 1772 return "invalid(" + ev + ")"; 1773 } 1774 case Sage: 1775 switch (ev) { 1776 case LEX: 1777 return "negrevlex"; 1778 case INVLEX: 1779 return "invlex"; 1780 case GRLEX: 1781 return "negdegrevlex"; 1782 case ITDEGLEX: //IGRLEX: 1783 return "degrevlex"; 1784 case REVLEX: 1785 return "neglex"; 1786 case REVILEX: 1787 return "lex"; 1788 case REVITDEG: //REVTDEG: 1789 return "negdeglex"; 1790 case REVITDG: 1791 return "deglex"; 1792 default: 1793 return "invalid(" + ev + ")"; 1794 } 1795 case Singular: 1796 switch (ev) { 1797 //case LEX: // missing 1798 //return "negrevlex"; 1799 case INVLEX: 1800 return "rp"; 1801 case GRLEX: 1802 return "ds"; 1803 case ITDEGLEX: //IGRLEX: 1804 return "dp"; 1805 case REVLEX: 1806 return "ls"; 1807 case REVILEX: 1808 return "lp"; 1809 case REVITDEG: //REVTDEG: 1810 return "Ds"; 1811 case REVITDG: 1812 return "Dp"; 1813 default: 1814 return "invalid(" + ev + ")"; 1815 } 1816 case JAS: 1817 default: 1818 switch (ev) { 1819 case LEX: 1820 return "LEX"; 1821 case INVLEX: 1822 return "INVLEX"; 1823 case GRLEX: 1824 return "GRLEX"; 1825 case IGRLEX: 1826 return "IGRLEX"; 1827 case REVLEX: 1828 return "REVLEX"; 1829 case REVILEX: 1830 return "REVILEX"; 1831 case REVTDEG: 1832 return "REVTDEG"; 1833 case REVITDG: 1834 return "REVITDG"; 1835 case ITDEGLEX: 1836 return "ITDEGLEX"; 1837 case REVITDEG: 1838 return "REVITDEG"; 1839 default: 1840 return "invalid(" + ev + ")"; 1841 } 1842 } 1843 //return "invalid(" + ev + ")"; 1844 } 1845 1846 1847 /** 1848 * Extend variables. Used e.g. in module embedding. Extend TermOrder by k 1849 * elements. <b>Note:</b> Use POT module term order. 1850 * @param r current number of variables. 1851 * @param k number of variables to extend. 1852 * @return extended TermOrder. 1853 */ 1854 public TermOrder extend(int r, int k) { 1855 return extend(r, k, false); 1856 } 1857 1858 1859 /** 1860 * Extend variables. Used e.g. in module embedding. Extend TermOrder by k 1861 * elements. <b>Note:</b> Now TOP and POT orders are distinguished. 1862 * @param r current number of variables. 1863 * @param k number of variables to extend. 1864 * @param top true for TOP term order, false for POT term order. 1865 * @return extended TermOrder. 1866 */ 1867 public TermOrder extend(int r, int k, boolean top) { 1868 if (weight != null) { 1869 long[][] w = new long[weight.length][]; 1870 for (int i = 0; i < weight.length; i++) { 1871 long[] wi = weight[i]; 1872 long max = 0; 1873 // long min = Long.MAX_VALUE; 1874 for (int j = 0; j < wi.length; j++) { 1875 if (wi[j] > max) 1876 max = wi[j]; 1877 //if ( wi[j] < min ) min = wi[j]; 1878 } 1879 max++; 1880 long[] wj = new long[wi.length + k]; 1881 for (int j = 0; j < i; j++) { 1882 wj[j] = max; 1883 } 1884 System.arraycopy(wi, 0, wj, i, wi.length); 1885 w[i] = wj; 1886 } 1887 return new TermOrder(w); 1888 } 1889 if (evord2 != 0) { 1890 logger.debug("warn: TermOrder is already extended"); 1891 if (debug) { 1892 throw new IllegalArgumentException("TermOrder is already extended: " + this); 1893 } 1894 return new TermOrder(evord, evord2, r + k, evend1 + k, top); 1895 } 1896 //System.out.println("evord = " + evord); 1897 //System.out.println("DEFAULT_EVORD = " + DEFAULT_EVORD); 1898 //System.out.println("tord = " + this); 1899 return new TermOrder(DEFAULT_EVORD/*evord*/, evord, r + k, k, top); // todo param 1900 // don't change to evord, cause REVITDG 1901 } 1902 1903 1904 /** 1905 * Extend lower variables. Extend TermOrder by k elements. <b>Note:</b> todo 1906 * distinguish TOP and POT orders. 1907 * @param r current number of variables. 1908 * @param k number of variables to extend. 1909 * @return extended TermOrder. 1910 */ 1911 public TermOrder extendLower(int r, int k) { 1912 if (weight != null) { 1913 long[][] w = new long[weight.length][]; 1914 for (int i = 0; i < weight.length; i++) { 1915 long[] wi = weight[i]; 1916 //long max = 0; 1917 long min = Long.MAX_VALUE; 1918 for (int j = 0; j < wi.length; j++) { 1919 //if ( wi[j] > max ) max = wi[j]; 1920 if (wi[j] < min) 1921 min = wi[j]; 1922 } 1923 //max++; 1924 long[] wj = new long[wi.length + k]; 1925 for (int j = 0; j < i; j++) { 1926 wj[wi.length + j] = min; 1927 } 1928 System.arraycopy(wi, 0, wj, 0, wi.length); 1929 w[i] = wj; 1930 } 1931 return new TermOrder(w); 1932 } 1933 if (evord2 != 0) { 1934 if (debug) { 1935 logger.warn("TermOrder is already extended"); 1936 } 1937 return new TermOrder(evord, evord2, r + k, evend1 + k); 1938 } 1939 //System.out.println("evord = " + evord); 1940 //System.out.println("DEFAULT_EVORD = " + DEFAULT_EVORD); 1941 //System.out.println("tord = " + this); 1942 return new TermOrder(evord); 1943 } 1944 1945 1946 /** 1947 * Contract variables. Used e.g. in module embedding. Contract TermOrder to 1948 * non split status. 1949 * @param k position of first element to be copied. 1950 * @param len new length. 1951 * @return contracted TermOrder. 1952 */ 1953 public TermOrder contract(int k, int len) { 1954 if (weight != null) { 1955 long[][] w = new long[weight.length][]; 1956 for (int i = 0; i < weight.length; i++) { 1957 long[] wi = weight[i]; 1958 long[] wj = new long[len]; 1959 System.arraycopy(wi, k, wj, 0, len); 1960 w[i] = wj; 1961 } 1962 return new TermOrder(w); 1963 } 1964 if (evord2 == 0) { 1965 if (debug) { 1966 logger.warn("TermOrder is already contracted"); 1967 } 1968 return new TermOrder(evord); 1969 } 1970 if (evend1 > k) { // < IntMax since evord2 != 0 1971 int el = evend1 - k; 1972 while (el > len) { 1973 el -= len; 1974 } 1975 if (el == 0L) { 1976 return new TermOrder(evord); 1977 } 1978 if (el == len) { 1979 return new TermOrder(evord); 1980 } 1981 return new TermOrder(evord, evord2, len, el); 1982 } 1983 return new TermOrder(evord2); 1984 } 1985 1986 1987 /** 1988 * Reverse variables. Used e.g. in opposite rings. 1989 * @return TermOrder for reversed variables. 1990 */ 1991 public TermOrder reverse() { 1992 return reverse(false); 1993 } 1994 1995 1996 /** 1997 * Reverse variables. Used e.g. in opposite rings. 1998 * @param partial true for partialy reversed term orders. 1999 * @return TermOrder for reversed variables. 2000 */ 2001 public TermOrder reverse(boolean partial) { 2002 TermOrder t; 2003 if (weight != null) { 2004 if (partial) { 2005 logger.error("partial reversed weight order not implemented"); 2006 } 2007 long[][] w = new long[weight.length][]; 2008 for (int i = 0; i < weight.length; i++) { 2009 long[] wi = weight[i]; 2010 long[] wj = new long[wi.length]; 2011 for (int j = 0; j < wj.length; j++) { 2012 wj[j] = wi[wj.length - 1 - j]; 2013 } 2014 w[i] = wj; 2015 } 2016 t = new TermOrder(w); 2017 logger.info("reverse = " + t + ", from = " + this); 2018 return t; 2019 } 2020 if (evord2 == 0) { 2021 t = new TermOrder(revert(evord)); 2022 return t; 2023 } 2024 if (partial) { 2025 t = new TermOrder(revert(evord), revert(evord2), evend2, evend1); 2026 } else { 2027 t = new TermOrder(revert(evord2), revert(evord), evend2, evend2 - evbeg2); 2028 } 2029 logger.info("reverse = " + t + ", from = " + this); 2030 return t; 2031 } 2032 2033 2034 /** 2035 * Revert exponent order. Used e.g. in opposite rings. 2036 * @param evord exponent order to be reverted. 2037 * @return reverted exponent order. 2038 */ 2039 public static int revert(int evord) { 2040 int i = evord; 2041 switch (evord) { 2042 case LEX: 2043 i = REVLEX; 2044 break; 2045 case INVLEX: 2046 i = REVILEX; 2047 break; 2048 case GRLEX: 2049 i = REVTDEG; 2050 break; 2051 case IGRLEX: 2052 i = REVITDG; 2053 break; 2054 case REVLEX: 2055 i = LEX; 2056 break; 2057 case REVILEX: 2058 i = INVLEX; 2059 break; 2060 case REVTDEG: 2061 i = GRLEX; 2062 break; 2063 case REVITDG: 2064 i = IGRLEX; 2065 break; 2066 default: // REVITDEG, ITDEGLEX 2067 logger.error("can not revert " + evord); 2068 break; 2069 } 2070 return i; 2071 } 2072 2073 2074 /** 2075 * Permutation of a long array. 2076 * @param a array of long. 2077 * @param P permutation. 2078 * @return P(a). 2079 */ 2080 public static long[] longArrayPermutation(List<Integer> P, long[] a) { 2081 if (a == null || a.length <= 1) { 2082 return a; 2083 } 2084 long[] b = new long[a.length]; 2085 int j = 0; 2086 for (Integer i : P) { 2087 b[j] = a[i]; 2088 j++; 2089 } 2090 return b; 2091 } 2092 2093 2094 /** 2095 * Permutation of the termorder. 2096 * @param P permutation. 2097 * @return P(a). 2098 */ 2099 public TermOrder permutation(List<Integer> P) { 2100 TermOrder tord = this; 2101 if (getEvord2() != 0) { 2102 //throw new IllegalArgumentException("split term orders not permutable"); 2103 tord = new TermOrder(getEvord2()); 2104 logger.warn("split term order '" + this + "' not permutable, resetting to most base term order " 2105 + tord); 2106 } 2107 long[][] weight = getWeight(); 2108 if (weight != null) { 2109 long[][] w = new long[weight.length][]; 2110 for (int i = 0; i < weight.length; i++) { 2111 w[i] = longArrayPermutation(P, weight[i]); 2112 } 2113 tord = new TermOrder(w); 2114 } 2115 return tord; 2116 } 2117 2118 2119 /** 2120 * Weight TermOrder with reversed weight vectors. 2121 * @param w weight matrix 2122 * @return TermOrder with reversed weight vectors 2123 */ 2124 public static TermOrder reverseWeight(long[][] w) { 2125 if (w == null) { 2126 logger.warn("null weight matrix ignored"); 2127 return new TermOrder(); 2128 } 2129 long[][] wr = new long[w.length][]; 2130 for (int j = 0; j < w.length; j++) { 2131 long[] wj = w[j]; 2132 //System.out.println("reverseWeight: " + wj); 2133 long[] wrj = new long[wj.length]; 2134 for (int i = 0; i < wj.length; i++) { 2135 wrj[i] = wj[wj.length - 1 - i]; 2136 } 2137 wr[j] = wrj; 2138 } 2139 return new TermOrder(wr); 2140 } 2141 2142}