
edu.jas.application.SolvableIdeal Maven / Gradle / Ivy
The newest version!
/*
* $Id: SolvableIdeal.java 4408 2013-04-30 10:48:20Z kredel $
*/
package edu.jas.application;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import edu.jas.gb.SolvableExtendedGB;
import edu.jas.gb.SolvableGroebnerBaseAbstract;
import edu.jas.gb.SolvableGroebnerBaseSeq;
import edu.jas.gb.SolvableReduction;
import edu.jas.gb.SolvableReductionSeq;
import edu.jas.poly.ExpVector;
import edu.jas.poly.GenPolynomial;
import edu.jas.poly.GenSolvablePolynomial;
import edu.jas.poly.GenSolvablePolynomialRing;
import edu.jas.poly.PolynomialList;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.NotInvertibleException;
/**
* Solvable Ideal implements some methods for ideal arithmetic, for example
* sum, intersection, quotient.
* Note: only left ideals at the moment.
* @author Heinz Kredel
*/
public class SolvableIdeal> implements Comparable>, Serializable {
private static final Logger logger = Logger.getLogger(SolvableIdeal.class);
private final boolean debug = logger.isDebugEnabled();
/**
* The data structure is a PolynomialList.
*/
protected PolynomialList list;
/**
* Indicator if list is a Groebner Base.
*/
protected boolean isGB;
/**
* Indicator if test has been performed if this is a Groebner Base.
*/
protected boolean testGB;
/**
* Indicator if list has optimized term order.
*/
protected boolean isTopt;
/**
* Groebner base engine.
*/
protected final SolvableGroebnerBaseAbstract bb;
/**
* Reduction engine.
*/
protected final SolvableReduction red;
/**
* Constructor.
* @param ring solvable polynomial ring
*/
public SolvableIdeal(GenSolvablePolynomialRing ring) {
this(ring, new ArrayList>());
}
/**
* Constructor.
* @param ring solvable polynomial ring
* @param F list of solvable polynomials
*/
public SolvableIdeal(GenSolvablePolynomialRing ring, List> F) {
this(new PolynomialList(ring, F));
}
/**
* Constructor.
* @param ring solvable polynomial ring
* @param F list of solvable polynomials
* @param gb true if F is known to be a Groebner Base, else false
*/
public SolvableIdeal(GenSolvablePolynomialRing ring, List> F, boolean gb) {
this(new PolynomialList(ring, F), gb);
}
/**
* Constructor.
* @param ring solvable polynomial ring
* @param F list of solvable polynomials
* @param gb true if F is known to be a Groebner Base, else false
* @param topt true if term order is optimized, else false
*/
public SolvableIdeal(GenSolvablePolynomialRing ring, List> F, boolean gb,
boolean topt) {
this(new PolynomialList(ring, F), gb, topt);
}
/**
* Constructor.
* @param list solvable polynomial list
*/
public SolvableIdeal(PolynomialList list) {
this(list, false);
}
/**
* Constructor.
* @param list solvable polynomial list
* @param bb Groebner Base engine
* @param red Reduction engine
*/
public SolvableIdeal(PolynomialList list, SolvableGroebnerBaseAbstract bb, SolvableReduction red) {
this(list, false, bb, red);
}
/**
* Constructor.
* @param list solvable polynomial list
* @param gb true if list is known to be a Groebner Base, else false
*/
public SolvableIdeal(PolynomialList list, boolean gb) {
this(list, gb, new SolvableGroebnerBaseSeq(), new SolvableReductionSeq());
//this(list, gb, GBFactory.getImplementation(list.ring.coFac));
}
/**
* Constructor.
* @param list solvable polynomial list
* @param gb true if list is known to be a Groebner Base, else false
* @param topt true if term order is optimized, else false
*/
public SolvableIdeal(PolynomialList list, boolean gb, boolean topt) {
this(list, gb, topt, new SolvableGroebnerBaseSeq(), new SolvableReductionSeq());
//this(list, gb, topt, GBFactory.getImplementation(list.ring.coFac));
}
/**
* Constructor.
* @param list solvable polynomial list
* @param gb true if list is known to be a Groebner Base, else false
* @param bb Groebner Base engine
* @param red Reduction engine
*/
public SolvableIdeal(PolynomialList list, boolean gb, SolvableGroebnerBaseAbstract bb,
SolvableReduction red) {
this(list, gb, false, bb, red);
}
/**
* Constructor.
* @param list solvable polynomial list
* @param gb true if list is known to be a Groebner Base, else false
* @param bb Groebner Base engine
*/
public SolvableIdeal(PolynomialList list, boolean gb, SolvableGroebnerBaseAbstract bb) {
this(list, gb, false, bb, bb.sred);
}
/**
* Constructor.
* @param list solvable polynomial list
* @param gb true if list is known to be a Groebner Base, else false
* @param topt true if term order is optimized, else false
* @param bb Groebner Base engine
*/
public SolvableIdeal(PolynomialList list, boolean gb, boolean topt, SolvableGroebnerBaseAbstract bb) {
this(list, gb, topt, bb, bb.sred);
}
/**
* Constructor.
* @param list solvable polynomial list
* @param gb true if list is known to be a Groebner Base, else false
* @param topt true if term order is optimized, else false
* @param bb Groebner Base engine
* @param red Reduction engine
*/
public SolvableIdeal(PolynomialList list, boolean gb, boolean topt,
SolvableGroebnerBaseAbstract bb, SolvableReduction red) {
if (list == null || list.list == null) {
throw new IllegalArgumentException("list and list.list may not be null");
}
this.list = list;
this.isGB = gb;
this.isTopt = topt;
this.testGB = (gb ? true : false); // ??
this.bb = bb;
this.red = red;
}
/**
* Clone this.
* @return a copy of this.
*/
public SolvableIdeal copy() {
return new SolvableIdeal(list.copy(), isGB, isTopt, bb, red);
}
/**
* Get the List of GenSolvablePolynomials.
* @return (cast) list.list
*/
public List> getList() {
return list.getSolvableList();
}
/**
* Get the GenSolvablePolynomialRing.
* @return (cast) list.ring
*/
public GenSolvablePolynomialRing getRing() {
return list.getSolvableRing();
}
/**
* Get the zero ideal.
* @return ideal(0)
*/
public SolvableIdeal getZERO() {
List> z = new ArrayList>(0);
PolynomialList pl = new PolynomialList(getRing(), z);
return new SolvableIdeal(pl, true, isTopt, bb, red);
}
/**
* Get the one ideal.
* @return ideal(1)
*/
public SolvableIdeal getONE() {
List> one = new ArrayList>(1);
one.add(getRing().getONE());
PolynomialList pl = new PolynomialList(getRing(), one);
return new SolvableIdeal(pl, true, isTopt, bb, red);
}
/**
* String representation of the solvable ideal.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return list.toString();
}
/**
* Get a scripting compatible string representation.
* @return script compatible representation for this Element.
* @see edu.jas.structure.Element#toScript()
*/
public String toScript() {
// any script case
return list.toScript();
}
/**
* Comparison with any other object. Note: If not both ideals are
* Groebner Bases, then false may be returned even the ideals are equal.
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@SuppressWarnings("unchecked")
public boolean equals(Object b) {
if (!(b instanceof SolvableIdeal)) {
logger.warn("equals no Ideal");
return false;
}
SolvableIdeal B = null;
try {
B = (SolvableIdeal) b;
} catch (ClassCastException ignored) {
return false;
}
//if ( isGB && B.isGB ) {
// return list.equals( B.list ); requires also monic polys
//} else { // compute GBs ?
return this.contains(B) && B.contains(this);
//}
}
/**
* SolvableIdeal comparison.
* @param L other solvable ideal.
* @return compareTo() of polynomial lists.
*/
public int compareTo(SolvableIdeal L) {
return list.compareTo(L.list);
}
/**
* Hash code for this solvable ideal.
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int h;
h = list.hashCode();
if (isGB) {
h = h << 1;
}
if (testGB) {
h += 1;
}
return h;
}
/**
* Test if ZERO ideal.
* @return true, if this is the 0 ideal, else false
*/
public boolean isZERO() {
return list.isZERO();
}
/**
* Test if ONE is contained in the ideal. To test for a proper ideal use
* ! id.isONE()
.
* @return true, if this is the 1 ideal, else false
*/
public boolean isONE() {
return list.isONE();
}
/**
* Test if this is a left Groebner base.
* @return true, if this is a left Groebner base, else false
*/
public boolean isGB() {
if (testGB) {
return isGB;
}
logger.warn("isGB computing");
isGB = bb.isLeftGB(getList());
testGB = true;
return isGB;
}
/**
* Do Groebner Base. compute the Groebner Base for this ideal.
*/
@SuppressWarnings("unchecked")
public void doGB() {
if (isGB && testGB) {
return;
}
//logger.warn("GB computing");
List> G = getList();
logger.info("GB computing = " + G);
G = bb.leftGB(G);
//if (isTopt) {
// List perm = ((OptimizedPolynomialList) list).perm;
// list = new OptimizedPolynomialList(perm, getRing(), G);
//} else {
list = new PolynomialList(getRing(), G);
//}
isGB = true;
testGB = true;
return;
}
/**
* Groebner Base. Get a Groebner Base for this ideal.
* @return leftGB(this)
*/
public SolvableIdeal GB() {
if (isGB) {
return this;
}
doGB();
return this;
}
/**
* Solvable ideal containment. Test if B is contained in this ideal. Note:
* this is eventually modified to become a Groebner Base.
* @param B solvable ideal
* @return true, if B is contained in this, else false
*/
public boolean contains(SolvableIdeal B) {
if (B == null || B.isZERO()) {
return true;
}
return contains(B.getList());
}
/**
* Solvable ideal containment. Test if b is contained in this ideal. Note:
* this is eventually modified to become a Groebner Base.
* @param b solvable polynomial
* @return true, if b is contained in this, else false
*/
public boolean contains(GenSolvablePolynomial b) {
if (b == null || b.isZERO()) {
return true;
}
if (this.isONE()) {
return true;
}
if (this.isZERO()) {
return false;
}
if (!isGB) {
doGB();
}
GenSolvablePolynomial z = red.leftNormalform(getList(), b);
if (z == null || z.isZERO()) {
return true;
}
return false;
}
/**
* Solvable ideal containment. Test if each b in B is contained in this
* ideal. Note: this is eventually modified to become a Groebner Base.
* @param B list of solvable polynomials
* @return true, if each b in B is contained in this, else false
*/
public boolean contains(List> B) {
if (B == null || B.size() == 0) {
return true;
}
if (this.isONE()) {
return true;
}
if (!isGB) {
doGB();
}
for (GenSolvablePolynomial b : B) {
if (b == null) {
continue;
}
GenSolvablePolynomial z = red.leftNormalform(getList(), b);
if (!z.isZERO()) {
//System.out.println("contains nf(b) != 0: " + b);
return false;
}
}
return true;
}
/**
* Solvable ideal summation. Generators for the sum of ideals. Note: if both
* ideals are Groebner bases, a Groebner base is returned.
* @param B solvable ideal
* @return ideal(this+B)
*/
public SolvableIdeal sum(SolvableIdeal B) {
if (B == null || B.isZERO()) {
return this;
}
if (this.isZERO()) {
return B;
}
int s = getList().size() + B.getList().size();
List> c;
c = new ArrayList>(s);
c.addAll(getList());
c.addAll(B.getList());
SolvableIdeal I = new SolvableIdeal(getRing(), c, false);
if (isGB && B.isGB) {
I.doGB();
}
return I;
}
/**
* Solvable summation. Generators for the sum of ideal and a polynomial.
* Note: if this ideal is a Groebner base, a Groebner base is returned.
* @param b solvable polynomial
* @return ideal(this+{b})
*/
public SolvableIdeal sum(GenSolvablePolynomial b) {
if (b == null || b.isZERO()) {
return this;
}
int s = getList().size() + 1;
List> c;
c = new ArrayList>(s);
c.addAll(getList());
c.add(b);
SolvableIdeal I = new SolvableIdeal(getRing(), c, false);
if (isGB) {
I.doGB();
}
return I;
}
/**
* Solvable summation. Generators for the sum of this ideal and a list of
* polynomials. Note: if this ideal is a Groebner base, a Groebner base is
* returned.
* @param L list of solvable polynomials
* @return ideal(this+L)
*/
public SolvableIdeal sum(List> L) {
if (L == null || L.isEmpty()) {
return this;
}
int s = getList().size() + L.size();
List> c = new ArrayList>(s);
c.addAll(getList());
c.addAll(L);
SolvableIdeal I = new SolvableIdeal(getRing(), c, false);
if (isGB) {
I.doGB();
}
return I;
}
/**
* Product. Generators for the product of ideals. Note: if both ideals are
* Groebner bases, a Groebner base is returned.
* @param B solvable ideal
* @return ideal(this*B)
*/
public SolvableIdeal product(SolvableIdeal B) {
if (B == null || B.isZERO()) {
return B;
}
if (this.isZERO()) {
return this;
}
int s = getList().size() * B.getList().size();
List> c;
c = new ArrayList>(s);
for (GenSolvablePolynomial p : getList()) {
for (GenSolvablePolynomial q : B.getList()) {
q = p.multiply(q);
c.add(q);
}
}
SolvableIdeal I = new SolvableIdeal(getRing(), c, false);
if (isGB && B.isGB) {
I.doGB();
}
return I;
}
/**
* Intersection. Generators for the intersection of ideals. Using an
* iterative algorithm.
* @param Bl list of solvable ideals
* @return ideal(cap_i B_i), a Groebner base
*/
public SolvableIdeal intersect(List> Bl) {
if (Bl == null || Bl.size() == 0) {
return getZERO();
}
SolvableIdeal I = null;
for (SolvableIdeal B : Bl) {
if (I == null) {
I = B;
continue;
}
if (I.isONE()) {
return I;
}
I = I.intersect(B);
}
return I;
}
/**
* Intersection. Generators for the intersection of ideals.
* @param B solvable ideal
* @return ideal(this \cap B), a Groebner base
*/
public SolvableIdeal intersect(SolvableIdeal B) {
if (B == null || B.isZERO()) { // (0)
return B;
}
if (this.isZERO()) {
return this;
}
int s = getList().size() + B.getList().size();
List> c;
c = new ArrayList>(s);
List> a = getList();
List> b = B.getList();
GenSolvablePolynomialRing tfac = getRing().extend(1);
// term order is also adjusted
for (GenSolvablePolynomial p : a) {
p = (GenSolvablePolynomial) p.extend(tfac, 0, 1L); // t*p
c.add(p);
}
for (GenSolvablePolynomial p : b) {
GenSolvablePolynomial q = (GenSolvablePolynomial) p.extend(tfac, 0, 1L);
GenSolvablePolynomial r = (GenSolvablePolynomial) p.extend(tfac, 0, 0L);
p = (GenSolvablePolynomial) r.subtract(q); // (1-t)*p
c.add(p);
}
logger.warn("intersect computing GB");
List> g = bb.leftGB(c);
if (debug) {
logger.debug("intersect GB = " + g);
}
SolvableIdeal E = new SolvableIdeal(tfac, g, true);
SolvableIdeal I = E.intersect(getRing());
return I;
}
/**
* Intersection. Generators for the intersection of a ideal with a
* polynomial ring. The polynomial ring of this ideal must be a contraction
* of R and the TermOrder must be an elimination order.
* @param R solvable polynomial ring
* @return ideal(this \cap R)
*/
public SolvableIdeal intersect(GenSolvablePolynomialRing R) {
if (R == null) {
throw new IllegalArgumentException("R may not be null");
}
int d = getRing().nvar - R.nvar;
if (d <= 0) {
return this;
}
List> H = new ArrayList>(getList().size());
for (GenSolvablePolynomial p : getList()) {
Map> m = null;
m = p.contract(R);
if (debug) {
logger.debug("intersect contract m = " + m);
}
if (m.size() == 1) { // contains one power of variables
for (Map.Entry> me : m.entrySet()) {
ExpVector e = me.getKey();
GenSolvablePolynomial mv = (GenSolvablePolynomial) me.getValue();
if (e.isZERO()) {
H.add(mv); //m.get(e));
}
}
}
}
GenSolvablePolynomialRing tfac = getRing().contract(d);
if (tfac.equals(R)) { // check
return new SolvableIdeal(R, H, isGB, isTopt);
}
logger.info("tfac, R = " + tfac + ", " + R);
// throw new RuntimeException("contract(this) != R");
return new SolvableIdeal(R, H); // compute GB
}
/**
* Eliminate. Generators for the intersection of this ideal with a solvable
* polynomial ring. The solvable polynomial ring of this ideal must be a
* contraction of R and the TermOrder must be an elimination order.
* @param R solvable polynomial ring
* @return ideal(this \cap R)
*/
public SolvableIdeal eliminate(GenSolvablePolynomialRing R) {
if (R == null) {
throw new IllegalArgumentException("R may not be null");
}
if (getRing().equals(R)) {
return this;
}
return intersect(R);
}
/**
* Quotient. Generators for the solvable ideal quotient.
* @param h solvable polynomial
* @return ideal(this : h), a Groebner base
*/
public SolvableIdeal quotient(GenSolvablePolynomial h) {
if (h == null) { // == (0)
return this;
}
if (h.isZERO()) {
return this;
}
if (this.isZERO()) {
return this;
}
List> H;
H = new ArrayList>(1);
H.add(h);
SolvableIdeal Hi = new SolvableIdeal(getRing(), H, true);
SolvableIdeal I = this.intersect(Hi);
List> Q;
Q = new ArrayList>(I.getList().size());
for (GenSolvablePolynomial q : I.getList()) {
q = (GenSolvablePolynomial) q.divide(h); // remainder == 0
Q.add(q);
}
return new SolvableIdeal(getRing(), Q, true /*false?*/);
}
/**
* Quotient. Generators for the solvable ideal quotient.
* @param H solvable ideal
* @return ideal(this : H), a Groebner base
*/
public SolvableIdeal quotient(SolvableIdeal H) {
if (H == null) { // == (0)
return this;
}
if (H.isZERO()) {
return this;
}
if (this.isZERO()) {
return this;
}
SolvableIdeal Q = null;
for (GenSolvablePolynomial h : H.getList()) {
SolvableIdeal Hi = this.quotient(h);
if (Q == null) {
Q = Hi;
} else {
Q = Q.intersect(Hi);
}
}
return Q;
}
/**
* Infinite quotient. Generators for the infinite solvable ideal quotient.
* @param h solvable polynomial
* @return ideal(this : hs), a Groebner base
*/
public SolvableIdeal infiniteQuotientRab(GenSolvablePolynomial h) {
if (h == null || h.isZERO()) { // == (0)
return getONE();
}
if (h.isONE()) {
return this;
}
if (this.isZERO()) {
return this;
}
if ( ! getRing().isCommutative() ) {
throw new UnsupportedOperationException("Rabinowich trick only for commutative polynomial rings");
}
SolvableIdeal I = this.GB(); // should be already
List> a = I.getList();
List> c;
c = new ArrayList>(a.size() + 1);
GenSolvablePolynomialRing tfac = getRing().extend(1);
// term order is also adjusted
for (GenSolvablePolynomial p : a) {
p = (GenSolvablePolynomial) p.extend(tfac, 0, 0L); // p
c.add(p);
}
GenSolvablePolynomial q = (GenSolvablePolynomial) h.extend(tfac, 0, 1L);
GenSolvablePolynomial r = tfac.getONE(); // h.extend( tfac, 0, 0L );
GenSolvablePolynomial hs = (GenSolvablePolynomial) q.subtract(r); // 1 - t*h // (1-t)*h
c.add(hs);
logger.warn("infiniteQuotientRab computing GB ");
List> g = bb.leftGB(c);
if (debug) {
logger.info("infiniteQuotientRab = " + tfac + ", c = " + c);
logger.info("infiniteQuotientRab GB = " + g);
}
SolvableIdeal E = new SolvableIdeal(tfac, g, true);
SolvableIdeal Is = E.intersect(getRing());
return Is;
}
/**
* Infinite quotient exponent.
* @param h solvable polynomial
* @param Q quotient this : h^\infinity
* @return s with Q = this : hs
*/
public int infiniteQuotientExponent(GenSolvablePolynomial h, SolvableIdeal Q) {
int s = 0;
if (h == null) { // == 0
return s;
}
if (h.isZERO() || h.isONE()) {
return s;
}
if (this.isZERO() || this.isONE()) {
return s;
}
//see below: if (this.contains(Q)) {
// return s;
//}
GenSolvablePolynomial p = getRing().getONE();
for (GenSolvablePolynomial q : Q.getList()) {
if (this.contains(q)) {
continue;
}
//System.out.println("q = " + q + ", p = " + p + ", s = " + s);
GenSolvablePolynomial qp = q.multiply(p);
while (!this.contains(qp)) {
p = p.multiply(h);
s++;
qp = q.multiply(p);
}
}
return s;
}
/**
* Infinite quotient. Generators for the infinite solvable ideal quotient.
* @param h solvable polynomial
* @return ideal(this : hs), a Groebner base
*/
public SolvableIdeal infiniteQuotient(GenSolvablePolynomial h) {
if (h == null) { // == (0)
return this;
}
if (h.isZERO()) {
return this;
}
if (this.isZERO()) {
return this;
}
int s = 0;
SolvableIdeal I = this.GB(); // should be already
GenSolvablePolynomial hs = h;
SolvableIdeal Is = I;
boolean eq = false;
while (!eq) {
Is = I.quotient(hs);
Is = Is.GB(); // should be already
logger.info("infiniteQuotient s = " + s);
eq = Is.contains(I); // I.contains(Is) always
if (!eq) {
I = Is;
s++;
// hs = hs.multiply( h );
}
}
return Is;
}
/**
* Radical membership test.
* @param h solvable polynomial
* @return true if h is contained in the radical of ideal(this), else false.
*/
public boolean isRadicalMember(GenSolvablePolynomial h) {
if (h == null) { // == (0)
return true;
}
if (h.isZERO()) {
return true;
}
if (this.isZERO()) {
return true;
}
SolvableIdeal x = infiniteQuotientRab(h); // may fail
if (debug) {
logger.debug("infiniteQuotientRab = " + x);
}
return x.isONE();
}
/**
* Infinite Quotient. Generators for the solvable ideal infinite quotient.
* @param H solvable ideal
* @return ideal(this : Hs), a Groebner base
*/
public SolvableIdeal infiniteQuotient(SolvableIdeal H) {
if (H == null) { // == (0)
return this;
}
if (H.isZERO()) {
return this;
}
if (this.isZERO()) {
return this;
}
SolvableIdeal Q = null;
for (GenSolvablePolynomial h : H.getList()) {
SolvableIdeal Hi = this.infiniteQuotient(h);
if (Q == null) {
Q = Hi;
} else {
Q = Q.intersect(Hi);
}
}
return Q;
}
/**
* Infinite Quotient. Generators for the solvable ideal infinite quotient.
* @param H solvable ideal
* @return ideal(this : Hs), a Groebner base
*/
public SolvableIdeal infiniteQuotientRab(SolvableIdeal H) {
if (H == null) { // == (0)
return this;
}
if (H.isZERO()) {
return this;
}
if (this.isZERO()) {
return this;
}
SolvableIdeal Q = null;
for (GenSolvablePolynomial h : H.getList()) {
SolvableIdeal Hi = this.infiniteQuotientRab(h); // may fail
if (Q == null) {
Q = Hi;
} else {
Q = Q.intersect(Hi);
}
}
return Q;
}
/**
* Power. Generators for the power of this solvable ideal. Note: if this
* ideal is a Groebner base, a Groebner base is returned.
* @param d integer
* @return ideal(this^d)
*/
public SolvableIdeal power(int d) {
if (d <= 0) {
return getONE();
}
if (this.isZERO() || this.isONE()) {
return this;
}
SolvableIdeal c = this;
for (int i = 1; i < d; i++) {
c = c.product(this);
}
return c;
}
/**
* Normalform for element.
* @param h solvable polynomial
* @return left normalform of h with respect to this
*/
public GenSolvablePolynomial normalform(GenSolvablePolynomial h) {
if (h == null) {
return h;
}
if (h.isZERO()) {
return h;
}
if (this.isZERO()) {
return h;
}
GenSolvablePolynomial r;
r = red.leftNormalform(getList(), h);
return r;
}
/**
* Normalform for list of solvable elements.
* @param L solvable polynomial list
* @return list of left normalforms of the elements of L with respect to this
*/
public List> normalform(List> L) {
if (L == null) {
return L;
}
if (L.size() == 0) {
return L;
}
if (this.isZERO()) {
return L;
}
List> M = new ArrayList>(L.size());
for (GenSolvablePolynomial h : L) {
GenSolvablePolynomial r = normalform(h);
if (r != null && !r.isZERO()) {
M.add(r);
}
}
return M;
}
/**
* Inverse for element modulo this ideal.
* @param h solvable polynomial
* @return inverse of h with respect to this, if defined
*/
public GenSolvablePolynomial inverse(GenSolvablePolynomial h) {
if (h == null || h.isZERO()) {
throw new NotInvertibleException("zero not invertible");
}
if (this.isZERO()) {
throw new NotInvertibleException("zero ideal");
}
if (h.isUnit()) {
return (GenSolvablePolynomial) h.inverse();
}
doGB();
List> F = new ArrayList>(1 + list.list.size());
F.add(h);
F.addAll(getList());
//System.out.println("F = " + F);
SolvableExtendedGB x = bb.extLeftGB(F);
List> G = x.G;
//System.out.println("G = " + G);
GenSolvablePolynomial one = null;
int i = -1;
for (GenSolvablePolynomial p : G) {
i++;
if (p == null) {
continue;
}
if (p.isUnit()) {
one = p;
break;
}
}
if (one == null) {
throw new NotInvertibleException("h = " + h);
}
List> row = x.G2F.get(i); // != -1
//System.out.println("row = " + row);
GenSolvablePolynomial g = row.get(0);
if (g == null || g.isZERO()) {
throw new NotInvertibleException("h = " + h);
}
GenSolvablePolynomial gp = red.leftNormalform(getList(), g);
if (gp.isZERO()) { // can happen with solvable rings
throw new NotInvertibleException("h = " + h + ", g = " + g);
}
// adjust leading coefficient of g to get g*h == 1
GenSolvablePolynomial f = g.multiply(h);
//System.out.println("f = " + f);
GenSolvablePolynomial k = red.leftNormalform(getList(), f);
//System.out.println("k = " + k);
if (!k.isONE()) {
C lbc = k.leadingBaseCoefficient();
lbc = lbc.inverse();
g = g.multiply(lbc);
}
if (debug) {
//logger.info("inv G = " + G);
//logger.info("inv G2F = " + x.G2F);
//logger.info("inv row "+i+" = " + row);
//logger.info("inv h = " + h);
//logger.info("inv g = " + g);
//logger.info("inv f = " + f);
f = g.multiply(h);
k = red.leftNormalform(getList(), f);
logger.debug("inv k = " + k);
if (!k.isUnit()) {
throw new NotInvertibleException(" k = " + k);
}
}
return g;
}
/**
* Test if element is a unit modulo this ideal.
* @param h solvable polynomial
* @return true if h is a unit with respect to this, else false
*/
public boolean isUnit(GenSolvablePolynomial h) {
if (h == null || h.isZERO()) {
return false;
}
if (this.isZERO()) {
return false;
}
List> F = new ArrayList>(1 + list.list.size());
F.add(h);
F.addAll(getList());
List> G = bb.leftGB(F);
for (GenSolvablePolynomial p : G) {
if (p == null) {
continue;
}
if (p.isUnit()) {
return true;
}
}
return false;
}
/**
* Ideal common zero test.
* @return -1, 0 or 1 if dimension(this) &eq; -1, 0 or ≥ 1.
*/
public int commonZeroTest() {
if (this.isZERO()) {
return 1;
}
if (!isGB) {
doGB();
}
if (this.isONE()) {
return -1;
}
return bb.commonZeroTest(getList());
}
/**
* Test if this ideal is maximal.
* @return true, if this is maximal and not one, else false.
*/
public boolean isMaximal() {
if (commonZeroTest() != 0) {
return false;
}
for (Long d : univariateDegrees()) {
if (d > 1L) {
// todo: test if irreducible
return false;
}
}
return true;
}
/**
* Univariate head term degrees.
* @return a list of the degrees of univariate head terms.
*/
public List univariateDegrees() {
List ud = new ArrayList();
if (this.isZERO()) {
return ud;
}
if (!isGB) {
doGB();
}
if (this.isONE()) {
return ud;
}
return bb.univariateDegrees(getList());
}
/**
* Ideal dimension.
* @return a dimension container (dim,maxIndep,list(maxIndep),vars).
*/
public Dimension dimension() {
Ideal ci = new Ideal(list);
return ci.dimension();
}
/**
* Construct univariate polynomials of minimal degree in all variables in
* zero dimensional ideal(G).
* @return list of univariate solvable polynomial of minimal degree in each
* variable in ideal(G)
*/
public List> constructUnivariate() {
List> univs = new ArrayList>();
for (int i = getRing().nvar - 1; i >= 0; i--) {
GenSolvablePolynomial u = constructUnivariate(i);
univs.add(u);
}
return univs;
}
/**
* Construct univariate polynomial of minimal degree in variable i in zero
* dimensional ideal(G).
* @param i variable index.
* @return univariate solvable polynomial of minimal degree in variable i in
* ideal(G)
*/
public GenSolvablePolynomial constructUnivariate(int i) {
doGB();
return bb.constructUnivariate(i, getList());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy