Extend AbstractAlgebra ideals to rational coefficients

The extension should also let us work over finite fields of prime order,
although we don't need to do that.
This commit is contained in:
Aaron Fenyes 2024-01-29 19:11:21 -05:00
parent 0731c7aac1
commit 6349f298ae

View File

@ -7,6 +7,26 @@ using LinearAlgebra
using AbstractAlgebra
using Groebner
# --- commutative algebra ---
# as of version 0.36.6, AbstractAlgebra only supports ideals in multivariate
# polynomial rings when coefficients are integers. in `reduce_gens`, the
# `lmnode` constructor requires < to be defined on the coefficients, and the
# `reducer_size` heuristic requires `ndigits` to be defined on the coefficients.
# this patch for `reducer_size` removes the `ndigits` dependency
##function Generic.reducer_size(f::T) where {U <: MPolyRingElem{<:FieldElement}, V, N, T <: Generic.lmnode{U, V, N}}
## if f.size != 0.0
## return f.size
## end
## return 0.0 + sum(j^2 for j in 1:length(f.poly))
##end
# as of version 0.36.6, AbstractAlgebra only supports ideals in multivariate
# polynomial rings when the coefficients are integers. we use Groebner to extend
# support to rationals and to finite fields of prime order
Generic.reduce_gens(I::Generic.Ideal{U}) where {T <: FieldElement, U <: MPolyRingElem{T}} =
Generic.Ideal{U}(base_ring(I), groebner(gens(I)))
# --- primitve elements ---
abstract type Element{T} end
@ -23,8 +43,6 @@ mutable struct Point{T} <: Element{T}
) where T = new(coords, vec, nothing)
end
##coordnames(_::Point) = [:xₚ, :yₚ, :zₚ]
function buildvec!(pt::Point)
coordring = parent(pt.coords[1])
pt.vec = [one(coordring), dot(pt.coords, pt.coords), pt.coords...]
@ -43,8 +61,6 @@ mutable struct Sphere{T} <: Element{T}
) where T = new(coords, vec, rel)
end
##coordnames(_::Sphere) = [:rₛ, :sₛ, :xₛ, :yₛ, :zₛ]
function buildvec!(sph::Sphere)
coordring = parent(sph.coords[1])
sph.vec = sph.coords
@ -130,10 +146,6 @@ function realize(ctx::Construction{T}) where T
end
end
display(collect(elemenum))
display(coordnamelist)
println()
# construct coordinate ring
coordring, coordqueue = polynomial_ring(parent_type(T)(), coordnamelist, ordering = :degrevlex)
@ -150,16 +162,14 @@ function realize(ctx::Construction{T}) where T
# construct coordinate vectors
for (_, elem) in elemenum
buildvec!(elem)
display(elem.coords)
display(elem.vec)
println()
end
# turn relations into equations
vcat(
eqns = vcat(
equation.(ctx.relations),
[elem.rel for elem in ctx.elements if !isnothing(elem.rel)]
)
Generic.Ideal(coordring, eqns)
end
end
@ -172,22 +182,23 @@ a = Engine.Point{CoeffType}()
s = Engine.Sphere{CoeffType}()
a_on_s = Engine.LiesOn{CoeffType}(a, s)
ctx = Engine.Construction{CoeffType}(elements = Set([a]), relations= Set([a_on_s]))
eqns_a_s = Engine.realize(ctx)
ideal_a_s = Engine.realize(ctx)
b = Engine.Point{CoeffType}()
b_on_s = Engine.LiesOn{CoeffType}(b, s)
Engine.push!(ctx, b)
Engine.push!(ctx, s)
Engine.push!(ctx, b_on_s)
eqns_ab_s = Engine.realize(ctx)
ideal_ab_s = Engine.realize(ctx)
spheres = [Engine.Sphere{CoeffType}() for _ in 1:3]
tangencies = [
Engine.AlignsWithBy{CoeffType}(
spheres[n],
spheres[mod1(n+1, length(spheres))],
-1//1
CoeffType(-1//1)
)
for n in 1:3
]
ctx_chain = Engine.Construction{CoeffType}(elements = Set(spheres), relations = Set(tangencies))
ctx_chain = Engine.Construction{CoeffType}(elements = Set(spheres), relations = Set(tangencies))
ideal_chain = Engine.realize(ctx_chain)