How to build a matrix from a set of vectors and other matrices using ArrayFlatten

TL;DR;

myArrayFlatten = Flatten /@ Flatten[#, {{1, 3}}] & 

{x,y,z} or {{x},{y},{z}} is considered column vector.

Usage example:

v1 = {1, 2, 3}; vNew = {{4, 5}, {6, 7}, {8, 9}};
v4 = {10, 11, 12}; v5 = {13, 14, 15}; v6 = List /@ {16, 17, 18};

{
 {v1, vNew, v1},
 {v4, v5, v6, v1},
 {vNew, vNew}
} // myArrayFlatten // MatrixForm

enter image description here

Flatten approach:

The fact that it is not working is due to:

In ArrayFlatten[{{m11, m12, ...},{m21, m22, ...},...}] all the matrices m_ij in the same row must have the same first dimension, and matrices m_ij in the same column must have the same second dimension.

and

ArrayFlatten[a] is normally equivalent to Flatten[a,{{1,3},{2,4}}]

is not our "normal(ly)" case! Beacuse it works when stated expicitly:

blocks = {{v1, vNew}, {v4, v5, v6}} // Replace[#, x_?VectorQ :> Transpose@List@x, {2}] &;

blocks // Flatten[#, {{1, 3}, {2, 4}}] &
blocks // ArrayFlatten
{{1,4,5},{2,6,7},{3,8,9},{10,13,16},{11,14,17},{12,15,18}}

ArrayFlatten[{{{{1},{2},{3}},{{4,5},{6,7},{8,9}}},{{{10},{11},{12}},{{13},{14},
               {15}},{{16},{17},{18}}}}]

Not always though, will fail for example for: {{v1, vNew}, {vNew, v6}}. So let's just do the first flip and then Map with Flatten, so at the end you can use:

myArrayFlatten = Flatten /@ Flatten[#, {{1, 3}}] & 

it automatically takes {x,y,z} to be column vector.

I don't understand everything well enough that I can post here quick explanation but a good start to learn more is in Flatten command: matrix as second argument


old anser, working but ugly

I really don't know why it is not that simple :/.

I hope I've not missed anything, this function will help you if dimensions are ok. So don't expect anything like build block matrix.

toMatrix = Composition[

  Join @@ # &,
  Join[##, 2] & @@@ # &,
  Replace[#, x_?VectorQ :> Transpose@List@x, {2}] &

  ]

Replace part is only in case someone provides {x,y,z} lists and want them to be column vectors.

toMatrix@{
 {vNew, vNew, v1},
 {v1, v4, v1, vNew}
} // MatrixForm

enter image description here


First a simpler way to get your first example:

(m = ArrayFlatten[Transpose /@ {{v1, v2, v3}, {v4, v5, v6}}, 1]) // MatrixForm

enter image description here

An alternative way to do @bill's undoing trick:

(m2 = ArrayFlatten[Transpose /@ {{v1, ## & @@ Transpose[vNew]}, {v4, v5, v6}}, 1]) // MatrixForm

enter image description here

Using ArrayReshape as an alternative to ArrayFlatten:

ArrayReshape[Transpose /@ {{v1, vNew}, {v4, v5, v6}}, {6, 3}] // MatrixForm

enter image description here


How about just breaking up the matrix and then reconstructing the same way. Here are your source vectors

v1 = {1, 2, 3}; vNew = {{4, 5}, {6, 7}, {8, 9}};
v4 = {10, 11, 12}; v5 = {13, 14, 15}; v6 = {16, 17, 18};

So now define and reconstruct:

{v2, v3} = Transpose[vNew]; 
ArrayFlatten[{Transpose@{v1, v2, v3}, Transpose@{v4, v5, v6}}, 1] // MatrixForm

If you want to do it all in one command:

ArrayFlatten[{Transpose@Partition[Flatten[{v1, Transpose@vNew}], 3], Transpose@{v4, v5, v6}}, 1]