001/* 002 * $Id: TermOrder.java 5912 2018-08-26 22:03:29Z 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 logger.info("module TermOrder is " + (TOP ? "TOP" : "POT") + ", split = " + split 421 + ", evord = " + toScriptOrder(evord) + ", evord2 = " + toScriptOrder(evord2)) ; 422 switch (evord) { // horder = new EVhorder(); 423 case TermOrder.LEX: { 424 switch (evord2) { 425 case TermOrder.LEX: { 426 horder = new EVComparator() { 427 428 429 @Override 430 public int compare(ExpVector e1, ExpVector e2) { 431 int t = e1.invLexCompareTo(e2, evbeg1, evend1); 432 if (t != 0) { 433 return t; 434 } 435 return e1.invLexCompareTo(e2, evbeg2, evend2); 436 } 437 }; 438 break; 439 } 440 case TermOrder.INVLEX: { 441 horder = new EVComparator() { 442 443 444 @Override 445 public int compare(ExpVector e1, ExpVector e2) { 446 int t = e1.invLexCompareTo(e2, evbeg1, evend1); 447 if (t != 0) { 448 return t; 449 } 450 return -e1.invLexCompareTo(e2, evbeg2, evend2); 451 } 452 }; 453 break; 454 } 455 case TermOrder.GRLEX: { 456 horder = new EVComparator() { 457 458 459 @Override 460 public int compare(ExpVector e1, ExpVector e2) { 461 int t = e1.invLexCompareTo(e2, evbeg1, evend1); 462 if (t != 0) { 463 return t; 464 } 465 return e1.invGradCompareTo(e2, evbeg2, evend2); 466 } 467 }; 468 break; 469 } 470 case TermOrder.IGRLEX: { 471 horder = new EVComparator() { 472 473 474 @Override 475 public int compare(ExpVector e1, ExpVector e2) { 476 int t = e1.invLexCompareTo(e2, evbeg1, evend1); 477 if (t != 0) { 478 return t; 479 } 480 return -e1.invGradCompareTo(e2, evbeg2, evend2); 481 } 482 }; 483 break; 484 } 485 default: { 486 horder = null; 487 } 488 } 489 break; 490 } 491 case TermOrder.INVLEX: { 492 switch (evord2) { 493 case TermOrder.LEX: { 494 horder = new EVComparator() { 495 496 497 @Override 498 public int compare(ExpVector e1, ExpVector e2) { 499 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 500 if (t != 0) { 501 return t; 502 } 503 return e1.invLexCompareTo(e2, evbeg2, evend2); 504 } 505 }; 506 break; 507 } 508 case TermOrder.INVLEX: { 509 if (!TOP) { 510 horder = new EVComparator() { // POT 511 512 @Override 513 public int compare(ExpVector e1, ExpVector e2) { 514 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 515 if (t != 0) { 516 return t; 517 } 518 return -e1.invLexCompareTo(e2, evbeg2, evend2); 519 } 520 }; 521 break; 522 } 523 horder = new EVComparator() { // TOP 524 525 @Override 526 public int compare(ExpVector e1, ExpVector e2) { 527 int t = -e1.invLexCompareTo(e2, evbeg2, evend2); 528 if (t != 0) { 529 return t; 530 } 531 return -e1.invLexCompareTo(e2, evbeg1, evend1); 532 } 533 }; 534 break; 535 } 536 case TermOrder.GRLEX: { 537 horder = new EVComparator() { 538 539 540 @Override 541 public int compare(ExpVector e1, ExpVector e2) { 542 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 543 if (t != 0) { 544 return t; 545 } 546 return e1.invGradCompareTo(e2, evbeg2, evend2); 547 } 548 }; 549 break; 550 } 551 case TermOrder.IGRLEX: { 552 if (!TOP) { 553 horder = new EVComparator() { // POT 554 555 @Override 556 public int compare(ExpVector e1, ExpVector e2) { 557 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 558 if (t != 0) { 559 return t; 560 } 561 return -e1.invGradCompareTo(e2, evbeg2, evend2); 562 } 563 }; 564 break; 565 } 566 horder = new EVComparator() { // TOP 567 568 @Override 569 public int compare(ExpVector e1, ExpVector e2) { 570 int t = -e1.invGradCompareTo(e2, evbeg2, evend2); 571 if (t != 0) { 572 return t; 573 } 574 return -e1.invLexCompareTo(e2, evbeg1, evend1); 575 } 576 }; 577 break; 578 } 579 case TermOrder.REVLEX: { 580 horder = new EVComparator() { 581 582 583 @Override 584 public int compare(ExpVector e1, ExpVector e2) { 585 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 586 if (t != 0) { 587 return t; 588 } 589 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 590 } 591 }; 592 break; 593 } 594 case TermOrder.REVILEX: { 595 horder = new EVComparator() { 596 597 598 @Override 599 public int compare(ExpVector e1, ExpVector e2) { 600 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 601 if (t != 0) { 602 return t; 603 } 604 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 605 } 606 }; 607 break; 608 } 609 case TermOrder.REVTDEG: { 610 horder = new EVComparator() { 611 612 613 @Override 614 public int compare(ExpVector e1, ExpVector e2) { 615 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 616 if (t != 0) { 617 return t; 618 } 619 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 620 } 621 }; 622 break; 623 } 624 case TermOrder.REVITDG: { 625 horder = new EVComparator() { 626 627 628 @Override 629 public int compare(ExpVector e1, ExpVector e2) { 630 int t = -e1.invLexCompareTo(e2, evbeg1, evend1); 631 if (t != 0) { 632 return t; 633 } 634 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 635 } 636 }; 637 break; 638 } 639 default: { 640 horder = null; 641 } 642 } 643 break; 644 } 645 case TermOrder.GRLEX: { 646 switch (evord2) { 647 case TermOrder.LEX: { 648 horder = new EVComparator() { 649 650 651 @Override 652 public int compare(ExpVector e1, ExpVector e2) { 653 int t = e1.invGradCompareTo(e2, evbeg1, evend1); 654 if (t != 0) { 655 return t; 656 } 657 return e1.invLexCompareTo(e2, evbeg2, evend2); 658 } 659 }; 660 break; 661 } 662 case TermOrder.INVLEX: { 663 horder = new EVComparator() { 664 665 666 @Override 667 public int compare(ExpVector e1, ExpVector e2) { 668 int t = e1.invGradCompareTo(e2, evbeg1, evend1); 669 if (t != 0) { 670 return t; 671 } 672 return -e1.invLexCompareTo(e2, evbeg2, evend2); 673 } 674 }; 675 break; 676 } 677 case TermOrder.GRLEX: { 678 horder = new EVComparator() { 679 680 681 @Override 682 public int compare(ExpVector e1, ExpVector e2) { 683 int t = e1.invGradCompareTo(e2, evbeg1, evend1); 684 if (t != 0) { 685 return t; 686 } 687 return e1.invGradCompareTo(e2, evbeg2, evend2); 688 } 689 }; 690 break; 691 } 692 case TermOrder.IGRLEX: { 693 horder = new EVComparator() { 694 695 696 @Override 697 public int compare(ExpVector e1, ExpVector e2) { 698 int t = e1.invGradCompareTo(e2, evbeg1, evend1); 699 if (t != 0) { 700 return t; 701 } 702 return -e1.invGradCompareTo(e2, evbeg2, evend2); 703 } 704 }; 705 break; 706 } 707 default: { 708 horder = null; 709 } 710 } 711 break; 712 } 713 case TermOrder.IGRLEX: { 714 switch (evord2) { 715 case TermOrder.LEX: { 716 horder = new EVComparator() { 717 718 719 @Override 720 public int compare(ExpVector e1, ExpVector e2) { 721 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 722 if (t != 0) { 723 return t; 724 } 725 return e1.invLexCompareTo(e2, evbeg2, evend2); 726 } 727 }; 728 break; 729 } 730 case TermOrder.INVLEX: { 731 if (!TOP) { 732 horder = new EVComparator() { // POT 733 734 @Override 735 public int compare(ExpVector e1, ExpVector e2) { 736 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 737 if (t != 0) { 738 return t; 739 } 740 return -e1.invLexCompareTo(e2, evbeg2, evend2); 741 } 742 }; 743 break; 744 } 745 horder = new EVComparator() { // TOP 746 747 @Override 748 public int compare(ExpVector e1, ExpVector e2) { 749 int t = -e1.invLexCompareTo(e2, evbeg2, evend2); 750 if (t != 0) { 751 return t; 752 } 753 return -e1.invGradCompareTo(e2, evbeg1, evend1); 754 } 755 }; 756 break; 757 } 758 case TermOrder.GRLEX: { 759 horder = new EVComparator() { 760 761 762 @Override 763 public int compare(ExpVector e1, ExpVector e2) { 764 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 765 if (t != 0) { 766 return t; 767 } 768 return e1.invGradCompareTo(e2, evbeg2, evend2); 769 } 770 }; 771 break; 772 } 773 case TermOrder.IGRLEX: { 774 if (!TOP) { 775 horder = new EVComparator() { // POT 776 777 @Override 778 public int compare(ExpVector e1, ExpVector e2) { 779 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 780 if (t != 0) { 781 return t; 782 } 783 return -e1.invGradCompareTo(e2, evbeg2, evend2); 784 } 785 }; 786 break; 787 } 788 horder = new EVComparator() { // TOP 789 790 @Override 791 public int compare(ExpVector e1, ExpVector e2) { 792 int t = -e1.invGradCompareTo(e2, evbeg2, evend2); 793 if (t != 0) { 794 return t; 795 } 796 return -e1.invGradCompareTo(e2, evbeg1, evend1); 797 } 798 }; 799 break; 800 } 801 case TermOrder.REVLEX: { 802 horder = new EVComparator() { 803 804 805 @Override 806 public int compare(ExpVector e1, ExpVector e2) { 807 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 808 if (t != 0) { 809 return t; 810 } 811 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 812 } 813 }; 814 break; 815 } 816 case TermOrder.REVILEX: { 817 horder = new EVComparator() { 818 819 820 @Override 821 public int compare(ExpVector e1, ExpVector e2) { 822 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 823 if (t != 0) { 824 return t; 825 } 826 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 827 } 828 }; 829 break; 830 } 831 case TermOrder.REVTDEG: { 832 horder = new EVComparator() { 833 834 835 @Override 836 public int compare(ExpVector e1, ExpVector e2) { 837 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 838 if (t != 0) { 839 return t; 840 } 841 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 842 } 843 }; 844 break; 845 } 846 case TermOrder.REVITDG: { 847 horder = new EVComparator() { 848 849 850 @Override 851 public int compare(ExpVector e1, ExpVector e2) { 852 int t = -e1.invGradCompareTo(e2, evbeg1, evend1); 853 if (t != 0) { 854 return t; 855 } 856 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 857 } 858 }; 859 break; 860 } 861 default: { 862 horder = null; 863 } 864 } 865 break; 866 } 867 //----- begin reversed ----------- 868 case TermOrder.REVLEX: { 869 switch (evord2) { 870 case TermOrder.LEX: { 871 horder = new EVComparator() { 872 873 874 @Override 875 public int compare(ExpVector e1, ExpVector e2) { 876 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 877 if (t != 0) { 878 return t; 879 } 880 return e1.invLexCompareTo(e2, evbeg2, evend2); 881 } 882 }; 883 break; 884 } 885 case TermOrder.INVLEX: { 886 horder = new EVComparator() { 887 888 889 @Override 890 public int compare(ExpVector e1, ExpVector e2) { 891 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 892 if (t != 0) { 893 return t; 894 } 895 return -e1.invLexCompareTo(e2, evbeg2, evend2); 896 } 897 }; 898 break; 899 } 900 case TermOrder.GRLEX: { 901 horder = new EVComparator() { 902 903 904 @Override 905 public int compare(ExpVector e1, ExpVector e2) { 906 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 907 if (t != 0) { 908 return t; 909 } 910 return e1.invGradCompareTo(e2, evbeg2, evend2); 911 } 912 }; 913 break; 914 } 915 case TermOrder.IGRLEX: { 916 horder = new EVComparator() { 917 918 919 @Override 920 public int compare(ExpVector e1, ExpVector e2) { 921 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 922 if (t != 0) { 923 return t; 924 } 925 return -e1.invGradCompareTo(e2, evbeg2, evend2); 926 } 927 }; 928 break; 929 } 930 case TermOrder.REVLEX: { 931 horder = new EVComparator() { 932 933 934 @Override 935 public int compare(ExpVector e1, ExpVector e2) { 936 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 937 if (t != 0) { 938 return t; 939 } 940 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 941 } 942 }; 943 break; 944 } 945 case TermOrder.REVILEX: { 946 horder = new EVComparator() { 947 948 949 @Override 950 public int compare(ExpVector e1, ExpVector e2) { 951 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 952 if (t != 0) { 953 return t; 954 } 955 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 956 } 957 }; 958 break; 959 } 960 case TermOrder.REVTDEG: { 961 horder = new EVComparator() { 962 963 964 @Override 965 public int compare(ExpVector e1, ExpVector e2) { 966 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 967 if (t != 0) { 968 return t; 969 } 970 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 971 } 972 }; 973 break; 974 } 975 case TermOrder.REVITDG: { 976 horder = new EVComparator() { 977 978 979 @Override 980 public int compare(ExpVector e1, ExpVector e2) { 981 int t = e1.revInvLexCompareTo(e2, evbeg1, evend1); 982 if (t != 0) { 983 return t; 984 } 985 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 986 } 987 }; 988 break; 989 } 990 default: { 991 horder = null; 992 } 993 } 994 break; 995 } 996 case TermOrder.REVILEX: { 997 switch (evord2) { 998 case TermOrder.LEX: { 999 horder = new EVComparator() { 1000 1001 1002 @Override 1003 public int compare(ExpVector e1, ExpVector e2) { 1004 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1005 if (t != 0) { 1006 return t; 1007 } 1008 return e1.invLexCompareTo(e2, evbeg2, evend2); 1009 } 1010 }; 1011 break; 1012 } 1013 case TermOrder.INVLEX: { 1014 horder = new EVComparator() { 1015 1016 1017 @Override 1018 public int compare(ExpVector e1, ExpVector e2) { 1019 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1020 if (t != 0) { 1021 return t; 1022 } 1023 return -e1.invLexCompareTo(e2, evbeg2, evend2); 1024 } 1025 }; 1026 break; 1027 } 1028 case TermOrder.GRLEX: { 1029 horder = new EVComparator() { 1030 1031 1032 @Override 1033 public int compare(ExpVector e1, ExpVector e2) { 1034 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1035 if (t != 0) { 1036 return t; 1037 } 1038 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 1039 } 1040 }; 1041 break; 1042 } 1043 case TermOrder.IGRLEX: { 1044 horder = new EVComparator() { 1045 1046 1047 @Override 1048 public int compare(ExpVector e1, ExpVector e2) { 1049 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1050 if (t != 0) { 1051 return t; 1052 } 1053 return -e1.invGradCompareTo(e2, evbeg2, evend2); 1054 } 1055 }; 1056 break; 1057 } 1058 case TermOrder.REVLEX: { 1059 horder = new EVComparator() { 1060 1061 1062 @Override 1063 public int compare(ExpVector e1, ExpVector e2) { 1064 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1065 if (t != 0) { 1066 return t; 1067 } 1068 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 1069 } 1070 }; 1071 break; 1072 } 1073 case TermOrder.REVILEX: { 1074 horder = new EVComparator() { 1075 1076 1077 @Override 1078 public int compare(ExpVector e1, ExpVector e2) { 1079 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1080 if (t != 0) { 1081 return t; 1082 } 1083 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 1084 } 1085 }; 1086 break; 1087 } 1088 case TermOrder.REVTDEG: { 1089 horder = new EVComparator() { 1090 1091 1092 @Override 1093 public int compare(ExpVector e1, ExpVector e2) { 1094 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1095 if (t != 0) { 1096 return t; 1097 } 1098 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 1099 } 1100 }; 1101 break; 1102 } 1103 case TermOrder.REVITDG: { 1104 horder = new EVComparator() { 1105 1106 1107 @Override 1108 public int compare(ExpVector e1, ExpVector e2) { 1109 int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1); 1110 if (t != 0) { 1111 return t; 1112 } 1113 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 1114 } 1115 }; 1116 break; 1117 } 1118 default: { 1119 horder = null; 1120 } 1121 } 1122 break; 1123 } 1124 case TermOrder.REVTDEG: { 1125 switch (evord2) { 1126 case TermOrder.LEX: { 1127 horder = new EVComparator() { 1128 1129 1130 @Override 1131 public int compare(ExpVector e1, ExpVector e2) { 1132 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1133 if (t != 0) { 1134 return t; 1135 } 1136 return e1.invLexCompareTo(e2, evbeg2, evend2); 1137 } 1138 }; 1139 break; 1140 } 1141 case TermOrder.INVLEX: { 1142 horder = new EVComparator() { 1143 1144 1145 @Override 1146 public int compare(ExpVector e1, ExpVector e2) { 1147 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1148 if (t != 0) { 1149 return t; 1150 } 1151 return -e1.invLexCompareTo(e2, evbeg2, evend2); 1152 } 1153 }; 1154 break; 1155 } 1156 case TermOrder.GRLEX: { 1157 horder = new EVComparator() { 1158 1159 1160 @Override 1161 public int compare(ExpVector e1, ExpVector e2) { 1162 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1163 if (t != 0) { 1164 return t; 1165 } 1166 return e1.invGradCompareTo(e2, evbeg2, evend2); 1167 } 1168 }; 1169 break; 1170 } 1171 case TermOrder.IGRLEX: { 1172 horder = new EVComparator() { 1173 1174 1175 @Override 1176 public int compare(ExpVector e1, ExpVector e2) { 1177 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1178 if (t != 0) { 1179 return t; 1180 } 1181 return -e1.invGradCompareTo(e2, evbeg2, evend2); 1182 } 1183 }; 1184 break; 1185 } 1186 case TermOrder.REVLEX: { 1187 horder = new EVComparator() { 1188 1189 1190 @Override 1191 public int compare(ExpVector e1, ExpVector e2) { 1192 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1193 if (t != 0) { 1194 return t; 1195 } 1196 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 1197 } 1198 }; 1199 break; 1200 } 1201 case TermOrder.REVILEX: { 1202 horder = new EVComparator() { 1203 1204 1205 @Override 1206 public int compare(ExpVector e1, ExpVector e2) { 1207 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1208 if (t != 0) { 1209 return t; 1210 } 1211 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 1212 } 1213 }; 1214 break; 1215 } 1216 case TermOrder.REVTDEG: { 1217 horder = new EVComparator() { 1218 1219 1220 @Override 1221 public int compare(ExpVector e1, ExpVector e2) { 1222 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1223 if (t != 0) { 1224 return t; 1225 } 1226 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 1227 } 1228 }; 1229 break; 1230 } 1231 case TermOrder.REVITDG: { 1232 horder = new EVComparator() { 1233 1234 1235 @Override 1236 public int compare(ExpVector e1, ExpVector e2) { 1237 int t = e1.revInvGradCompareTo(e2, evbeg1, evend1); 1238 if (t != 0) { 1239 return t; 1240 } 1241 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 1242 } 1243 }; 1244 break; 1245 } 1246 default: { 1247 horder = null; 1248 } 1249 } 1250 break; 1251 } 1252 case TermOrder.REVITDG: { 1253 switch (evord2) { 1254 case TermOrder.LEX: { 1255 horder = new EVComparator() { 1256 1257 1258 @Override 1259 public int compare(ExpVector e1, ExpVector e2) { 1260 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1261 if (t != 0) { 1262 return t; 1263 } 1264 return e1.invLexCompareTo(e2, evbeg2, evend2); 1265 } 1266 }; 1267 break; 1268 } 1269 case TermOrder.INVLEX: { 1270 horder = new EVComparator() { 1271 1272 1273 @Override 1274 public int compare(ExpVector e1, ExpVector e2) { 1275 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1276 if (t != 0) { 1277 return t; 1278 } 1279 return -e1.invLexCompareTo(e2, evbeg2, evend2); 1280 } 1281 }; 1282 break; 1283 } 1284 case TermOrder.GRLEX: { 1285 horder = new EVComparator() { 1286 1287 1288 @Override 1289 public int compare(ExpVector e1, ExpVector e2) { 1290 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1291 if (t != 0) { 1292 return t; 1293 } 1294 return e1.invGradCompareTo(e2, evbeg2, evend2); 1295 } 1296 }; 1297 break; 1298 } 1299 case TermOrder.IGRLEX: { 1300 horder = new EVComparator() { 1301 1302 1303 @Override 1304 public int compare(ExpVector e1, ExpVector e2) { 1305 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1306 if (t != 0) { 1307 return t; 1308 } 1309 return -e1.invGradCompareTo(e2, evbeg2, evend2); 1310 } 1311 }; 1312 break; 1313 } 1314 case TermOrder.REVLEX: { 1315 horder = new EVComparator() { 1316 1317 1318 @Override 1319 public int compare(ExpVector e1, ExpVector e2) { 1320 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1321 if (t != 0) { 1322 return t; 1323 } 1324 return e1.revInvLexCompareTo(e2, evbeg2, evend2); 1325 } 1326 }; 1327 break; 1328 } 1329 case TermOrder.REVILEX: { 1330 horder = new EVComparator() { 1331 1332 1333 @Override 1334 public int compare(ExpVector e1, ExpVector e2) { 1335 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1336 if (t != 0) { 1337 return t; 1338 } 1339 return -e1.revInvLexCompareTo(e2, evbeg2, evend2); 1340 } 1341 }; 1342 break; 1343 } 1344 case TermOrder.REVTDEG: { 1345 horder = new EVComparator() { 1346 1347 1348 @Override 1349 public int compare(ExpVector e1, ExpVector e2) { 1350 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1351 if (t != 0) { 1352 return t; 1353 } 1354 return e1.revInvGradCompareTo(e2, evbeg2, evend2); 1355 } 1356 }; 1357 break; 1358 } 1359 case TermOrder.REVITDG: { 1360 horder = new EVComparator() { 1361 1362 1363 @Override 1364 public int compare(ExpVector e1, ExpVector e2) { 1365 int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1); 1366 if (t != 0) { 1367 return t; 1368 } 1369 return -e1.revInvGradCompareTo(e2, evbeg2, evend2); 1370 } 1371 }; 1372 break; 1373 } 1374 default: { 1375 horder = null; 1376 } 1377 } 1378 break; 1379 } 1380 //----- end reversed----------- 1381 default: { 1382 horder = null; 1383 } 1384 } 1385 if (horder == null) { 1386 throw new IllegalArgumentException("invalid term order: " + evord + " 2 " + evord2); 1387 } 1388 1389 lorder = new EVComparator() { 1390 1391 1392 @Override 1393 public int compare(ExpVector e1, ExpVector e2) { 1394 return -horder.compare(e1, e2); 1395 } 1396 }; 1397 1398 // sugar = new EVsugar(); 1399 sugar = new EVComparator() { 1400 1401 1402 @Override 1403 public int compare(ExpVector e1, ExpVector e2) { 1404 return e1.invGradCompareTo(e2); 1405 } 1406 }; 1407 } 1408 1409 1410 /* 1411 * Constructor for default split order. 1412 * @param r max number of exponents to compare. 1413 * @param split index. 1414 public TermOrder(int r, int split) { 1415 this(DEFAULT_EVORD, DEFAULT_EVORD, r, split); 1416 } 1417 */ 1418 1419 1420 /** 1421 * Create block term order at split index. 1422 * @param s split index. 1423 * @return block TermOrder with split index. 1424 */ 1425 public TermOrder blockOrder(int s) { 1426 return blockOrder(s, Integer.MAX_VALUE); 1427 } 1428 1429 1430 /** 1431 * Create block term order at split index. 1432 * @param s split index. 1433 * @param len length of ExpVectors to compare 1434 * @return block TermOrder with split index. 1435 */ 1436 public TermOrder blockOrder(int s, int len) { 1437 return new TermOrder(evord, evord, len, s); 1438 } 1439 1440 1441 /** 1442 * Create block term order at split index. 1443 * @param s split index. 1444 * @param t second term order. 1445 * @return block TermOrder with split index. 1446 */ 1447 public TermOrder blockOrder(int s, TermOrder t) { 1448 return blockOrder(s, t, Integer.MAX_VALUE); 1449 } 1450 1451 1452 /** 1453 * Create block term order at split index. 1454 * @param s split index. 1455 * @param t second term order. 1456 * @param len length of ExpVectors to compare 1457 * @return block TermOrder with split index. 1458 */ 1459 public TermOrder blockOrder(int s, TermOrder t, int len) { 1460 return new TermOrder(evord, t.evord, len, s); 1461 } 1462 1463 1464 /** 1465 * Get the first defined order indicator. 1466 * @return evord. 1467 */ 1468 public int getEvord() { 1469 return evord; 1470 } 1471 1472 1473 /** 1474 * Get the second defined order indicator. 1475 * @return evord2. 1476 */ 1477 public int getEvord2() { 1478 return evord2; 1479 } 1480 1481 1482 /** 1483 * Get the split index. 1484 * @return split. 1485 */ 1486 public int getSplit() { 1487 return evend1; // = evbeg2 1488 } 1489 1490 1491 /** 1492 * Get the exponent vector size. 1493 * <b>Note:</b> can be INTEGER.MAX_VALUE. 1494 * @return size. 1495 */ 1496 public int getSize() { 1497 return evend2; // can be INTEGER.MAX_VALUE 1498 } 1499 1500 1501 /** 1502 * Get the weight array. 1503 * @return weight. 1504 */ 1505 public long[][] getWeight() { 1506 if (weight == null) { 1507 return null; 1508 } 1509 return Arrays.copyOf(weight, weight.length); // > Java-5 1510 } 1511 1512 1513 /** 1514 * Get the descending order comparator. Sorts the highest terms first. 1515 * @return horder. 1516 */ 1517 public EVComparator getDescendComparator() { 1518 return horder; 1519 } 1520 1521 1522 /** 1523 * Get the ascending order comparator. Sorts the lowest terms first. 1524 * @return lorder. 1525 */ 1526 public EVComparator getAscendComparator() { 1527 return lorder; 1528 } 1529 1530 1531 /** 1532 * Get the sugar order comparator. Sorts the graded lowest terms first. 1533 * @return sugar. 1534 */ 1535 public EVComparator getSugarComparator() { 1536 return sugar; 1537 } 1538 1539 1540 /** 1541 * Comparison with any other object. 1542 * @see java.lang.Object#equals(java.lang.Object) 1543 */ 1544 @Override 1545 public boolean equals(Object B) { 1546 if (!(B instanceof TermOrder)) { 1547 return false; 1548 } 1549 TermOrder b = (TermOrder) B; 1550 boolean t = evord == b.getEvord() && evord2 == b.evord2 && evbeg1 == b.evbeg1 && evend1 == b.evend1 1551 && evbeg2 == b.evbeg2 && evend2 == b.evend2; 1552 if (!t) { 1553 return t; 1554 } 1555 if (!Arrays.deepEquals(weight, b.weight)) { 1556 return false; 1557 } 1558 return true; 1559 } 1560 1561 1562 /** 1563 * Hash code. 1564 * @see java.lang.Object#hashCode() 1565 */ 1566 @Override 1567 public int hashCode() { 1568 int h = evord; 1569 h = (h << 3) + evord2; 1570 h = (h << 4) + evbeg1; 1571 h = (h << 4) + evend1; 1572 h = (h << 4) + evbeg2; 1573 h = (h << 4) + evend2; 1574 if (weight == null) { 1575 return h; 1576 } 1577 h = h * 7 + Arrays.deepHashCode(weight); 1578 return h; 1579 } 1580 1581 1582 /** 1583 * String representation of weight matrix. 1584 * @return string representation of weight matrix. 1585 */ 1586 public String weightToString() { 1587 StringBuffer erg = new StringBuffer(); 1588 if (weight != null) { 1589 erg.append("("); 1590 for (int j = 0; j < weight.length; j++) { 1591 if (j > 0) { 1592 erg.append(","); 1593 } 1594 long[] wj = weight[j]; 1595 erg.append("("); 1596 for (int i = 0; i < wj.length; i++) { 1597 if (i > 0) { 1598 erg.append(","); 1599 } 1600 erg.append(String.valueOf(wj[wj.length - 1 - i])); 1601 } 1602 erg.append(")"); 1603 } 1604 erg.append(")"); 1605 } 1606 return erg.toString(); 1607 } 1608 1609 1610 /** 1611 * Script representation of weight matrix. 1612 * @return script representation of weight matrix. 1613 */ 1614 public String weightToScript() { 1615 // cases Python and Ruby 1616 StringBuffer erg = new StringBuffer(); 1617 if (weight != null) { 1618 erg.append("["); 1619 for (int j = 0; j < weight.length; j++) { 1620 if (j > 0) { 1621 erg.append(","); 1622 } 1623 long[] wj = weight[j]; 1624 erg.append("["); 1625 for (int i = 0; i < wj.length; i++) { 1626 if (i > 0) { 1627 erg.append(","); 1628 } 1629 erg.append(String.valueOf(wj[wj.length - 1 - i])); 1630 } 1631 erg.append("]"); 1632 } 1633 erg.append("]"); 1634 } 1635 return erg.toString(); 1636 } 1637 1638 1639 /** 1640 * String representation of TermOrder. 1641 * @return script representation of TermOrder. 1642 */ 1643 public String toScript() { 1644 // cases Python and Ruby 1645 if (weight != null) { 1646 StringBuffer erg = new StringBuffer(); 1647 //erg.append("TermOrder( "); 1648 erg.append(weightToScript()); 1649 if (evend1 == evend2) { 1650 //erg.append(" )"); 1651 return erg.toString(); 1652 } 1653 erg.append("[" + evbeg1 + "," + evend1 + "]"); 1654 erg.append("[" + evbeg2 + "," + evend2 + "]"); 1655 //erg.append(" )"); 1656 return erg.toString(); 1657 } 1658 return toScriptPlain(); 1659 } 1660 1661 1662 /** 1663 * String representation of TermOrder. 1664 * @see java.lang.Object#toString() 1665 */ 1666 @Override 1667 public String toString() { 1668 if (weight != null) { 1669 StringBuffer erg = new StringBuffer(); 1670 erg.append("W( "); 1671 erg.append(weightToString()); 1672 if (evend1 == evend2) { 1673 erg.append(" )"); 1674 return erg.toString(); 1675 } 1676 erg.append("[" + evbeg1 + "," + evend1 + "]"); 1677 erg.append("[" + evbeg2 + "," + evend2 + "]"); 1678 erg.append(" )"); 1679 return erg.toString(); 1680 } 1681 return toStringPlain(); 1682 } 1683 1684 1685 /** 1686 * String representation of TermOrder without prefix and weight matrix. 1687 */ 1688 public String toStringPlain() { 1689 StringBuffer erg = new StringBuffer(); 1690 if (weight != null) { 1691 return erg.toString(); 1692 } 1693 erg.append(toScriptOrder(evord)); // JAS only 1694 if (evord2 <= 0) { 1695 return erg.toString(); 1696 } 1697 erg.append("[" + evbeg1 + "," + evend1 + "]"); 1698 erg.append(toScriptOrder(evord2)); // JAS only 1699 erg.append("[" + evbeg2 + "," + evend2 + "]"); 1700 return erg.toString(); 1701 } 1702 1703 1704 /** 1705 * Script representation of TermOrder without prefix and weight matrix. 1706 */ 1707 public String toScriptPlain() { 1708 StringBuffer erg = new StringBuffer(); 1709 if (weight != null) { 1710 return toScript(); 1711 } 1712 erg.append("Order"); 1713 switch (Scripting.getLang()) { 1714 case Ruby: 1715 erg.append("::"); 1716 break; 1717 case Python: 1718 default: 1719 erg.append("."); 1720 } 1721 erg.append(toScriptOrder(evord)); 1722 if (evord2 <= 0) { 1723 return erg.toString(); 1724 } 1725 if (evord == evord2) { 1726 erg.append(".blockOrder(" + evend1 + ")"); 1727 return erg.toString(); 1728 } 1729 erg.append(".blockOrder("); 1730 erg.append(evend1 + ","); 1731 erg.append("Order"); 1732 switch (Scripting.getLang()) { 1733 case Ruby: 1734 erg.append("::"); 1735 break; 1736 case Python: 1737 default: 1738 erg.append("."); 1739 } 1740 erg.append(toScriptOrder(evord2)); 1741 erg.append(")"); 1742 return erg.toString(); 1743 } 1744 1745 1746 /** 1747 * Script and String representation of TermOrder name. 1748 */ 1749 public String toScriptOrder(int ev) { 1750 switch (Scripting.getCAS()) { 1751 case Math: 1752 switch (ev) { 1753 case LEX: 1754 return "NegativeReverseLexicographic"; 1755 case INVLEX: 1756 return "ReverseLexicographic"; 1757 case GRLEX: 1758 return "NegativeDegreeReverseLexicographic"; 1759 case ITDEGLEX: //IGRLEX: 1760 return "DegreeReverseLexicographic"; 1761 case REVLEX: 1762 return "NegativeLexicographic"; 1763 case REVILEX: 1764 return "Lexicographic"; 1765 case REVITDEG: //REVTDEG: 1766 return "NegativeDegreeLexicographic"; 1767 case REVITDG: 1768 return "DegreeLexicographic"; 1769 default: 1770 return "invalid(" + ev + ")"; 1771 } 1772 case Sage: 1773 switch (ev) { 1774 case LEX: 1775 return "negrevlex"; 1776 case INVLEX: 1777 return "invlex"; 1778 case GRLEX: 1779 return "negdegrevlex"; 1780 case ITDEGLEX: //IGRLEX: 1781 return "degrevlex"; 1782 case REVLEX: 1783 return "neglex"; 1784 case REVILEX: 1785 return "lex"; 1786 case REVITDEG: //REVTDEG: 1787 return "negdeglex"; 1788 case REVITDG: 1789 return "deglex"; 1790 default: 1791 return "invalid(" + ev + ")"; 1792 } 1793 case Singular: 1794 switch (ev) { 1795 //case LEX: // missing 1796 //return "negrevlex"; 1797 case INVLEX: 1798 return "rp"; 1799 case GRLEX: 1800 return "ds"; 1801 case ITDEGLEX: //IGRLEX: 1802 return "dp"; 1803 case REVLEX: 1804 return "ls"; 1805 case REVILEX: 1806 return "lp"; 1807 case REVITDEG: //REVTDEG: 1808 return "Ds"; 1809 case REVITDG: 1810 return "Dp"; 1811 default: 1812 return "invalid(" + ev + ")"; 1813 } 1814 case JAS: 1815 default: 1816 switch (ev) { 1817 case LEX: 1818 return "LEX"; 1819 case INVLEX: 1820 return "INVLEX"; 1821 case GRLEX: 1822 return "GRLEX"; 1823 case IGRLEX: 1824 return "IGRLEX"; 1825 case REVLEX: 1826 return "REVLEX"; 1827 case REVILEX: 1828 return "REVILEX"; 1829 case REVTDEG: 1830 return "REVTDEG"; 1831 case REVITDG: 1832 return "REVITDG"; 1833 case ITDEGLEX: 1834 return "ITDEGLEX"; 1835 case REVITDEG: 1836 return "REVITDEG"; 1837 default: 1838 return "invalid(" + ev + ")"; 1839 } 1840 } 1841 //return "invalid(" + ev + ")"; 1842 } 1843 1844 1845 /** 1846 * Extend variables. Used e.g. in module embedding. Extend TermOrder by k 1847 * elements. <b>Note:</b> Use POT module term order. 1848 * @param r current number of variables. 1849 * @param k number of variables to extend. 1850 * @return extended TermOrder. 1851 */ 1852 public TermOrder extend(int r, int k) { 1853 return extend(r, k, false); 1854 } 1855 1856 1857 /** 1858 * Extend variables. Used e.g. in module embedding. Extend TermOrder by k 1859 * elements. <b>Note:</b> Now TOP and POT orders are distinguished. 1860 * @param r current number of variables. 1861 * @param k number of variables to extend. 1862 * @param top true for TOP term order, false for POT term order. 1863 * @return extended TermOrder. 1864 */ 1865 public TermOrder extend(int r, int k, boolean top) { 1866 if (weight != null) { 1867 long[][] w = new long[weight.length][]; 1868 for (int i = 0; i < weight.length; i++) { 1869 long[] wi = weight[i]; 1870 long max = 0; 1871 // long min = Long.MAX_VALUE; 1872 for (int j = 0; j < wi.length; j++) { 1873 if (wi[j] > max) 1874 max = wi[j]; 1875 //if ( wi[j] < min ) min = wi[j]; 1876 } 1877 max++; 1878 long[] wj = new long[wi.length + k]; 1879 for (int j = 0; j < i; j++) { 1880 wj[j] = max; 1881 } 1882 System.arraycopy(wi, 0, wj, i, wi.length); 1883 w[i] = wj; 1884 } 1885 return new TermOrder(w); 1886 } 1887 if (evord2 != 0) { 1888 logger.debug("warn: TermOrder is already extended"); 1889 if (debug) { 1890 throw new IllegalArgumentException("TermOrder is already extended: " + this); 1891 } 1892 return new TermOrder(evord, evord2, r + k, evend1 + k, top); 1893 } 1894 //System.out.println("evord = " + evord); 1895 //System.out.println("DEFAULT_EVORD = " + DEFAULT_EVORD); 1896 //System.out.println("tord = " + this); 1897 return new TermOrder(DEFAULT_EVORD/*evord*/, evord, r + k, k, top); // todo param 1898 // don't change to evord, cause REVITDG 1899 } 1900 1901 1902 /** 1903 * Extend lower variables. Extend TermOrder by k elements. <b>Note:</b> todo 1904 * distinguish TOP and POT orders. 1905 * @param r current number of variables. 1906 * @param k number of variables to extend. 1907 * @return extended TermOrder. 1908 */ 1909 public TermOrder extendLower(int r, int k) { 1910 if (weight != null) { 1911 long[][] w = new long[weight.length][]; 1912 for (int i = 0; i < weight.length; i++) { 1913 long[] wi = weight[i]; 1914 //long max = 0; 1915 long min = Long.MAX_VALUE; 1916 for (int j = 0; j < wi.length; j++) { 1917 //if ( wi[j] > max ) max = wi[j]; 1918 if (wi[j] < min) 1919 min = wi[j]; 1920 } 1921 //max++; 1922 long[] wj = new long[wi.length + k]; 1923 for (int j = 0; j < i; j++) { 1924 wj[wi.length + j] = min; 1925 } 1926 System.arraycopy(wi, 0, wj, 0, wi.length); 1927 w[i] = wj; 1928 } 1929 return new TermOrder(w); 1930 } 1931 if (evord2 != 0) { 1932 if (debug) { 1933 logger.warn("TermOrder is already extended"); 1934 } 1935 return new TermOrder(evord, evord2, r + k, evend1 + k); 1936 } 1937 //System.out.println("evord = " + evord); 1938 //System.out.println("DEFAULT_EVORD = " + DEFAULT_EVORD); 1939 //System.out.println("tord = " + this); 1940 return new TermOrder(evord); 1941 } 1942 1943 1944 /** 1945 * Contract variables. Used e.g. in module embedding. Contract TermOrder to 1946 * non split status. 1947 * @param k position of first element to be copied. 1948 * @param len new length. 1949 * @return contracted TermOrder. 1950 */ 1951 public TermOrder contract(int k, int len) { 1952 if (weight != null) { 1953 long[][] w = new long[weight.length][]; 1954 for (int i = 0; i < weight.length; i++) { 1955 long[] wi = weight[i]; 1956 long[] wj = new long[len]; 1957 System.arraycopy(wi, k, wj, 0, len); 1958 w[i] = wj; 1959 } 1960 return new TermOrder(w); 1961 } 1962 if (evord2 == 0) { 1963 if (debug) { 1964 logger.warn("TermOrder is already contracted"); 1965 } 1966 return new TermOrder(evord); 1967 } 1968 if (evend1 > k) { // < IntMax since evord2 != 0 1969 int el = evend1 - k; 1970 while (el > len) { 1971 el -= len; 1972 } 1973 if (el == 0L) { 1974 return new TermOrder(evord); 1975 } 1976 if (el == len) { 1977 return new TermOrder(evord); 1978 } 1979 return new TermOrder(evord, evord2, len, el); 1980 } 1981 return new TermOrder(evord2); 1982 } 1983 1984 1985 /** 1986 * Reverse variables. Used e.g. in opposite rings. 1987 * @return TermOrder for reversed variables. 1988 */ 1989 public TermOrder reverse() { 1990 return reverse(false); 1991 } 1992 1993 1994 /** 1995 * Reverse variables. Used e.g. in opposite rings. 1996 * @param partial true for partialy reversed term orders. 1997 * @return TermOrder for reversed variables. 1998 */ 1999 public TermOrder reverse(boolean partial) { 2000 TermOrder t; 2001 if (weight != null) { 2002 if (partial) { 2003 logger.error("partial reversed weight order not implemented"); 2004 } 2005 long[][] w = new long[weight.length][]; 2006 for (int i = 0; i < weight.length; i++) { 2007 long[] wi = weight[i]; 2008 long[] wj = new long[wi.length]; 2009 for (int j = 0; j < wj.length; j++) { 2010 wj[j] = wi[wj.length - 1 - j]; 2011 } 2012 w[i] = wj; 2013 } 2014 t = new TermOrder(w); 2015 logger.info("reverse = " + t + ", from = " + this); 2016 return t; 2017 } 2018 if (evord2 == 0) { 2019 t = new TermOrder(revert(evord)); 2020 return t; 2021 } 2022 if (partial) { 2023 t = new TermOrder(revert(evord), revert(evord2), evend2, evend1); 2024 } else { 2025 t = new TermOrder(revert(evord2), revert(evord), evend2, evend2 - evbeg2); 2026 } 2027 logger.info("reverse = " + t + ", from = " + this); 2028 return t; 2029 } 2030 2031 2032 /** 2033 * Revert exponent order. Used e.g. in opposite rings. 2034 * @param evord exponent order to be reverted. 2035 * @return reverted exponent order. 2036 */ 2037 public static int revert(int evord) { 2038 int i = evord; 2039 switch (evord) { 2040 case LEX: 2041 i = REVLEX; 2042 break; 2043 case INVLEX: 2044 i = REVILEX; 2045 break; 2046 case GRLEX: 2047 i = REVTDEG; 2048 break; 2049 case IGRLEX: 2050 i = REVITDG; 2051 break; 2052 case REVLEX: 2053 i = LEX; 2054 break; 2055 case REVILEX: 2056 i = INVLEX; 2057 break; 2058 case REVTDEG: 2059 i = GRLEX; 2060 break; 2061 case REVITDG: 2062 i = IGRLEX; 2063 break; 2064 default: // REVITDEG, ITDEGLEX 2065 logger.error("can not revert " + evord); 2066 break; 2067 } 2068 return i; 2069 } 2070 2071 2072 /** 2073 * Permutation of a long array. 2074 * @param a array of long. 2075 * @param P permutation. 2076 * @return P(a). 2077 */ 2078 public static long[] longArrayPermutation(List<Integer> P, long[] a) { 2079 if (a == null || a.length <= 1) { 2080 return a; 2081 } 2082 long[] b = new long[a.length]; 2083 int j = 0; 2084 for (Integer i : P) { 2085 b[j] = a[i]; 2086 j++; 2087 } 2088 return b; 2089 } 2090 2091 2092 /** 2093 * Permutation of the termorder. 2094 * @param P permutation. 2095 * @return P(a). 2096 */ 2097 public TermOrder permutation(List<Integer> P) { 2098 TermOrder tord = this; 2099 if (getEvord2() != 0) { 2100 //throw new IllegalArgumentException("split term orders not permutable"); 2101 tord = new TermOrder(getEvord2()); 2102 logger.warn("split term order '" + this + "' not permutable, resetting to most base term order " 2103 + tord); 2104 } 2105 long[][] weight = getWeight(); 2106 if (weight != null) { 2107 long[][] w = new long[weight.length][]; 2108 for (int i = 0; i < weight.length; i++) { 2109 w[i] = longArrayPermutation(P, weight[i]); 2110 } 2111 tord = new TermOrder(w); 2112 } 2113 return tord; 2114 } 2115 2116 2117 /** 2118 * Weight TermOrder with reversed weight vectors. 2119 * @param w weight matrix 2120 * @return TermOrder with reversed weight vectors 2121 */ 2122 public static TermOrder reverseWeight(long[][] w) { 2123 if (w == null) { 2124 logger.warn("null weight matrix ignored"); 2125 return new TermOrder(); 2126 } 2127 long[][] wr = new long[w.length][]; 2128 for (int j = 0; j < w.length; j++) { 2129 long[] wj = w[j]; 2130 //System.out.println("reverseWeight: " + wj); 2131 long[] wrj = new long[wj.length]; 2132 for (int i = 0; i < wj.length; i++) { 2133 wrj[i] = wj[wj.length - 1 - i]; 2134 } 2135 wr[j] = wrj; 2136 } 2137 return new TermOrder(wr); 2138 } 2139 2140}