Compare commits
3 Commits
0731c7aac1
...
65d23fb667
Author | SHA1 | Date | |
---|---|---|---|
|
65d23fb667 | ||
|
4e02ee16fc | ||
|
6349f298ae |
@ -1,3 +1,5 @@
|
||||
include("HittingSet.jl")
|
||||
|
||||
module Engine
|
||||
|
||||
export Construction, mprod
|
||||
@ -6,6 +8,24 @@ import Subscripts
|
||||
using LinearAlgebra
|
||||
using AbstractAlgebra
|
||||
using Groebner
|
||||
using ..HittingSet
|
||||
|
||||
# --- commutative algebra ---
|
||||
|
||||
# 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)))
|
||||
|
||||
function codimension(I::Generic.Ideal{U}, maxdepth = Inf) where {T <: RingElement, U <: MPolyRingElem{T}}
|
||||
leading = [exponent_vector(f, 1) for f in gens(I)]
|
||||
targets = [Set(findall(.!iszero.(exp_vec))) for exp_vec in leading]
|
||||
length(HittingSet.solve(HittingSetProblem(targets), maxdepth))
|
||||
end
|
||||
|
||||
dimension(I::Generic.Ideal{U}, maxdepth = Inf) where {T <: RingElement, U <: MPolyRingElem{T}} =
|
||||
length(gens(base_ring(I))) - codimension(I, maxdepth)
|
||||
|
||||
# --- primitve elements ---
|
||||
|
||||
@ -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,26 @@ 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)
|
||||
println("A point on a sphere: ", Engine.dimension(ideal_a_s), " degrees of freeom")
|
||||
|
||||
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)
|
||||
println("Two points on a sphere: ", Engine.dimension(ideal_ab_s), " degrees of freeom")
|
||||
|
||||
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_tan_sph = Engine.Construction{CoeffType}(elements = Set(spheres), relations = Set(tangencies))
|
||||
ideal_tan_sph = Engine.realize(ctx_tan_sph)
|
||||
println("Three mutually tangent spheres: ", Engine.dimension(ideal_tan_sph), " degrees of freeom")
|
@ -1,13 +1,15 @@
|
||||
module HittingSet
|
||||
|
||||
export HittingSetProblem, solve
|
||||
|
||||
HittingSetProblem{T} = Pair{Set{T}, Vector{Pair{T, Set{Set{T}}}}}
|
||||
|
||||
# `subsets` should be a collection of Set objects
|
||||
function HittingSetProblem(subsets, chosen = Set())
|
||||
wholeset = union(subsets...)
|
||||
# `targets` should be a collection of Set objects
|
||||
function HittingSetProblem(targets, chosen = Set())
|
||||
wholeset = union(targets...)
|
||||
T = eltype(wholeset)
|
||||
unsorted_moves = [
|
||||
elt => Set(filter(s -> elt ∉ s, subsets))
|
||||
elt => Set(filter(s -> elt ∉ s, targets))
|
||||
for elt in wholeset
|
||||
]
|
||||
moves = sort(unsorted_moves, by = pair -> length(pair.second))
|
||||
@ -32,7 +34,6 @@ end
|
||||
|
||||
function solve(pblm::HittingSetProblem{T}, maxdepth = Inf) where T
|
||||
problems = Dict(pblm)
|
||||
println(typeof(problems))
|
||||
while length(first(problems).first) < maxdepth
|
||||
subproblems = typeof(problems)()
|
||||
for (chosen, moves) in problems
|
||||
@ -56,7 +57,7 @@ end
|
||||
|
||||
function test(n = 1)
|
||||
T = [Int64, Int64, Symbol, Symbol][n]
|
||||
subsets = Set{T}.([
|
||||
targets = Set{T}.([
|
||||
[
|
||||
[1, 3, 5],
|
||||
[2, 3, 4],
|
||||
@ -98,7 +99,7 @@ function test(n = 1)
|
||||
[:b, :z, :t14]
|
||||
]
|
||||
][n])
|
||||
problem = HittingSetProblem(subsets)
|
||||
problem = HittingSetProblem(targets)
|
||||
if isa(problem, HittingSetProblem{T})
|
||||
println("Correct type")
|
||||
else
|
Loading…
Reference in New Issue
Block a user