JuliaAlgebra / DynamicPolynomials.jl

Multivariate polynomials implementation of commutative and non-commutative variables
Other
60 stars 21 forks source link

How are variables attributed to polynomials? #79

Open tweisser opened 3 years ago

tweisser commented 3 years ago
using DynamicPolynomials

@polyvar x[1:4]

polys = [1 0 1 0; 0 1 0 1]*x
variables.(polys)
"""
2-element Array{Array{PolyVar{true},1},1}:
 [x₁, x₃]
 [x₁, x₂, x₃, x₄]
"""

Why is the first polynomial a polynomial in two variables whereas the second polynomial has all four variables?

blegat commented 3 years ago

Indeed, it should be

2-element Array{Array{PolyVar{true},1},1}:
 [x₁, x₂, x₃, x₄]
 [x₁, x₂, x₃, x₄]
manuelbb-upb commented 3 years ago

One fix is to overwrite the method _multconstant_to! (exported by MultivariatePolynomials, abbreviated as MP). The signature reads as _multconstant_to!(output, α, f, p) where output is a polynomial-like buffer. By default, if α == 0, the method performs operate_to!(zero, output). This creates an empty polynomial which only takes into account the variables already stored in output but disregards the variable(s) of p.

So in the file mult.jl I did define

function MP._multconstant_to!(output, α, f, p :: DMonomialLike)
    MP.mapcoefficientsnz_to!(output, f, p)
end

Now all variables are returned by variables.(polys).

manuelbb-upb commented 3 years ago

Ok, this leads to the tests of MP failing. I was looking at the right place but misinterpreted the output buffer. By the above method, zero coefficients get introduced. This seems to work fine though:

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

(effectively changing output to zero polynomial)