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