From 28da9ab2b06e0f257a82f7371e1101dd957893bd Mon Sep 17 00:00:00 2001 From: manuelbb-upb Date: Fri, 12 Mar 2021 08:10:36 +0100 Subject: [PATCH 1/5] fix of issue #81 (merged commits) --- src/mult.jl | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/mult.jl b/src/mult.jl index 06a3e85..60e4ff9 100644 --- a/src/mult.jl +++ b/src/mult.jl @@ -29,6 +29,19 @@ include("cmult.jl") include("ncmult.jl") MP.multconstant(α, x::Monomial) = MP.term(α, MA.mutable_copy(x)) + +function zero_with_variables( ::Type{Polynomial{C,T}}, vars :: Vector{PolyVar{C}} ) where{C, T} + Polynomial( T[], emptymonovec(vars) ) +end + +function MP._multconstant(α::T, f, p::Polynomial{C,S} ) where {T, C, S} + if iszero(α) + zero_with_variables(polynomialtype(p, MA.promote_operation(*, T, S)), variables(p)) + else + MP.mapcoefficientsnz(f, p) + end +end + MP.mapcoefficientsnz(f::Function, p::Polynomial) = Polynomial(map(f, p.a), MA.mutable_copy(p.x)) function MP.mapcoefficientsnz_to!(output::Polynomial, f::Function, t::MP.AbstractTermLike) MP.mapcoefficientsnz_to!(output, f, polynomial(t)) @@ -60,7 +73,7 @@ end function _term_poly_mult(t::Term{C, S}, p::Polynomial{C, T}, op::Function) where {C, S, T} U = MA.promote_operation(op, S, T) if iszero(t) - zero(Polynomial{C, U}) + zero( Polynomial{C,U} ) else n = nterms(p) allvars, maps = mergevars([t.x.vars, p.x.vars]) @@ -135,6 +148,7 @@ function MA.mutable_operate_to!(p::Polynomial{true, T}, ::typeof(*), q1::MP.Abst polynomialclean_to!(p, _mul(T, q1, q2)...) end end + function MA.mutable_operate!(::typeof(*), p::Polynomial{C}, q::Polynomial{C}) where C return MA.mutable_operate_to!(p, *, p, q) end From a77f780ee7f2070687cc5871490e29aa410f3168 Mon Sep 17 00:00:00 2001 From: manuelbb-upb Date: Fri, 12 Mar 2021 08:19:22 +0100 Subject: [PATCH 2/5] 1) fix of issue #79; also extended to work with terms --- src/mult.jl | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/mult.jl b/src/mult.jl index 60e4ff9..e97acb4 100644 --- a/src/mult.jl +++ b/src/mult.jl @@ -30,11 +30,11 @@ include("ncmult.jl") MP.multconstant(α, x::Monomial) = MP.term(α, MA.mutable_copy(x)) -function zero_with_variables( ::Type{Polynomial{C,T}}, vars :: Vector{PolyVar{C}} ) where{C, T} +function zero_with_variables( ::Type{<:TermPoly{C,T}}, vars :: Vector{PolyVar{C}} ) where{C, T} Polynomial( T[], emptymonovec(vars) ) end -function MP._multconstant(α::T, f, p::Polynomial{C,S} ) where {T, C, S} +function MP._multconstant(α::T, f, p::TermPoly{C,S} ) where {T, C, S} if iszero(α) zero_with_variables(polynomialtype(p, MA.promote_operation(*, T, S)), variables(p)) else @@ -148,7 +148,15 @@ function MA.mutable_operate_to!(p::Polynomial{true, T}, ::typeof(*), q1::MP.Abst polynomialclean_to!(p, _mul(T, q1, q2)...) end end - function MA.mutable_operate!(::typeof(*), p::Polynomial{C}, q::Polynomial{C}) where C return MA.mutable_operate_to!(p, *, p, q) end + +# Overwrite this method for monomial-like terms because +# otherwise it would check `iszero(α)` and in that case +# dismiss of the variable of `p` by performing +# `operate_to!(zero, output :: Polynomial )` which only +# respects the variables that are stored already +function MP._multconstant_to!(output, α, f, p :: DMonomialLike) + MP.mapcoefficientsnz_to!(output, f, p) +end From 645a0c13138fa2638cf63a563cda73da0560363e Mon Sep 17 00:00:00 2001 From: manuelbb-upb Date: Fri, 12 Mar 2021 10:43:46 +0100 Subject: [PATCH 3/5] concerning #79: Now mutating output buffer; concerning #81: removed overspecialization of last commit - that broke tests too --- src/mult.jl | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/mult.jl b/src/mult.jl index e97acb4..9433ae3 100644 --- a/src/mult.jl +++ b/src/mult.jl @@ -30,11 +30,11 @@ include("ncmult.jl") MP.multconstant(α, x::Monomial) = MP.term(α, MA.mutable_copy(x)) -function zero_with_variables( ::Type{<:TermPoly{C,T}}, vars :: Vector{PolyVar{C}} ) where{C, T} +function zero_with_variables( ::Type{Polynomial{C,T}}, vars :: Vector{PolyVar{C}} ) where{C, T} Polynomial( T[], emptymonovec(vars) ) end -function MP._multconstant(α::T, f, p::TermPoly{C,S} ) where {T, C, S} +function MP._multconstant(α::T, f, p::Polynomial{C,S} ) where {T, C, S} if iszero(α) zero_with_variables(polynomialtype(p, MA.promote_operation(*, T, S)), variables(p)) else @@ -153,10 +153,18 @@ function MA.mutable_operate!(::typeof(*), p::Polynomial{C}, q::Polynomial{C}) wh end # Overwrite this method for monomial-like terms because -# otherwise it would check `iszero(α)` and in that case -# dismiss of the variable of `p` by performing +# otherwise it would check `iszero(α)` and in that case +# dismiss of the variable of `p` by performing # `operate_to!(zero, output :: Polynomial )` which only # respects the variables that are stored already -function MP._multconstant_to!(output, α, f, p :: DMonomialLike) - MP.mapcoefficientsnz_to!(output, f, p) +function MP._multconstant_to!(output::Polynomial, α, f, p :: DMonomialLike) + if iszero(α) + empty!(output.a) + empty!(output.x.vars) + push!(output.x.vars, variables(p)...) + empty!(output.x.Z) + return output + else + MP.mapcoefficientsnz_to!(output, f, p) + end end From bc08ce064358f7fa1260d6895d25c62713ab76a9 Mon Sep 17 00:00:00 2001 From: Manuel Berkemeier Date: Mon, 15 Mar 2021 09:36:40 +0100 Subject: [PATCH 4/5] Implemented review suggestions; added tests from issue descriptions --- src/mult.jl | 12 +++++------- test/runtests.jl | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/mult.jl b/src/mult.jl index 9433ae3..b4e492a 100644 --- a/src/mult.jl +++ b/src/mult.jl @@ -30,8 +30,8 @@ include("ncmult.jl") MP.multconstant(α, x::Monomial) = MP.term(α, MA.mutable_copy(x)) -function zero_with_variables( ::Type{Polynomial{C,T}}, vars :: Vector{PolyVar{C}} ) where{C, T} - Polynomial( T[], emptymonovec(vars) ) +function zero_with_variables(::Type{Polynomial{C,T}}, vars::Vector{PolyVar{C}}) where{C, T} + Polynomial(T[], emptymonovec(vars)) end function MP._multconstant(α::T, f, p::Polynomial{C,S} ) where {T, C, S} @@ -73,7 +73,7 @@ end function _term_poly_mult(t::Term{C, S}, p::Polynomial{C, T}, op::Function) where {C, S, T} U = MA.promote_operation(op, S, T) if iszero(t) - zero( Polynomial{C,U} ) + zero(Polynomial{C,U}) else n = nterms(p) allvars, maps = mergevars([t.x.vars, p.x.vars]) @@ -159,10 +159,8 @@ end # respects the variables that are stored already function MP._multconstant_to!(output::Polynomial, α, f, p :: DMonomialLike) if iszero(α) - empty!(output.a) - empty!(output.x.vars) - push!(output.x.vars, variables(p)...) - empty!(output.x.Z) + MA.mutable_operate!(zero, output) + Future.copy!(output.x,vars, variables(p)) return output else MP.mapcoefficientsnz_to!(output, f, p) diff --git a/test/runtests.jl b/test/runtests.jl index 99dbf13..4bfcef7 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -12,6 +12,25 @@ using LinearAlgebra @test p(x0 => y0, x1 => y1) == y1 * y0 * y1 end +@testset "Issue #79 and Issue #80" begin + @polyvar x[1:2] + p1 = x[1] * 0.0 + x[2] * 0 + p2 = ( x[1] + x[2] ) * 0.0 + @test variables(p1) == x + @test variables(p1) == variables(p2) + + @polyvar χ[1:4] + poly_array_int = [1 0 1 0; 0 1 0 1]*χ; + poly_array_float = Float64.([1 0 1 0; 0 1 0 1])*χ; + + vars_array_int = variables.(poly_array_int); + vars_array_float = variables.(poly_array_float) + @test isa(vars_array_int, Vector{<:Vector{<:PolyVar}}) + @test isa(vars_array_float, Vector{<:Vector{<:PolyVar}}) + @test vars_array_int == vars_array_float + @test vars_array_int[1] == vars_array_float[2] == χ +end + include("mono.jl") include("poly.jl") include("comp.jl") From 82f3c355a1dd051eb1fb687f4d7ff0cd41a4e6cc Mon Sep 17 00:00:00 2001 From: Manuel Berkemeier Date: Mon, 15 Mar 2021 10:01:03 +0100 Subject: [PATCH 5/5] `.` instead of accidental `comma` in file `mult.jl`, function `_multconstant_to!` --- src/mult.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mult.jl b/src/mult.jl index b4e492a..eba42b1 100644 --- a/src/mult.jl +++ b/src/mult.jl @@ -160,7 +160,7 @@ end function MP._multconstant_to!(output::Polynomial, α, f, p :: DMonomialLike) if iszero(α) MA.mutable_operate!(zero, output) - Future.copy!(output.x,vars, variables(p)) + Future.copy!(output.x.vars, variables(p)) return output else MP.mapcoefficientsnz_to!(output, f, p)