9x25dillon's picture
Upload 19 files
60a3e1e verified
function Base.:(*)(x::PolyVar{false}, y::PolyVar{false})
if x === y
Monomial{false}([x], [2])
else
Monomial{false}([x, y], [1, 1])
end
end
function multiplyvar(v::Vector{PolyVar{false}}, z::Vector{Int}, x::PolyVar{false})
i = length(v)
while i > 0 && z[i] == 0
i -= 1
end
if v[i] == x
multiplyexistingvar(v, x, i)
else
# ---->
# \ |\ |\
# \ | \ | \
# \| \| \
# If z[i] > x, we wait either for a rise (v[i] > v[i-1]) or v[i] < x
# Otherwise, we first wait for a drop and then wait for the same thing
ndrop = 0
if v[i] > x
droplim1 = 0
droplim2 = 1
else
droplim1 = 1
droplim2 = 2
end
i += 1
while i <= length(v) && v[i] != x
if v[i] > v[i-1]
ndrop += 1
end
if ndrop >= droplim2 || (ndrop >= droplim1 && v[i] < x)
break
end
i += 1
end
if i <= length(v) && v[i] == x
multiplyexistingvar(v, x, i)
else
insertvar(v, x, i)
end
end
end
function multiplyvar(x::PolyVar{false}, v::Vector{PolyVar{false}}, z::Vector{Int})
i = 1
while i <= length(v) && z[i] == 0
i += 1
end
if v[i] == x
multiplyexistingvar(v, x, i)
else
# <----
# \ |\ |\
# \ | \ | \
# \| \| \
# If z[i] < x, we wait either for a drop (v[i] < v[i+1]) or v[i] > x
# Otherwise, we first wait for a drop and then wait for the same thing
ndrop = 0
if v[i] < x
droplim1 = 0
droplim2 = 1
else
droplim1 = 1
droplim2 = 2
end
i -= 1
while i > 0 && v[i] != x
if v[i] < v[i+1]
ndrop += 1
end
if ndrop >= droplim2 || (ndrop >= droplim1 && v[i] > x)
break
end
i -= 1
end
if i > 0 && v[i] == x
multiplyexistingvar(v, x, i)
else
insertvar(v, x, i+1)
end
end
end
function Base.:(*)(x::PolyVar{false}, y::Monomial{false})
w, updatez = multiplyvar(x, y.vars, y.z)
Monomial{false}(w, updatez(y.z))
end
function Base.:(*)(y::Monomial{false}, x::PolyVar{false})
w, updatez = multiplyvar(y.vars, y.z, x)
Monomial{false}(w, updatez(y.z))
end
function Base.:(*)(x::Monomial{false}, y::Monomial{false})
i = findlast(z -> z > 0, x.z)
if i == nothing || i == 0
return y
end
j = findfirst(z -> z > 0, y.z)
if j == nothing || j == 0
return x
end
if x.vars[i] == y.vars[j]
w = [x.vars[1:i]; y.vars[j+1:end]]
z = [x.z[1:i-1]; x.z[i] + y.z[j]; y.z[j+1:end]]
else
w = [x.vars[1:i]; y.vars[j:end]]
z = [x.z[1:i]; y.z[j:end]]
end
return Monomial{false}(w, z)
end
function Base.:(*)(y::MonomialVector{false}, x::DMonomialLike{false})
MonomialVector{false}([yi * x for yi in y])
end
function Base.:(*)(x::DMonomialLike{false}, y::MonomialVector{false})
# The order may change
# Example: y * [x^2, y^2] == [y^3, yx^2]
MonomialVector{false}([x * yi for yi in y])
end