Ask Your Question

Toric Ideal of Point Configuration Yielding Whole Ring?

asked 2020-06-09 00:03:49 -0500

DerekH gravatar image

updated 2020-06-09 10:15:44 -0500

So I am trying to find the toric ideal of a point configuration given by the lattice points contained within a family of polytopes I am studying to assess regularity/unimodularity of triangulations of the point configuration (I'm attempting to follow the guidelines specified in Bernd Sturmfels' text Grobner Bases and Convex Polytopes). I know that toric ideals are supposed to be prime and their reduced Grobner bases are generated by binomials, but for whatever reason, the ToricIdeal() sage function is indicating that the corresponding ideal is the entire ring, which should definitely not be the case.

For example, say that we're looking at the point configuration given by the lattice points (1,0), (0,1), (0,0), (0,-1), (-1,-1), (-1,-2), (-2,-3). Inputting these points as columns in a matrix and computing the toric ideal as indicated in the sage documentation should be as simple as:

A = matrix([[1,0,0,0,-1,-1,-2],[0,1,0,-1,-1,-2,-3]])
IA = ToricIdeal(A); IA

However, when I run this I get the following output:

Ideal (1) of Multivariate Polynomial Ring in z0, z1, z2, z3, z4, z5, z6 over Rational Field

I cannot determine why this is the case. For some context, I asked a colleague to compute the toric ideal using Macaulay2, and that program indicated that the toric ideal is generated by z2 - 1, z1*z3 - 1, z0*z1*z4 - 1, z0*z1^2*z5 - 1, z0^2*z1^3*z6 - 1, z0^4*z1^7*z2*z3*z4*z5*z6 - 1 which seems far more reasonable. Any idea if my input is incorrect or misguided? I'm having a similar issue on another project when attempting to compute toric ideals of point configurations comprised of the vertices of order polytopes. Without the correct toric ideal, I cannot compute a corresponding Grobner basis to assess regularity or unimodularity. Any help is greatly appreciated. Thank you.

edit retag flag offensive close merge delete


with the notation of the answer by @rburing, you probably need

sage: IA._naive_ideal(IA.ring()).groebner_basis()
[z0*z1*z6 - z5, z1*z3 - 1, z3^2 - z0*z5, z0*z4 - z3, z3*z4 - z5, z4^2 - z1*z6, z1*z5 - z4, z3*z5 - z0*z6, z4*z5 - z6, z5^2 - z3*z6, z2 - 1]

the difference with the Macaulay2 answer is probably due to a different monomial order used. (In Sage computation it's the default order used).

Unfortunately our Macaulay2 insterface is brokek atm:

Dima gravatar imageDima ( 2020-06-09 05:54:24 -0500 )edit
Dima gravatar imageDima ( 2020-06-09 06:38:43 -0500 )edit

Thank you so much!

DerekH gravatar imageDerekH ( 2020-06-09 10:13:11 -0500 )edit

2 answers

Sort by ยป oldest newest most voted

answered 2020-06-09 03:42:42 -0500

rburing gravatar image

updated 2020-06-09 03:51:29 -0500

In the terms used by the documentation on Toric ideals, it seems that you want the "naive ideal".

This is implemented (but hidden):

sage: IA._naive_ideal(IA.ring())
Ideal (-z2 + 1, -z1*z3 + 1, -z0*z1*z4 + 1, -z1*z5 + z4, z4*z5 - z6) of Multivariate Polynomial Ring in z0, z1, z2, z3, z4, z5, z6 over Rational Field

This is the same as the ideal obtained by your colleague:

sage: IA.ring().inject_variables()
sage: IA._naive_ideal(IA.ring()) == IA.ring().ideal(z2 - 1, z1*z3 - 1, z0*z1*z4 - 1, z0*z1^2*z5 - 1, z0^2*z1^3*z6 - 1, z0^4*z1^7*z2*z3*z4*z5*z6 - 1)

According to the source code, the (non-naive) toric ideal is computed from the naive one as follows:

ring = self._init_ring('neglex')
J = self._naive_ideal(ring)
if J.is_zero():
    return J
for i in range(0,self.nvariables()):
    J = self._ideal_quotient_by_variable(ring, J, i)
return J

where _ideal_quotient_by_variable computes $(J:x_i^\infty)$.

I'm not an expert on toric ideals so I cannot judge who is naive here. Maybe it is a matter of conventions?

edit flag offensive delete link more


That 'neglex' order (a local order, not a proper Groebner basis order) looks out of place there. Without it, the saturations of the naive ideal with x_i are already done, so the answer shoud be the same as the naive ideal.

Dima gravatar imageDima ( 2020-06-09 05:33:47 -0500 )edit

Awesome, thank you so much! I think this will work well for my purposes. Greatly appreciate it!

DerekH gravatar imageDerekH ( 2020-06-09 10:15:15 -0500 )edit

Not sure if this is useful for anyone, but I wrote another implementation that obtains the appropriate naive ideal using the basis for kernel of the point configuration matrix. The answer is the same as _naive_ideal() method.

from sage.rings.polynomial.polydict import ETuple
R = PolynomialRing(QQ, 'z', 7, order='invlex')
z = R.gens()
IA = ToricIdeal([[1,0,0,0,-1,-1,-2],[0,1,0,-1,-1,-2,-3]])
A = IA.A()
V = A.right_kernel();B = V.basis_matrix()
gens = []
for i in range(B.nrows()):
    u = ETuple(list(B[i]));other = ETuple([0]*len(u))
    uplus = tuple(u.combine_to_positives(other)[1])
    uminus = tuple(u.combine_to_positives(other)[2])
    gens.append(R.monomial(*uplus) - R.monomial(*uminus))
I = ideal(gens)
GB = I.groebner_basis()
DerekH gravatar imageDerekH ( 2020-06-09 10:52:17 -0500 )edit

The naive ideal is not in general enough. See for example the comment about the twisted cubic in the documentation, so in general it is necessary to saturate.

mwageringel gravatar imagemwageringel ( 2020-06-09 12:24:39 -0500 )edit

answered 2020-06-09 14:34:25 -0500

DerekH gravatar image

I believe I have some more insight as to why this issue was happening. Since I want to consider toric ideals in the context of a lattice polytope $P$, my point configuration matrix should have had a row of $1$'s appended to the bottom since I'm really looking at the polytope embedded at height $1$ in the cone over $P$ (${\rm cone}(P)$). I was operating in the wrong dimension! Generating the whole ring makes sense with the setup in my original problem statement since two of the lattice points are the standard basis vectors. I made this realization because the ideal should be homogenenous as the polytope given as the convex hull of those $7$ points is IDP but several of the generators contained a constant term. So, I should have had something more along the lines of

R = PolynomialRing(QQ, 'z', 7, order='lex')
z = R.gens()
IA = ToricIdeal([[1,0,0,0,-1,-1,-2],[0,1,0,-1,-1,-2,-3],[1,1,1,1,1,1,1]],polynomial_ring=R)
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2020-06-09 00:03:49 -0500

Seen: 65 times

Last updated: Jun 09