ujimushi(@旧sradjp(15364))の日記

旧スラドの日記の引越先です

Using Luxor.Table to visualize Julia 2D matrix results in transposed view [勝手に回答]

調子に乗って続けて書いてみる「勝手に回答」シリーズ。今回は Using Luxor.Table to visualize Julia 2D matrix results in transposed view 。前回に引き続きJulia Discourseの質問です。

Luxor.TableとJuliaの二次元行列を一次元で参照していく時の順番がそれぞれ行,列で方向が 違うけど,CartesinanIndices()permutedims(m)は使いたくないとのことです。

っていうか,こういう時は転置行列を作るtranspose()を使うのがお約束。

質問のソースリストの

for n in eachindex(table)
    Luxor.text(string(m[n]), table[n], halign=:center, valign=:middle)
end

の部分を

for (n, k) in zip(eachindex(table), transpose(m))
    Luxor.text("$k", table[n], halign=:center, valign=:middle)
end

に変更するだけでOKです。一応次が結果画像。

確かにpermutedims(m)は実際にメモリを確保して転置するのでサイズが大きいと遅くて メモリをたくさん消費します。

transpose()と比較してみます。

julia> m_big = rand(1000, 10000);

julia> @time permutedims(m_big);
  0.140805 seconds (2 allocations: 76.294 MiB, 59.17% gc time)

julia> @time transpose(m_big);
  0.000003 seconds (1 allocation: 16 bytes)
  
julia> permutedims(m_big) == transpose(m_big)
true

permutedims()が76MB使っているのに対し,transpose()は16byte, これは,m_bigを転置してるぜという情報と元行列の参照だけを 確保しているだけで,実際には計算していないためだと思います。

このtransposeが使えるのは,全て数値の行列の時だけで, How to transpose Matrix{Any} that contains strings?のように文字列とかが入っていると transpose()は使えないということになります。