Julia - permutedims は何をやっているのか

環境

  • Julia 1.3.0

{ A } がベクトル(1次元配列) or 行列のとき

$$ \mathrm{permutedims}(A)[i,j] = A[j,i] $$

ようするに転置を取るのに等しい。 ベクトルの場合は要素へのアクセスの仕方は変わらないが、{ 1\times n} ベクトルは { n \times 1} になり、その逆も然り。

$$ \mathrm{permutedims}(A) = A^t $$

しかし、transpose は各要素の中にまで transpose を作用させるのに対して permutedims は単に要素の位置が変わるだけ。また transpose は新しい配列を作成しないが、permutedims は新しい配列を作成する。

julia> a = rand(3,3)
3×3 Array{Float64,2}:
 0.938485  0.960965  0.773617
 0.462651  0.827826  0.143645
 0.622512  0.15178   0.565898

julia> pointer(a)
Ptr{Float64} @0x00007fb0aa55b610

julia> t = transpose(a)
3×3 LinearAlgebra.Transpose{Float64,Array{Float64,2}}:
 0.938485  0.462651  0.622512
 0.960965  0.827826  0.15178 
 0.773617  0.143645  0.565898`

julia> pointer(t.parent)
Ptr{Float64} @0x00007fb0aa55b610

julia> p = permutedims(a)
3×3 Array{Float64,2}:
 0.938485  0.462651  0.622512
 0.960965  0.827826  0.15178 
 0.773617  0.143645  0.565898

julia> pointer(p)
Ptr{Float64} @0x00007fb0aaf30c30

{ A } が多次元配列のとき

permutedims の前後での要素の対応関係は以下のようになる。

$$ \mathrm{permutedims}(A, [p_1, p_2, \cdots, p_n] )[i_{p_1}, i_{p_2}, \cdots, i_{p_n}] = A[i_1, i_2 \cdots i_n] $$

たとえば {(p_1, p_2, p_3) = (2, 3, 1)} とすると $$ \mathrm{permutedims}(A, [2, 3, 1] )[i_{2}, i_{3}, i_{1}] = A[i_1, i_2, i_3] $$

julia> x = rand(2, 3, 4)
2×3×4 Array{Float64,3}:
[:, :, 1] =
 0.358402  0.109111  0.351109
 0.487991  0.634374  0.374851

[:, :, 2] =
 0.937965  0.0958944  0.0710523
 0.334342  0.871918   0.805091 

[:, :, 3] =
 0.836717  0.121055  0.806076
 0.934635  0.990332  0.768735

[:, :, 4] =
 0.822568  0.270672  0.420414
 0.23469   0.985192  0.016411

julia> y = permutedims(x, [2, 3, 1])
3×4×2 Array{Float64,3}:
[:, :, 1] =
 0.358402  0.937965   0.836717  0.822568
 0.109111  0.0958944  0.121055  0.270672
 0.351109  0.0710523  0.806076  0.420414

[:, :, 2] =
 0.487991  0.334342  0.934635  0.23469 
 0.634374  0.871918  0.990332  0.985192
 0.374851  0.805091  0.768735  0.016411

julia> for i₁ in 1:2
           for i₂ in 1:3
               for i₃ in 1:4
                   if x[i₁, i₂, i₃] != y[i₂, i₃, i₁]
                       println("Not match")
                   end
               end
           end
       end