Skip to content

Commit 7c5153d

Browse files
committed
v0.4.0
1 parent 603d61c commit 7c5153d

File tree

6 files changed

+50
-13
lines changed

6 files changed

+50
-13
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "MultivariatePolynomials"
22
uuid = "102ac46a-7ee4-5c85-9060-abc95bfdeaa3"
33
license = "MIT"
44
repo = "https://github.com/JuliaAlgebra/MultivariatePolynomials.jl"
5-
version = "0.3.18"
5+
version = "0.4.0"
66

77
[deps]
88
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"

docs/make.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ makedocs(
77
# See https://github.com/JuliaDocs/Documenter.jl/issues/868
88
prettyurls = get(ENV, "CI", nothing) == "true"
99
),
10-
# See https://github.com/JuliaOpt/JuMP.jl/issues/1576
10+
# See https://github.com/jump-dev/JuMP.jl/issues/1576
1111
strict = true,
1212

1313
pages = [

src/conversion.jl

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export variable
1+
export variable, convert_to_constant
22

33
function convertconstant end
44
Base.convert(::Type{P}, α) where P<:APL = convertconstant(P, α)
@@ -60,18 +60,23 @@ function Base.convert(::Type{T}, p::AbstractPolynomial) where T <: AbstractTermL
6060
end
6161

6262
MA.scaling(p::AbstractPolynomialLike{T}) where {T} = convert(T, p)
63-
# Conversion polynomial -> scalar
64-
function scalarize(::Type{S}, p::APL) where S
63+
# Conversion polynomial -> constant
64+
# We don't define a method for `Base.convert` to reduce invalidations;
65+
# see https://github.com/JuliaAlgebra/MultivariatePolynomials.jl/pull/172
66+
function convert_to_constant(::Type{S}, p::APL) where S
6567
s = zero(S)
6668
for t in terms(p)
6769
if !isconstant(t)
6870
# The polynomial is not constant
69-
throw(InexactError(:convert, S, p))
71+
throw(InexactError(:convert_to_constant, S, p))
7072
end
71-
s += S(coefficient(t))
73+
s = MA.add!!(s, convert(S, coefficient(t)))
7274
end
73-
s
75+
return s
76+
end
77+
Base.convert(::Type{T}, p::APL) where T<:Number = convert_to_constant(T, p)
78+
function convert_to_constant(p::APL{S}) where {S}
79+
return convert_to_constant(S, p)
7480
end
75-
Base.convert(::Type{T}, p::APL) where T<:Number = scalarize(T, p)
7681

7782
Base.convert(::Type{PT}, p::PT) where {PT<:APL} = p

src/monovec.jl

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,34 @@ function monovec(X::AbstractVector{MT}) where {MT<:AbstractMonomial}
2626
end
2727
monovec(X::AbstractVector{TT}) where {TT<:AbstractTermLike} = monovec(AbstractVector{monomialtype(TT)}(X))
2828

29+
"""
30+
monovec(a, X::AbstractVector{MT}) where {MT<:AbstractMonomialLike}
31+
32+
Returns `b, Y` where `Y` is the vector of monomials of `X` in decreasing order
33+
and without any duplicates and `b` is the vector of corresponding coefficients
34+
in `a`, where coefficients of duplicate entries are summed together.
35+
36+
### Examples
37+
38+
Calling `monovec` on ``[2, 1, 4, 3, -1], [xy, x, xy, x^2y, x]`` should return
39+
``[3, 6, 0], [x^2y, xy, x]``.
40+
"""
2941
function monovec(a, x)
3042
if length(a) != length(x)
3143
throw(ArgumentError("There should be as many coefficient than monomials"))
3244
end
3345
σ, X = sortmonovec(x)
34-
(a[σ], X)
46+
b = a[σ]
47+
if length(x) > length(X)
48+
rev = Dict(X[j] => j for j in eachindex(σ))
49+
for i in eachindex(x)
50+
j = rev[x[i]]
51+
if i != σ[j]
52+
b[j] += a[i]
53+
end
54+
end
55+
end
56+
return b, X
3557
end
3658

3759
"""

src/polynomial.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ end
5858

5959
polynomial(f::Function, mv::AbstractVector{<:AbstractMonomialLike}) = polynomial!([term(f(i), mv[i]) for i in 1:length(mv)])
6060

61-
polynomial(a::AbstractVector, x::AbstractVector, s::ListState=MessyState()) = polynomial([term(α, m) for (α, m) in zip(a, x)], s)
61+
function polynomial(a::AbstractVector, x::AbstractVector, s::ListState=MessyState())
62+
# If `x` is e.g. `[v, 1]` then it will contains terms that are convertible to monomials.
63+
return polynomial([term(α, convert(monomialtype(m), m)) for (α, m) in zip(a, x)], s)
64+
end
6265

6366
polynomial(ts::AbstractVector, s::ListState=MessyState()) = sum(ts)
6467
polynomial!(ts::AbstractVector, s::ListState=MessyState()) = sum(ts)

test/polynomial.jl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,9 @@ const MP = MultivariatePolynomials
105105

106106
@inferred polynomial(i -> float(i), [x, x*x])
107107
@inferred polynomial(i -> 3 - float(i), monovec([x*x, x]))
108-
for p in (polynomial(i -> float(i), [x, x*x]),
109-
polynomial(i -> 3 - float(i), monovec([x*x, x])))
108+
for p in [polynomial(i -> float(i), [x, x*x]),
109+
polynomial(i -> 1.0, [x*x, x, x*x]),
110+
polynomial(i -> 3 - float(i), monovec([x*x, x]))]
110111
@test coefficients(p) == [2.0, 1.0]
111112
@test monomials(p) == monovec([x^2, x])
112113
end
@@ -143,10 +144,16 @@ const MP = MultivariatePolynomials
143144
end
144145

145146
@testset "Convertion" begin
147+
Mod.@polyvar x y z
146148
p = 2.5x + 1 - 2.5x
147149
@test convert(Int, p) == 1
148150
@test convert(typeof(p), p) === p
149151
@test convert(Union{Nothing, typeof(p)}, p) === p
152+
a = 2y
153+
q = polynomial([a, z, -a], [x, 1, x])
154+
@test convert_to_constant(q) == z
155+
q = polynomial([a, z], [x, 1])
156+
@test_throws InexactError convert_to_constant(q)
150157
end
151158

152159
@testset "Vector" begin

0 commit comments

Comments
 (0)