diff --git a/docs/src/matrix.md b/docs/src/matrix.md index f46fb6f78c..9a549d63af 100644 --- a/docs/src/matrix.md +++ b/docs/src/matrix.md @@ -566,7 +566,8 @@ julia> c = M[1, 1] ### Transpose ```@docs -transpose(::MatrixElem{T}) where T <: RingElement +transpose(::MatrixElem) +transpose!(::MatrixElem) ``` ### Submatrices diff --git a/src/Matrix.jl b/src/Matrix.jl index a5fe96ddaf..a5eae17c40 100644 --- a/src/Matrix.jl +++ b/src/Matrix.jl @@ -1482,9 +1482,9 @@ end @doc raw""" - transpose(x::MatrixElem{T}) where T <: NCRingElement + transpose(x::MatrixElem) -Return the transpose of the given matrix. +Return the transpose of `x`. # Examples @@ -1508,9 +1508,43 @@ julia> B = transpose(A) ``` """ -transpose(x::MatrixElem{T}) where T <: NCRingElement +function transpose(x::MatrixElem) + z = similar(base_ring(x), ncols(x), nrows(x)) + return transpose!(z, x) +end + +@doc raw""" + transpose!(x::MatrixElem) + transpose!(z::T, x::T) where T <: MatrixElem + +Return the transpose of `x`, possibly modifying the object `z` in the process. +Aliasing is permitted. +The unary version may modify `x` in-place (but this is not always possible). +""" +function transpose!(x::MatrixElem) + if is_square(x) + # square matrix, so we can transpose it in-place + n = nrows(x) + for i in 1:n + for j in i+1:n + x[i, j], x[j, i] = x[j, i], x[i, j] + end + end + return x + end + # we have no generic way to change the dimensions of x, so instead we + # delegate to the two argument version of transpose! + z = similar(base_ring(x), ncols(x), nrows(x)) + return transpose!(z, x) +end + +function transpose!(z::T, x::T) where T <: MatrixElem + for i in 1:nrows(x), j in 1:ncols(x) + z[j, i] = x[i, j] + end + return z +end -transpose!(A::MatrixElem) = transpose(A) ############################################################################### # diff --git a/src/exports.jl b/src/exports.jl index 11dbc97cb6..ee48a02ab0 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -554,6 +554,8 @@ export total_degree export total_ring_of_fractions export tr export trailing_coefficient +export transpose +export transpose! export truncate export typed_hcat export typed_hvcat diff --git a/test/Rings-conformance-tests.jl b/test/Rings-conformance-tests.jl index 3e45769ee7..eb74e3cbd0 100644 --- a/test/Rings-conformance-tests.jl +++ b/test/Rings-conformance-tests.jl @@ -805,10 +805,23 @@ function test_MatSpace_interface(S::MatSpace; reps = 20) t = transpose(a) @test t isa ST + @test base_ring(t) == base_ring(a) @test nrows(t) == ncols(S) @test ncols(t) == nrows(S) @test transpose(t) == a @test a == A + + t = transpose!(deepcopy(a)) + @test t isa ST + @test base_ring(t) == base_ring(a) + @test t == transpose(a) + + z = zero_matrix(R, ncols(a), nrows(a)) + t = transpose!(z, a) + @test t isa ST + @test base_ring(t) == base_ring(a) + @test t == transpose(a) + @test a == A end end