@@ -31,6 +31,20 @@ include("ncmult.jl")
3131
3232MP. multconstant (α, x:: Monomial ) = Term (α, x)
3333MP. mapcoefficientsnz (f:: Function , p:: Polynomial ) = Polynomial (f .(p. a), p. x)
34+ function MP. mapcoefficientsnz_to! (output:: Polynomial , f:: Function , t:: MP.AbstractTermLike )
35+ MP. mapcoefficientsnz_to! (output, f, polynomial (t))
36+ end
37+ function MP. mapcoefficientsnz_to! (output:: Polynomial , f:: Function , p:: Polynomial )
38+ resize! (output. a, length (p. a))
39+ @. output. a = f (p. a)
40+ Future. copy! (output. x. vars, p. x. vars)
41+ # TODO reuse the part of `Z` that is already in `output`.
42+ resize! (output. x. Z, length (p. x. Z))
43+ for i in eachindex (p. x. Z)
44+ output. x. Z[i] = copy (p. x. Z[i])
45+ end
46+ return output
47+ end
3448
3549# I do not want to cast x to TermContainer because that would force the promotion of eltype(q) with Int
3650function Base.:(* )(x:: DMonomialLike , p:: Polynomial )
@@ -48,7 +62,7 @@ function Base.:(*)(p::Polynomial, x::DMonomialLike)
4862end
4963
5064function _term_poly_mult (t:: Term{C, S} , p:: Polynomial{C, T} , op:: Function ) where {C, S, T}
51- U = Base . promote_op (op, S, T)
65+ U = MA . promote_operation (op, S, T)
5266 if iszero (t)
5367 zero (Polynomial{C, U})
5468 else
6781Base.:(* )(p:: Polynomial , t:: Term ) = _term_poly_mult (t, p, (α, β) -> β * α)
6882Base.:(* )(t:: Term , p:: Polynomial ) = _term_poly_mult (t, p, * )
6983_sumprod (a, b) = a * b + a * b
70- function Base.:(* )(p:: Polynomial{C, S} , q:: Polynomial{C, T} ) where {C, S, T}
71- U = Base. promote_op (_sumprod, S, T)
72- if iszero (p) || iszero (q)
73- zero (Polynomial{C, U})
84+ function _mul (:: Type{T} , p:: AbstractPolynomialLike , q:: AbstractPolynomialLike ) where T
85+ return _mul (T, polynomial (p), polynomial (q))
86+ end
87+ function _mul (:: Type{T} , p:: Polynomial{true} , q:: Polynomial{true} ) where T
88+ samevars = _vars (p) == _vars (q)
89+ if samevars
90+ allvars = _vars (p)
7491 else
75- samevars = _vars (p) == _vars (q)
76- if samevars
77- allvars = _vars (p)
78- else
79- allvars, maps = mergevars ([_vars (p), _vars (q)])
80- end
81- N = length (p)* length (q)
82- Z = Vector {Vector{Int}} (undef, N)
83- a = Vector {U} (undef, N)
84- i = 0
85- for u in p
86- for v in q
87- if samevars
88- z = u. x. z + v. x. z
89- else
90- z = zeros (Int, length (allvars))
91- z[maps[1 ]] += u. x. z
92- z[maps[2 ]] += v. x. z
93- end
94- i += 1
95- Z[i] = z
96- a[i] = u. α * v. α
92+ allvars, maps = mergevars ([_vars (p), _vars (q)])
93+ end
94+ N = length (p) * length (q)
95+ Z = Vector {Vector{Int}} (undef, N)
96+ a = Vector {T} (undef, N)
97+ i = 0
98+ for u in p
99+ for v in q
100+ if samevars
101+ z = u. x. z + v. x. z
102+ else
103+ z = zeros (Int, length (allvars))
104+ z[maps[1 ]] += u. x. z
105+ z[maps[2 ]] += v. x. z
97106 end
107+ i += 1
108+ Z[i] = z
109+ a[i] = u. α * v. α
98110 end
99- polynomialclean (allvars, a, Z)
100111 end
112+ return allvars, a, Z
113+ end
114+ function Base.:(* )(p:: Polynomial{true, S} , q:: Polynomial{true, T} ) where {S, T}
115+ if iszero (p) || iszero (q)
116+ zero (MA. promote_operation (* , typeof (p), typeof (q)))
117+ else
118+ polynomialclean (_mul (MA. promote_operation (MA. add_mul, S, T), p, q)... )
119+ end
120+ end
121+ function MA. mutable_operate_to! (p:: Polynomial{false, T} , :: typeof (* ), q1:: MP.AbstractPolynomialLike , q2:: MP.AbstractPolynomialLike ) where T
122+ if iszero (q1) || iszero (q2)
123+ MA. mutable_operate! (zero, p)
124+ else
125+ ts = Term{false , T}[]
126+ MP. mul_to_terms! (ts, q1, q2)
127+ # TODO do better than create tmp
128+ tmp = polynomial! (ts)
129+ Future. copy! (p. a, tmp. a)
130+ Future. copy! (p. x. vars, tmp. x. vars)
131+ Future. copy! (p. x. Z, tmp. x. Z)
132+ return p
133+ end
134+ end
135+ function MA. mutable_operate_to! (p:: Polynomial{true, T} , :: typeof (* ), q1:: MP.AbstractPolynomialLike , q2:: MP.AbstractPolynomialLike ) where T
136+ if iszero (q1) || iszero (q2)
137+ MA. mutable_operate! (zero, p)
138+ else
139+ polynomialclean_to! (p, _mul (T, q1, q2)... )
140+ end
141+ end
142+ function MA. mutable_operate! (:: typeof (* ), p:: Polynomial{C} , q:: Polynomial{C} ) where C
143+ return MA. mutable_operate_to! (p, * , p, q)
101144end
0 commit comments