3737# Fix ambiguity between above methods and methods in MA
3838Base.:+ (:: MA.Zero , p:: APL ) = MA. copy_if_mutable (p)
3939Base.:+ (p:: APL , :: MA.Zero ) = MA. copy_if_mutable (p)
40+
41+ # Special case AbstractArrays of APLs
42+ # We add these instead of relying on the broadcasting API since the above method definitions are very wide.
43+ # In particular, there is support for Matrices as coefficents. In order to avoid issues like #104 we therefore
44+ # explicitly define this (instead of implictly getting unexpected results).
45+ for op in [:+ , :- ]
46+ @eval Base.$ op (p:: APL , A:: AbstractArray{<:APL} ) = map (f -> $ op (p, f), A)
47+ @eval Base.$ op (A:: AbstractArray{<:APL} , p:: APL ) = map (f -> $ op (f, p), A)
48+ end
49+ Base.:* (p:: APL , A:: AbstractArray ) = map (f -> p * f, A)
50+ Base.:* (A:: AbstractArray , p:: APL ) = map (f -> f * p, A)
51+ Base.:/ (A:: AbstractArray , p:: APL ) = map (f -> f / p, A)
52+
4053constant_function (:: typeof (+ )) = plusconstant
4154constant_function (:: typeof (- )) = minusconstant
4255MA. mutable_operate! (op:: Union{typeof(+), typeof(-)} , p:: APL , α) = MA. mutable_operate! (constant_function (op), p, α)
163176# MA.mutable_operate!(op::Union{typeof(+), typeof(-)}, p::AbstractPolynomial, q::AbstractPolynomial) = MA.mutable_operate_to!(p, op, p, q)
164177MA. mutable_operate! (op:: Union{typeof(+), typeof(-)} , p:: AbstractPolynomial , q:: AbstractPolynomialLike ) = MA. mutable_operate! (op, p, polynomial (q))
165178
166- # Special case AbstractArrays of APLs
167- # We add these instead of relying on the broadcasting API since the above method definitions are very wide.
168- # In particular, there is support for Matrices as coefficents. In order to avoid issues like #104 we therefore
169- # explicitly define this (instead of implictly getting unexpected results).
170- for op in [:+ , :- , :* ]
171- @eval Base.$ op (p:: APL , A:: AbstractArray{<:APL} ) = map (f -> $ op (p, f), A)
172- @eval Base.$ op (A:: AbstractArray{<:APL} , p:: APL ) = map (f -> $ op (f, p), A)
173- end
174- Base.:/ (A:: AbstractArray{<:APL} , p:: APL ) = map (f -> f / p, A)
175-
176179function mul_to_terms! (ts:: Vector{<:AbstractTerm} , p1:: APL , p2:: APL )
177180 for t1 in terms (p1)
178181 for t2 in terms (p2)
188191Base. isapprox (p:: APL , α; kwargs... ) = isapprox (promote (p, α)... ; kwargs... )
189192Base. isapprox (α, p:: APL ; kwargs... ) = isapprox (promote (p, α)... ; kwargs... )
190193
191- Base.:- (m:: AbstractMonomialLike ) = (- 1 ) * m
192- Base.:- (t:: AbstractTermLike ) = (- coefficient (t)) * monomial (t)
194+ # `MA.operate(-, p)` redirects to `-p` as it assumes that `-p` can be modified
195+ # through the MA API without modifying `p`. We should either copy the monomial
196+ # here or implement a `MA.operate(-, p)` that copies it. We choose the first
197+ # option.
198+ Base.:- (m:: AbstractMonomialLike ) = (- 1 ) * MA. copy_if_mutable (m)
199+ Base.:- (t:: AbstractTermLike ) = MA. operate (- , coefficient (t)) * MA. copy_if_mutable (monomial (t))
193200Base.:- (p:: APL ) = polynomial! ((- ). (terms (p)))
194201Base.:+ (p:: Union{APL, RationalPoly} ) = p
195202Base.:* (p:: Union{APL, RationalPoly} ) = p
@@ -206,6 +213,12 @@ function MA.mutable_operate!(::typeof(plusconstant), p::APL, α)
206213end
207214minusconstant (p:: APL{S} , α:: T ) where {S, T} = iszero (α) ? polynomial ( p, MA. promote_operation (- , S, T)) : p - constantterm (α, p)
208215minusconstant (α:: S , p:: APL{T} ) where {S, T} = iszero (α) ? polynomial (- p, MA. promote_operation (- , S, T)) : constantterm (α, p) - p
216+ function MA. mutable_operate! (:: typeof (minusconstant), p:: APL , α)
217+ if ! iszero (α)
218+ MA. mutable_operate! (- , p, constantterm (α, p))
219+ end
220+ return p
221+ end
209222
210223# Coefficients and variables commute
211224multconstant (α, v:: AbstractVariable ) = multconstant (α, monomial (v)) # TODO linear term
@@ -325,18 +338,18 @@ Base.vec(vars::Tuple{Vararg{AbstractVariable}}) = [vars...]
325338# https://github.com/JuliaLang/julia/pull/23332
326339Base.:^ (x:: AbstractPolynomialLike , p:: Integer ) = Base. power_by_squaring (x, p)
327340
328- function MA. mutable_operate_to! (output:: AbstractPolynomial , :: typeof ( MA. add_mul) , x, args:: Vararg{Any, N} ) where N
329- return MA. mutable_operate_to! (output, + , x, * (args... ))
341+ function MA. mutable_operate_to! (output:: AbstractPolynomial , op :: MA.AddSubMul , x, args:: Vararg{Any, N} ) where N
342+ return MA. mutable_operate_to! (output, MA . add_sub_op (op) , x, * (args... ))
330343end
331- function MA. mutable_operate! (:: typeof ( MA. add_mul) , x, y, z, args:: Vararg{Any, N} ) where N
332- return MA. mutable_operate! (+ , x, * (y, z, args... ))
344+ function MA. mutable_operate! (op :: MA.AddSubMul , x, y, z, args:: Vararg{Any, N} ) where N
345+ return MA. mutable_operate! (MA . add_sub_op (op) , x, * (y, z, args... ))
333346end
334- MA. buffer_for (:: typeof ( MA. add_mul) , :: Type{<:AbstractPolynomial} , args:: Vararg{Type, N} ) where {N} = zero (MA. promote_operation (* , args... ))
335- function MA. mutable_buffered_operate_to! (buffer:: AbstractPolynomial , output:: AbstractPolynomial , :: typeof ( MA. add_mul) , x, y, z, args:: Vararg{Any, N} ) where N
347+ MA. buffer_for (:: MA.AddSubMul , :: Type{<:AbstractPolynomial} , args:: Vararg{Type, N} ) where {N} = zero (MA. promote_operation (* , args... ))
348+ function MA. mutable_buffered_operate_to! (buffer:: AbstractPolynomial , output:: AbstractPolynomial , op :: MA.AddSubMul , x, y, z, args:: Vararg{Any, N} ) where N
336349 product = MA. operate_to! (buffer, * , y, z, args... )
337- return MA. mutable_operate_to! (output, + , x, product)
350+ return MA. mutable_operate_to! (output, MA . add_sub_op (op) , x, product)
338351end
339- function MA. mutable_buffered_operate! (buffer:: AbstractPolynomial , :: typeof ( MA. add_mul) , x, y, z, args:: Vararg{Any, N} ) where N
352+ function MA. mutable_buffered_operate! (buffer:: AbstractPolynomial , op :: MA.AddSubMul , x, y, z, args:: Vararg{Any, N} ) where N
340353 product = MA. operate_to! (buffer, * , y, z, args... )
341- return MA. mutable_operate! (+ , x, product)
354+ return MA. mutable_operate! (MA . add_sub_op (op) , x, product)
342355end
0 commit comments