# Matrix Rotation

If I have a matrix of any size, say

$\begin{pmatrix} 72 & 32 & 64 \\ 18 & 8 & 16 \\ 63 & 28 & 56 \\ \end{pmatrix}$

$\begin{pmatrix} 72 & 32 \\ 18 & 8 \\ 63 & 28 \\ \end{pmatrix}$

How can I rotate/transform it exactly 45 Degrees (diagonal becomes row) to look like below matrix (preferably sparse array) (not as image) ? Prefer a generic solution

Imagine looking towards 63 in the above matrix diagonally from 64 and fill the space between numbers with zero  $\begin{pmatrix} 0 & 0 & 64 & 0 & 0 \\ 0 & 32 & 0 & 16 & 0 \\ 72 & 0 & 8 & 0 & 56 \\ 0 & 18 & 0 & 28 & 0 \\ 0 & 0 & 63 & 0 & 0 \\ \end{pmatrix}$

$\begin{pmatrix} 0 & 32 & 0 & 0 \\ 72 & 0 & 8 & 0 \\ 0 & 18 & 0 & 28 \\ 0 & 0 & 63 & 0 \\ \end{pmatrix}$

Background

below function f generates outer product of digits
f = Outer[Times, ##] & @@ IntegerDigits /@ # &
f[{123, 456}]

4   5   6
8   10  12
12  15  18


When this Matrix is rotated 45 degrees

rotate45@f[{123, 456}]

0   0   6   0   0
0   5   0   12  0
4   0   10  0   18
0   8   0   15  0
0   0   12  0   0


Total of rotated matrix results in

Total@rotate45@f[{123, 456}]

4  13       28      27      18


Adding above list in following way result is 123 * 456 .

04
13
28
27
18
56088


I am trying to create a demonstration to depict this in an interesting way will share the details when done. See this for further details

• Great question. :-) – Mr.Wizard Apr 7 '13 at 5:29
• Out of general interest, why do you want to know? – Lucas Apr 7 '13 at 15:15
• @Lucas please see updated details – Prashant Bhate Apr 7 '13 at 17:42
• @PrashantBhate Aha, thanks. – Lucas Apr 8 '13 at 1:01
• @Prashant I notice you never Accepted an answer to this. Do you find all of them lacking? Is there something we can do to improve them? – Mr.Wizard Sep 18 '13 at 18:31

array0 = {{72, 32, 64}, {18, 8, 16}, {63, 28, 56}};
array1 = SparseArray[Band[{# - 1 + Length@array0[[#]], #}, Automatic, {-1, 1}] ->
array0[[#]] & /@ {1, 2, 3}, {5, 5}];
array1 // MatrixForm Update: Generalizing for arbitrary matrix input:

rttF = Function[{mat}, With[{dims = Dimensions[mat]},
SparseArray[Band[{# - 1 + Last@dims, #}, Automatic, {-1, 1}] -> mat[[#]] & /@
Range[First@dims], {Total@dims - 1, Total@dims - 1}]]]


Examples:

 rttF@array0 // MatrixForm mtrx = Partition[CharacterRange["a", "x"], 4];
mtrx // MatrixForm Row[MatrixForm@rttF[mtrx[[;; #, All]]] & /@ {2, 3, 4, 5, 6}] Row[MatrixForm@rttF[mtrx[[All, ;; #]]] & /@ {2, 3, 4}] Update 2: shorter version:

rttF2 = Function[{mat}, With[{m = Last@Dimensions[mat]},
SparseArray[Band[{m + 1 - #, #}] -> Transpose[mat][[#]] & /@ Range[m]]]]

mat = {{72, 32, 64}, {18, 8, 16}, {63, 28, 56}};
With[{j = Length[mat] - 1},
Table[ArrayPad[Riffle[Diagonal[mat, k], 0], Abs[k]], {k, j, -j, -1}]]


For any number of dimensions ( two versions):

rot[m_] := Transpose@SparseArray[ Flatten@Map[Band[#] -> Transpose[m][[#[]]] &,
Permutations /@ IntegerPartitions[Length@m + 1, {2}], {2}]]


or (keeping it short)

rot[m_]:= With[{t = Transpose},
t[SparseArray[Band@#-> t[m][[#[]]]&/@ t@{#, Reverse@#}&@Range@Length@m]]]

s = {{72, 32, 64}, {18, 8, 16}, {63, 28, 56}}
MatrixForm@rot[s] This works with matrix of any size (remove Reverse to get it in other direction)

rotate45[m_] :=
SparseArray@
MapIndexed[
Band[{#2[], Length@m + #2[] - 1}, Automatic, {1, -1}] ->
Reverse@# & , m]

MatrixForm[rotate45[{{72, 32, 64}, {18, 8, 16}, {63, 28, 56}}]]

0   0   64  0   0
0   32  0   16  0
72  0   8   0   56
0   18  0   28  0
0   0   63  0   0

• Slightly shorter, and theoretically one less operation: Band[{0, Length@m - 1} + #2[], Automatic, {1, -1}] & – Mr.Wizard Apr 7 '13 at 8:17

Shorter form of kguler's general function:

f[a_?MatrixQ] := Dimensions[a] /. {y_, x_} :>
SparseArray[Band[{# - 1 + x, #}, Automatic, {-1,1}] -> a[[#]] & ~Array~ y, x + y - {1,1}]

{{72, 32, 64}, {18, 8, 16}, {63, 28, 56}} // f // MatrixForm J. M.'s code in my own style (just because I feel like it):

Table[#2 ~Diagonal~ k ~Riffle~ 0 ~ArrayPad~ Abs[k], {k, #, -#, -1}] &[Length@# - 1, #] &;

{{72, 32, 64}, {18, 8, 16}, {63, 28, 56}} // % // MatrixForm


An old-fashioned I guess rotation of indices.

Turn[m_?MatrixQ] :=
With[{ax = {1, Length[First@m]}},
MapIndexed[Round[Composition[
ScalingTransform[Sqrt {1, 1}, ax],
RotationTransform[Pi/4., ax]]@#2] -> #1 &,
m, {2}]] // Flatten // SparseArray

{{72, 32, 64}, {18, 8, 16}, {63, 28, 56}} // Turn // Normal

(* {{0,0,64,0,0},{0,32,0,16,0},
{72,0,8,0,56},{0,18,0,28,0},{0,0,63,0,0}} *)

Partition[CharacterRange["a", "l"], 3] // Turn // Normal

(* {{0,0,"c",0,0,0},{0,"b",0,"f",0,0},{"a",0,"e",0,"i",0},
{0,"d",0,"h",0,"l"},{0,0,"g",0,"k",0},{0,0,0,"j",0,0}} *)