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