Edit: The matGen
and matBuildAux
codes are updated moving the null arrays into the module variable, offering slight readability improvements and even slighter performance improvement on very large submatrices.
This is more of an extended comment than an answer because, as @march has pointed out multiple times, there is more detail required to frame your question.
To get you started, here is a function to generate the two matrices you describe when the variables/submatrices are known
Clear[matGen]
matGen[inits_List] /; AllTrue[inits, AtomQ] && Length[inits] == 4 :=
{{0, inits[[1]], 0}, {inits[[3]], 0, inits[[2]]}, {0, inits[[4]], 0}}
matGen[inits_List] /; Length[inits] == 4 :=
Module[{null = ConstantArray[0, Dimensions[inits[[1]]]]},
{{null, inits[[1]], null},
{inits[[3]], null, inits[[2]]},
{null, inits[[4]], null}} // ArrayFlatten]
matGen[inits_List] /; AllTrue[inits, AtomQ] && Length[inits] == 9 :=
{{0, inits[[1]], inits[[4]], 0},
{inits[[9]], 0, inits[[5]], inits[[6]]},
{inits[[9]], inits[[2]], 0, inits[[3]]},
{inits[[8]], inits[[7]], inits[[7]], 0}}
matGen[inits_List] /; Length[inits] == 9 :=
Module[{null = ConstantArray[0, Dimensions[inits[[1]]]]},
{{null, inits[[1]], inits[[4]], null},
{inits[[9]], null, inits[[5]], inits[[6]]},
{inits[[9]], inits[[2]], null, inits[[3]]},
{inits[[8]], inits[[7]], inits[[7]], null}} //ArrayFlatten]
These are a lazy attempt at generating the matrices and contain very few guards on the input. They mostly assume they're being fed an appropriate list of initial values where:
- The
List
argument is a list containing all the initial values/matrices to build the matrix.
- An A matrix will come from a list of 4 elements, while a B matrix comes from a list of 9 elements.
- If the elements of
List
are not atomic(symbols or numbers usually), then they are equally-sized square matrices.
Examples:
arr = Array[(#1 - 1) 2 + #2 &, {2, 2}];
matGen[{arr, arr, arr, arr}]//MatrixForm
matGen[{a, b, c, d, e, f, g, h, i}]//MatrixForm

How to proceed with the recursive generation then seems rather ambiguous, given the current information, since you have stated that variables/submatrices in the composition are not the same. This leads to the necessity of specifying the initial values for all the submatrices involved at the first level. Just looking at something like the $3+3+2+2$ example, that requires specifying up to $9\times 9\times 4\times 4=1296$ different values for the initial iteration. Further, if the intermediate matrices and all of these values are unique then there needs to be a means of specifying which sets of values are associated with the submatrices at each position, a constraint which needs clarification in your problem description.
If for any reason you were interested in identical submatrices, then this function could take the decomposition represented as an ordered List
and the initial values as an appropriately-sized List
.
Clear[matBuildAux]
matBuildAux[elem_, 2] :=
Module[{null = ConstantArray[0, Dimensions[elem]]},
{{null, elem, null},
{elem, null, elem},
{null, elem, null}} //ArrayFlatten]
matBuildAux[elem_, 3] :=
Module[{null = ConstantArray[0, Dimensions[elem]]},
{{null, elem, elem, null},
{elem, null, elem, elem},
{elem, elem, null, elem},
{elem, elem, elem, null}} // ArrayFlatten]
Clear[matBuild]
matBuild[decomp_List, inits_List] /;
Which[Last[decomp] == 3, Length[inits] == 9, Last[decomp] == 2, Length[inits] == 4] :=
Fold[matBuildAux, matGen[inits], Reverse[Most[decomp]]]
Here's an example
matBuild[{2, 2, 3}, {a, b, c, d, e, f, g, h, i}] // MatrixForm
