# How can I create a class of matrices programmatically?

I am trying to figure out how to create a function that can create the matrix pattern below, where:

f[1] returns {{1}}

f[2] returns {{1,2,2}}, i.e., inserts 2 cells to the back

f[3] returns {{3,3,3}, {{1,2,2}}}, i.e., inserts a row of size 3 in front

f[4] returns {{4,4,3,3,3}, {4,4,1,2,2}}, i.e., inserts 2 new cells in front of both rows

f[5] returns {{4,4,3,3,3}, {4,4,1,2,2}, {5,5,5,5,5}}, i.e., inserts a row of size 5 at the back

and f[12] returns

{
{12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
{12, 12, 8, 8, 7, 7, 7, 7, 7, 7, 7, 10, 10},
{12, 12, 8, 8, 4, 4, 3, 3, 3, 6, 6, 10, 10},
{12, 12, 8, 8, 4, 4, 1, 2, 2, 6, 6, 10, 10},
{12, 12, 8, 8, 5, 5, 5, 5, 5, 6, 6, 10, 10},
{12, 12, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10}
}


The function attaches n number of cells to the current matrix at every iteration in a counter clockwise direction. The odd number cells can be done by inserting a row of size n. for example Insert[{{1, 2, 2}}, ConstantArray[3, 3], 1]

However I am stuck on the even numbered blocks because they would need to be inserted on multiple rows.

Can someone please point me to where I can find how to create such a function?

• How about adding a description of the pattern/rules, rather than having the reader decode it from the example. – ciao Jun 24 '14 at 0:23
• Very closely related: mathematica.stackexchange.com/q/50416/12 – Szabolcs Jun 24 '14 at 0:31
• @rasher - I edited the question which hopefully explains rules for creating such a matrix – spaceKnot Jun 24 '14 at 1:28

I think this does what you want.

f[1] = {{1}};
f[n_?EvenQ] := ArrayPad[f[n - 1], {0, {2 - #, #} &@Mod[n, 4]}, n]
f[n_?OddQ] /; Mod[n, 4] == 3 := Prepend[f[n - 1], ConstantArray[n, n]]
f[n_?OddQ] /; Mod[n, 4] == 1 := Append[f[n - 1], ConstantArray[n, n]]

f[12]


Okay, more to my own liking:

ClearAll[f]

f[1] = BoxMatrix[0] (* produces a packed array *);

f[n_Integer?Positive] :=
ArrayPad[f[n - 1], {{{0, 1}, 0}, {0, {0, 2}}, {{1, 0}, 0}, {0, {2, 0}}}[[ Mod[n, 4, 1] ]], n]


This uses the remainder of the n value to pick a padding specification to give to ArrayPad. It's a bit long but I still like unifying this under ArrayPad.

I also start with a packed array via BoxMatrix which will keep the output smaller and speed computation.

To do: convert recursion to iteration.

• Yes, that is what I was looking for. Thank you! – spaceKnot Jun 24 '14 at 1:49
• @spaceKnot Okay, great. This is not as concise or pretty a solution as I'd like so I'll try to improve it as I have time. Also, thanks for the Accept but I always suggest waiting 24 hours to give everyone around the world a change to respond; you never know the answers you might get. :-) – Mr.Wizard Jun 24 '14 at 1:52
• @spaceKnot. At this point an upvote is more appropriate than an acceptance. You can add your acceptance later, say after 24 hours. This protocol is to encourage alternative answers. – m_goldberg Jun 24 '14 at 1:52
• @Mr.Wizard Good advice on the Accept. I'll wait a little more before accepting. I got excited because your answer gives me direction and more insight to understanding/learning Mathematica. I look forward to an update when you get a chance! – spaceKnot Jun 24 '14 at 1:58
• Yeah, and you've said it before -- to me! Also, you rightly didn't beg for an up-vote, but I want to remind the OP about that. – m_goldberg Jun 24 '14 at 2:02

Late to the party, but I think this kind of neat:

fr[1] = {{1}};
fr[a_] := ArrayPad[fr[a - 1], {{{0, 1}, {0, 0}}, {{0, 0}, {0, 2}}, {{1, 0}, {0, 0}},
{{0,0}, {2, 0}}}[[Mod[a, 4, 1]]], a];


Ah - lol - just saw Mr. Wizard's update...

Edit: Here's an attempt at shaving some size off - just for fun...

fr2[1]={{1}};