package jscl.math.polynomial; import jscl.math.Expression; import jscl.math.Generic; import jscl.math.JsclInteger; import jscl.math.Variable; import jscl.math.polynomial.groebner.Standard; import jscl.util.ArrayUtils; import java.util.ArrayList; import java.util.List; public class Basis { public static final int DATA_STRUCT = 0x3; public static final int ARRAY_DECLINED = 0x0; public static final int ARRAY = 0x1; public static final int TREE = 0x2; public static final int LIST = 0x3; public static final int DEGREE = 0x4; public static final int DEFINING_EQS = 0x8; public static final int POWER_SIZE = 0x30; public static final int POWER_32 = 0x00; public static final int POWER_8 = 0x10; public static final int POWER_2 = 0x20; public static final int POWER_2_DEFINED = 0x30; public static final int GEO_BUCKETS = 0x40; public static final int ALGORITHM = 0x180; public static final int BUCHBERGER = 0x000; public static final int F4 = 0x080; public static final int BLOCK = 0x100; public static final int INSTRUMENTED = 0x200; public static final int GM_SETTING = 0x400; public static final int SUGAR = 0x800; public static final int FUSSY = 0x1000; public static final int F4_SIMPLIFY = 0x2000; static final int DEFAULT = GM_SETTING | SUGAR; final Polynomial factory; final Generic element[]; public Basis(Generic element[], Polynomial factory) { this.element = element; this.factory = factory; } public static Basis compute(Generic generic[], Variable unknown[]) { return compute(generic, unknown, Monomial.lexicographic); } public static Basis compute(Generic generic[], Variable unknown[], Ordering ordering) { return compute(generic, unknown, ordering, 0); } public static Basis compute(Generic generic[], Variable unknown[], Ordering ordering, int modulo) { return compute(generic, unknown, ordering, modulo, 0); } public static Basis compute(Generic generic[], Variable unknown[], Ordering ordering, int modulo, int flags) { flags ^= DEFAULT; return compute(generic, unknown, ordering, modulo, flags, (flags & Basis.DEGREE) > 0, (flags & DEFINING_EQS) > 0); } static Basis compute(Generic generic[], Variable unknown[], Ordering ordering, int modulo, int flags, boolean degree, boolean defining) { if (degree) return compute(compute(generic, unknown, Monomial.degreeReverseLexicographic, modulo, flags, false, defining).elements(), unknown, ordering, modulo, flags, false, defining); return Standard.compute(new Basis(defining ? augment(defining(unknown, modulo), generic) : generic, Polynomial.factory(unknown, ordering, modulo, flags)), flags); } public static Generic[] defining(Variable unknown[], int modulo) { Generic a[] = new Generic[unknown.length]; for (int i = 0; i < unknown.length; i++) { Generic s = unknown[i].expressionValue(); a[i] = s.subtract(s.pow(modulo)); } return a; } public static boolean compatible(Generic generic[]) { return !(generic.length > 0 && generic[0].compareTo(JsclInteger.valueOf(1)) == 0); } public static Generic[] augment(Generic element[], Generic generic[]) { return (Generic[]) ArrayUtils.concat(element, generic, new Generic[element.length + generic.length]); } public static Variable[] augmentUnknown(Variable unknown[], Generic generic[]) { Variable va[] = Expression.variables(generic); List l = new ArrayList(); for (Variable anUnknown : unknown) l.add(anUnknown); int n = 0; for (int i = 0; i < va.length; i++) { Variable v = va[i]; if (!l.contains(v)) { l.add(n++, v); } } return (Variable[]) ArrayUtils.toArray(l, new Variable[l.size()]); } public Basis valueof(Generic generic[]) { return new Basis(generic, factory); } public Basis modulo(int modulo) { return new Basis(element, Polynomial.factory(factory, modulo)); } public Generic[] elements() { return element; } public Ordering ordering() { return factory.ordering(); } public Polynomial polynomial(Generic generic) { return factory.valueOf(generic).normalize().freeze(); } public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("{"); for (int i = 0; i < element.length; i++) { buffer.append(polynomial(element[i])).append(i < element.length - 1 ? ", " : ""); } buffer.append("}"); buffer.append(", " + ArrayUtils.toString(factory.monomialFactory.unknown())); return buffer.toString(); } }