@@ -68,9 +68,54 @@ function MA.mutable_operate_to!(output::Polynomial{C}, op::Union{typeof(+), type
68
68
return output
69
69
end
70
70
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
71
94
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
74
119
end
75
120
const _NoVarTerm{T} = Tuple{T, Vector{Int}}
76
121
function MA. mutable_operate! (op:: Union{typeof(+), typeof(-)} , p:: Polynomial{false} ,
80
125
# TODO need to check that this also works for non-commutative
81
126
function MA. mutable_operate! (op:: Union{typeof(+), typeof(-)} , p:: Polynomial{true} ,
82
127
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)
102
129
get1 (i) = (p. a[i], p. x. Z[i])
103
130
get2 (i) = (MA. scaling_convert (eltype (p. a), MA. operate (op, q. a[i])), copy (q. x. Z[i]))
104
131
function set (i, t:: _NoVarTerm )
0 commit comments