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 }