Convert 2d matrix to 3d

I have a large matrix, n x m in size.

I like to convert it to a 3d matrix, taking k rows at a time. n is always divisible by k.

newmatrix’s dimensions should be ‘k x M x n/k’

newmatrix[:,:,1] .= bigmat[1:k,:]
newmatrix[:,:,2] .= bigmat[k+1:2k,:]
newmatrix[:,:,3] .= bigmat[2k+1:3k,:]

I’ve tried reshape and permutedims so far with no luck.

I guess I could create the new matrix and write a loop to do the indexing and assigning. I figured there would be an easier way.

Thanks for any help.

1 Like

I made a package for doing such things, when I got tired of getting the permutations wrong by hand:

julia> using TensorCast

julia> N,M,K = 6,7,2; bigmat = rand(Int8,N,M)
6×7 Matrix{Int8}:
 -115  -123   56    64   -60   -99  102
   16     7    5   -97   -56  -101  -19
   79   119  -88  -110   -51   113   62
   21  -125   32    81  -125   105  -50
  -57    15  -34     3    85   -67    8
 -116    17  -11    67  -109  -104   25

julia> @cast out[i,m,k] := bigmat[(i,k),m]  k:K
3×7×2 PermutedDimsArray(::Array{Int8, 3}, (1, 3, 2)) with eltype Int8:
[:, :, 1] =
 -115  -123   56    64  -60   -99  102
   16     7    5   -97  -56  -101  -19
   79   119  -88  -110  -51   113   62

[:, :, 2] =
   21  -125   32  81  -125   105  -50
  -57    15  -34   3    85   -67    8
 -116    17  -11  67  -109  -104   25

julia> @pretty @cast out[i,m,k] := bigmat[(i,k),m] k:K
begin
    @assert_ ndims(bigmat) == 2 "expected a 2-tensor bigmat[(i, k), m]"
    local (sz_i, sz_k, sz_m) = (:, K, size(bigmat, 2))
    local quetzal = PermutedDimsArray(reshape(bigmat, (sz_i, sz_k, sz_m)), (1, 3, 2))
    out = quetzal
end

julia> out == permutedims(reshape(bigmat, :,K,M),(1,3,2))
true

Here k:K means for k in 1:K, and (i,k) is a combined index, with i changing fastest.

4 Likes