Skip to content

Commit 24ec8a3

Browse files
author
Alexandru Iosif
committed
First Commit
0 parents  commit 24ec8a3

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

.gitignore~

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

Binomials.mpl

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
#####
2+
with(ListTools):
3+
with(Groebner):
4+
5+
6+
7+
8+
9+
#####
10+
Binomials := module()
11+
description "Some functions for Binomial Ideals";
12+
option package;
13+
#with(ListTools):
14+
#with(Groebner):
15+
export isBinomial, isBinomialGroebner, coefficientsMatrix, monomialCoefficient;
16+
17+
18+
19+
20+
21+
#####Main Functions:
22+
23+
monomialCoefficient := proc(f::polynom,variablesf::list, m::monomial)
24+
# This procedure takes a polynomial f and it returns the coefficient of the monomial m in with respect to the variables variablesf
25+
local monomialsf, TermsList, termsf, coefficientsf, fd, kk, indexm, positionm;
26+
if m = 1 then return (tcoeff(f,variablesf)); end if;
27+
fd := collect(f,variablesf,'distributed');
28+
TermsList := e->`if`(type(e,`+`), convert(e,list), [e]); #taken from Internet
29+
termsf := TermsList(fd);
30+
termsf := collect(termsf,variablesf);
31+
coefficientsf := seq(coeffs(termsf[kk],variablesf),kk=1..(nops(termsf)));
32+
monomialsf := termsf/~[coefficientsf];
33+
positionm := member(m,monomialsf,'indexm');
34+
if (positionm = true) then coeffs(termsf[indexm],variablesf); else 0; end if;
35+
end proc;
36+
37+
coefficientsMatrix := proc(F::list,variablesF::list)
38+
#Input: a list of polynomials
39+
#Output: a matrix C of coefficients and a list m of monomials such that
40+
local vectorF, Fd, TermsList, termsF, kkk, coefficientsF, monomialsF, kk, nrElemsTermsF, nrElemsF;
41+
Fd := collect(F,variablesF,distributed);
42+
TermsList := e->`if`(type(e,`+`), convert(e,list), [e]); #taken from Internet
43+
nrElemsF := nops(F);
44+
termsF := [seq(TermsList(Fd[kkk]),kkk=1..nrElemsF)];
45+
termsF := op~(termsF);
46+
termsF := collect(termsF,variablesF);
47+
nrElemsTermsF := nops(termsF);
48+
coefficientsF := seq(coeffs(termsF[kkk],variablesF),kkk=1..nrElemsTermsF);
49+
monomialsF := termsF/~coefficientsF;convert(%,set);
50+
monomialsF := convert(%,list);
51+
coefficientsF :=
52+
[seq(
53+
[seq(
54+
monomialCoefficient(F[kkk],variablesF,monomialsF[kk])
55+
,kk=1..nops(monomialsF))]
56+
,kkk=1..nops(F))];
57+
return (Matrix(coefficientsF), convert(monomialsF,Vector));
58+
end proc;
59+
60+
isBinomial := proc(F::list,variablesF::list)
61+
description "tests binomiality";
62+
# --Checks binomiality of an ideal (here binomial means no monomials are in the ideal)
63+
local isB, kk,A,M,rowDimA,maxNrRowElementsA,minNrRowElementsA;
64+
(A,M) := coefficientsMatrix (F,variablesF);
65+
A := LinearAlgebra[ReducedRowEchelonForm](A);
66+
rowDimA := LinearAlgebra[RowDimension](A);
67+
if (rowDimA = 1) then maxNrRowElementsA := ArrayNumElems(Array(A),NonZero);
68+
else
69+
maxNrRowElementsA := max(seq(ArrayNumElems(Array(A[kk]),NonZero),kk=1..rowDimA));
70+
minNrRowElementsA := min(seq(ArrayNumElems(Array(A[kk]),NonZero),kk=1..rowDimA));
71+
end if;
72+
if maxNrRowElementsA < 2 or minNrRowElementsA = 1 then return (false); end if;
73+
if maxNrRowElementsA = 2 and minNrRowElementsA = 2 then return (true); end if;
74+
isB := isBinomialGroebnerFree(F,variablesF)[1];
75+
if isB then return isB; end if;
76+
if (F = Homogenize(F,ttt,variablesF)) then return isB; end if;
77+
if not isB then
78+
print("Gröbner free method failed.");
79+
end if;
80+
return 0;
81+
end proc;
82+
83+
isBinomialGroebner := proc(F::list,variablesF::list)
84+
#test binomiality using a Groebner Basis
85+
local B, numTermsB, maxNumTermsB, minNumTermsB;
86+
B := Basis(F,tdeg(op(variablesF)));
87+
numTermsB := nops~(B);
88+
maxNumTermsB := max(numTermsB);
89+
minNumTermsB := min(numTermsB);
90+
if maxNumTermsB = 2 and minNumTermsB = 2 then true else false end if
91+
end proc;
92+
93+
94+
95+
96+
97+
#####Local Functions:
98+
99+
local isBinomialGroebnerFree;
100+
isBinomialGroebnerFree := proc(F::list,variablesF::list)
101+
description "test for Binomiality with Conradi-Kahle algorithm";
102+
#Detecting Binomiality using Groebner Free method.
103+
#Implements Algorithm 3.3 in [CK15] and part of Recipe 4.5 in [CK15]
104+
local needToDehom, FF, variablesFF, ttt, isB, bins;
105+
needToDehom := false;
106+
FF := F;
107+
variablesFF := variablesF;
108+
if not (FF = Homogenize(FF,ttt,variablesF)) then
109+
# homogenize the generators of the ideal as in Recipe 4.5 in [CK15]
110+
# The last variable is the homogenization variable
111+
FF := Homogenize(FF,ttt,variablesF);
112+
needToDehom := true;
113+
variablesFF := [op(variablesF),ttt];
114+
end if;
115+
(isB, bins) := CKbasisRecursion (FF,variablesFF);
116+
if not isB then return (false, {}); end if;
117+
if needToDehom then
118+
bins := subs(ttt = 1, bins);
119+
end if;
120+
return (true,bins);
121+
end proc;
122+
123+
local minDegreeElements;
124+
minDegreeElements := proc(F::list,variablesF::list)
125+
local kkkk, degreesList, minDegree, elementsMinDegree, indicesMinDegree;
126+
degreesList := [seq(degree(F[kkkk],variablesF),kkkk=1..nops(F))];
127+
minDegree := min(degreesList);
128+
indicesMinDegree := SearchAll(minDegree, degreesList);
129+
indicesMinDegree := [SearchAll(minDegree, degreesList)];
130+
elementsMinDegree := [seq(F[kkkk], kkkk in indicesMinDegree)];
131+
return elementsMinDegree;
132+
end proc;
133+
134+
local CKbasisRecursion;
135+
CKbasisRecursion := proc(F::list,variablesF::list)
136+
# Taken and adapted to Maple from the Macaulay2 package Binomials, by Thomas Kahle
137+
#Input: A set of standard-graded polynomials,
138+
#Output: (Boolean, a matrix of binomials)
139+
#Algorithm 3.3. in [CK15]
140+
local FF, Fmin, A, M, setFF, setFmin, diffFFmin, maxNrRowElementsA, k, B, setAM, GB, minNrRowElementsA;
141+
if nops (F) = 0 then return (true, Matrix(0)); end if;
142+
B:={};
143+
Fmin:={};
144+
FF := F; # MakeUnique(F);
145+
while (nops(FF) > 0) do
146+
Fmin := minDegreeElements(FF,variablesF);
147+
(A,M) := coefficientsMatrix (Fmin,variablesF);
148+
A := LinearAlgebra[ReducedRowEchelonForm](A);
149+
local rowDimA; rowDimA := LinearAlgebra[RowDimension](A);
150+
if (rowDimA = 1) then maxNrRowElementsA := ArrayNumElems(Array(A),NonZero);
151+
else
152+
maxNrRowElementsA := max(seq(ArrayNumElems(Array(A[k]),NonZero),k=1..rowDimA));
153+
minNrRowElementsA := min(seq(ArrayNumElems(Array(A[k]),NonZero),k=1..rowDimA));
154+
end if;
155+
if maxNrRowElementsA > 2 or minNrRowElementsA = 1 then return (false, {}); end if;
156+
setAM := convert(op~([entries(LinearAlgebra[Multiply](A,M))]),set);
157+
B := B union setAM;
158+
B := remove(member, B, [0]);
159+
setFF := convert(FF,set);
160+
setFmin := convert(Fmin,set);
161+
diffFFmin := setFF minus setFmin;
162+
FF := (convert(FF,set)) minus (convert(Fmin,set));
163+
GB := Basis(Fmin,tdeg(op(variablesF)));
164+
convert([seq( NormalForm(FF[k],GB,tdeg(op(variablesF))), k=1..(nops(FF)) )],set); FF:= convert(%,list);
165+
FF := remove(member, FF, [0]);
166+
if nops(FF) = 0 then return (true, B); end if; ##this avoids the next step in case F is empty
167+
#Check again if the reduction made things zero
168+
if nops(FF) = 0 then return [true, B]; end if; ##this avoids the next step in case F is empty
169+
end do;
170+
# # -- We should never reach this:
171+
print ("You have found a bug in the binomials package. Please report.");
172+
return (0,Matrix[0]);
173+
end proc;
174+
175+
176+
177+
178+
179+
end module; # Binomials
180+
181+
182+
183+
184+
185+
#####Bibliography:
186+
#[CK15] Conradi, Kahle. Detecting Binomiality, 2015.

0 commit comments

Comments
 (0)