Skip to content

Commit 0d7b5e3

Browse files
committed
Implement mutable addition of term
1 parent bc6a145 commit 0d7b5e3

File tree

4 files changed

+57
-21
lines changed

4 files changed

+57
-21
lines changed

src/mono.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,10 @@ MP.monomial(m::Monomial) = m
8080
# end
8181
# i > length(m1.z)
8282
#end
83+
function _add_variables!(mono::Monomial, allvars, map)
84+
Future.copy!(mono.vars, allvars)
85+
tmp = copy(mono.z)
86+
resize!(mono.z, length(allvars))
87+
fill!(mono.z, 0)
88+
mono.z[map] = tmp
89+
end

src/operators.jl

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,54 @@ function MA.mutable_operate_to!(output::Polynomial{C}, op::Union{typeof(+), type
6868
return output
6969
end
7070

71+
_copy_monos(m::Monomial) = copy(m)
72+
_copy_monos(t::Term) = Term(t.α, copy(t.x))
73+
_copy_monos(p::Polynomial) = Polynomial(p.a, copy(p.x))
74+
function _merge_vars!(p, q)
75+
if _vars(p) == _vars(q)
76+
return q
77+
end
78+
varsvec = [_vars(p), _vars(q)]
79+
allvars, maps = mergevars(varsvec)
80+
if length(allvars) != length(_vars(p))
81+
_add_variables!(p.x, allvars, maps[1])
82+
end
83+
if length(allvars) != length(_vars(q))
84+
# We could avoid promoting `q` to the same variables
85+
# like in `plusorminus` to avoid extra allocation but it then
86+
# gives slower comparison. There is a tradeoff and the approach used here
87+
# should be better of `q` has less terms and then the same term is compared
88+
# many times.
89+
q = _copy_monos(q)
90+
_add_variables!(q, allvars, maps[2])
91+
end
92+
return q
93+
end
7194
function MA.mutable_operate!(op::Union{typeof(+), typeof(-)}, p::Polynomial,
72-
q::Union{PolyVar, Monomial, Term})
73-
return MA.mutable_operate!(op, p, polynomial(q))
95+
v::PolyVar)
96+
return MA.mutable_operate!(op, p, monomial(v))
97+
end
98+
function MA.mutable_operate!(op::Union{typeof(+), typeof(-)}, p::Polynomial,
99+
t::Union{Monomial, Term})
100+
t = _merge_vars!(p, t)
101+
z = MP.exponents(t)
102+
i = findfirst(eachindex(p.a)) do i
103+
return samevars_grlex(p.x.Z[i], z) <= 0
104+
end
105+
if i === nothing
106+
push!(p.a, MA.operate(op, MP.coefficient(t)))
107+
push!(p.x.Z, copy(z))
108+
else
109+
comp = samevars_grlex(p.x.Z[i], z)
110+
if iszero(comp)
111+
MA.operate!(op, p.a[i], coefficient(t))
112+
else
113+
@assert comp < 0
114+
insert!(p.a, i, MA.operate(op, MP.coefficient(t)))
115+
insert!(p.x.Z, i, copy(z))
116+
end
117+
end
118+
return p
74119
end
75120
const _NoVarTerm{T} = Tuple{T, Vector{Int}}
76121
function MA.mutable_operate!(op::Union{typeof(+), typeof(-)}, p::Polynomial{false},
@@ -80,25 +125,7 @@ end
80125
# TODO need to check that this also works for non-commutative
81126
function MA.mutable_operate!(op::Union{typeof(+), typeof(-)}, p::Polynomial{true},
82127
q::Polynomial{true})
83-
if _vars(p) != _vars(q)
84-
varsvec = [_vars(p), _vars(q)]
85-
allvars, maps = mergevars(varsvec)
86-
if length(allvars) != length(_vars(p))
87-
_add_variables!(p.x, allvars, maps[1])
88-
end
89-
if length(allvars) == length(_vars(q))
90-
rhs = q
91-
else
92-
# We could avoid promoting `q` to the same variables
93-
# like in `plusorminus` to avoid extra allocation but it then
94-
# gives slower comparison. There is a tradeoff and the approach used here
95-
# should be better of `q` has less terms and then the same term is compared
96-
# many times.
97-
rhs = Polynomial(q.a, copy(q.x))
98-
_add_variables!(rhs.x, allvars, maps[2])
99-
end
100-
return MA.mutable_operate!(op, p, rhs)
101-
end
128+
q = _merge_vars!(p, q)
102129
get1(i) = (p.a[i], p.x.Z[i])
103130
get2(i) = (MA.scaling_convert(eltype(p.a), MA.operate(op, q.a[i])), copy(q.x.Z[i]))
104131
function set(i, t::_NoVarTerm)

src/poly.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,4 @@ function MA.mutable_operate!(::typeof(one), p::Polynomial{C, T}) where {C, T}
262262
end
263263
return p
264264
end
265+
_add_variables!(p::Polynomial, allvars, map) = _add_variables(p.x, allvars, map)

src/term.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,4 @@ function MA.mutable_operate!(::typeof(one), t::Term)
6868
MA.mutable_operate!(zero, t.x.z)
6969
return t
7070
end
71+
_add_variables!(t::Term, allvars, map) = _add_variables(t.x, allvars, map)

0 commit comments

Comments
 (0)