001    /*
002     * $Id: ExpVectorLong.java 3295 2010-08-26 17:01:10Z kredel $
003     */
004    
005    package edu.jas.poly;
006    
007    
008    import java.util.Vector;
009    
010    
011    /**
012     * ExpVectorLong implements exponent vectors for polynomials using arrays of
013     * long as storage unit. This class is used by ExpVector internally, there is no
014     * need to use this class directly.
015     * @see ExpVector
016     * @author Heinz Kredel
017     */
018    
019    public class ExpVectorLong extends ExpVector
020    /*implements AbelianGroupElem<ExpVectorLong>*/{
021    
022    
023        /**
024         * The data structure is an array of longs.
025         */
026        /*package*/final long[] val;
027    
028    
029        /**
030         * Constructor for ExpVector.
031         * @param n length of exponent vector.
032         */
033        public ExpVectorLong(int n) {
034            this(new long[n]);
035        }
036    
037    
038        /**
039         * Constructor for ExpVector. Sets exponent i to e.
040         * @param n length of exponent vector.
041         * @param i index of exponent to be set.
042         * @param e exponent to be set.
043         */
044        public ExpVectorLong(int n, int i, long e) {
045            this(new long[n]);
046            val[i] = e;
047        }
048    
049    
050        /**
051         * Constructor for ExpVector. Sets val.
052         * @param v internal representation array.
053         */
054        public ExpVectorLong(long[] v) {
055            super();
056            if (v == null) {
057                throw new IllegalArgumentException("null val not allowed");
058            }
059            val = v;
060        }
061    
062    
063        /**
064         * Constructor for ExpVector. Converts a String representation to an
065         * ExpVector. Accepted format = (1,2,3,4,5,6,7).
066         * @param s String representation.
067         */
068        public ExpVectorLong(String s) throws NumberFormatException {
069            super();
070            // first format = (1,2,3,4,5,6,7)
071            Vector<Long> exps = new Vector<Long>();
072            s = s.trim();
073            int b = s.indexOf('(');
074            int e = s.indexOf(')', b + 1);
075            String teil;
076            int k;
077            long a;
078            if (b >= 0 && e >= 0) {
079                b++;
080                while ((k = s.indexOf(',', b)) >= 0) {
081                    teil = s.substring(b, k);
082                    a = Long.parseLong(teil);
083                    exps.add(new Long(a));
084                    b = k + 1;
085                }
086                if (b <= e) {
087                    teil = s.substring(b, e);
088                    a = Long.parseLong(teil);
089                    exps.add(new Long(a));
090                }
091                int length = exps.size();
092                val = new long[length];
093                for (int j = 0; j < length; j++) {
094                    val[j] = exps.elementAt(j).longValue();
095                }
096            } else {
097                // not implemented
098                val = null;
099                // length = -1;
100                //Vector names = new Vector();
101                //vars = s;
102            }
103        }
104    
105    
106        /**
107         * Clone this.
108         * @see java.lang.Object#clone()
109         */
110        @Override
111        public ExpVectorLong clone() {
112            long[] w = new long[val.length];
113            System.arraycopy(val, 0, w, 0, val.length);
114            return new ExpVectorLong(w);
115        }
116    
117    
118        /**
119         * Get the exponent vector.
120         * @return val.
121         */
122        @Override
123        /*package*/long[] getVal() {
124            return val;
125        }
126    
127    
128        /**
129         * Get the exponent at position i.
130         * @param i position.
131         * @return val[i].
132         */
133        @Override
134        public long getVal(int i) {
135            return val[i];
136        }
137    
138    
139        /**
140         * Set the exponent at position i to e.
141         * @param i
142         * @param e
143         * @return old val[i].
144         */
145        @Override
146        protected long setVal(int i, long e) {
147            long x = val[i];
148            val[i] = e;
149            hash = 0; // beware of race condition
150            return x;
151        }
152    
153    
154        /**
155         * Get the length of this exponent vector.
156         * @return val.length.
157         */
158        @Override
159        public int length() {
160            return val.length;
161        }
162    
163    
164        /**
165         * Extend variables. Used e.g. in module embedding. Extend this by i
166         * elements and set val[j] to e.
167         * @param i number of elements to extend.
168         * @param j index of element to be set.
169         * @param e new exponent for val[j].
170         * @return extended exponent vector.
171         */
172        @Override
173        public ExpVectorLong extend(int i, int j, long e) {
174            long[] w = new long[val.length + i];
175            System.arraycopy(val, 0, w, i, val.length);
176            if (j >= i) {
177                throw new IllegalArgumentException("i " + i + " <= j " + j + " invalid");
178            }
179            w[j] = e;
180            return new ExpVectorLong(w);
181        }
182    
183    
184        /**
185         * Extend lower variables. Extend this by i lower elements and set val[j] to
186         * e.
187         * @param i number of elements to extend.
188         * @param j index of element to be set.
189         * @param e new exponent for val[j].
190         * @return extended exponent vector.
191         */
192        @Override
193        public ExpVectorLong extendLower(int i, int j, long e) {
194            long[] w = new long[val.length + i];
195            System.arraycopy(val, 0, w, 0, val.length);
196            if (j >= i) {
197                throw new IllegalArgumentException("i " + i + " <= j " + j + " invalid");
198            }
199            w[val.length + j] = e;
200            return new ExpVectorLong(w);
201        }
202    
203    
204        /**
205         * Contract variables. Used e.g. in module embedding. Contract this to len
206         * elements.
207         * @param i position of first element to be copied.
208         * @param len new length.
209         * @return contracted exponent vector.
210         */
211        @Override
212        public ExpVectorLong contract(int i, int len) {
213            if (i + len > val.length) {
214                throw new IllegalArgumentException("len " + len + " > val.len " + val.length);
215            }
216            long[] w = new long[len];
217            System.arraycopy(val, i, w, 0, len);
218            return new ExpVectorLong(w);
219        }
220    
221    
222        /**
223         * Reverse variables. Used e.g. in opposite rings.
224         * @return reversed exponent vector.
225         */
226        @Override
227        public ExpVectorLong reverse() {
228            long[] w = new long[val.length];
229            for (int i = 0; i < val.length; i++) {
230                w[i] = val[val.length - 1 - i];
231            }
232            return new ExpVectorLong(w);
233        }
234    
235    
236        /**
237         * Reverse j variables. Used e.g. in opposite rings. Reverses the first j-1
238         * variables, the rest is unchanged.
239         * @param j index of first variable not reversed.
240         * @return reversed exponent vector.
241         */
242        @Override
243        public ExpVectorLong reverse(int j) {
244            if (j <= 0 || j > val.length) {
245                return this;
246            }
247            long[] w = new long[val.length];
248            for (int i = 0; i < j; i++) {
249                w[i] = val[j - 1 - i];
250            }
251            // copy rest
252            for (int i = j; i < val.length; i++) {
253                w[i] = val[i];
254            }
255            return new ExpVectorLong(w);
256        }
257    
258    
259        /**
260         * Combine with ExpVector. Combine this with the other ExpVector V.
261         * @param V the other exponent vector.
262         * @return combined exponent vector.
263         */
264        @Override
265        public ExpVectorLong combine(ExpVector V) {
266            if (V == null || V.length() == 0) {
267                return this;
268            }
269            ExpVectorLong Vl = (ExpVectorLong) V;
270            if (val.length == 0) {
271                return Vl;
272            }
273            long[] w = new long[val.length + Vl.val.length];
274            System.arraycopy(val, 0, w, 0, val.length);
275            System.arraycopy(Vl.val, 0, w, val.length, Vl.val.length);
276            return new ExpVectorLong(w);
277        }
278    
279    
280        /**
281         * Get the string representation.
282         * @see java.lang.Object#toString()
283         */
284        @Override
285        public String toString() {
286            return super.toString() + ":long";
287        }
288    
289    
290        /**
291         * Comparison with any other object.
292         * @see java.lang.Object#equals(java.lang.Object)
293         */
294        @Override
295        public boolean equals(Object B) {
296            if (!(B instanceof ExpVectorLong)) {
297                return false;
298            }
299            ExpVectorLong b = (ExpVectorLong) B;
300            int t = this.invLexCompareTo(b);
301            //System.out.println("equals: this = " + this + " B = " + B + " t = " + t);
302            return (0 == t);
303        }
304    
305    
306        /**
307         * ExpVector absolute value.
308         * @return abs(this).
309         */
310        @Override
311        public ExpVectorLong abs() {
312            long[] u = val;
313            long[] w = new long[u.length];
314            for (int i = 0; i < u.length; i++) {
315                if (u[i] >= 0L) {
316                    w[i] = u[i];
317                } else {
318                    w[i] = -u[i];
319                }
320            }
321            return new ExpVectorLong(w);
322            //return EVABS(this);
323        }
324    
325    
326        /**
327         * ExpVector negate.
328         * @return -this.
329         */
330        @Override
331        public ExpVectorLong negate() {
332            long[] u = val;
333            long[] w = new long[u.length];
334            for (int i = 0; i < u.length; i++) {
335                w[i] = -u[i];
336            }
337            return new ExpVectorLong(w);
338            // return EVNEG(this);
339        }
340    
341    
342        /**
343         * ExpVector summation.
344         * @param V
345         * @return this+V.
346         */
347        @Override
348        public ExpVectorLong sum(ExpVector V) {
349            long[] u = val;
350            long[] v = ((ExpVectorLong) V).val;
351            long[] w = new long[u.length];
352            for (int i = 0; i < u.length; i++) {
353                w[i] = u[i] + v[i];
354            }
355            return new ExpVectorLong(w);
356            // return EVSUM(this, V);
357        }
358    
359    
360        /**
361         * ExpVector subtract. Result may have negative entries.
362         * @param V
363         * @return this-V.
364         */
365        @Override
366        public ExpVectorLong subtract(ExpVector V) {
367            long[] u = val;
368            long[] v = ((ExpVectorLong) V).val;
369            long[] w = new long[u.length];
370            for (int i = 0; i < u.length; i++) {
371                w[i] = u[i] - v[i];
372            }
373            return new ExpVectorLong(w);
374            //return EVDIF(this, V);
375        }
376    
377    
378        /**
379         * ExpVector substitution. Clone and set exponent to d at position i.
380         * @param i position.
381         * @param d new exponent.
382         * @return substituted ExpVector.
383         */
384        @Override
385        public ExpVectorLong subst(int i, long d) {
386            ExpVectorLong V = (ExpVectorLong) this.clone();
387            long e = V.setVal(i, d);
388            return V;
389            //return EVSU(this, i, d);
390        }
391    
392    
393        /**
394         * ExpVector signum.
395         * @return 0 if this is zero, -1 if some entry is negative, 1 if no entry is
396         *         negative and at least one entry is positive.
397         */
398        @Override
399        public int signum() {
400            int t = 0;
401            long[] u = val;
402            for (int i = 0; i < u.length; i++) {
403                if (u[i] < 0) {
404                    return -1;
405                }
406                if (u[i] > 0) {
407                    t = 1;
408                }
409            }
410            return t;
411            //return EVSIGN(this);
412        }
413    
414    
415        /**
416         * ExpVector total degree.
417         * @return sum of all exponents.
418         */
419        @Override
420        public long totalDeg() {
421            long t = 0;
422            long[] u = val; // U.val;
423            for (int i = 0; i < u.length; i++) {
424                t += u[i];
425            }
426            return t;
427            //return EVTDEG(this);
428        }
429    
430    
431        /**
432         * ExpVector maximal degree.
433         * @return maximal exponent.
434         */
435        @Override
436        public long maxDeg() {
437            long t = 0;
438            long[] u = val;
439            for (int i = 0; i < u.length; i++) {
440                if (u[i] > t) {
441                    t = u[i];
442                }
443            }
444            return t;
445            //return EVMDEG(this);
446        }
447    
448    
449        /**
450         * ExpVector weighted degree.
451         * @param w weights.
452         * @return weighted sum of all exponents.
453         */
454        @Override
455        public long weightDeg(long[][] w) {
456            if (w == null || w.length == 0) {
457                return totalDeg(); // assume weight 1 
458            }
459            long t = 0;
460            long[] u = val;
461            for (int j = 0; j < w.length; j++) {
462                long[] wj = w[j];
463                for (int i = 0; i < u.length; i++) {
464                    t += wj[i] * u[i];
465                }
466            }
467            return t;
468            //return EVWDEG( w, this );
469        }
470    
471    
472        /**
473         * ExpVector least common multiple.
474         * @param V
475         * @return component wise maximum of this and V.
476         */
477        @Override
478        public ExpVectorLong lcm(ExpVector V) {
479            long[] u = val;
480            long[] v = ((ExpVectorLong) V).val;
481            long[] w = new long[u.length];
482            for (int i = 0; i < u.length; i++) {
483                w[i] = (u[i] >= v[i] ? u[i] : v[i]);
484            }
485            return new ExpVectorLong(w);
486            //return EVLCM(this, V);
487        }
488    
489    
490        /**
491         * ExpVector greatest common divisor.
492         * @param V
493         * @return component wise minimum of this and V.
494         */
495        @Override
496        public ExpVectorLong gcd(ExpVector V) {
497            long[] u = val;
498            long[] v = ((ExpVectorLong) V).val;
499            long[] w = new long[u.length];
500            for (int i = 0; i < u.length; i++) {
501                w[i] = (u[i] <= v[i] ? u[i] : v[i]);
502            }
503            return new ExpVectorLong(w);
504            //return EVGCD(this, V);
505        }
506    
507    
508        /**
509         * ExpVector dependency on variables.
510         * @return array of indices where val has positive exponents.
511         */
512        @Override
513        public int[] dependencyOnVariables() {
514            long[] u = val;
515            int l = 0;
516            for (int i = 0; i < u.length; i++) {
517                if (u[i] > 0) {
518                    l++;
519                }
520            }
521            int[] dep = new int[l];
522            if (l == 0) {
523                return dep;
524            }
525            int j = 0;
526            for (int i = 0; i < u.length; i++) {
527                if (u[i] > 0) {
528                    dep[j] = i;
529                    j++;
530                }
531            }
532            return dep;
533        }
534    
535    
536        /**
537         * ExpVector multiple test. Test if this is component wise greater or equal
538         * to V.
539         * @param V
540         * @return true if this is a multiple of V, else false.
541         */
542        @Override
543        public boolean multipleOf(ExpVector V) {
544            long[] u = val;
545            long[] v = ((ExpVectorLong) V).val;
546            boolean t = true;
547            for (int i = 0; i < u.length; i++) {
548                if (u[i] < v[i]) {
549                    return false;
550                }
551            }
552            return t;
553            //return EVMT(this, V);
554        }
555    
556    
557        /**
558         * ExpVector compareTo.
559         * @param V
560         * @return 0 if U == V, -1 if U &lt; V, 1 if U &gt; V.
561         */
562        //@Override
563        public int compareTo(ExpVectorLong V) {
564            return this.invLexCompareTo(V);
565        }
566    
567    
568        /**
569         * ExpVector inverse lexicographical compareTo.
570         * @param V
571         * @return 0 if U == V, -1 if U &lt; V, 1 if U &gt; V.
572         */
573        @Override
574        public int invLexCompareTo(ExpVector V) {
575            long[] u = val;
576            long[] v = ((ExpVectorLong) V).val;
577            int t = 0;
578            for (int i = 0; i < u.length; i++) {
579                if (u[i] > v[i])
580                    return 1;
581                if (u[i] < v[i])
582                    return -1;
583            }
584            return t;
585            //return EVILCP(this, V);
586        }
587    
588    
589        /**
590         * ExpVector inverse lexicographical compareTo.
591         * @param V
592         * @param begin
593         * @param end
594         * @return 0 if U == V, -1 if U &lt; V, 1 if U &gt; V.
595         */
596        @Override
597        public int invLexCompareTo(ExpVector V, int begin, int end) {
598            long[] u = val;
599            long[] v = ((ExpVectorLong) V).val;
600            int t = 0;
601            for (int i = begin; i < end; i++) {
602                if (u[i] > v[i])
603                    return 1;
604                if (u[i] < v[i])
605                    return -1;
606            }
607            return t;
608            //return EVILCP(this, V, begin, end);
609        }
610    
611    
612        /**
613         * ExpVector inverse graded lexicographical compareTo.
614         * @param V
615         * @return 0 if U == V, -1 if U &lt; V, 1 if U &gt; V.
616         */
617        @Override
618        public int invGradCompareTo(ExpVector V) {
619            long[] u = val;
620            long[] v = ((ExpVectorLong) V).val;
621            int t = 0;
622            int i;
623            for (i = 0; i < u.length; i++) {
624                if (u[i] > v[i]) {
625                    t = 1;
626                    break;
627                }
628                if (u[i] < v[i]) {
629                    t = -1;
630                    break;
631                }
632            }
633            if (t == 0) {
634                return t;
635            }
636            long up = 0;
637            long vp = 0;
638            for (int j = i; j < u.length; j++) {
639                up += u[j];
640                vp += v[j];
641            }
642            if (up > vp) {
643                t = 1;
644            } else {
645                if (up < vp) {
646                    t = -1;
647                }
648            }
649            return t;
650            //return EVIGLC(this, V);
651        }
652    
653    
654        /**
655         * ExpVector inverse graded lexicographical compareTo.
656         * @param V
657         * @param begin
658         * @param end
659         * @return 0 if U == V, -1 if U &lt; V, 1 if U &gt; V.
660         */
661        @Override
662        public int invGradCompareTo(ExpVector V, int begin, int end) {
663            long[] u = val;
664            long[] v = ((ExpVectorLong) V).val;
665            int t = 0;
666            int i;
667            for (i = begin; i < end; i++) {
668                if (u[i] > v[i]) {
669                    t = 1;
670                    break;
671                }
672                if (u[i] < v[i]) {
673                    t = -1;
674                    break;
675                }
676            }
677            if (t == 0) {
678                return t;
679            }
680            long up = 0;
681            long vp = 0;
682            for (int j = i; j < end; j++) {
683                up += u[j];
684                vp += v[j];
685            }
686            if (up > vp) {
687                t = 1;
688            } else {
689                if (up < vp) {
690                    t = -1;
691                }
692            }
693            return t;
694            //return EVIGLC(this, V, begin, end);
695        }
696    
697    
698        /**
699         * ExpVector reverse inverse lexicographical compareTo.
700         * @param V
701         * @return 0 if U == V, -1 if U &lt; V, 1 if U &gt; V.
702         */
703        @Override
704        public int revInvLexCompareTo(ExpVector V) {
705            long[] u = val;
706            long[] v = ((ExpVectorLong) V).val;
707            int t = 0;
708            for (int i = u.length - 1; i >= 0; i--) {
709                if (u[i] > v[i])
710                    return 1;
711                if (u[i] < v[i])
712                    return -1;
713            }
714            return t;
715            //return EVRILCP(this, V);
716        }
717    
718    
719        /**
720         * ExpVector reverse inverse lexicographical compareTo.
721         * @param V
722         * @param begin
723         * @param end
724         * @return 0 if U == V, -1 if U &lt; V, 1 if U &gt; V.
725         */
726        @Override
727        public int revInvLexCompareTo(ExpVector V, int begin, int end) {
728            long[] u = val;
729            long[] v = ((ExpVectorLong) V).val;
730            int t = 0;
731            for (int i = end - 1; i >= begin; i--) {
732                if (u[i] > v[i])
733                    return 1;
734                if (u[i] < v[i])
735                    return -1;
736            }
737            return t;
738            //return EVRILCP(this, V, begin, end);
739        }
740    
741    
742        /**
743         * ExpVector reverse inverse graded compareTo.
744         * @param V
745         * @return 0 if U == V, -1 if U &lt; V, 1 if U &gt; V.
746         */
747        @Override
748        public int revInvGradCompareTo(ExpVector V) {
749            long[] u = val;
750            long[] v = ((ExpVectorLong) V).val;
751            int t = 0;
752            int i;
753            for (i = u.length - 1; i >= 0; i--) {
754                if (u[i] > v[i]) {
755                    t = 1;
756                    break;
757                }
758                if (u[i] < v[i]) {
759                    t = -1;
760                    break;
761                }
762            }
763            if (t == 0) {
764                return t;
765            }
766            long up = 0;
767            long vp = 0;
768            for (int j = i; j >= 0; j--) {
769                up += u[j];
770                vp += v[j];
771            }
772            if (up > vp) {
773                t = 1;
774            } else {
775                if (up < vp) {
776                    t = -1;
777                }
778            }
779            return t;
780            //return EVRIGLC(this, V);
781        }
782    
783    
784        /**
785         * ExpVector reverse inverse graded compareTo.
786         * @param V
787         * @param begin
788         * @param end
789         * @return 0 if U == V, -1 if U &lt; V, 1 if U &gt; V.
790         */
791        @Override
792        public int revInvGradCompareTo(ExpVector V, int begin, int end) {
793            long[] u = val;
794            long[] v = ((ExpVectorLong) V).val;
795            int t = 0;
796            int i;
797            for (i = end - 1; i >= begin; i--) {
798                if (u[i] > v[i]) {
799                    t = 1;
800                    break;
801                }
802                if (u[i] < v[i]) {
803                    t = -1;
804                    break;
805                }
806            }
807            if (t == 0) {
808                return t;
809            }
810            long up = 0;
811            long vp = 0;
812            for (int j = i; j >= begin; j--) {
813                up += u[j];
814                vp += v[j];
815            }
816            if (up > vp) {
817                t = 1;
818            } else {
819                if (up < vp) {
820                    t = -1;
821                }
822            }
823            return t;
824            //return EVRIGLC(this, V, begin, end);
825        }
826    
827    
828        /**
829         * ExpVector inverse weighted lexicographical compareTo.
830         * @param w weight array.
831         * @param V
832         * @return 0 if U == V, -1 if U &lt; V, 1 if U &gt; V.
833         */
834        @Override
835        public int invWeightCompareTo(long[][] w, ExpVector V) {
836            long[] u = val;
837            long[] v = ((ExpVectorLong) V).val;
838            int t = 0;
839            int i;
840            for (i = 0; i < u.length; i++) {
841                if (u[i] > v[i]) {
842                    t = 1;
843                    break;
844                }
845                if (u[i] < v[i]) {
846                    t = -1;
847                    break;
848                }
849            }
850            if (t == 0) {
851                return t;
852            }
853            for (int k = 0; k < w.length; k++) {
854                long[] wk = w[k];
855                long up = 0;
856                long vp = 0;
857                for (int j = i; j < u.length; j++) {
858                    up += wk[j] * u[j];
859                    vp += wk[j] * v[j];
860                }
861                if (up > vp) {
862                    return 1;
863                } else if (up < vp) {
864                    return -1;
865                }
866            }
867            return t;
868            //return EVIWLC(w, this, V);
869        }
870    
871    
872        /**
873         * ExpVector inverse weighted lexicographical compareTo.
874         * @param w weight array.
875         * @param V
876         * @param begin
877         * @param end
878         * @return 0 if U == V, -1 if U &lt; V, 1 if U &gt; V.
879         */
880        @Override
881        public int invWeightCompareTo(long[][] w, ExpVector V, int begin, int end) {
882            long[] u = val;
883            long[] v = ((ExpVectorLong) V).val;
884            int t = 0;
885            int i;
886            for (i = begin; i < end; i++) {
887                if (u[i] > v[i]) {
888                    t = 1;
889                    break;
890                }
891                if (u[i] < v[i]) {
892                    t = -1;
893                    break;
894                }
895            }
896            if (t == 0) {
897                return t;
898            }
899            for (int k = 0; k < w.length; k++) {
900                long[] wk = w[k];
901                long up = 0;
902                long vp = 0;
903                for (int j = i; j < end; j++) {
904                    up += wk[j] * u[j];
905                    vp += wk[j] * v[j];
906                }
907                if (up > vp) {
908                    return 1;
909                } else if (up < vp) {
910                    return -1;
911                }
912            }
913            return t;
914            //return EVIWLC(w, this, V, begin, end);
915        }
916    
917    }