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][[1]], 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}]]][[1]], {100}]] 0.038844
Mean[Table[Timing[rotateRowsProcedural[RandomInteger[{0,10},{1000,1000}]]][[1]], {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.



MapandRangewould be the most concise way..." - nope. There'sMapIndexed[]... $\endgroup$rr[rin_] := (RotateRight[rin[[#]], # - 1] & /@ Range[Length[rin]]). $\endgroup$Moduleas you are defining global variables (clonedmat) within them. It's best to keep track of the scope of such variables when you can. $\endgroup$