How do I make a matrix of vectors?

I’m cryptanalyzing a hash function I invented. I get a big amount of data which I want to return as a matrix

normalize(cd0a) normalize(cd0b)
normalize(cd1a) normalize(cd1b)

where the two rows represent using the three S-boxes in a different order and the two columns represent different plaintexts. Each normalize(cd) is a 40-element vector (the number varies) of 255-element vectors of 256-element offset vectors (the number varies, if the whole thing has 44 elements then each innermost offset vector has 288 elements, etc.).

Here’s the end of my function:

  end # of a for loop that computes all the data
  ([round1same0,round2same0,round1same1,round2same1]./(2*iters),
   [normalize(cd0a) normalize(cd0b);normalize(cd1a) normalize(cd1b)])
  #normalize(cd0a)
end

The commented-out line is for debugging; if I uncomment it, I get a 40-element vector. With it commented out, I get a tuple where the first element is a 4-element vector (and it’s correct) and the second element is not the expected 2×2 matrix of 40-element vectors but an 80×2 matrix of 255-element vectors (two 40-element vectors have been concatenated). How do I prevent concatenation and get a 2×2 matrix of vectors?

You can do

reshape([a,b,c,d], 2,2)

to get a 2×2 matrix of vectors, if a,b,c,d are vectors.

Thanks! (Code is still running but I tried reshape([1,2,3,4],2,2).) It should be reshape([normalize(cd0a),normalize(cd1a),normalize(cd0b),normalize(cd1b)],2,2) to get what I want.

It’s not really better than the reshape but another option is to fool the concatenation to work on a wrapping vector.

julia> a, b, c, d = rand(2), rand(2), rand(2), rand(2);

julia> [[a] [b]
        [c] [d]]
2×2 Matrix{Vector{Float64}}:
 [0.668767, 0.556128]  [0.776861, 0.865317]
 [0.170214, 0.638821]  [0.0869913, 0.647021]

An alternative approach is to use TensorCast.jl, which provides control of where each vector element goes in the built matrix:

using TensorCast

V = [a, b, c, d]
@cast M[i,j] := V[i⊗j]  i in 1:2      # "⊗" can be typed by \otimes<tab>

In my eyes the most straightforward approach is to use Matrix{Vector{Vector{Vector{Float64}}}}(undef, 2, 2) or whatever is the appropriate type in your case, and fill it in your loop.

Maybe you meant to use an expression like that :slight_smile:

a,b,c,d=[rand(40) for _ in 1:4]

[[a] [b]; [c] [d]]