Skip to content

Speed up vector_space_basis for SubquoModule#5915

Draft
Syz-MS wants to merge 8 commits intooscar-system:masterfrom
Syz-MS:ms/tune-vector_space_basis
Draft

Speed up vector_space_basis for SubquoModule#5915
Syz-MS wants to merge 8 commits intooscar-system:masterfrom
Syz-MS:ms/tune-vector_space_basis

Conversation

@Syz-MS
Copy link
Copy Markdown
Contributor

@Syz-MS Syz-MS commented Apr 2, 2026

Tunes vector_space_basis for a SubquoModule over a MPolyAnyRing by reducing the number of monomials that need to be checked individually to be in the leading module of interest.
This is achieved by computing (and caching):

  • the smallest degrees of monomials on each axes of the monomial diagramm of the leading module,
  • the smallest degree of monomials contained in the leading module for each cooardinate,
  • cheap upper bounds on the degree for monomials not contained in the leading module for each coordinate.

Using this data the number of monomials which need to be check individually in each coordinate of the ambient free module is reduced.

Examples like this motivated these optimizations:

R, (v, w, y, x, z, a, b, c) = QQ[:v, :w, :y, :x, :z, :a, :b, :c];
F = free_module(R, 6);
rels = [F[1], F[2], F[3], F[4], F[5], v*F[6], w*F[6], x*F[6], z*F[6], b*F[6], c*F[6], y*a*F[6], y^7*F[6], a^8*F[6]];
T1, _ = quo(F, rels);


# Before:

julia> @be vector_space_basis(QQ, M)
Benchmark: 1 sample with 1 evaluation
        3.958 s (30679969 allocs: 1.059 GiB, 21.62% gc time, without a warmup)


# After:

julia> @be vector_space_basis(QQ, M)
Benchmark: 77 samples with 1 evaluation
 min    1.275 ms (11307 allocs: 406.172 KiB)
 median 1.304 ms (12417 allocs: 423.516 KiB)
 mean   1.306 ms (12365.94 allocs: 424.931 KiB)
 max    1.346 ms (12417 allocs: 428.391 KiB)

Even in (smaller) examples, which profit less from these optimizations, there is a slight speed up:

R, (x,y) = QQ[:x, :y]; 
F = free_module(R, 2);
M, _ = quo(F, [x^2*F[1], y^3*F[1], x^15*F[2], y*F[2]]);

m = ideal(R, gens(R)); 
S,_ = m^3*F;
N,_ = quo(F, S);


# Before:

@be vector_space_basis(QQ, M)
Benchmark: 20 samples with 1 evaluation
 min    5.083 ms (55547 allocs: 1.614 MiB)
 median 5.162 ms (56627 allocs: 1.630 MiB)
 mean   5.223 ms (56553.45 allocs: 1.629 MiB)
 max    5.794 ms (56627 allocs: 1.630 MiB)

julia> @be vector_space_basis(QQ, N)
Benchmark: 82 samples with 1 evaluation
 min    891.864 μs (9041 allocs: 249.273 KiB)
 median 1.265 ms (9041 allocs: 249.273 KiB)
 mean   1.216 ms (9041 allocs: 249.273 KiB)
 max    1.541 ms (9041 allocs: 249.273 KiB)


# After:

julia> @be vector_space_basis(QQ, M)
Benchmark: 98 samples with 1 evaluation
 min    957.708 μs (8263 allocs: 246.797 KiB)
 median 1.011 ms (8263 allocs: 246.797 KiB)
 mean   1.018 ms (8263 allocs: 246.797 KiB)
 max    1.389 ms (8263 allocs: 246.797 KiB)

julia> @be vector_space_basis(QQ, N)
Benchmark: 316 samples with 1 evaluation
 min    284.945 μs (2503 allocs: 75.867 KiB)
 median 298.716 μs (2503 allocs: 75.867 KiB)
 mean   302.136 μs (2503 allocs: 75.867 KiB)
 max    491.052 μs (2503 allocs: 75.867 KiB)

Edit: Also overwrites the generic function _vector_space_dim(kk::Field, M::SubquoModule; check::Bool=true) for presented SubquoModules over a MPolyAnyRing over a Field (Localized rings only at a point) with wrappers to Singular's vdim.

@joschmitt joschmitt added enhancement New feature or request optimization Simpler/more performant code or more/better tests topic: commutative algebra release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes labels Apr 2, 2026
Copy link
Copy Markdown
Collaborator

@HechtiDerLachs HechtiDerLachs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Looks good on a first glance. I will read it more carefully later.

Comment thread src/Modules/UngradedModules/Methods.jl Outdated
o = negdegrevlex(base_ring(M_shift))*lex(ambient_free_module(M_shift))
return _has_monomials_on_all_axes(leading_module(M_shift.quo, o))
ord = negdegrevlex(base_ring(M_shift))*lex(ambient_free_module(M_shift))
return _has_monomials_on_all_axes(standard_basis(M_shift.quo, ordering = ord))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid, this might be doing something wrong here. @afkafkafk13 : There was a reason why the leading_module was used in the local case, wasn't it? Or was this resolved?

Copy link
Copy Markdown
Contributor Author

@Syz-MS Syz-MS Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced the code of _has_monomials_on_all_axes() above to accept the ModuleGens of a standard basis GB as an input and compute for the corresponding leading module whether it has monomials on all axes.

So maybe the function should be renamed to _has_leading_monomials_on_all_axes(GB) ??

Edit: I also forgot to change the signature in the docstring

singular_gens = singular_generators(F)
return ModuleGens(oscar_free_module(F), Singular.lead(singular_gens))
mg = ModuleGens(oscar_free_module(F), Singular.lead(singular_gens))
mg.S.isGB = true # TODO: should be set in lead in Singular
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we open a PR on Singular.jl for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can open a PR later.

@Syz-MS
Copy link
Copy Markdown
Contributor Author

Syz-MS commented Apr 2, 2026

This should fix the failing doctest due to #5914

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request optimization Simpler/more performant code or more/better tests release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes topic: commutative algebra

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants