Skip to content

Commit

Permalink
Add some more MatElem/MatRingElem conversions (#1839)
Browse files Browse the repository at this point in the history
  • Loading branch information
lgoettgens authored Oct 8, 2024
1 parent 7b88c46 commit c8aec15
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 22 deletions.
53 changes: 45 additions & 8 deletions src/Matrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,42 @@ function _check_bases(a, b)
return nothing
end

function (s::MatSpace{T})(a::M) where {T, M <: MatrixElem{T}}
# create a zero matrix
function (s::MatSpace{T})() where {T <: NCRingElement}
return zero_matrix(base_ring(s), nrows(s), ncols(s))::eltype(s)
end

function (s::MatSpace{T})(a::MatrixElem{T}) where {T <: NCRingElement}
_check_dim(nrows(s), ncols(s), a)
_check_bases(s, a)
a isa eltype(s) && return a
b = eltype(s)(a)
b.base_ring = base_ring(s)
return b
M = s() # zero matrix
R = base_ring(s)
if R == base_ring(a)
for i = 1:nrows(s)
for j = 1:ncols(s)
M[i, j] = a[i, j]
end
end
else
for i = 1:nrows(s)
for j = 1:ncols(s)
M[i, j] = R(a[i, j])
end
end
end
return M
end

# create a matrix with b on the diagonal
function (s::MatSpace)(b::NCRingElement)
M = s() # zero matrix
R = base_ring(s)
rb = R(b)
for i in 1:min(nrows(s), ncols(s))
M[i, i] = rb
end
return M
end

_checkbounds(i::Int, j::Int) = 1 <= j <= i
Expand Down Expand Up @@ -6577,22 +6606,30 @@ function matrix(R::NCRing, arr::AbstractMatrix{T}) where {T}
end

function matrix(R::NCRing, arr::MatElem)
return map_entries(R, arr)
return map_entries(R, arr)
end

function matrix(R::NCRing, arr::MatRingElem)
return matrix_space(R, nrows(arr), ncols(arr))(arr)
end

function matrix(mat::MatrixElem{T}) where {T<:NCRingElement}
return matrix(base_ring(mat), mat)
end

function matrix(arr::AbstractMatrix{T}) where {T<:NCRingElem}
function matrix(arr::AbstractMatrix{T}) where {T<:NCRingElement}
r, c = size(arr)
(r < 0 || c < 0) && error("Array must be non-empty")
R = parent(arr[1, 1])
all(e -> parent(e) === R, arr) || error("Non-compatible elements")
return matrix(R, arr)
end

function matrix(arr::AbstractVector{T}) where {T<:NCRingElem}
function matrix(arr::AbstractVector{T}) where {T<:NCRingElement}
return matrix(reshape(arr, length(arr), 1))
end

function matrix(arr::Vector{Vector{T}}) where {T<:NCRingElem}
function matrix(arr::Vector{Vector{T}}) where {T<:NCRingElement}
return matrix(permutedims(reduce(hcat, arr), (2, 1)))
end

Expand Down
31 changes: 31 additions & 0 deletions src/generic/MatRing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,42 @@ function (a::MatRing{T})(b::S) where {S <: NCRingElement, T <: NCRingElement}
return z
end

# to resolve ambiguity for MatRing{MatRing{...}}
function (a::MatRing{T})(b::T) where {S <: NCRingElement, T <: MatRingElem{S}}
R = base_ring(a)
entries = Matrix{T}(undef, a.n, a.n)
rb = R(b)
for i = 1:a.n
for j = 1:a.n
if i != j
entries[i, j] = zero(R)
else
entries[i, j] = rb
end
end
end
z = MatRingElem{T}(R, entries)
return z
end

function (a::MatRing{T})(b::MatRingElem{T}) where {T <: NCRingElement}
parent(b) != a && error("Unable to coerce matrix")
return b
end

function (a::MatRing{T})(b::MatrixElem{S}) where {S <: NCRingElement, T <: NCRingElement}
R = base_ring(a)
_check_dim(nrows(a), ncols(a), b)
entries = Matrix{T}(undef, nrows(a), ncols(a))
for i = 1:nrows(a)
for j = 1:ncols(a)
entries[i, j] = R(b[i, j])
end
end
z = MatRingElem{T}(R, entries)
return z
end

function (a::MatRing{T})(b::Matrix{S}) where {S <: NCRingElement, T <: NCRingElement}
R = base_ring(a)
_check_dim(a.n, a.n, b)
Expand Down
14 changes: 0 additions & 14 deletions src/generic/Matrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -148,21 +148,7 @@ end
#
###############################################################################

# create a zero matrix
function (a::Generic.MatSpace{T})() where {T <: NCRingElement}
return zero_matrix(base_ring(a), nrows(a), ncols(a))::dense_matrix_type(T)
end

# create a matrix with b on the diagonal
function (a::Generic.MatSpace)(b::NCRingElement)
M = a() # zero matrix
R = base_ring(a)
rb = R(b)
for i in 1:min(nrows(a), ncols(a))
M[i, i] = rb
end
return M
end

# convert a Julia matrix
function (a::Generic.MatSpace{T})(b::AbstractMatrix{S}) where {T <: NCRingElement, S}
Expand Down
20 changes: 20 additions & 0 deletions test/Matrix-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,26 @@ end
@test T == matrix(QQ, [42 0 0; 0 42 0; 0 0 42])
end

@testset "Matrix.conversion" begin
U, t = polynomial_ring(QQ, "t")

R = matrix_ring(U, 2)
S = matrix_space(U, 2, 2)
a = U.([1 2; t^2 (t-1)]) # Matrix
Ra = R(a) # MatRingElem
Sa = S(a) # MatElem
@test Ra == R(Ra)
@test Ra == R(Sa)
@test Sa == S(Sa)
@test Sa == S(Ra)
@test matrix(Ra) == Sa
@test matrix(U, Ra) == Ra
@test matrix(Sa) == Sa
@test matrix(U, Sa) == Sa
@test Matrix(Ra) == a
@test Matrix(Sa) == a
end

@testset "Strassen" begin
S = matrix(QQ, rand(-10:10, 100, 100))
T = S*S
Expand Down

0 comments on commit c8aec15

Please sign in to comment.