3

I can't find an answer to this simple question.

I have the following:

A(a,j)=[a*j*i*k for i in 1:2, k in 1:2];

B=[A(a,j) for a in 1:2, j in 1:2];

B is a an array of arrays: 2×2 Array{Array{Int64,2},2}. This is useful to easily access the subarrays with indices (e.g., B[2,1]). However, I also need to convert B to a 4 by 4 matrix. I tried hcat(B...) but that yields a 2 by 8 matrix, and other options are worse (e.g., cat(Test2...;dims=(2,1))).

Is there an efficient way of writing B as a matrix while keeping the ability to easily access its subarrays, especially as B gets very large?

2
  • Do you mean doing something like [B[1,1] B[1,2]; B[2,1] B[2,2]] ? Commented Oct 6, 2020 at 20:51
  • Yes, that's what I meant. Should have said it explicitly. Commented Oct 7, 2020 at 7:33

2 Answers 2

5

Do you want this:

julia> hvcat(size(B,1), B...)
4×4 Array{Int64,2}:
 1  2  2   4
 2  4  4   8
 2  4  4   8
 4  8  8  16

or without defining B:

julia> hvcat(2, (A(a,j) for a in 1:2, j in 1:2)...)
4×4 Array{Int64,2}:
 1  2  2   4
 2  4  4   8
 2  4  4   8
 4  8  8  16
Sign up to request clarification or add additional context in comments.

1 Comment

Perfect! Thanks so much!
3

What about

B = reduce(hcat, reduce(vcat, A(a,j) for a in 1:2) for j in 1:2)

EDIT: Actually this is very slow, I would recommend making a function, e.g.,

function buildB(A, n)
    A0 = A(1,1)
    nA = size(A0, 1)
    B = Array{eltype(A0),2}(undef, n * nA, n * nA)
    for a in 1:n, j in 1:n
        B[(a-1)*nA .+ (1:nA), (j-1)*nA .+ (1:nA)] .= A(a,j)
    end
    return B
end

or maybe consider a package like BlockArrays.jl?


EDIT 2 This is an example with BlockArrays.jl:

using BlockArrays
function blockarrays(A, n)
    A0 = A(1,1)
    nA = size(A0, 1)
    B = BlockArray{eltype(A0)}(undef_blocks, fill(nA,n), fill(nA,n))
    for a in 1:n, j in 1:n
        setblock!(B, A(a,j), a, j)
    end
    return B
end

which should do what you want:

julia> B = blockarrays(A, 2)
2×2-blocked 4×4 BlockArray{Int64,2}:
 1  2  │  2   4
 2  4  │  4   8
 ──────┼───────
 2  4  │  4   8
 4  8  │  8  16

julia> getblock(B, 1, 2)
2×2 Array{Int64,2}:
 2  4
 4  8

julia> B[4,2]
8

2 Comments

Thanks! This one seems like a good option, but @Bogumił-Kamiński's answer seems to do it nicely so I'm accepting that answer.
You're welcome! Yes, Bogumil's answer is good! The benefit of BlockArrays is that you have the standard indexing but you also get the subarray/block indexing, which is what I thought you wanted there: > Is there an efficient way of writing B as a matrix while keeping the ability to easily access its subarrays, especially as B gets very large?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.