Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak vector_space(K, polynomials) a bit more #3727

Merged
merged 3 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions src/Rings/mpoly-graded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,7 @@ end
homogeneous_component(R::MPolyDecRing, g::FinGenAbGroupElem)

Given a polynomial ring `R` over a field which is graded by a free
group of type `FinGenAbGroup`, and given an element `g` of that group,
group, and given an element `g` of that group,
return the homogeneous component of `R` of degree `g` as a standard
vector space. Additionally, return the map which sends an element
of that vector space to the corresponding monomial in `R`.
Expand All @@ -1287,7 +1287,7 @@ an integer `d`, convert `d` into an element `g` of the grading group of `R`
proceed as above.

!!! note
If the component is not finite dimensional, an error message will be thrown.
If the component is not finite dimensional, an error will be thrown.

# Examples
```jldoctest
Expand Down Expand Up @@ -1348,9 +1348,9 @@ end


@doc raw"""
vector_space(K::Field, polys::Vector{T}; target = nothing) where {T <: MPolyRingElem}
vector_space(K::Field, polys::Vector{T}; target = nothing) where {T <: MPolyRingElem}

Return a `K`-vector space `V` and an epimorphism from `V` onto the `K`-vector
Return a `K`-vector space `V` and an isomorphism from `V` to the `K`-vector
Copy link
Collaborator

Choose a reason for hiding this comment

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

Caution: You should not change the (user-visible) behaviour of vector_space(Field, Polys) without looking at the other functions vector_space(Field, something), like vector_space(Field, MPolyQuoLocRing).
This needs to be consistent in behaviour!!! You are only tweaking one function here.

The main application is to pass from a zero-dimensional quotient ring R/I or slice of a graded ring R_d, which of course happens to carry the structure of a finite dimensional vector space, to an object of type vector space by using a monomial basis of the vector space. However, if this family of functions is provided to the user, it must be consistent in all instances.

Copy link
Collaborator

Choose a reason for hiding this comment

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

P.S.: I am not against the change per se.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm sorry, but I don't understand what should change here.
This is editing the doc string of the function vector_space(::Field, ::Vector{<:MPolyRingElem}). The other vector_space functions that seem related are:

vector_space(K::Field, Q::MPolyQuoRing)
vector_space(kk::Field, W::Oscar.MPolyQuoLocRing{<:Field, <:FieldElem, <:MPolyRing, <:MPolyRingElem, <:Oscar.MPolyComplementOfKPointIdeal}; ordering) 
vector_space(kk::Field, W::Oscar.MPolyQuoLocRing; ordering)

Neither of them is documented. Looking at the implementation, I assume that all of them return an isomorphic vector space and not just one that maps surjectively onto the quotient ring. If this assumption is correct, then this pull request will actually increase consistency.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, I abused "changes requested" to buy the time for checking myself that everything is consistent. I should have sent an e-mail instead.
I am now convinced that this does not break anything and does not cause anything inconsistent.

space spanned by the polynomials in `polys`.

Note that all polynomials must have the same parent `R`, and `K` must be equal
Expand All @@ -1363,13 +1363,12 @@ julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
julia> polys = [x + y, x - y, 2x + 3y];

julia> V, VtoPoly = vector_space(QQ, polys)
(Vector space of dimension 3 over QQ, Map: V -> R)
(Vector space of dimension 2 over QQ, Map: V -> R)

julia> VtoPoly.(basis(V))
3-element Vector{QQMPolyRingElem}:
2-element Vector{QQMPolyRingElem}:
x
y
0
```
"""
function vector_space(K::Field, polys::Vector{T}; target = nothing) where {T <: MPolyRingElem}
Expand All @@ -1385,7 +1384,7 @@ function vector_space(K::Field, polys::Vector{T}; target = nothing) where {T <:
expvec = Dict{Vector{Int}, Int}()
expvec_idx = Vector{Vector{Int}}()
M = sparse_matrix(K)

# take polynomials and turn them into sparse row vectors
for f in polys
pos = Vector{Int}()
Expand All @@ -1402,21 +1401,21 @@ function vector_space(K::Field, polys::Vector{T}; target = nothing) where {T <:
end

# row reduce
rref!(M)
d = rref!(M)

# turn the reduced sparse rows back into polynomials
b = Vector{elem_type(R)}()
for i in 1:nrows(M)
b = Vector{elem_type(R)}(undef, d)
for i in 1:d
s = MPolyBuildCtx(R)
for (k,v) in M[i]
push_term!(s, v, expvec_idx[k])
end
push!(b, finish(s))
b[i] = finish(s)
end

# create a standard vector space of the right dimension
F = free_module(K, length(b); cached = false)

# helper computing images
function img(x)
sum([x[i] * b[i] for i in 1:length(b) if !is_zero_entry(x.v, 1, i)]; init = zero(R))
Expand Down
2 changes: 2 additions & 0 deletions test/Rings/mpoly-graded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -255,13 +255,15 @@ end

M, h = vector_space(base_ring(R), elem_type(R)[], target = R)
t = h(zero(M))
@test dim(M) == 0
@test iszero(t)
@test parent(t) == R

# in this test the number of monomials exceed the dimension
# of the various vector spaces (this used to not work correctly)
polys = [x, y, (x+y+z)^3, 2*x - 5*y];
V, VtoPoly = vector_space(QQ, polys)
@test dim(V) == 3
@test all(f -> VtoPoly(preimage(VtoPoly, f)) == f, polys)
@test_throws ErrorException preimage(VtoPoly, z)

Expand Down
Loading