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

Curves: add missing parametric constructors, remove _assure_has_components #267

Merged
merged 2 commits into from
Feb 9, 2021
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
4 changes: 2 additions & 2 deletions examples/AffinePlaneCurve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,13 @@ end
Return the reduced singular locus of `C` as a list whose first element is the affine plane curve consisting of the singular components of `C` (if any), and the second element is the list of the isolated singular points (which may be contained in the singular component). The singular component might not contain any point over the considered field.
"""
function curve_singular_locus(C::AffinePlaneCurve)
_assure_has_components(C)
comp = curve_components(C)
D = reduction(C)
Pts = Array{Point, 1}()
CC = Array{AffinePlaneCurve, 1}()
# The components with multiplicity > 1 are singular
f = []
for (h, c) in C.components
for (h, c) in comp
if c != 1
push!(f, h.eq)
end
Expand Down
63 changes: 28 additions & 35 deletions examples/DivisorCurve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct AffineCurveDivisor{S <: FieldElem} <: CurveDivisor
C::AffinePlaneCurve{S}
divisor::Dict{Point{S}, Int}
degree::Int
function AffineCurveDivisor(C::AffinePlaneCurve{S}, D::Dict{Point{S}, Int}) where S <: FieldElem
function AffineCurveDivisor{S}(C::AffinePlaneCurve{S}, D::Dict{Point{S}, Int}) where S <: FieldElem
for (P, m) in D
P in C || error("The point ", P.coord, " is not on the curve")
if m == 0
Expand All @@ -27,8 +27,16 @@ struct AffineCurveDivisor{S <: FieldElem} <: CurveDivisor
end
end

function AffineCurveDivisor(C::AffinePlaneCurve{S}) where S <: FieldElem
return AffineCurveDivisor{S}(C, Dict{Point{S}, Int}())
end

function AffineCurveDivisor(C::AffinePlaneCurve{S}, D::Dict{Point{S}, Int}) where S <: FieldElem
return AffineCurveDivisor{S}(C, D)
end

function AffineCurveDivisor(C::AffinePlaneCurve{S}, P::Point{S}, m::Int=1) where S <: FieldElem
return AffineCurveDivisor(C, Dict(P => m))
return AffineCurveDivisor{S}(C, Dict(P => m))
end

################################################################################
Expand All @@ -42,7 +50,7 @@ struct ProjCurveDivisor{S <: FieldElem} <: CurveDivisor
C::ProjPlaneCurve{S}
divisor::Dict{Oscar.Geometry.ProjSpcElem{S}, Int}
degree::Int
function ProjCurveDivisor(C::ProjPlaneCurve{S}, D::Dict{Oscar.Geometry.ProjSpcElem{S}, Int}) where S <: FieldElem
function ProjCurveDivisor{S}(C::ProjPlaneCurve{S}, D::Dict{Oscar.Geometry.ProjSpcElem{S}, Int}) where S <: FieldElem
for (P, m) in D
P in C || error("The point ", P, " is not on the curve")
if m == 0
Expand All @@ -53,8 +61,16 @@ struct ProjCurveDivisor{S <: FieldElem} <: CurveDivisor
end
end

function ProjCurveDivisor(C::ProjPlaneCurve{S}) where S <: FieldElem
return ProjCurveDivisor{S}(C, Dict{Oscar.Geometry.ProjSpcElem{S}, Int}())
end

function ProjCurveDivisor(C::ProjPlaneCurve{S}, D::Dict{Oscar.Geometry.ProjSpcElem{S}, Int}) where S <: FieldElem
return ProjCurveDivisor{S}(C, D)
end

function ProjCurveDivisor(C::ProjPlaneCurve{S}, P::Oscar.Geometry.ProjSpcElem{S}, m::Int=1) where S <: FieldElem
return ProjCurveDivisor(C, Dict(P => m))
return ProjCurveDivisor{S}(C, Dict(P => m))
end

################################################################################
Expand Down Expand Up @@ -116,14 +132,9 @@ end
################################################################################
# Sum of two divisors

function Base.:+(D::AffineCurveDivisor, E::AffineCurveDivisor)
function Base.:+(D::T, E::T) where T <: CurveDivisor
_check_same_curve(D, E)
return AffineCurveDivisor(D.C, merge(+, D.divisor, E.divisor))
end

function Base.:+(D::ProjCurveDivisor, E::ProjCurveDivisor)
_check_same_curve(D, E)
return ProjCurveDivisor(D.C, merge(+, D.divisor, E.divisor))
return T(D.C, merge(+, D.divisor, E.divisor))
end

################################################################################
Expand All @@ -141,35 +152,17 @@ function _help_minus(D::CurveDivisor, E::CurveDivisor)
return F
end

function Base.:-(D::AffineCurveDivisor, E::AffineCurveDivisor)
return AffineCurveDivisor(D.C, _help_minus(D, E))
end

function Base.:-(D::ProjCurveDivisor, E::ProjCurveDivisor)
return ProjCurveDivisor(D.C, _help_minus(D, E))
function Base.:-(D::T, E::T) where T <: CurveDivisor
return T(D.C, _help_minus(D, E))
end

################################################################################
################################################################################

function Base.:*(k::Int, D::AffineCurveDivisor{S}) where S <: FieldElem
if k == 0
return AffineCurveDivisor(D.C, Dict{Point{S}, Int}())
elseif k == 1
return D
else
return AffineCurveDivisor(D.C, Dict((P, k*m) for (P, m) in D.divisor))
end
end

function Base.:*(k::Int, D::ProjCurveDivisor{S}) where S <: FieldElem
if k == 0
return ProjCurveDivisor(D.C, Dict{Oscar.Geometry.ProjSpcElem{S}, Int}())
elseif k == 1
return D
else
return ProjCurveDivisor(D.C, Dict((P, k*m) for (P, m) in D.divisor))
end
function Base.:*(k::Int, D::T) where T <: CurveDivisor
k == 0 && return T(D.C)
k == 1 && return D
return T(D.C, Dict((P, k*m) for (P, m) in D.divisor))
end

################################################################################
Expand Down
64 changes: 23 additions & 41 deletions examples/PlaneCurve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ mutable struct AffinePlaneCurve{S <: FieldElem} <: PlaneCurve
degree::Int # degree of the equation of the curve
dimension::Int # dimension of the curve (as a variety)
components::Dict{AffinePlaneCurve{S}, Int}
function AffinePlaneCurve(eq::Oscar.MPolyElem{S}) where {S <: FieldElem}
function AffinePlaneCurve{S}(eq::Oscar.MPolyElem{S}) where {S <: FieldElem}
nvars(parent(eq)) == 2 || error("The defining equation must belong to a ring with two variables")
!isconstant(eq) || error("The defining equation must be non constant")
new{S}(eq,
Expand All @@ -106,6 +106,9 @@ mutable struct AffinePlaneCurve{S <: FieldElem} <: PlaneCurve
Dict{AffinePlaneCurve{S}, Int}())
end
end

AffinePlaneCurve(eq::Oscar.MPolyElem{S}) where {S <: FieldElem} = AffinePlaneCurve{S}(eq)

function Base.show(io::IO, C::AffinePlaneCurve)
if !get(io, :compact, false)
println(io, "Affine plane curve defined by ", C.eq)
Expand All @@ -121,7 +124,7 @@ mutable struct ProjPlaneCurve{S <: FieldElem} <: PlaneCurve
degree::Int # degree of the equation of the curve
dimension::Int # dimension of the curve (as a variety)
components::Dict{ProjPlaneCurve{S}, Int}
function ProjPlaneCurve(eq::Oscar.MPolyElem_dec{S}) where {S <: FieldElem}
function ProjPlaneCurve{S}(eq::Oscar.MPolyElem_dec{S}) where {S <: FieldElem}
nvars(parent(eq)) == 3 || error("The defining equation must belong to a ring with three variables")
!isconstant(eq) || error("The defining equation must be non constant")
ishomogenous(eq) || error("The defining equation is not homogeneous")
Expand All @@ -130,10 +133,12 @@ mutable struct ProjPlaneCurve{S <: FieldElem} <: PlaneCurve
1, # since C is a plane curve, the dimension is always 1
Dict{ProjPlaneCurve{S}, Int}())
end
function ProjPlaneCurve(eq::Oscar.MPolyElem{S}) where {S <: FieldElem}
R = grade(parent(eq))
return ProjPlaneCurve(R(eq))
end
end

ProjPlaneCurve(eq::Oscar.MPolyElem_dec{S}) where {S <: FieldElem} = ProjPlaneCurve{S}(eq)
function ProjPlaneCurve(eq::Oscar.MPolyElem{S}) where {S <: FieldElem}
R = grade(parent(eq))
return ProjPlaneCurve{S}(R(eq))
end

function Base.show(io::IO, C::ProjPlaneCurve)
Expand Down Expand Up @@ -218,28 +223,6 @@ function Oscar.jacobi_ideal(C::PlaneCurve)
return jacobi_ideal(C.eq)
end

################################################################################
# helping function: computes the irreducible components of the curve

function compo(C::AffinePlaneCurve)
D = factor(C.eq)
C.components = Dict(AffinePlaneCurve(x) => D.fac[x] for x in keys(D.fac))
end

function compo(C::ProjPlaneCurve)
D = factor(C.eq)
C.components = Dict(ProjPlaneCurve(x) => D.fac[x] for x in keys(D.fac))
end

################################################################################
# Helping function

function _assure_has_components(C::PlaneCurve)
if isempty(C.components)
compo(C)
end
end

################################################################################
# Components of the curve

Expand All @@ -249,7 +232,11 @@ end
Return a dictionary containing the irreducible components of `C` and their multiplicity.
"""
function curve_components(C::PlaneCurve)
_assure_has_components(C)
if isempty(C.components)
T = typeof(C)
D = factor(C.eq)
C.components = Dict(T(x) => D.fac[x] for x in keys(D.fac))
end
return C.components
end

Expand All @@ -263,8 +250,8 @@ end
Return `true` if `C` is irreducible, and `false` otherwise.
"""
function Oscar.isirreducible(C::PlaneCurve)
_assure_has_components(C)
return length(C.components) == 1 && all(isone, values(C.components))
comp = curve_components(C)
return length(comp) == 1 && all(isone, values(comp))
end

################################################################################
Expand Down Expand Up @@ -308,27 +295,22 @@ function reduction(C::AffinePlaneCurve)
end

function reduction(C::ProjPlaneCurve)
_assure_has_components(C)
F = prod(D -> D.eq, keys(C.components))
comp = curve_components(C)
F = prod(D -> D.eq, keys(comp))
rC = ProjPlaneCurve(F)
rC.components = Dict(ProjPlaneCurve(D.eq) => 1 for D in keys(C.components))
rC.components = Dict(ProjPlaneCurve(D.eq) => 1 for D in keys(comp))
return rC
end

################################################################################
# Union of two plane curves of the same type (with multiplicity)

@doc Markdown.doc"""
union(C::PlaneCurve{S}, D::PlaneCurve{S}) where S <: FieldElem
union(C::T, D::T) where T <: PlaneCurve

Return the union of `C` and `D` (with multiplicity).
"""
function Base.union(C::T, D::T) where T <: AffinePlaneCurve
return AffinePlaneCurve(C.eq*D.eq)
end
function Base.union(C::T, D::T) where T <: ProjPlaneCurve
return ProjPlaneCurve(C.eq*D.eq)
end
Base.union(C::T, D::T) where T <: PlaneCurve = T(C.eq*D.eq)

################################################################################

Expand Down