From 2ba25569b7123f1d3e5c875449c78f9f3a277e53 Mon Sep 17 00:00:00 2001 From: Andy Ferris Date: Wed, 29 Nov 2017 22:09:59 +1000 Subject: [PATCH] Make shallow matrix transpose default for `permutedims` * Also allow `permutedims(vector)` to make row matrix * Make clearer the relationships between `transpose`, `adjoint` and `permutedims` in the docstrings. --- NEWS.md | 6 ++++++ base/linalg/transpose.jl | 6 +++++- base/operators.jl | 6 +++++- base/permuteddimsarray.jl | 27 +++++++++++++++++++++------ test/arrayops.jl | 6 ++++++ 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/NEWS.md b/NEWS.md index 7d1277a02dc3a..679f790eb319b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -430,6 +430,12 @@ Library improvements definition relies on `ncodeunits` however, so for optimal performance you may need to define a custom method for that function. + * `permutedims(m::AbstractMatrix)` is now short for `permutedims(m, (2,1))`, and is now a + more convenient way of making a "shallow transpose" of a 2D array. This is the + recommended approach for manipulating arrays of data, rather than the recursively + defined, linear-algebra function `transpose`. Similarly, + `permutedims(v::AbstractVector)` will create a row matrix ([#24839]). + Compiler/Runtime improvements ----------------------------- diff --git a/base/linalg/transpose.jl b/base/linalg/transpose.jl index e5388fbdea948..bc29c5ec346f9 100644 --- a/base/linalg/transpose.jl +++ b/base/linalg/transpose.jl @@ -147,7 +147,11 @@ end """ transpose(A::AbstractMatrix) -The transposition operator (`.'`). +The transposition operator (`.'`). Note that the transposition is applied recursively to +elements. + +This operation is intended for linear algebra usage - for general data manipulation see +[`permutedims`](@ref), which is non-recursive. # Examples ```jldoctest diff --git a/base/operators.jl b/base/operators.jl index d40cf227410e1..96412593dddf3 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -744,7 +744,11 @@ fldmod1(x::T, y::T) where {T<:Integer} = (fld1(x,y), mod1(x,y)) """ adjoint(A) -The conjugate transposition operator (`'`). +The conjugate transposition operator (`'`). Note that `adjoint` is applied recursively to +elements. + +This operation is intended for linear algebra usage - for general data manipulation see +[`permutedims`](@ref). # Examples ```jldoctest diff --git a/base/permuteddimsarray.jl b/base/permuteddimsarray.jl index fd875a644360d..0e7f79b230710 100644 --- a/base/permuteddimsarray.jl +++ b/base/permuteddimsarray.jl @@ -2,7 +2,8 @@ module PermutedDimsArrays -export permutedims, PermutedDimsArray +import Base: permutedims, permutedims! +export PermutedDimsArray # Some day we will want storage-order-aware iteration, so put perm in the parameters struct PermutedDimsArray{T,N,perm,iperm,AA<:AbstractArray} <: AbstractArray{T,N} @@ -77,11 +78,10 @@ end @inline genperm(I, perm::AbstractVector{Int}) = genperm(I, (perm...,)) """ - permutedims(A, perm) + permutedims(A::AbstractArray, perm) Permute the dimensions of array `A`. `perm` is a vector specifying a permutation of length -`ndims(A)`. This is a generalization of transpose for multi-dimensional arrays. Transpose is -equivalent to `permutedims(A, [2,1])`. +`ndims(A)`. See also: [`PermutedDimsArray`](@ref). @@ -108,11 +108,26 @@ julia> permutedims(A, [3, 2, 1]) 6 8 ``` """ -function Base.permutedims(A::AbstractArray, perm) +function permutedims(A::AbstractArray, perm) dest = similar(A, genperm(indices(A), perm)) permutedims!(dest, A, perm) end +""" + permutedims(m::AbstractMatrix) + +Permute the dimensions of the matrix `m`, by flipping the elements across the diagonal of +the matrix. Differs from [`transpose`](@ref) in that the operation is not recursive. +""" +permutedims(A::AbstractMatrix) = permutedims(A, (2,1)) + +""" + permutedims(v::AbstractVector) + +Reshape vector `v` into a `1 × length(v)` row matrix. +""" +permutedims(v::AbstractVector) = reshape(v, (1, length(v))) + """ permutedims!(dest, src, perm) @@ -124,7 +139,7 @@ regions. See also [`permutedims`](@ref). """ -function Base.permutedims!(dest, src::AbstractArray, perm) +function permutedims!(dest, src::AbstractArray, perm) Base.checkdims_perm(dest, src, perm) P = PermutedDimsArray(dest, invperm(perm)) _copy!(P, src) diff --git a/test/arrayops.jl b/test/arrayops.jl index f3a4a0015d1f7..f5b4ccccd528a 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -577,6 +577,12 @@ end @test isequal(A,permutedims(permutedims(A,perm),invperm(perm))) @test isequal(A,permutedims(permutedims(A,invperm(perm)),perm)) end + + m = [1 2; 3 4] + @test permutedims(m) == [1 3; 2 4] + + v = [1,2,3] + @test permutedims(v) == [1 2 3] end @testset "circshift" begin