4
$\begingroup$

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

Original matrix

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:

New matrix

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).

Could someone please help me solve this problem?

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.

Thanks for your help.

$\endgroup$
1
  • $\begingroup$ 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]]}]] $\endgroup$ Nov 2, 2017 at 17:18

3 Answers 3

4
$\begingroup$
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}$

$\endgroup$
3
$\begingroup$
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

$\endgroup$
2
  • $\begingroup$ 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]. $\endgroup$ Nov 2, 2017 at 17:24
  • $\begingroup$ Thank you @J.M. I added something along the line you suggested. $\endgroup$
    – kglr
    Nov 2, 2017 at 17:38
2
$\begingroup$

(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)$

$\endgroup$
1
  • $\begingroup$ Thank you very much for the solution of the shift. $\endgroup$
    – wojtek009
    Nov 8, 2017 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.