# How generalizes (automate) recursive code

This is a small version of my code (for n=2):

V0 = {{{3, 3, 2, 2}}};
S0 = {{{1, 2, 0, 4}}, {{0, 3, 2, 2}}, {{2, 2, 0, 3}}, {{1, 2, 1, 2}}};
S1 = Join @@@ Tuples[{S0, V0}];
S2 = Pick[DeleteDuplicatesBy[Sort]@S1,
MatrixRank[#] == 2 & /@ DeleteDuplicatesBy[Sort]@S1];
S3 = Join @@@ Tuples[{S0, S2}];
S4 = Pick[DeleteDuplicatesBy[Sort]@S3,
MatrixRank[#] == 3 & /@ DeleteDuplicatesBy[Sort]@S3];
S5 = Join @@@ Tuples[{S0, S4}];
S6 = Pick[DeleteDuplicatesBy[Sort]@S5,
MatrixRank[#] == 4 & /@ DeleteDuplicatesBy[Sort]@S5];
MatrixForm /@ S6


As you can see, it repeats the action of joining the matrices with the last set, deleting the duplicates and picking those with maximal rank. The final result is a set of 4×4 matrices. In general, for a given $n\in\Bbb N$, I have to manually write $2(n^n-1)$ lines. Is there I way to automate this procedure?

The aim of the code: Obtain the set of all invertible matrices with {3,3,2,2} as the first line and elements of S0 as the other ones.

I could generate the the set of $3\times4$ matrices formed by elements of S0 and then Prependthe vector {3,3,2,2} to each one, but the task "pick those with rank 4" (or "with non null determinant") is harder for the computer. Because of this, I add one line per time and take out those matrices whose rank is not maximal. The example above is very easy, but for sets with 1 million matrices, calculate the rank of each one may take a while.

• You may find Fold or Nest helpful, but to help further, could you explain in words what you are trying to achieve with your code? – MarcoB Oct 2 '17 at 18:37
• @MarcoB Just added to the OP. Tell me if there is something more that deserves a better explanation. – Filburt Oct 2 '17 at 18:50

One way:

f[S0_, {i_, V0_}] := Module[{S1, S2},
S1 = Join @@@ Tuples[{S0, V0}];
S2 = Pick[DeleteDuplicatesBy[Sort]@S1, MatrixRank[#] == i & /@ DeleteDuplicatesBy[Sort]@S1];
{i + 1, S2}
]

MatrixForm /@ Last@Nest[f[S0, #] &, {2, V0}, 3]


• Thanks for your answer. Could you please help me to understand your code? I want to know for example what makes the action repeat and what makes it stop. In the case of matrices $9\times9$, what I have to change in your code? I am really new on Mathematica, so I am not understanding the Module Documentation. Is there a place with better explained examples about module? – Filburt Oct 2 '17 at 22:57
• @Fil, why not try plugging in a matrix and vector with appropriate dimensions yourself? Note that C. E.'s code never needed to determine the dimensions of the matrices involved. As for Module[]: if you're writing functions for personal use, you'll use it a lot to encapsulate an algorithm and localize any intermediate variables used. – J. M. will be back soon Oct 2 '17 at 23:50
• @J.M. But for bigger dimensions, you have to repeat more times those two lines inside Module. As I wrote in the OP, for $n\in\Bbb N$ there will be $2(n^n-1)$ lines. If this code put two lines each time, so we will have to tell him to repeat $n^n-1$ times. It corresponds to the number 3 inside Nest, isn't it? ($2^2-1$) – Filburt Oct 3 '17 at 0:07
• In that case, @Fil, then the responsibility of determining the right dimensions is on you and not on C. E.'s routine, no? I'm only saying that C. E. had written his routine to be independent of dimensions. So, if you'll be doing anything before or after this routine that is dimension-dependent, then that's your call. – J. M. will be back soon Oct 3 '17 at 1:14
• @Fil, The 2 in the last line is just the desired rank. If you look at the code for f[], note that the argument i corresponds to what is being compared with MatrixRank[]. In Nest[], this is passed along to f[]. (Recall that Nest[f, x, 3] is another way to write f[f[f[x]]].) – J. M. will be back soon Oct 3 '17 at 1:27