Soma
Soma

Reputation: 743

Make a matrix of matrices

I want to have a matrix whose elements are matrices too.

For example

A=[[1 2 3;3 4 1;2 3 6]  [1 4 5;4 8 7;2 0 1];[1 5 8;6 4 7;2 0 0]  [2 1 5;4 7 7;2 4 6]]

How can I make this matrix in Julia?

Upvotes: 2

Views: 1238

Answers (5)

Kipton Barros
Kipton Barros

Reputation: 21112

Yes, there is a nice syntax available! The trick is to add extra brackets [...] that wrap each block sub-matrix. Here is the syntax:

# These are arbitrary
a11 = [1 2 3; 3 4 1; 2 3 6]
a21 = [1 4 5; 4 8 7; 2 0 1]
a12 = [1 5 8; 6 4 7; 2 0 0]
a22 = [2 1 5; 4 7 7; 2 4 6]

# This is the trick to construct a matrix from blocks
A = [[a11] [a12]; [a21] [a22]]

# Verify that it works
@assert A[1,1] == a11
@assert A[2,1] == a21
@assert A * [4, 5] == [4*a11 + 5*a12, 4*a21 + 5*a22]

Upvotes: 0

A.Yazdiha
A.Yazdiha

Reputation: 1378

You can create an empty matrix of the aformentioned dimensions first by :

X = zeros(Int64, (3, 3,4))

You can further assign each matrix accordingly:

X[:,:,1] = [1 2 3;3 4 1;2 3 6]
X[:,:,2] = [1 4 5;4 8 7;2 0 1]
X[:,:,3] = [1 5 8;6 4 7;2 0 0]
X[:,:,4] = [2 1 5;4 7 7;2 4 6]

And the matrix X is :

julia > X
julia > 3×3×4 Array{Int64,3}:
[:, :, 1] =
1  2  3
3  4  1
2  3  6

[:, :, 2] =
1  4  5
4  8  7
2  0  1

[:, :, 3] =
1  5  8
6  4  7
2  0  0

[:, :, 4] =
2  1  5
4  7  7
2  4  6

An easier thing to do is to read every element as is by a vector and reshape it.

x = [1,2,3,3,4,1,2,3,6,1,4,5,4,8,7,2,0,1,1,5,8,6,4,7,2,0,0,2,1,5,4,7,7,2,4,6]
x = reshape(x, (3, 3, 4))

This will result in 4 matrices that need a transpose, so for that you can use the permutedims as folows to change the order of the first and second dimensions(each matrix):

 permutedims(x,(2,1,3))

Upvotes: 0

Liso
Liso

Reputation: 2260

I don't know why Julia has this (from my POV strange) property:

julia> [1 2 [3 4]]
1×4 Array{Int64,2}:
 1  2  3  4

But we could use it to make this trick:

julia> A=[[[1 2 3;3 4 1;2 3 6]] [[1 4 5;4 8 7;2 0 1]];
          [[1 5 8;6 4 7;2 0 0]] [[2 1 5;4 7 7;2 4 6]]]

Another strange possibility is (be aware that it is visually transposed!):

julia> A=hcat([[1 2 3;3 4 1;2 3 6], [2 1 5;4 7 7;2 4 6]], 
              [[1 4 5;4 8 7;2 0 1], [1 5 8;6 4 7;2 0 0]])

or (this needs to be visually transposed too!)

julia> A=reshape([[1 2 3;3 4 1;2 3 6], [2 1 5;4 7 7;2 4 6], 
                  [1 4 5;4 8 7;2 0 1], [1 5 8;6 4 7;2 0 0],], 
                 (2,2))

Edit: Ad your additional question - you could create Array of desired length and then use reshape:

U = reshape(Matrix{Float64}[zeros(8, 5) for i in 1:20*20], (20,20));

Upvotes: 1

Dan Getz
Dan Getz

Reputation: 18227

A = first.([([1 2 3;3 4 1;2 3 6],) ([1 4 5;4 8 7;2 0 1],);
            ([1 5 8;6 4 7;2 0 0],) ([2 1 5;4 7 7;2 4 6],)])

works (on Julia 0.6). Making elements tuples stops the fusing of the submatrices and then first. untuples them.

Upvotes: 3

AmanicA
AmanicA

Reputation: 5513

I'm not sure about a shorthand / literal, but you can construct it and then populate it:

B=Matrix{Matrix}(3,3)
Out[4]:
3×3 Array{Array{T,2} where T,2}:
 #undef  #undef  #undef
 #undef  #undef  #undef
 #undef  #undef  #undef
B[1,1]=[1 2 ; 3 4]
B
Out[8]:
3×3 Array{Array{T,2} where T,2}:
    [1 2; 3 4]  #undef  #undef
 #undef         #undef  #undef
 #undef         #undef  #undef

Upvotes: 1

Related Questions