diff --git a/src/MatRing.jl b/src/MatRing.jl index d5dac0337a..4cac25d258 100644 --- a/src/MatRing.jl +++ b/src/MatRing.jl @@ -252,6 +252,67 @@ end ==(x::MatRingElem{T}, y::MatRingElem{T}) where {T <: NCRingElement} = matrix(x) == matrix(y) +############################################################################### +# +# Ad hoc binary operators +# +############################################################################### + +function *(x::JuliaRingElement, y::MatRingElem{T}) where T <: NCRingElement + return Generic.MatRingElem(x * matrix(y)) +end + +function *(x::T, y::MatRingElem{T}) where {T <: NCRingElem} + return Generic.MatRingElem(x * matrix(y)) +end + +function *(x::MatRingElem{T}, y::JuliaRingElement) where T <: NCRingElement + return Generic.MatRingElem(matrix(x) * y) +end + +function *(x::MatRingElem{T}, y::T) where {T <: NCRingElem} + return Generic.MatRingElem(matrix(x) * y) +end + +function +(x::JuliaRingElement, y::MatRingElem{T}) where T <: NCRingElement + return Generic.MatRingElem(x + matrix(y)) +end + +function +(x::MatRingElem{T}, y::JuliaRingElement) where T <: NCRingElement + return Generic.MatRingElem(matrix(x) + y) +end + +function +(x::T, y::MatRingElem{T}) where {T <: NCRingElem} + return Generic.MatRingElem(x + matrix(y)) +end + +function +(x::MatRingElem{T}, y::T) where {T <: NCRingElem} + return Generic.MatRingElem(matrix(x) + y) +end + +function -(x::JuliaRingElement, y::MatRingElem{T}) where T <: NCRingElement + return Generic.MatRingElem(x - matrix(y)) +end + +function -(x::MatRingElem{T}, y::JuliaRingElement) where T <: NCRingElement + return Generic.MatRingElem(matrix(x) - y) +end + +function -(x::T, y::MatRingElem{T}) where {T <: NCRingElem} + return Generic.MatRingElem(x - matrix(y)) +end + +function -(x::MatRingElem{T}, y::T) where {T <: NCRingElem} + return Generic.MatRingElem(matrix(x) - y) +end + +function *(x::MatRingElem{T}, y::Vector{T}) where T <: NCRingElement + return matrix(x) * y +end + +function *(x::Vector{T}, y::MatRingElem{T}) where T <: NCRingElement + return x * matrix(y) +end ############################################################################### # @@ -498,6 +559,50 @@ end randmat_with_rank(S::MatRing{T}, rank::Int, v...) where {T <: RingElement} = randmat_with_rank(Random.default_rng(), S, rank, v...) +################################################################################ +# +# Promotion +# +################################################################################ + +function Base.promote(x::MatRingElem{S}, + y::MatRingElem{T}) where {S <: NCRingElement, + T <: NCRingElement} + U = promote_rule_sym(S, T) + if U === S + return x, change_base_ring(base_ring(x), y) + elseif U === T + return change_base_ring(base_ring(y), x), y + else + error("Cannot promote to common type") + end +end + +# matrix * vec and vec * matrx +function Base.promote(x::MatRingElem{S}, + y::Vector{T}) where {S <: NCRingElement, + T <: NCRingElement} + U = promote_rule_sym(S, T) + if U === S + return x, map(base_ring(x), y)::Vector{S} # Julia needs help here + elseif U === T && length(y) != 0 + return change_base_ring(parent(y[1]), x), y + else + error("Cannot promote to common type") + end +end + +function Base.promote(x::Vector{S}, + y::MatRingElem{T}) where {S <: NCRingElement, + T <: NCRingElement} + yy, xx = promote(y, x) + return xx, yy +end + +*(x::MatRingElem, y::Vector) = *(promote(x, y)...) + +*(x::Vector, y::MatRingElem) = *(promote(x, y)...) + ############################################################################### # # Conformance test element generation diff --git a/src/Matrix.jl b/src/Matrix.jl index 122886f09c..9bdff8aff5 100644 --- a/src/Matrix.jl +++ b/src/Matrix.jl @@ -953,7 +953,7 @@ end # ############################################################################### -function *(x::JuliaRingElement, y::MatrixElem{T}) where T <: NCRingElement +function *(x::JuliaRingElement, y::MatElem{T}) where T <: NCRingElement z = similar(y) for i = 1:nrows(y) for j = 1:ncols(y) @@ -963,7 +963,7 @@ function *(x::JuliaRingElement, y::MatrixElem{T}) where T <: NCRingElement return z end -function *(x::T, y::MatrixElem{T}) where {T <: NCRingElem} +function *(x::T, y::MatElem{T}) where {T <: NCRingElem} z = similar(y) for i = 1:nrows(y) for j = 1:ncols(y) @@ -973,7 +973,7 @@ function *(x::T, y::MatrixElem{T}) where {T <: NCRingElem} return z end -function *(x::MatrixElem{T}, y::JuliaRingElement) where T <: NCRingElement +function *(x::MatElem{T}, y::JuliaRingElement) where T <: NCRingElement z = similar(x) for i = 1:nrows(x) for j = 1:ncols(x) @@ -983,7 +983,7 @@ function *(x::MatrixElem{T}, y::JuliaRingElement) where T <: NCRingElement return z end -function *(x::MatrixElem{T}, y::T) where {T <: NCRingElem} +function *(x::MatElem{T}, y::T) where {T <: NCRingElem} z = similar(x) for i = 1:nrows(x) for j = 1:ncols(x) @@ -993,7 +993,7 @@ function *(x::MatrixElem{T}, y::T) where {T <: NCRingElem} return z end -function +(x::JuliaRingElement, y::MatrixElem{T}) where T <: NCRingElement +function +(x::JuliaRingElement, y::MatElem{T}) where T <: NCRingElement z = similar(y) R = base_ring(y) for i = 1:nrows(y) @@ -1008,14 +1008,14 @@ function +(x::JuliaRingElement, y::MatrixElem{T}) where T <: NCRingElement return z end -+(x::MatrixElem{T}, y::JuliaRingElement) where T <: NCRingElement = y + x ++(x::MatElem{T}, y::JuliaRingElement) where T <: NCRingElement = y + x @doc raw""" - +(x::NCRingElement, y::MatrixElem{<:NCRingElement}) + +(x::NCRingElement, y::MatElem{<:NCRingElement}) Return $S(x) + y$ where $S$ is the parent of $y$. """ -function +(x::T, y::MatrixElem{T}) where {T <: NCRingElem} +function +(x::T, y::MatElem{T}) where {T <: NCRingElem} z = similar(y) for i = 1:nrows(y) for j = 1:ncols(y) @@ -1030,13 +1030,13 @@ function +(x::T, y::MatrixElem{T}) where {T <: NCRingElem} end @doc raw""" - +(x::MatrixElem{<:NCRingElement}, y::NCRingElement) + +(x::MatElem{<:NCRingElement}, y::NCRingElement) Return $x + S(y)$, where $S$ is the parent of $a$. """ -+(x::MatrixElem{T}, y::T) where {T <: NCRingElem} = y + x ++(x::MatElem{T}, y::T) where {T <: NCRingElem} = y + x -function -(x::JuliaRingElement, y::MatrixElem{T}) where T <: NCRingElement +function -(x::JuliaRingElement, y::MatElem{T}) where T <: NCRingElement z = similar(y) R = base_ring(y) for i = 1:nrows(y) @@ -1051,7 +1051,7 @@ function -(x::JuliaRingElement, y::MatrixElem{T}) where T <: NCRingElement return z end -function -(x::MatrixElem{T}, y::JuliaRingElement) where T <: NCRingElement +function -(x::MatElem{T}, y::JuliaRingElement) where T <: NCRingElement z = similar(x) R = base_ring(x) for i = 1:nrows(x) @@ -1067,11 +1067,11 @@ function -(x::MatrixElem{T}, y::JuliaRingElement) where T <: NCRingElement end @doc raw""" - -(x::NCRingElement, y::MatrixElem{<:NCRingElement}) + -(x::NCRingElement, y::MatElem{<:NCRingElement}) Return $S(x) - y$ where $S$ is the parent of $y$. """ -function -(x::T, y::MatrixElem{T}) where {T <: NCRingElem} +function -(x::T, y::MatElem{T}) where {T <: NCRingElem} z = similar(y) R = base_ring(y) for i = 1:nrows(y) @@ -1087,11 +1087,11 @@ function -(x::T, y::MatrixElem{T}) where {T <: NCRingElem} end @doc raw""" - -(x::MatrixElem{<:NCRingElem}, y::NCRingElement) + -(x::MatElem{<:NCRingElem}, y::NCRingElement) Return $x - S(y)$, where $S$ is the parent of $a$. """ -function -(x::MatrixElem{T}, y::T) where {T <: NCRingElem} +function -(x::MatElem{T}, y::T) where {T <: NCRingElem} z = similar(x) R = base_ring(x) for i = 1:nrows(x) @@ -1123,7 +1123,7 @@ function mul!(z::Vector{T}, x::MatrixElem{T}, y::Vector{T}) where T <: NCRingEle return z end -function *(x::MatrixElem{T}, y::Vector{T}) where T <: NCRingElement +function *(x::MatElem{T}, y::Vector{T}) where T <: NCRingElement ncols(x) == length(y) || error("Incompatible dimensions") return mul!(T[base_ring(x)() for i in 1:nrows(x)], x, y) end @@ -1145,7 +1145,7 @@ function mul!(z::Vector{T}, x::Vector{T}, y::MatrixElem{T}) where T <: NCRingEle return z end -function *(x::Vector{T}, y::MatrixElem{T}) where T <: NCRingElement +function *(x::Vector{T}, y::MatElem{T}) where T <: NCRingElement length(x) == nrows(y) || error("Incompatible dimensions") return mul!(T[base_ring(y)() for j in 1:ncols(y)], x, y) end @@ -1175,9 +1175,9 @@ end # ################################################################################ -function Base.promote(x::MatrixElem{S}, - y::MatrixElem{T}) where {S <: NCRingElement, - T <: NCRingElement} +function Base.promote(x::MatElem{S}, + y::MatElem{T}) where {S <: NCRingElement, + T <: NCRingElement} U = promote_rule_sym(S, T) if U === S return x, change_base_ring(base_ring(x), y) @@ -1197,7 +1197,7 @@ end ==(x::MatElem, y::MatElem) = ==(promote(x, y)...) # matrix * vec and vec * matrx -function Base.promote(x::MatrixElem{S}, +function Base.promote(x::MatElem{S}, y::Vector{T}) where {S <: NCRingElement, T <: NCRingElement} U = promote_rule_sym(S, T) @@ -1211,15 +1211,15 @@ function Base.promote(x::MatrixElem{S}, end function Base.promote(x::Vector{S}, - y::MatrixElem{T}) where {S <: NCRingElement, + y::MatElem{T}) where {S <: NCRingElement, T <: NCRingElement} yy, xx = promote(y, x) return xx, yy end -*(x::MatrixElem, y::Vector) = *(promote(x, y)...) +*(x::MatElem, y::Vector) = *(promote(x, y)...) -*(x::Vector, y::MatrixElem) = *(promote(x, y)...) +*(x::Vector, y::MatElem) = *(promote(x, y)...) function Base.promote(x::MatElem{S}, y::T) where {S <: NCRingElement, T <: NCRingElement} U = promote_rule_sym(S, T)