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