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