Macaulay2 / Macaulay2/M2

reesIdeal(I, a) saturates in a tower ring, where most saturate strategies decline, so it cannot finish where flattening first takes ten seconds

Open
#4,638 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bugs directory Core
Dominant language
Macaulay2
Stars
435
Forks
297
Avg merge
4d 20h
Merged PRs (30d)
11

Description

This issue was triaged from bugs/mike/bench-1-rees.m2, one of the 857 files removed from the pre-GitHub bugs/ tree by d2c8d27826 and catalogued in #36. The commentary below was written by Claude (Claude Opus 5, via Claude Code), not by @d-torrance, whose account posted it -- please weigh it accordingly.

The original file, verbatim
-- Add these examples to the ReesAlgebra benchmark code
kk=ZZ/101
n=6
S=kk[vars(0..n)]
i=monomialCurveIdeal(S,{4,8,11,13,15})
time reesIdeal(i) -- 1.7 sec
--time reesIdeal(i,i_0) -- doesn't finish before I get impatient (10 min?)!


restart
loadPackage "ReesAlgebra2"
kk=ZZ/101
n=3
S=kk[vars(0..n)]
i=ideal random(S^1, S^{-3,-4,-5,-6})
time reesIdeal(i) --8.4 sec
time reesIdeal(i,i_0) --1.4sec
Where it stands today

reesIdeal(I, a) — the two-argument form, whose comment in the source reads "the following method, usually
faster" — does not finish on a 7-variable monomial curve where the one-argument form takes two seconds:

i1 : needsPackage "ReesAlgebra";

i2 : S = ZZ/101[vars(0..6)];

i3 : i = monomialCurveIdeal(S, {4,8,11,13,15});

o3 : Ideal of S

i4 : elapsedTime reesIdeal i;                  -- 24 generators
 -- 1.93899s elapsed

i5 : elapsedTime reesIdeal(i, i_0);            -- killed at 15 minutes

i_0 is e^2-d*f, a nonzero element of a domain, so it is a non-zerodivisor and the method's precondition
holds. The file this comes from records the same behaviour in 2013 — "doesn't finish before I get impatient
(10 min?)" — so this is not a regression.

Where the time goes
reesIdeal(Module, RingElement) := Ideal => o -> (I, I0) -> (
    if o.Trim == true then I' := trim I else I' = I;
    K' := if o.Jacobian == true then expectedReesIdeal I' else (
    K' = symmetricAlgebraIdeal I';
    R := ring K';
    IR := substitute(I0, R);
    trim saturate(K', IR)                                    -- <-- unbounded
    ))
step cost
trim i, then trim module 0.0008 s, 0.0003 s
symmetricAlgebraIdeal 56.8 s
saturate(K', IR) > 180 s, no result
The saturation happens in a tower, which disables most of saturate

symmetricAlgebraIdeal returns an ideal in S[w_0..w_7] — a polynomial ring whose coefficient ring is
itself a polynomial ring:

i6 : R = ring symmetricAlgebraIdeal trim module trim i;

i7 : numgens R, coefficientRing R
o7 = (8, S)

saturate's strategies gate on isFlatPolynomialRing, defined at Saturation.m2:72 as

isFlatPolynomialRing = R -> isPolynomialRing R and (isField(kk := coefficientRing R) or kk === ZZ)

which is false here because coefficientRing R is S. It is checked at Saturation.m2:533, 555 and
579, so Linear, Bayer, GRevLex and Eliminate all decline the input — each returns in under a
millisecond — leaving only Iterate, which is the naive loop.

Flattening the ring first, and changing nothing else, makes the same saturation finish:

ring isFlatPolynomialRing saturate(K, i_0), default options
S[w_0..w_7], 8 vars over S false > 180 s, no result
flattenRing of it: 15 vars over ZZ/101 true 9.9 s, 24 generators

The 24 generators agree with what reesIdeal i returns, so this is the same answer by a different route.

What I could not determine

In the flat ring, Strategy => Eliminate and Strategy => Iterate each also exceeded 300 s, yet the
default chain returned in 9.9 s. So the measurement above shows that flattening makes the step fast, but
not which strategy is responsible for that, and the mechanism I can name — the four strategies declining
the tower — does not by itself account for the flat-ring default being faster than any strategy I could
select by hand. Worth someone with more knowledge of the hook order looking at, since it may point at a
second, separate problem in how (saturate, Ideal, RingElement) dispatches.

One caveat about what fixing this would buy

Even with the saturation flattened, the two-argument form would total roughly 67 s on this example against
1.94 s for reesIdeal i, so the "usually faster" claim above the method still would not hold here. The
change is from does not finish to finishes, not from slow to fast. The file's second example runs the
other way — reesIdeal(i) 8.4 s against reesIdeal(i, i_0) 1.4 s on
ideal random(S^1, S^{-3,-4,-5,-6}) in four variables — so the method is genuinely worth having; it just
should not be able to hang on a seven-variable monomial curve.

Searches this rests on

Titles and bodies for reesIdeal, ReesAlgebra, symmetricKernel, symmetricAlgebraIdeal, saturate,
flattenRing, tower and isFlatPolynomialRing, and comments via gh search issues for reesIdeal.
Nothing mentions reesIdeal outside the package's own history.
#4308 is (saturate, Module, Ideal) being broken, a
different method; the open flattenRing issues
(#2133,
#3887,
#4578,
#4579) are about flattenRing itself rather than about
callers that fail to use it.

open · disposition issue · source of truth: bug-triage/catalog.tsv

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the monomial-curve example with the two-argument reesIdeal entry point, then inspect the saturation dispatch and the isFlatPolynomialRing checks at Saturation.m2:72, 533, 555, and 579. Compare the tower-ring and flattenRing timings and review the default strategy hook order. Done means the case finishes reliably without changing the computed 24 generators.

Written by the indexing model from the issue text.

Assessment

Domain
tooling
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.