# Matrix expansion and reorganisation

I have a matrix (not square one) with an elements that are repeating, for example:

Starting from second column, I need to shift up each column in order to align in rows elements with the same values. Empty elements of a new matrix should be replaced by the zeros. In result I should have:

Then the same pattern of a shift I should be able to apply to any other matrix with the same dimensions as the original one (but this time without such nicely repeating numbers as elements).

EDIT:

Sorry I was not very specific in my question.

I have two matrixes. One n x m, lets call it MAIN, with results that I have to process (with some more or less random numbers), and second n x m, lets call it AUXILIARY, that is an indication how the first has to be processed (matrix from my example, with repeating numbers).

I need to analysie the auxiliary matrix in a way I've described in my question and find about how many positions I have to shift each column. In my example I need to shift 1st column by 0 positions, 2nd by 1 position up etc.

Then I need to apply the same pattern to the main matrix. So 1st column of main matrix is unchanged, 2nd should be shifted by 1 position up etc.

I hope now it's more clear.

• I'm not giving an answer since I'm not entirely sure what you mean by "I should be able to apply to any other matrix with the same dimensions as the original one (but this time without such nicely repeating numbers as elements)", but for your specific example: Transpose[MapThread[ArrayPad, {Transpose[{{4, 5, 6, 7, 8}, {3, 4, 5, 6, 7}, {2, 3, 4, 5, 6}, {1, 2, 3, 4, 5}}], Reverse[FrobeniusSolve[{1, 1}, 4]]}]] Commented Nov 2, 2017 at 17:18

mat = {{4, 5, 6, 7, 8}, {3, 4, 5, 6, 7}, {2, 3, 4, 5, 6}, {1, 2, 3, 4, 5}};
MapIndexed[RotateLeft[PadLeft[#1, 8], #2 - 1] &, Transpose[mat]] //Transpose//MatrixForm


$\begin{pmatrix} 0 & 0 & 0 & 0 & 8 \\ 0 & 0 & 0 & 7 & 7 \\ 0 & 0 & 6 & 6 & 6 \\ 0 & 5 & 5 & 5 & 5 \\ 4 & 4 & 4 & 4 & 0 \\ 3 & 3 & 3 & 0 & 0 \\ 2 & 2 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 & 0 \\\end{pmatrix}$

ClearAll[f1, f2]
f1 = SparseArray@MapIndexed[Band[{#2[[1]], -1}, Automatic, {1, -1}]->#&, Reverse /@ #] &;

f2 = Module[{i = 1}, SparseArray[Band[{i++, -1}, Automatic, {1, -1}] ->
Reverse[#] & /@ #]] &;


Examples:

mat = Reverse @ Partition[Range[8], 5, 1];
mat // MatrixForm // TeXForm


$\left( \begin{array}{ccccc} 4 & 5 & 6 & 7 & 8 \\ 3 & 4 & 5 & 6 & 7 \\ 2 & 3 & 4 & 5 & 6 \\ 1 & 2 & 3 & 4 & 5 \\ \end{array} \right)$

f1 @ mat // MatrixForm // TeXForm


$\left( \begin{array}{ccccc} 0 & 0 & 0 & 0 & 8 \\ 0 & 0 & 0 & 7 & 7 \\ 0 & 0 & 6 & 6 & 6 \\ 0 & 5 & 5 & 5 & 5 \\ 4 & 4 & 4 & 4 & 0 \\ 3 & 3 & 3 & 0 & 0 \\ 2 & 2 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

f1 @ mat == f2 @ mat


True

• In the same vein: Reverse[SparseArray[MapIndexed[Band[Append[#2, 1]] -> #1 &, Reverse[{{4, 5, 6, 7, 8}, {3, 4, 5, 6, 7}, {2, 3, 4, 5, 6}, {1, 2, 3, 4, 5}}, 2]]], 2]. Commented Nov 2, 2017 at 17:24
• Thank you @J.M. I added something along the line you suggested.
– kglr
Commented Nov 2, 2017 at 17:38

(This answer describes how to perform a given set of shifts to an arbitrary matrix. I do not answer the question about how to determine what these shifts should be.)

For your given matrix, you need to shift each column upwards by 0, 1, 2, 3, and 4 respectively. This can be achieved as follows:

shiftMatrix[mat_, shift_] := Transpose @ PadLeft @ MapThread[
PadLeft[#1, Length[mat] + #2, 0, #2]&,
{Transpose[mat], shift}
]

shiftMatrix[mat, {0, 1, 2, 3, 4}] //TeXForm


$\left( \begin{array}{ccccc} 0 & 0 & 0 & 0 & 8 \\ 0 & 0 & 0 & 7 & 7 \\ 0 & 0 & 6 & 6 & 6 \\ 0 & 5 & 5 & 5 & 5 \\ 4 & 4 & 4 & 4 & 0 \\ 3 & 3 & 3 & 0 & 0 \\ 2 & 2 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

You can call shiftMatrix with a different matrix, but the same shifts. For example:

shiftMatrix[RandomInteger[10, {4, 5}], {0, 1, 2, 3, 4}] //TeXForm


$\left( \begin{array}{ccccc} 0 & 0 & 0 & 0 & 4 \\ 0 & 0 & 0 & 7 & 1 \\ 0 & 0 & 7 & 2 & 2 \\ 0 & 10 & 9 & 2 & 4 \\ 1 & 4 & 2 & 9 & 0 \\ 4 & 2 & 10 & 0 & 0 \\ 2 & 3 & 0 & 0 & 0 \\ 9 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

• Thank you very much for the solution of the shift. Commented Nov 8, 2017 at 8:59