# RotateRight ith row of a matrix by i - 1

first time stack exchange poster here! So I was working on a problem, the purpose of which was to write a function in the procedural style to rotate right the ith row of a matrix by i - 1 spaces. Ok, easy enough here was my implementation:

rotateRowsProcedural[mat_?MatrixQ] :=
(
clonedMat = mat;
i = 1;
While[i <= Dimensions[clonedMat][],
clonedMat[[i]] = RotateRight[clonedMat[[i]], i - 1];
i++;
];
clonedMat
)


This was too boring so I decided I wanted to try and solve the problem using pattern matching approach and I came up with

rotateRowsPattern[matrix_?MatrixQ] :=
matrix /. mat : {x__List} :> (RotateRight[#, Position[mat, #][[1, 1]] - 1] & /@ {x}) 


Now I thought this was pretty awesome I mean to me its the essence of Mathematica. However, I then decided to compare the efficiency of the two functions

Mean[Table[Timing[rotateRowsPattern[RandomInteger[{0, 10},{1000, 1000}]]][], {100}]]


0.038844

Mean[Table[Timing[rotateRowsProcedural[RandomInteger[{0,10},{1000,1000}]]][], {100}]]


0.0165361

I was surprised that the procedural implementation was faster. Then I thought it over and I think it is the case that calling Position in the pattern implementation must slow things down. My question then is if I want to use pattern matching how can I reference the location of x (from x__List) so that I don't have to call Position.

Also, I'm aware that combining Map and Range would be the most concise way to do this but I'm interested in the pattern matching.

• "Map and Range would be the most concise way..." - nope. There's MapIndexed[]... – J. M.'s technical difficulties May 30 '13 at 6:00
• This isn't using pattern matching but for a speed up this may help: rr[rin_] := (RotateRight[rin[[#]], # - 1] & /@ Range[Length[rin]]). – Jonathan Shock May 30 '13 at 6:07
• I would also define your functions as Module as you are defining global variables (clonedmat) within them. It's best to keep track of the scope of such variables when you can. – Jonathan Shock May 30 '13 at 6:09
• @LarryS, please feel free to ignore my comment in that case. You are right that you did explicitly say that and I had missed that point in your post, my apologies. – Jonathan Shock May 30 '13 at 6:22
• @LarryS Be civil. People are only attempting to be helpful. Leaving stray global symbols in your function is bad programming practice and code exhibiting such will often be remarked upon. – Mr.Wizard May 30 '13 at 6:27

Since the summary of your question is:

My question then is if I want to use pattern matching how can I reference the location of x (from x__List) so that I don't have to call Position.

I believe it is a duplicate of: Position of a pattern-matched part of an expression

Nevertheless in an effort to be helpful I would like to comment on your code.

Your procedural function should use Module to localize the Symbols that you use. It would also be more efficient to calculate the dimensions only once:

rotateRowsProcedural[mat_?MatrixQ] :=
Module[{clonedMat = mat, i = 1, dims = Dimensions[mat][]},
While[i <= dims, clonedMat[[i]] = RotateRight[clonedMat[[i]], i - 1]; i++;];
clonedMat
]


Your pattern based function is a bit confusing. The pattern matching is purely incidental to the operation of the function itself which could be written simply:

rotateRowsPattern[matrix_?MatrixQ] :=
RotateRight[#, Position[matrix, #][[1, 1]] - 1] & /@ matrix


But both this function and yours will fail of there are repeated rows in the matrix.

You will see from the linked question above that there is no known easy and general solution to the problem of getting the position of a matched pattern. However, for this simple application you can simply increment a counter for each row that is matched, which is perhaps in the spirit of what you intend:

rotateRows1[m_?MatrixQ] :=
Module[{i = 0}, m /. x_?VectorQ :> RotateRight[x, i++]]


Still, this might be better formulated without the pattern matching as:

rotateRows2[m_?MatrixQ] := Module[{i = 0}, RotateRight[#, i++] & /@ m]


But this is really nothing more than a manual implementation of MapIndexed:

rotateRows3[m_?MatrixQ] := MapIndexed[RotateRight[#, #2[] - 1] &, m]

• One could of course do Length[mat] instead of Dimensions[mat][]. Using While[] here looks a bit clunky; I'd have used Do[] myself. – J. M.'s technical difficulties May 30 '13 at 6:39
• @J.M. Agreed. I was attempting to work with the OP's style, for what it's worth. – Mr.Wizard May 30 '13 at 6:55
• @Mr.Wizard (of Oz) thanks for the link. I'm somewhat disappointed that matched elements from the pattern matcher don't know by default their position but thus is life. – John Smith May 30 '13 at 15:16

You could consider using MapIndexed just to "tag" each row with its row number and then use a replacement rule from there:

rot[mat_] := MapIndexed[List, mat] /. {x_, i_} :> RotateRight[x, i - 1]


Faster, but less readable, is to use Transpose and Range instead of MapIndexed:

rot[mat_] := Transpose[{mat, Range@Length@mat}] /. {x_, i_} :> RotateRight[x, i - 1]
`