001/*
002 * $Id: TermOrderByName.java 5872 2018-07-20 16:01:46Z kredel $
003 */
004
005package edu.jas.poly;
006
007
008import java.util.List;
009
010import org.apache.logging.log4j.Logger;
011import org.apache.logging.log4j.LogManager; 
012
013
014/**
015 * Term order names for ordered polynomials. Defines names for the most used
016 * term orders: graded and lexicographical orders. For the definitions see for
017 * example the articles <a href="http://doi.acm.org/10.1145/43882.43887">Kredel
018 * "Admissible term orderings used in computer algebra systems"</a> and
019 * <a href="http://doi.acm.org/10.1145/70936.70941">Sit,
020 * "Some comments on term-ordering in Gr&ouml;bner basis computations"</a>. Not
021 * all algorithms may work with all term orders since not all are well-founded,
022 * so watch your step.
023 * 
024 * <b>Note:</b> Variables in printed JAS polynomial <b>(low, ..., medium, ...,
025 * high)</b> Variables in other CAS polynomial <b>(high, ..., medium, ...,
026 * low)</b> with <b>low</b> &lt; <b>medium</b> &lt; <b>high</b>. Example: for
027 * variables x<sub>1</sub>, ..., x<sub>r</sub> it is assumed in JAS that x
028 * <sub>1</sub> &lt; ... &lt; x<sub>r</sub> in other CAS it means x<sub>1</sub>
029 * &gt; ... &gt; x<sub>r</sub>.
030 * 
031 * @author Heinz Kredel
032 */
033
034public class TermOrderByName {
035
036
037    private static final Logger logger = LogManager.getLogger(TermOrderByName.class);
038
039
040    /**
041     * TermOrder named LEX.
042     */
043    public static final TermOrder LEX = new TermOrder(TermOrder.LEX);
044
045
046    /**
047     * TermOrder named INVLEX.
048     */
049    public static final TermOrder INVLEX = new TermOrder(TermOrder.INVLEX);
050
051
052    /**
053     * TermOrder named GRLEX.
054     */
055    public static final TermOrder GRLEX = new TermOrder(TermOrder.GRLEX);
056
057
058    /**
059     * TermOrder named IGRLEX.
060     */
061    public static final TermOrder IGRLEX = new TermOrder(TermOrder.IGRLEX);
062
063
064    /**
065     * TermOrder named REVLEX.
066     */
067    public static final TermOrder REVLEX = new TermOrder(TermOrder.REVLEX);
068
069
070    /**
071     * TermOrder named REVILEX.
072     */
073    public static final TermOrder REVILEX = new TermOrder(TermOrder.REVILEX);
074
075
076    /**
077     * TermOrder named REVTDEG.
078     */
079    public static final TermOrder REVTDEG = new TermOrder(TermOrder.REVTDEG);
080
081
082    /**
083     * TermOrder named REVITDG.
084     */
085    public static final TermOrder REVITDG = new TermOrder(TermOrder.REVITDG);
086
087
088    /**
089     * TermOrder named ITDEGLEX.
090     */
091    public static final TermOrder ITDEGLEX = new TermOrder(TermOrder.ITDEGLEX);
092
093
094    /**
095     * TermOrder named REVITDEG.
096     */
097    public static final TermOrder REVITDEG = new TermOrder(TermOrder.REVITDEG);
098
099
100    /**
101     * Default TermOrder.
102     */
103    public final static TermOrder DEFAULT = new TermOrder(TermOrder.DEFAULT_EVORD);
104
105
106    // Math like term orders:
107
108    /**
109     * TermOrder name Lexicographic of Math like CAS.
110     */
111    public final static TermOrder Lexicographic = REVILEX;
112
113
114    /**
115     * TermOrder name NegativeLexicographic of Math like CAS.
116     */
117    public final static TermOrder NegativeLexicographic = REVLEX;
118
119
120    /**
121     * TermOrder name DegreeLexicographic of Math like CAS.
122     */
123    public final static TermOrder DegreeLexicographic = REVITDG;
124
125
126    /**
127     * TermOrder name NegativeDegreeLexicographic of Math like CAS.
128     */
129    public final static TermOrder NegativeDegreeLexicographic = REVITDEG; // was REVTDEG;
130
131
132    /**
133     * TermOrder name ReverseLexicographic of Math like CAS.
134     */
135    public final static TermOrder ReverseLexicographic = INVLEX;
136
137
138    /**
139     * TermOrder name DegreeReverseLexicographic of Math like CAS.
140     */
141    public final static TermOrder DegreeReverseLexicographic = ITDEGLEX; // was IGRLEX;
142
143
144    /**
145     * TermOrder name NegativeReverseLexicographic of Math like CAS.
146     */
147    public final static TermOrder NegativeReverseLexicographic = LEX;
148
149
150    /**
151     * TermOrder name NegativeDegreeReverseLexicographic of Math like CAS.
152     */
153    public final static TermOrder NegativeDegreeReverseLexicographic = GRLEX;
154
155
156    // Sage term orders:
157
158    /**
159     * TermOrder name lex of Sage.
160     */
161    public final static TermOrder lex = Lexicographic; // = REVILEX; 
162
163
164    /**
165     * TermOrder name degrevlex of Sage.
166     */
167    public final static TermOrder degrevlex = DegreeReverseLexicographic; // = IGRLEX; 
168
169
170    /**
171     * TermOrder name deglex of Sage.
172     */
173    public final static TermOrder deglex = DegreeLexicographic; // = REVITDG; 
174
175
176    /**
177     * TermOrder name invlex of Sage.
178     */
179    public final static TermOrder invlex = INVLEX; //ReverseLexicographic  
180
181
182    /**
183     * TermOrder name neglex of Sage.
184     */
185    public final static TermOrder neglex = NegativeLexicographic; // = REVLEX; 
186
187
188    /**
189     * TermOrder name negdegrevlex of Sage.
190     */
191    public final static TermOrder negdegrevlex = NegativeDegreeReverseLexicographic; // = GRLEX;
192
193
194    /**
195     * TermOrder name negdeglex of Sage.
196     */
197    public final static TermOrder negdeglex = NegativeDegreeLexicographic; // = REVTDEG; 
198
199
200    /**
201     * TermOrder name negrevlex of Sage.
202     */
203    public final static TermOrder negrevlex = NegativeReverseLexicographic; // = LEX; 
204
205
206    // Singular term orders:
207
208    /**
209     * TermOrder name lp of Singular.
210     */
211    public final static TermOrder lp = lex; // = REVILEX; 
212
213
214    /**
215     * TermOrder name dp of Singular.
216     */
217    public final static TermOrder dp = degrevlex; // = IGRLEX; 
218
219
220    /**
221     * TermOrder name Dp of Singular.
222     */
223    public final static TermOrder Dp = deglex; // = REVITDG; 
224
225
226    /**
227     * TermOrder name rp of Singular.
228     */
229    public final static TermOrder rp = invlex; // = INVLEX;  
230
231
232    /**
233     * TermOrder name ls of Singular.
234     */
235    public final static TermOrder ls = neglex; // = REVLEX; 
236
237
238    /**
239     * TermOrder name ds of Singular.
240     */
241    public final static TermOrder ds = negdegrevlex; // = GRLEX;
242
243
244    /**
245     * TermOrder name Ds of Singular.
246     */
247    public final static TermOrder Ds = negdeglex; // = REVTDEG; 
248
249
250    // missing: public final static TermOrder negrevlex; // = LEX; 
251
252
253    /**
254     * Construct elimination block TermOrder. Variables {x<sub>1</sub>, ..., x
255     * <sub>s-1</sub>} &lt; {x<sub>s</sub>, ..., x<sub>r</sub>}
256     * 
257     * @param t1 term order for both blocks
258     * @param s split index
259     * @return constructed term order
260     */
261    public final static TermOrder blockOrder(TermOrder t1, int s) {
262        return t1.blockOrder(s);
263    }
264
265
266    /**
267     * Construct elimination block TermOrder. Variables {x<sub>1</sub>, ..., x
268     * <sub>s-1</sub>} &lt; {x<sub>s</sub>, ..., x<sub>r</sub>}
269     * 
270     * @param t1 term order for both blocks
271     * @param e exponent vector of desired length, r = length(e)
272     * @param s split index
273     * @return constructed term order
274     */
275    public final static TermOrder blockOrder(TermOrder t1, ExpVector e, int s) {
276        return t1.blockOrder(s, e.length());
277    }
278
279
280    /**
281     * Construct elimination block TermOrder. Variables {x<sub>1</sub>, ..., x
282     * <sub>s-1</sub>} &lt; {x<sub>s</sub>, ..., x<sub>r</sub>}
283     * 
284     * @param t1 term order for lower valiables
285     * @param t2 term order for higher variables
286     * @param s split index
287     * @return constructed term order
288     */
289    public final static TermOrder blockOrder(TermOrder t1, TermOrder t2, int s) {
290        return new TermOrder(t1.getEvord(), t2.getEvord(), Integer.MAX_VALUE, s);
291    }
292
293
294    /**
295     * Construct elimination block TermOrder. Variables {x<sub>1</sub>, ..., x
296     * <sub>s-1</sub>} &lt; {x<sub>s</sub>, ..., x<sub>r</sub>}
297     * 
298     * @param t1 term order for lower valiables
299     * @param t2 term order for higher variables
300     * @param e exponent vector of desired length, r = length(e)
301     * @param s split index
302     * @return constructed term order
303     */
304    public final static TermOrder blockOrder(TermOrder t1, TermOrder t2, ExpVector e, int s) {
305        return new TermOrder(t1.getEvord(), t2.getEvord(), e.length(), s);
306    }
307
308
309    /**
310     * Construct weight TermOrder.
311     * 
312     * @param v weight vector
313     * @return constructed term order
314     */
315    public final static TermOrder weightOrder(long[] v) {
316        return TermOrder.reverseWeight(new long[][] { v });
317    }
318
319
320    /**
321     * Construct weight TermOrder.
322     * 
323     * @param w weight matrix
324     * @return constructed term order
325     */
326    public final static TermOrder weightOrder(long[][] w) {
327        return TermOrder.reverseWeight(w);
328    }
329
330
331    /**
332     * Construct weight TermOrder.
333     * 
334     * @param wa weight matrix as List
335     * @return constructed term order
336     */
337    public final static TermOrder weightOrder(List<List<Long>> wa) {
338        int n = wa.size();
339        long[][] w = new long[n][];
340        for (int i = 0; i < n; i++) {
341            List<Long> row = wa.get(i);
342            int m = row.size();
343            long[] wi = new long[m];
344            for (int j = 0; j < m; j++) {
345                wi[j] = row.get(j);
346            }
347            w[i] = wi;
348        }
349        //return TermOrder.reverseWeight(w);
350        return weightOrder(w);
351    }
352
353
354    /**
355     * Construct weight for term order.
356     * @param to term order
357     * @param n exponent vector size
358     * @return weight matrix
359     */
360    public final static long[][] weightForOrder(TermOrder to, int n) {
361        if (to.isSplit()) {
362            return weightForSplitOrder(to.getEvord(), to.getEvord2(), n, to.getSplit());
363        }
364        return weightForOrder(to.getEvord(), n);
365    }
366
367
368    /**
369     * Construct weight for term order.
370     * @param to term order indicator
371     * @param n exponent vector size
372     * @return weight matrix
373     */
374    /*public*/ final static long[][] weightForOrder(int to, int n) {
375        int k = 0;
376        switch (to) {
377        case TermOrder.IGRLEX:
378            k = n + 1;
379            break;
380        case TermOrder.REVILEX:
381            // no break
382        case TermOrder.INVLEX:
383            k = n;
384            break;
385        default:
386        }
387        logger.info("to = " + to + ", k = " + k);
388        long[][] w = new long[k][];
389        long[] wi;
390        switch (to) {
391        case TermOrder.INVLEX:
392            for (int i = 0; i < n; i++) {
393                w[i] = new long[n];
394                wi = w[i];
395                for (int j = 0; j < n; j++) {
396                    if (i == j) { //n - 1 -
397                        wi[j] = 1L;
398                    } else {
399                        wi[j] = 0L;
400                    }
401                }
402            }
403            break;
404        case TermOrder.IGRLEX:
405            w[0] = new long[n];
406            wi = w[0];
407            for (int j = 0; j < n; j++) {
408                wi[j] = 1L;
409            }
410            for (int i = 0; i < n; i++) {
411                w[i + 1] = new long[n];
412                wi = w[i + 1];
413                for (int j = 0; j < n; j++) {
414                    if (i == j) { //n - 1 -
415                        wi[j] = 1L;
416                    } else {
417                        wi[j] = 0L;
418                    }
419                }
420            }
421            break;
422        case TermOrder.REVILEX:
423            for (int i = 0; i < n; i++) {
424                w[i] = new long[n];
425                wi = w[i];
426                for (int j = 0; j < n; j++) {
427                    if ((n - 1 - i) == j) {
428                        wi[j] = 1L;
429                    } else {
430                        wi[j] = 0L;
431                    }
432                }
433            }
434            break;
435        default:
436            throw new UnsupportedOperationException("case " + to + " not implemented for weightForOrder");
437        }
438        return w;
439    }
440
441
442    /**
443     * Construct weight for split term order.
444     * @param to1 first term order indicator
445     * @param to2 second term order indicator
446     * @param n exponent vector size
447     * @param s slpit index
448     * @return weight matrix
449     */
450    /*public*/ final static long[][] weightForSplitOrder(int to, int to2, int n, int s) {
451        int k = 0;
452        switch (to) {
453        case TermOrder.IGRLEX:
454            k += 1;
455            break;
456        case TermOrder.INVLEX:
457            k += s;
458            break;
459        default:
460        }
461        //System.out.println("to = " + to + ", k = " + k);
462        switch (to2) {
463        case TermOrder.IGRLEX:
464            k += 1;
465            break;
466        case TermOrder.INVLEX:
467            k += n - s;
468            break;
469        default:
470        }
471        logger.info("to = " + to + ", k = " + k);
472        //System.out.println("to = " + to + ", k = " + k);
473        long[][] w = new long[k + n][];
474        boolean done = true;
475        switch (to) {
476        case TermOrder.IGRLEX:
477            w[0] = new long[n];
478            long[] wi = w[0];
479            int j;
480            for (j = 0; j < s; j++) {
481                wi[j] = 1L;
482            }
483            for (; j < n; j++) {
484                wi[j] = 0L;
485            }
486            break;
487        case TermOrder.INVLEX:
488            for (int i = 0; i < s; i++) {
489                w[i] = new long[n];
490                wi = w[i]; // long[]
491                for (j = 0; j < n; j++) {
492                    if ((n - 1 - i) == j) {
493                        wi[j] = 1L;
494                    } else {
495                        wi[j] = 0L;
496                    }
497                }
498            }
499            break;
500        default:
501            done = false;
502            // compiler/run time error:
503            //throw new UnsupportedOperationException("case " + to + "/" + to2 + " not implemented for weightForOrder");
504            break;
505        }
506        switch (to2) {
507        case TermOrder.IGRLEX:
508            w[k - 1] = new long[n];
509            long[] wi = w[k - 1];
510            int j;
511            for (j = 0; j < s; j++) {
512                wi[j] = 0L;
513            }
514            for (; j < n; j++) {
515                wi[j] = 1L;
516            }
517            break;
518        case TermOrder.INVLEX:
519            for (int i = 0; i < s; i++) {
520                w[s + i] = new long[n];
521                wi = w[s + i]; // long[]
522                for (j = 0; j < n; j++) {
523                    if ((n - 1 - i) == (s + j)) {
524                        wi[j] = 1L;
525                    } else {
526                        wi[j] = 0L;
527                    }
528                }
529            }
530            break;
531        default:
532            done = false;
533            break;
534        }
535        if (!done) {
536            //System.out.println("weightForSplitOrder case " + to + "/" + to2);
537            throw new UnsupportedOperationException(
538                            "case " + to + "/" + to2 + " not implemented for weightForOrder");
539        }
540        //System.out.println("weight: " + Arrays.toString(w));
541        // break ties by inv lex term order
542        for (int i = 0; i < n; i++) {
543            w[k + i] = new long[n];
544            long[] wi = w[k + i];
545            for (int j = 0; j < n; j++) {
546                if ((i) == j) { //n - 1 - 
547                    wi[j] = 1L;
548                } else {
549                    wi[j] = 0L;
550                }
551            }
552        }
553        return w;
554    }
555
556}