Skip to content

Commit 450870d

Browse files
authored
Fix variable with subs of zero power (#135)
* Fix variable with subs of zero power * Fix * Fix
1 parent b01cfa5 commit 450870d

File tree

7 files changed

+53
-90
lines changed

7 files changed

+53
-90
lines changed

src/DynamicPolynomials.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@ include("var.jl")
1313
#const NonCommutativeVariable{O,M} = Variable{NonCommutative{O},M}
1414
include("mono.jl")
1515
const DMonomialLike{V,M} = Union{Monomial{V,M},Variable{V,M}}
16-
MA.mutability(::Type{<:Monomial}) = MA.IsMutable()
16+
MA.mutability(::Type{<:Monomial{<:Commutative}}) = MA.IsMutable()
17+
MA.mutability(::Type{<:Monomial{<:NonCommutative}}) = MA.IsNotMutable()
1718
const _Term{V,M,T} = MP.Term{T,Monomial{V,M}}
19+
function __add_variables!(t::_Term, allvars, map)
20+
return __add_variables!(MP.monomial(t), allvars, map)
21+
end
1822
include("monomial_vector.jl")
1923
include("poly.jl")
2024
MA.mutability(::Type{<:Polynomial}) = MA.IsMutable()
@@ -28,7 +32,7 @@ function MP.variable_union_type(
2832
end
2933
MP.constant_monomial(::Type{<:PolyType{V,M}}) where {V,M} = Monomial{V,M}()
3034
function MP.constant_monomial(p::PolyType)
31-
return Monomial(MP.variables(p), zeros(Int, nvariables(p)))
35+
return Monomial(copy(MP.variables(p)), zeros(Int, nvariables(p)))
3236
end
3337
MP.monomial_type(::Type{<:PolyType{V,M}}) where {V,M} = Monomial{V,M}
3438
MP.monomial_type(::PolyType{V,M}) where {V,M} = Monomial{V,M}

src/mono.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,16 @@ MP.monomial(m::Monomial) = m
100100
# end
101101
# i > length(m1.z)
102102
#end
103+
104+
function __add_variables!(
105+
mono::Monomial{V,M},
106+
allvars::Vector{Variable{V,M}},
107+
map,
108+
) where {V,M}
109+
Future.copy!(mono.vars, allvars)
110+
tmp = copy(mono.z)
111+
resize!(mono.z, length(allvars))
112+
fill!(mono.z, 0)
113+
mono.z[map] = tmp
114+
return
115+
end

src/monomial_vector.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ function MP.merge_monomial_vectors(ms::Vector{MonomialVector{V,M}}) where {V,M}
355355
return MonomialVector{V,M}(buildZvarsvec(Variable{V,M}, X)...)
356356
end
357357

358-
function _add_variables!(
358+
function __add_variables!(
359359
monos::MonomialVector{V,M},
360360
allvars::Vector{Variable{V,M}},
361361
map,

src/operators.jl

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,7 @@ function MA.operate!(
125125
q::Polynomial{V},
126126
) where {V<:Commutative}
127127
if MP.variables(p) != MP.variables(q)
128-
varsvec = [MP.variables(p), MP.variables(q)]
129-
allvars, maps = mergevars(varsvec)
130-
if length(allvars) != length(MP.variables(p))
131-
_add_variables!(p.x, allvars, maps[1])
132-
end
128+
allvars, maps = ___add_variables!(p, q)
133129
if length(allvars) == length(MP.variables(q))
134130
rhs = q
135131
else
@@ -139,7 +135,7 @@ function MA.operate!(
139135
# should be better of `q` has less terms and then the same term is compared
140136
# many times.
141137
rhs = Polynomial(q.a, copy(q.x))
142-
_add_variables!(rhs.x, allvars, maps[2])
138+
__add_variables!(rhs, allvars, maps[2])
143139
end
144140
return MA.operate!(op, p, rhs)
145141
end

src/poly.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,3 +402,7 @@ function MP.map_exponents!(f::Function, p::Polynomial, m::DMonomialLike)
402402
MP.map_exponents!(f, p.x, m)
403403
return p
404404
end
405+
406+
function __add_variables!(p::Polynomial, allvars, map)
407+
return __add_variables!(p.x, allvars, map)
408+
end

src/subs.jl

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,38 @@ function subsmap(st, vars, s::Tuple{MP.VectorMultiSubstitution})
9494
end
9595
end
9696

97+
_add_variables!(α, β) = α
98+
_add_variables!(p::PolyType, α) = p
99+
_add_variables!(α, p::PolyType) = MP.operate!!(*, α, one(p))
100+
function _add_variables!(x::Variable, p::PolyType)
101+
return MP.operate!!(*, x, one(p))
102+
end
103+
function ___add_variables!(p, q)
104+
varsvec = [MP.variables(p), MP.variables(q)]
105+
allvars, maps = mergevars(varsvec)
106+
if length(allvars) != length(MP.variables(p))
107+
__add_variables!(p, allvars, maps[1])
108+
end
109+
return allvars, maps
110+
end
111+
function _add_variables!(p::PolyType, q::PolyType)
112+
___add_variables!(p, q)
113+
return p
114+
end
115+
97116
function monoeval(z::Vector{Int}, vals::AbstractVector)
98117
@assert length(z) == length(vals)
99118
if isempty(z)
100119
return one(eltype(vals))^1
101120
end
121+
# `Base.power_by_squaring` does a `copy` if `z[1]` is `1`
122+
# which is redirected to `MA.mutable_copy`
102123
val = vals[1]^z[1]
103124
for i in 2:length(vals)
104-
if z[i] > 0
105-
val *= vals[i]^z[i]
125+
if iszero(z[i])
126+
val = _add_variables!(val, vals[i])
127+
else
128+
val = MA.operate!!(*, val, vals[i]^z[i])
106129
end
107130
end
108131
return val
@@ -122,7 +145,7 @@ function _subs(
122145
if iszero(p)
123146
zero(Base.promote_op(*, S, T))
124147
else
125-
sum(i -> p.a[i] * monoeval(p.x.Z[i], vals), 1:length(p))
148+
sum(i -> p.a[i] * monoeval(p.x.Z[i], vals), eachindex(p.a))
126149
end
127150
end
128151
function _subs(
@@ -135,7 +158,7 @@ function _subs(
135158
Polynomial{V,M,Tout},
136159
mergevars_of(Variable{V,M}, vals)[1],
137160
)
138-
for i in 1:length(p.a)
161+
for i in eachindex(p.a)
139162
MA.operate!(+, q, p.a[i] * monoeval(p.x.Z[i], vals))
140163
end
141164
return q

src/term.jl

Lines changed: 0 additions & 77 deletions
This file was deleted.

0 commit comments

Comments
 (0)