001    /*
002     * $Id: ColorPolynomial.java 3426 2010-12-24 13:17:58Z kredel $
003     */
004    
005    package edu.jas.application;
006    
007    
008    import java.util.ArrayList;
009    import java.util.Collection;
010    import java.util.Comparator;
011    import java.util.List;
012    import java.util.Map;
013    
014    import edu.jas.poly.ExpVector;
015    import edu.jas.poly.GenPolynomial;
016    import edu.jas.structure.RingElem;
017    
018    
019    /**
020     * Colored Polynomials with green, red and white coefficients. Not implementing
021     * RingElem. <b>Note:</b> not general purpose, use only in comprehensive GB.
022     * @param <C> coefficient type
023     * @author Heinz Kredel
024     */
025    
026    public class ColorPolynomial<C extends RingElem<C>>
027        /* implements RingElem< ColorPolynomial<C> > */ {
028    
029    
030        /**
031         * The part with green (= zero) terms and coefficients.
032         */
033        public final GenPolynomial<GenPolynomial<C>> green;
034    
035    
036        /**
037         * The part with red (= non zero) terms and coefficients.
038         */
039        public final GenPolynomial<GenPolynomial<C>> red;
040    
041    
042        /**
043         * The part with white (= unknown color) terms and coefficients.
044         */
045        public final GenPolynomial<GenPolynomial<C>> white;
046    
047    
048        /**
049         * The constructor creates a colored polynomial from the colored parts.
050         * @param g green colored terms and coefficients.
051         * @param r red colored terms and coefficients.
052         * @param w white colored terms and coefficients.
053         */
054        public ColorPolynomial(GenPolynomial<GenPolynomial<C>> g,
055                GenPolynomial<GenPolynomial<C>> r, GenPolynomial<GenPolynomial<C>> w) {
056            if (g == null || r == null || w == null) {
057                throw new IllegalArgumentException("g,r,w may not be null");
058            }
059            green = g;
060            red = r;
061            white = w;
062        }
063    
064    
065        /**
066         * String representation of GenPolynomial.
067         * @see java.lang.Object#toString()
068         */
069        @Override
070        public String toString() {
071            StringBuffer s = new StringBuffer();
072            s.append(":green: ");
073            s.append(green.toString());
074            s.append(" :red: ");
075            s.append(red.toString());
076            s.append(" :white: ");
077            s.append(white.toString());
078            return s.toString();
079        }
080    
081    
082        /**
083         * Is this polynomial ZERO.
084         * @return true, if there are only green terms, else false.
085         */
086        public boolean isZERO() {
087            return (red.isZERO() && white.isZERO());
088        }
089    
090    
091        /**
092         * Is this polynomial ONE.
093         * @return true, if the only non green term is 1, else false.
094         */
095        public boolean isONE() {
096            return ((red.isZERO() && white.isONE()) || (red.isONE() && white.isZERO()));
097        }
098    
099    
100        /**
101         * Is this polynomial equal to other.
102         * @param p other polynomial.
103         * @return true, if this is equal to other, else false.
104         */
105        @Override
106        @SuppressWarnings("unchecked")
107        public boolean equals(Object p) {
108            ColorPolynomial<C> cp = null;
109            try {
110                cp = (ColorPolynomial<C>) p;
111            } catch (ClassCastException e) {
112                return false;
113            }
114            if (cp == null) {
115                return false;
116            }
117            return (green.equals(cp.green) && red.equals(cp.red) && white.equals(cp.white));
118        }
119    
120    
121        /**
122         * Hash code for this colored polynomial.
123         * @see java.lang.Object#hashCode()
124         */
125        @Override
126        public int hashCode() {
127            int h;
128            h = green.hashCode();
129            h = h << 11;
130            h += red.hashCode();
131            h = h << 11;
132            h += white.hashCode();
133            return h;
134        }
135    
136    
137        /**
138         * Is this polynomial determined.
139         * @return true, if there are nonzero red terms or if this == 0, else false.
140         */
141        public boolean isDetermined() {
142            return (!red.isZERO() || white.isZERO());
143        }
144    
145    
146        /**
147         * Check ordering invariants. TT(green) > LT(red) and TT(red) > LT(white).
148         * @return true, if all ordering invariants are met, else false.
149         */
150        public boolean checkInvariant() {
151            boolean t = true;
152            ExpVector ttg, ltr, ttr, ltw;
153            Comparator<ExpVector> cmp;
154            if (green.isZERO() && red.isZERO() && white.isZERO()) {
155                return true;
156            }
157            if (green.isZERO() && red.isZERO()) {
158                return true;
159            }
160            if (red.isZERO() && white.isZERO()) {
161                return true;
162            }
163    
164            if (!green.isZERO() && !red.isZERO()) {
165                ttg = green.trailingExpVector();
166                ltr = red.leadingExpVector();
167                cmp = green.ring.tord.getDescendComparator();
168                t = t && (cmp.compare(ttg, ltr) < 0);
169            }
170            if (!red.isZERO() && !white.isZERO()) {
171                ttr = red.trailingExpVector();
172                ltw = white.leadingExpVector();
173                cmp = white.ring.tord.getDescendComparator();
174                t = t && (cmp.compare(ttr, ltw) < 0);
175            }
176            if (red.isZERO() && !green.isZERO() && !white.isZERO()) {
177                ttg = green.trailingExpVector();
178                ltw = white.leadingExpVector();
179                cmp = white.ring.tord.getDescendComparator();
180                t = t && (cmp.compare(ttg, ltw) < 0);
181            }
182            if (!t) {
183                System.out.println("not invariant " + this);
184                // throw new RuntimeException("test");
185            }
186            return t;
187        }
188    
189    
190        /**
191         * Get zero condition on coefficients.
192         * @return green coefficients.
193         */
194        public List<GenPolynomial<C>> getGreenCoefficients() {
195            Collection<GenPolynomial<C>> c = green.getMap().values();
196            return new ArrayList<GenPolynomial<C>>(c);
197        }
198    
199    
200        /**
201         * Get non zero condition on coefficients.
202         * @return red coefficients.
203         */
204        public List<GenPolynomial<C>> getRedCoefficients() {
205            Collection<GenPolynomial<C>> c = red.getMap().values();
206            return new ArrayList<GenPolynomial<C>>(c);
207        }
208    
209    
210        /**
211         * Get full polynomial.
212         * @return sum of all parts.
213         */
214        public GenPolynomial<GenPolynomial<C>> getPolynomial() {
215            GenPolynomial<GenPolynomial<C>> f = green.sum(red).sum(white);
216            int s = green.length() + red.length() + white.length();
217            int t = f.length();
218            if (t != s) {
219                throw new RuntimeException("illegal coloring state " + s + " != " + t);
220            }
221            return f;
222        }
223    
224    
225        /**
226         * Get essential polynomial.
227         * @return sum of red and white parts.
228         */
229        public GenPolynomial<GenPolynomial<C>> getEssentialPolynomial() {
230            GenPolynomial<GenPolynomial<C>> f = red.sum(white);
231            int s = red.length() + white.length();
232            int t = f.length();
233            if (t != s) {
234                throw new RuntimeException("illegal coloring state " + s + " != " + t);
235            }
236            return f;
237        }
238    
239    
240        /**
241         * Length of red and white parts.
242         * @return length of essential parts.
243         */
244        public int length() {
245            int s = red.length() + white.length();
246            return s;
247        }
248    
249    
250        /**
251         * Get leading exponent vector.
252         * @return LT of red or white parts.
253         */
254        public ExpVector leadingExpVector() {
255            if (!red.isZERO()) {
256                return red.leadingExpVector();
257            }
258            return white.leadingExpVector();
259        }
260    
261    
262        /**
263         * Get leading monomial.
264         * @return LM of red or white parts.
265         */
266        public Map.Entry<ExpVector, GenPolynomial<C>> leadingMonomial() {
267            if (!red.isZERO()) {
268                return red.leadingMonomial();
269            }
270            return white.leadingMonomial();
271        }
272    
273    
274        /**
275         * ColorPolynomial absolute value.
276         * @return abs(this).
277         */
278        public ColorPolynomial<C> abs() {
279            GenPolynomial<GenPolynomial<C>> g, r, w;
280            int s = green.signum();
281            if (s > 0) {
282                return this;
283            }
284            if (s < 0) {
285                g = green.negate();
286                r = red.negate();
287                w = white.negate();
288                return new ColorPolynomial<C>(g, r, w);
289            }
290            // green == 0
291            g = green;
292            s = red.signum();
293            if (s > 0) {
294                return this;
295            }
296            if (s < 0) {
297                r = red.negate();
298                w = white.negate();
299                return new ColorPolynomial<C>(g, r, w);
300            }
301            // red == 0
302            r = red;
303            s = white.signum();
304            if (s > 0) {
305                return this;
306            }
307            if (s < 0) {
308                w = white.negate();
309                return new ColorPolynomial<C>(g, r, w);
310            }
311            // white == 0
312            w = white;
313            return new ColorPolynomial<C>(g, r, w);
314        }
315    
316    
317        /**
318         * ColorPolynomial summation. <b>Note:</b> green coefficients stay green,
319         * all others become white.
320         * @param S ColorPolynomial.
321         * @return this+S.
322         */
323        public ColorPolynomial<C> sum(ColorPolynomial<C> S) {
324            GenPolynomial<GenPolynomial<C>> g, r, w;
325            g = green.sum(S.green);
326            r = red.ring.getZERO();
327            w = getEssentialPolynomial().sum(S.getEssentialPolynomial());
328            return new ColorPolynomial<C>(g, r, w);
329        }
330    
331    
332        /**
333         * ColorPolynomial summation.
334         * @param s GenPolynomial.
335         * @param e exponent vector.
336         * @return this+(c e).
337         */
338        public ColorPolynomial<C> sum(GenPolynomial<C> s, ExpVector e) {
339            GenPolynomial<GenPolynomial<C>> g, r, w;
340            g = green;
341            r = red;
342            w = white;
343            if (green.getMap().keySet().contains(e)) {
344                g = green.sum(s, e);
345            } else if (red.getMap().keySet().contains(e)) {
346                r = red.sum(s, e);
347            } else {
348                w = white.sum(s, e);
349            }
350            return new ColorPolynomial<C>(g, r, w);
351        }
352    
353    
354        /**
355         * ColorPolynomial subtraction. <b>Note:</b> green coefficients stay green,
356         * all others become white.
357         * @param S ColorPolynomial.
358         * @return this-S.
359         */
360        public ColorPolynomial<C> subtract(ColorPolynomial<C> S) {
361            GenPolynomial<GenPolynomial<C>> g, r, w;
362            g = green.subtract(S.green);
363            r = red.ring.getZERO();
364            w = getEssentialPolynomial().subtract(S.getEssentialPolynomial());
365            return new ColorPolynomial<C>(g, r, w);
366        }
367    
368    
369        /**
370         * ColorPolynomial subtract.
371         * @param s GenPolynomial.
372         * @param e exponent vector.
373         * @return this-(c e).
374         */
375        public ColorPolynomial<C> subtract(GenPolynomial<C> s, ExpVector e) {
376            GenPolynomial<GenPolynomial<C>> g, r, w;
377            g = green;
378            r = red;
379            w = white;
380            if (green.getMap().keySet().contains(e)) {
381                g = green.subtract(s, e);
382            } else if (red.getMap().keySet().contains(e)) {
383                r = red.subtract(s, e);
384            } else {
385                w = white.subtract(s, e);
386            }
387            return new ColorPolynomial<C>(g, r, w);
388        }
389    
390    
391        /**
392         * ColorPolynomial multiplication by monomial.
393         * @param s Coefficient.
394         * @param e Expvector.
395         * @return this * (c t).
396         */
397        public ColorPolynomial<C> multiply(GenPolynomial<C> s, ExpVector e) {
398            GenPolynomial<GenPolynomial<C>> g, r, w;
399            g = green.multiply(s, e);
400            r = red.multiply(s, e);
401            w = white.multiply(s, e);
402            return new ColorPolynomial<C>(g, r, w);
403        }
404    
405    
406        /**
407         * ColorPolynomial multiplication by coefficient.
408         * @param s Coefficient.
409         * @return this * (s).
410         */
411        public ColorPolynomial<C> multiply(GenPolynomial<C> s) {
412            GenPolynomial<GenPolynomial<C>> g, r, w;
413            g = green.multiply(s);
414            r = red.multiply(s);
415            w = white.multiply(s);
416            return new ColorPolynomial<C>(g, r, w);
417        }
418    
419    
420        /**
421         * ColorPolynomial division by coefficient.
422         * @param s Coefficient.
423         * @return this / (s).
424         */
425        public ColorPolynomial<C> divide(GenPolynomial<C> s) {
426            GenPolynomial<GenPolynomial<C>> g, r, w;
427            g = green.divide(s);
428            r = red.divide(s);
429            w = white.divide(s);
430            return new ColorPolynomial<C>(g, r, w);
431        }
432    
433    
434    }