Skip to content

Commit d914c32

Browse files
feat: add fast in-place Polynomial + Variable implementation
1 parent 2d00591 commit d914c32

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

src/operators.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,33 @@ function MA.operate!(op::Union{typeof(+), typeof(-)}, p::Polynomial{V, M, T}, x:
133133
return p
134134
end
135135

136+
function MA.operate!(op::Union{typeof(+), typeof(-)}, p::Polynomial{V, M, T}, x::Variable{V, M}) where {V, M, T}
137+
vars = MP.variables(p)
138+
idx = searchsortedfirst(vars, x; rev = true)
139+
monos = MP.monomials(p)
140+
if idx > length(vars) || !isequal(vars[idx], x)
141+
for mono in monos
142+
insert!(MP.exponents(mono), idx, 0)
143+
end
144+
insert!(vars, idx, x)
145+
end
146+
mono = Monomial{V, M}(vars, zeros(Int, length(vars)))
147+
mono.z[idx] = 1
148+
idx = searchsortedfirst(monos, mono)
149+
coeffs = MP.coefficients(p)
150+
N = MP.nterms(p)
151+
if idx > N || !isequal(monos[idx], mono)
152+
insert!(monos.Z, idx, MP.exponents(mono))
153+
insert!(coeffs, idx, zero(T))
154+
end
155+
coeffs[idx] = op(coeffs[idx], one(T))
156+
if iszero(coeffs[idx])
157+
deleteat!(coeffs, idx)
158+
deleteat!(monos, idx)
159+
end
160+
return p
161+
end
162+
136163
function MA.operate!(
137164
op::Union{typeof(+),typeof(-)},
138165
p::Polynomial,

test/mutable_arithmetics.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,29 @@ end
7373
# subsequent additions don't allocate
7474
@test (@allocated MA.operate!(-, poly2, 2)) == 0
7575
end
76+
77+
@testset "Polynomial + Variable" begin
78+
poly = 2 * x^2 + 3 * x * y + z * y^2
79+
poly2 = copy(poly)
80+
result = poly + x
81+
MA.operate!(+, poly, x)
82+
@test isequal(poly, result)
83+
# down from 18752 using the generic method
84+
# 368 or 304 depending on ordering
85+
@test (@allocated MA.operate!(+, poly2, x)) <= 368
86+
# down from 1904 using the generic method
87+
@test (@allocated MA.operate!(+, poly2, x)) <= 144
88+
89+
# also test `-`
90+
poly = 2 * x^2 + 3 * x * y + z * y^2
91+
poly2 = copy(poly)
92+
result = poly - x
93+
MA.operate!(-, poly, x)
94+
@test isequal(poly, result)
95+
# down from 18752 using the generic method
96+
# 368 or 304 depending on ordering
97+
@test (@allocated MA.operate!(-, poly2, x)) <= 368
98+
# down from 1904 using the generic method
99+
@test (@allocated MA.operate!(-, poly2, x)) <= 144
100+
end
76101
end

0 commit comments

Comments
 (0)