JuliaAlgebra / DynamicPolynomials.jl

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

Substitution of matrix values #117

Open kbarros opened 2 years ago

kbarros commented 2 years ago

How can I make a polynomial matrix-valued? I tried this:

using DynamicPolynomials
@ncpolyvar u
subs(u, u => 2.0) # works
subs(u, u => ones(3,3)) # ERROR: MethodError: no method matching one(::Type{Any})

The problem may be related to the promote_rules defined in MultivariatePolynomials?

import MultivariatePolynomials as MP
promote_type(Float64, DynamicPolynomials.PolyVar{false}) # Term{false, Float64}
promote_type(Matrix{Float64}, DynamicPolynomials.PolyVar{false}) # Term{false, Any}

I suspect the latter case would need to be Term{false, Matrix{Float64}}. Help would be appreciated!

blegat commented 2 years ago

Thanks for reporting this bug. I'm afk right now so a stacktrace could help

kbarros commented 2 years ago

Input:

using DynamicPolynomials
@ncpolyvar u
subs(u, u => ones(3,3))

Output stack trace:

ERROR: MethodError: no method matching one(::Type{Any})
Closest candidates are:
  one(::Type{Union{Missing, T}}) where T at missing.jl:105
  one(::Union{Type{T}, T}) where T<:AbstractString at strings/basic.jl:262
  one(::Union{Type{P}, P}) where P<:Dates.Period at ~/.julia/juliaup/julia-1.8.1+0.aarch64/share/julia/stdlib/v1.8/Dates/src/periods.jl:54
  ...
Stacktrace:
  [1] one(#unused#::Type{Any})
    @ Base ./missing.jl:106
  [2] convert(#unused#::Type{Term{false, Any}}, x::Monomial{false})
    @ DynamicPolynomials ~/.julia/packages/DynamicPolynomials/juS7t/src/term.jl:18
  [3] convert(#unused#::Type{Term{false, Any}}, x::PolyVar{false})
    @ DynamicPolynomials ~/.julia/packages/DynamicPolynomials/juS7t/src/term.jl:24
  [4] setindex!(A::Vector{Term{false, Any}}, x::PolyVar{false}, i1::Int64)
    @ Base ./array.jl:966
  [5] _unsafe_copyto!(dest::Vector{Term{false, Any}}, doffs::Int64, src::Vector{PolyVar{false}}, soffs::Int64, n::Int64)
    @ Base ./array.jl:253
  [6] unsafe_copyto!
    @ ./array.jl:307 [inlined]
  [7] _copyto_impl!
    @ ./array.jl:331 [inlined]
  [8] copyto!
    @ ./array.jl:317 [inlined]
  [9] copyto!
    @ ./array.jl:343 [inlined]
 [10] copy!(dst::Vector{Term{false, Any}}, src::Vector{PolyVar{false}})
    @ Base ./abstractarray.jl:887
 [11] copy!
    @ ~/.julia/juliaup/julia-1.8.1+0.aarch64/share/julia/stdlib/v1.8/Future/src/Future.jl:25 [inlined]
 [12] _subsmap
    @ ~/.julia/packages/DynamicPolynomials/juS7t/src/subs.jl:54 [inlined]
 [13] subsmap
    @ ~/.julia/packages/DynamicPolynomials/juS7t/src/subs.jl:59 [inlined]
 [14] substitute(st::MultivariatePolynomials.Subs, p::PolyVar{false}, s::Tuple{Pair{PolyVar{false}, Matrix{Float64}}})
    @ DynamicPolynomials ~/.julia/packages/DynamicPolynomials/juS7t/src/subs.jl:105
 [15] subs(p::PolyVar{false}, s::Pair{PolyVar{false}, Matrix{Float64}})
    @ MultivariatePolynomials ~/.julia/packages/MultivariatePolynomials/1bIGc/src/substitution.jl:113
 [16] top-level scope
    @ ~/Desktop/scratch.jl:43

I suspect that the fundamental problem is this:

promote_type(Matrix{Float64}, DynamicPolynomials.PolyVar{false}) == Term{false, Any}

Somehow the type Matrix{Float64} is getting lost.

blegat commented 2 years ago

Indeed, as a workaround, you can try u(u => ones(3,3)) which assumes that all variables are substituted which is the case here

kbarros commented 2 years ago

Perfect, that solves the problem for me.