|
export Monomial |
|
|
|
const TupOrVec{T} = Union{AbstractVector{T}, Tuple{Vararg{T}}} |
|
|
|
|
|
|
|
|
|
struct Monomial{C} <: AbstractMonomial |
|
vars::Vector{PolyVar{C}} |
|
z::Vector{Int} |
|
|
|
function Monomial{C}(vars::Vector{PolyVar{C}}, z::Vector{Int}) where {C} |
|
if length(vars) != length(z) |
|
throw(ArgumentError("There should be as many vars than exponents")) |
|
end |
|
new(vars, z) |
|
end |
|
end |
|
|
|
Monomial{C}(vars::Tuple{Vararg{PolyVar{C}}}, z::Vector{Int}) where C = Monomial{C}([vars...], z) |
|
|
|
iscomm(::Type{Monomial{C}}) where C = C |
|
Monomial{C}() where C = Monomial{C}(PolyVar{C}[], Int[]) |
|
Monomial(vars::TupOrVec{PolyVar{C}}, z::Vector{Int}) where C = Monomial{C}(vars, z) |
|
function Base.convert(::Type{Monomial{C}}, x::PolyVar{C}) where C |
|
return Monomial{C}([x], [1]) |
|
end |
|
Monomial(x::PolyVar{C}) where C = convert(Monomial{C}, x) |
|
function MP.convertconstant(::Type{Monomial{C}}, α) where C |
|
α == 1 || error("Cannot convert $α to a Monomial{$C} as it is not one") |
|
Monomial{C}(PolyVar{C}[], Int[]) |
|
end |
|
|
|
|
|
Monomial(α::Number) = convert(Monomial{true}, α) |
|
|
|
Base.broadcastable(m::Monomial) = Ref(m) |
|
Base.copy(m::M) where {M<:Monomial} = M(m.vars, copy(m.z)) |
|
|
|
|
|
function canonical(m::Monomial) |
|
list = m.z .> 0 |
|
Monomial(_vars(m)[list], m.z[list]) |
|
end |
|
function Base.hash(x::Monomial, u::UInt) |
|
cx = canonical(x) |
|
if iszero(nvariables(cx)) |
|
hash(1, u) |
|
elseif nvariables(cx) == 1 && cx.z[1] == 1 |
|
hash(cx.vars[1], u) |
|
else |
|
hash(_vars(cx), hash(cx.z, u)) |
|
end |
|
end |
|
|
|
MP.exponents(m::Monomial) = m.z |
|
|
|
_vars(m::Union{Monomial}) = m.vars |
|
|
|
MP.monomial(m::Monomial) = m |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|