@@ -31,37 +31,71 @@ function (*)(x::PolyVar, y::PolyVar)
3131 Monomial (x > y ? [x,y] : [y,x], [1 ,1 ])
3232 end
3333end
34+ function multiplyvar (v, x)
35+ i = findfirst (w-> w <= x, v)
36+ if i > 0 && v[i] == x
37+ # /!\ no copy done here for efficiency, do not mess up with vars
38+ w = v
39+ updatez = z -> begin
40+ newz = copy (z)
41+ newz[i] += 1
42+ newz
43+ end
44+ else
45+ n = length (v)
46+ if i == 0
47+ i = n+ 1
48+ end
49+ I = 1 : i- 1
50+ J = i: n
51+ K = J+ 1
52+ w = Vector {PolyVar} (n+ 1 )
53+ w[I] = v[I]
54+ w[i] = x
55+ w[K] = v[J]
56+ updatez = z -> begin
57+ newz = Vector {Int} (n+ 1 )
58+ newz[I] = z[I]
59+ newz[i] = 1
60+ newz[K] = z[J]
61+ newz
62+ end
63+ end
64+ w, updatez
65+ end
66+ function multiplymono (v, x)
67+ if v == x. vars
68+ # /!\ no copy done here for efficiency, do not mess up with vars
69+ w = v
70+ updatez = z -> z + x. z
71+ else
72+ w, maps = myunion ([v, x. vars])
73+ updatez = z -> begin
74+ newz = zeros (Int, length (w))
75+ newz[maps[1 ]] += z
76+ newz[maps[2 ]] += x. z
77+ newz
78+ end
79+ end
80+ w, updatez
81+ end
3482function (* )(x:: PolyVar , y:: Monomial )
35- i = 1
36- vars = y. vars
37- n = length (vars)
38- while i <= n && x < vars[i]
39- i += 1
40- end
41- if i > n
42- Monomial ([vars; x], [y. z; 1 ])
43- elseif x == vars[i]
44- znew = copy (y. z)
45- znew[i] += 1
46- Monomial (vars, znew)
47- else
48- znew = copy (y. z)
49- znew[i] += 1
50- Monomial ([vars[1 : i- 1 ]; x; vars[i: end ]], [y. z[1 : i- 1 ]; 1 ; y. z[i: end ]])
51- end
83+ w, updatez = multiplyvar (y. vars, x)
84+ Monomial (w, updatez (y. z))
85+ end
86+ function (* )(x:: PolyVar , y:: MonomialVector )
87+ w, updatez = multiplyvar (y. vars, x)
88+ MonomialVector (w, updatez .(y. Z))
5289end
53- (* )(x:: Monomial , y:: PolyVar ) = y * x
5490function (* )(x:: Monomial , y:: Monomial )
55- if x. vars == y. vars
56- Monomial (x. vars, x. z + y. z)
57- else
58- allvars, maps = myunion ([x. vars, y. vars])
59- z = zeros (Int, length (allvars))
60- z[maps[1 ]] += x. z
61- z[maps[2 ]] += y. z
62- Monomial (allvars, z)
63- end
91+ w, updatez = multiplymono (y. vars, x)
92+ Monomial (w, updatez (y. z))
6493end
94+ function (* )(x:: Monomial , y:: MonomialVector )
95+ w, updatez = multiplymono (y. vars, x)
96+ MonomialVector (w, updatez .(y. Z))
97+ end
98+ (* )(x:: Monomial , y:: PolyVar ) = y * x
6599
66100# non-PolyType * PolyType: specific methods for speed
67101* (p:: PolyType , α) = α * p
80114* (p:: PolyType , q:: Term ) = TermContainer (p) * q
81115* (p:: PolyType , q:: VecPolynomial ) = TermContainer (p) * q
82116
117+ # I do not want to cast x to TermContainer because that would force the promotion of eltype(q) with Int
118+ function * {S<: Union{PolyVar,Monomial} }(x:: S , t:: Term )
119+ Term (t. α, x* t. x)
120+ end
121+ function * {S<: Union{PolyVar,Monomial} ,T}(x:: S , p:: VecPolynomial{T} )
122+ # /!\ No copy of a is done
123+ VecPolynomial {T} (p. a, x* p. x)
124+ end
125+
83126# TermContainer * TermContainer
84127* (x:: Term , y:: Term ) = Term (x. α* y. α, x. x* y. x)
85128* (p:: VecPolynomial , t:: Term ) = t * p
0 commit comments