/// <summary> /// Computes Groebner basis for the polynomial basis. Based on Theorem 2 of sectin 2.7, CLO. Not very efficient. /// </summary> /// <returns>A polynomial basis that is the reduced Groebner basis.</returns> public PolynomialBasis SimplifiedBuchberger() { PolynomialBasis groebner = this; PolynomialBasis groebnerTemp = this; do { groebnerTemp = new PolynomialBasis(groebner); // G' := G List <Polynomial> groebnerTempList = groebnerTemp.polynomialData.ToList(); for (int i = 0; i < groebnerTemp.polynomialData.Count; i++) { for (int j = (i + 1); j < groebnerTemp.polynomialData.Count; j++) { Polynomial s = groebnerTempList[i].GetSPolynomial(groebnerTempList[j]).GetRemainder(groebnerTemp); if (!s.IsZero) { groebner.polynomialData.Add(s); // G := G ∪ {S} } } } }while (!groebner.Equals(groebnerTemp)); groebner.MakeMinimal(); // First minimal and then reduced. groebner.MakeReduced(); return(groebner); }
/// <summary> /// Optimized Buchberger implementation based on Theorem 11 of section 2.9. /// </summary> /// <param name="basis">An array of polynomials that are going to form the basis.</param> /// <returns>A polynomial basis that wraps the polynomials that make up the Groebner basis.</returns> public PolynomialBasis OptimizedBuchberger(params Polynomial[] basis) { int t = basis.Length - 1; HashSet <Tuple <int, int> > b = new HashSet <Tuple <int, int> >(); for (int i = 0; i <= t; i++) { for (int j = i + 1; j <= t; j++) { b.Add(Tuple.Create(i, j)); // i will always be less than j. } } PolynomialBasis groebner = new PolynomialBasis(basis); List <Polynomial> listBasis = basis.ToList(); while (b.Count > 0) { List <Tuple <int, int> > bList = b.ToList(); foreach (Tuple <int, int> ij in bList) { int i = ij.Item1; int j = ij.Item2; if ( // First, is the combination relatively prime (see propositions 4 of section 2.9, CLO)? If so, we know the remainder by G will be zero. // So, just skip the if condition and remove it. listBasis[i].GetLeadingTerm().LCM(listBasis[j].GetLeadingTerm()) != listBasis[i].GetLeadingTerm() * (listBasis[j].GetLeadingTerm()) // Next, is it possible to remove this combination? If so, skip the if and remove ij. && !this.Criterion(i, j, b, listBasis) ) { Polynomial s = listBasis[i].GetSPolynomial(listBasis[j]).GetRemainder(new PolynomialBasis(listBasis)); // TODO: Implement remainder method that takes list. It will be more efficient. if (!s.IsZero) { t++; listBasis.Add(s); for (int l = 0; l < t; l++) { // We need to consider all combinations with this new polynomial that was introduced. b.Add(Tuple.Create(l, t)); // l will always be smaller than t. } } } b.Remove(ij); // ij has already been considered and its S-polynomial (if non-zero) added. So, we don't need to consider it again. } } PolynomialBasis grb = new PolynomialBasis(listBasis); grb.MakeMinimal(); // First minimal and then reduced. grb.MakeReduced(); return(grb); }